On 23 April 2015 at 03:49, Edgar E. Iglesias <edgar.igles...@gmail.com> wrote: > On Wed, Apr 22, 2015 at 12:09:21PM -0500, Greg Bellows wrote: >> void HELPER(wfe)(CPUARMState *env) >> { >> CPUState *cs = CPU(arm_env_get_cpu(env)); >> + int target_el = check_wfx_trap(env, true); >> >> /* Don't actually halt the CPU, just yield back to top >> * level loop >> */ >> - cs->exception_index = EXCP_YIELD; >> + if (target_el) { >> + cs->exception_index = EXCP_UDEF; >> + env->exception.syndrome = syn_wfx(1, 0xe, true); >> + env->exception.target_el = target_el; >> + env->pc -= 4; >> + } else { >> + cs->exception_index = EXCP_YIELD; >> + } >> cpu_loop_exit(cs); >> } > > > Hi Greg, > > Before trapping, don't you need to check that the CPU has no actual work? > e.g: > if (!cc->has_work(cs) && ..)
We don't track WFE-wakeup events, so we must always trap. (Well, I suppose strictly we could also go for "never trap" on the basis that really our implementation here is pretty much a NOP, but I think always-trap is closer to reasonable.) In theory you could maybe check has_work() for the WFI case, since doing an EXCP_HLT really should cause us to stop until has_work is true, but it seems a bit fragile -- could we really guarantee that nothing would change between this point and when we went back through the main loop that would change whether has_work evaluates true or not? I think that it's better there too to just always take the trap: setting EXCP_HLT is our "going into a low power state" and so we should take the trap if we would otherwise have done that. > I think you can still EXCP_YIELD the core if it has work though > as it's probably a good place to reschedule other CPUs in our > single-threaded SMP model. That is indeed the only reason we do anything with WFE at all (it used to be a no-op, but yielding gives better performance). -- PMM