2

我正在编写线程切换代码,其中内核将相关状态转储到内存,但实际的线程切换完全发生在用户模式下。

这可以正常工作,除非抢占点出现在 Thumb If-Then (IT) 块内。在那种情况下,我无法弄清楚如何恢复 ITSTATE(即 CPSR 的 [15:10] 和 [26:25] 位),因为这些位是用户 RAZ/WI,并且无论如何它可能不会给定 ITSTATE 的语义。

什么(如果有)是在不陷入内核的情况下恢复此状态的正确方法?

我已经考虑过倒带执行并从 IT 指令继续,但除了重量很大之外,我不确定这是否总是可能的。

编辑:对 ARMv7-A 感兴趣

4

2 回答 2

1

在架构上*,CPSR 中的任何执行状态位都不能在任何模式下读取或写入(只有特权模式下的 CPSR.E 位除外,甚至不推荐使用)。在正常执行之外修改它们的唯一方法是通过异常返回中的 SPSR,它预期直接返回到 IT 块内的相关指令。

正如您所提到的,重新启动整个 IT 块既不实际也不安全,主要是由于内存访问 - 虽然在大多数情况下,您可能可以静态分析指令以反转任何寄存器修改,但任何共享内存都可能意味着重复加载返回不同的值,或者重复的存储可能会破坏其他一些同时读取和修改原始值的进程。至于内存映射 I/O,由于多种原因,意外重复任何访问都可能是危险的。

另一个可能的想法是基于来自 SPSR 的 ITSTATE 和返回地址处的剩余指令 JIT 一个新的 IT 块,因为 Thumb-2 意味着您必须LDR PC,...从任何地方返回原始代码,而寄存器完好无损。但是,如果条件指令进行任何与 PC 相关的计算,即使这样仍然会破坏事情。

* 在任何具有 CPSR 并支持 Thumb-2 的东西上,无论如何

于 2014-09-26T13:10:28.100 回答
0

CPSR 在异常进入时自动存储在堆栈中,并在异常返回时从堆栈中恢复。我可能看不到你的确切问题,但通常你不需要做任何事情来让这个上下文切换工作 - 假设它是在异常中完成的,你只需将剩余的寄存器存储在堆栈上,切换堆栈指针,取消堆栈剩余的寄存器,然后从例外...我也不知道您使用的确切架构是什么,但这里有一个非常简单的 ARMv7-M (Cortex-M3/M4) 上下文切换:https ://github.com/DISTORTEC/distortos /blob/master/source/architecture/ARM/ARMv7-M/ARMv7-M-PendSV_Handler.cpp

于 2014-09-26T14:44:41.213 回答