我们在 feild 上运行了生产软件,它具有运行 linux 2.6.24 的带有 XSCALE arm 内核的 ixp23xx 网络处理器。我们从现场看到偶尔出现的问题,有时会在实验室中重现,控制台打印以下故障行“未处理的故障:在 0x40019004 处不精确的外部中止 (0x416)”。进一步挖掘,我们发现我们只有很少的页表条目,其中虚拟地址没有映射到有效的物理地址。因此,访问这些虚拟地址可能会导致错误的中止。最终的解决方案是删除错误的映射,因此下次我们应该得到精确且易于捕获的分段错误。但是删除错误的条目需要一些时间,我们必须使用调试信息创建构建,因此这个选项是稍后使用的。
回到问题上来,根据 XSCALE 数据表,通过设置 Xbit = 0、C 位 = 0 和 B 位 = 0,可以通过“停止直到完成”使这个故障几乎精确(+3 instr)。但我不确定如何在 linux 中做到这一点,它会有帮助吗?基本上这看起来像禁用 DCACHE。arc/arm/mm/proc-xscale.S 下的代码都是汇编代码,我不确定如何禁用。内核配置中有一个选项,即 CONFIG_CPU_DCACHE_DISABLE ,这似乎禁用了 DCACHE 但它是否与等于 0 的 X=C=B 位相同?以下是数据表的摘录
*
不精确的数据中止可能会造成中止处理程序难以恢复的情况。外部数据中止和数据缓存奇偶校验错误都可能导致目标寄存器数据损坏。由于这些故障不精确,因此可能在调用数据中止故障处理程序之前已使用损坏的数据。因此,软件应将不精确的数据中止视为不可恢复。即使内存访问标记为“停止直到完成”(参见第 3.2.2.4 节)也可能导致不精确的数据中止。对于这些类型的访问,故障比一般情况稍微不那么精确:它保证在导致它的指令的三个指令内引发。换句话说,如果“停止直到完成”的 LD 或 ST 指令触发了不精确的故障,那么程序将在三个指令内看到该故障。如果 MMU 被禁用,所有数据访问都将是不可缓存和不可缓冲的。这与启用 MMU 时的行为相同,并且数据访问使用 X、C 和 B 都设置为 0 的描述符。X、C 和 B 位确定处理器何时应将新数据放入 Data缓存。缓存将数据按行(也称为块)放入缓存中。因此,决定是否将新数据放入缓存的基础是所谓的“线路分配策略”。如果 Line Allocation Policy 为 read-allocate,则所有未命中缓存的加载操作 数据访问使用 X、C 和 B 都设置为 0 的描述符。X、C 和 B 位确定处理器何时应将新数据放入数据缓存中。缓存将数据按行(也称为块)放入缓存中。因此,决定是否将新数据放入缓存的基础是所谓的“线路分配策略”。如果 Line Allocation Policy 为 read-allocate,则所有未命中缓存的加载操作 数据访问使用 X、C 和 B 都设置为 0 的描述符。X、C 和 B 位确定处理器何时应将新数据放入数据缓存中。缓存将数据按行(也称为块)放入缓存中。因此,决定是否将新数据放入缓存的基础是所谓的“线路分配策略”。如果 Line Allocation Policy 为 read-allocate,则所有未命中缓存的加载操作
*