On 05/20/2011 02:30 PM, Max Filippov wrote: > - cycles fed into advance_ccount may (and on real hardware actually > do) depend on executed commands/pipeline/cache hits. Most of this > stuff may be counted at the translation time;
Since CCOUNT, as seen by any one thread of execution, on real hw depends on cache hits, interrupts, and other asynchronous stuff, then don't bother trying to account for it on a per-instruction basis. Just define a clock that runs at a given rate and be done. No need to advance it manually. > - timer_irq is a helper that raises IRQ generated by CCOMPARE match; That's what the callback from qemu_new_timer_ns is for. You've got N CCOMPARE registers, you can create N timers all of which are setup to raise the IRQ. cpu_xtensa_init(...) { ... for (i = 0; i < N; ++i) env->ccompare_timer[i] = qemu_new_timer(vm_clock, HZ, xtensa_ccompare_cb, env); } void xtensa_ccompare_cb(CPUState *env) { /* Set something in the processor state. */ cpu_interrupt(env, CPU_INTERRUPT_HARD); } void HELPER(wsr_ccompare)(int which, uint32_t match) { qemu_mod_timer(env->ccompare_timer[which], match); } > - waiti is a helper for the instruction of the same name; Sure, this one should exist for the translator. But it should do nothing except change PS.INTLEVEL, set env->halted, and do cpu_loop_exit. All of the actual waiting should be in the main QEMU loop. Because it exits to the main loop, it should also end the TB. > - check_interrupts converts IRQs on enabled interrupt sources into current > irq level. This is needed during do_interrupt, but should not be used by the translator itself. You may find some of this easier if you utilize the IRQ cleanup patch series that was recently committed to HEAD. See CPU_INTERRUPT_TGT_EXT_[0-4] in cpu-all.h and its uses in the various targets. r~