WFE指令的基本逻辑
ARM64中的WFE指令的基本描述可以参考这里。
模拟逻辑
可以看到WFE指令的基本逻辑是要触发CPU进入低功耗模式挂起执行,然后还需要模拟各种
触发CPU继续执行的激励。
在我们当前分析的qemu版本中,user mode和system mode对WFE的模拟是不一样的,不过两
者都没有完整模拟出WFE的相关功能。
首先,qemu翻译执行的主循环在遇到WFE指令时,断开tb,配置EXCP_YIELD异常,使用长跳转
跳出翻译执行主循环。
对于user mode,针对EXCP_YIELD异常没有做处理,模拟执行又继续到WFE指令,于是模拟程
序就一直在这里循环了?
对于system mode,跳出翻译执行主循环后,会在qemu_wait_io_event里把vCPU线程挂起等待。
1 | qemu_wait_io_event |
ARM spec里描述了多种触发CPU执行的激励,但是,当前的qemu里只实现了中断触发CPU继续
执行的逻辑。qemu tcg里模拟中断的基本逻辑可以参考这里。在整个中断模拟的逻辑里,会调用
到cpu_interrupt这个函数,对WFE的唤醒逻辑就在其中。
1 | /* system/cpus.c */ |
如上可以看到,对于发给其它CPU的中断,首先触发对应的CPU从挂起的状态继续运行,然后
使对应的CPU退出翻译执行主流程,进而可以去处理中断。如果这里的唤醒在对应CPU睡眠之
前,本次中断中的唤醒是无效的,那么对应CPU的睡眠就只能等后续的中断去唤醒。
这里为什么还要调用cpu_exit一下?cpu_exit中,先配置exit_request为1,再配置icount_decr.
u16.high为-1,在翻译执行的主流程里会检测后者,-1会触发vCPU跳出翻译执行的主逻辑,
进入中断异常处理逻辑,在cpu_handle_interrupt里会检测exit_request,exit_request
为1会触发vCPU彻底跳出翻译执行主逻辑(包括中断异常处理)。所以,cpu_exit的语意是明确
的,就是使vCPU退出运行。这里kick_vcpu_thread是要使vCPU继续运行,不清楚为什么还要
调用下cpu_exit。