Эмуляция QEMU обычно не пытается эмулировать фактические тактовые линии, которые посылают импульсы с частотой в мегагерц (это было бы невероятно неэффективно).Вместо этого, когда гость программирует устройство таймера, модель устройства таймера устанавливает внутренний таймер QEMU для срабатывания после соответствующей продолжительности (и обработчик для этого затем вызывает линию прерывания или делает все необходимое для эмуляции поведения аппаратного обеспечения).Длительность рассчитывается из значений, которые гость записал в регистры устройства, вместе со значением, равным тактовой частоте.
QEMU не имеет никакой инфраструктуры для обработки таких вещей, как программируемые делители тактовых импульсов или "«дерево часов», которое направляет сигналы часов вокруг SoC (можно добавить, но пока никто не дошел до него).Вместо этого таймерные устройства обычно либо записываются с жестко заданной частотой, либо могут быть записаны так, чтобы иметь свойство QOM, позволяющее устанавливать частоту с помощью кода платы или кода модели SoC, который их создает.
В частности, дляустройство SysTick в моделях Cortex-M текущей реализации запрограммирует используемый им таймер QEMU с длительностями, соответствующими частоте:
- 1 МГц, если гость установил бит CLKSOURCE в 1 (процессорclock)
- что-то, что модель платы сконфигурировала с помощью глобальной переменной system_clock_scale (например, 25 МГц для плат mps2), если гость установил CLKSOURCE в 0 (внешняя опорная частота)
(Глобальный system_clock_scale должен быть установлен в NANOSECONDS_PER_SECOND / clk_frq_in_hz.)
1 МГц - это просто глупое жестко закодированное значение, которое еще никто не удосужился улучшить, потому что мы не сталкивались с гостевым кодом, который заботитсяеще.Глобальный system_clock_scale неуклюж, но работает.
Ничто из этого не влияет на скорость эмулируемого ЦПУ QEMU (т.е. сколько инструкций он выполняет за данный период времени).По умолчанию процессоры QEMU будут работать «как можно быстрее».Вы можете использовать опцию -icount, чтобы указать, что вы хотите, чтобы ЦП работал с определенной частотой относительно реального времени, что неявно устанавливает частоту ЦП, но это только примерно устанавливает среднее значение - некоторые инструкциибудет работать намного быстрее, чем другие, не очень предсказуемым образом.В целом философия QEMU заключается в том, чтобы «запускать гостевой код так быстро, как мы можем», и мы не предпринимаем никаких попыток что-либо приблизиться к эмуляции с точностью до цикла или иным образом строго синхронизированной.