我想编写我的代码来处理 Microblaze 上的 TLB 未命中,当然还有页表等。这一切都在 OVPsim 上完成。
当我边走边学的时候,我编写了这个小程序集来引用一个未映射的位置(0x1000000)——我将它作为特权代码运行,并在 VM 上运行:
ori r20, r0, 0
ori r12, r0, 0x1000000
/* next line should break it */
sw r20, r12, r0
(即,将r20 == 0
out的内容写入ORing形成的地址r12 == 0x1000000
,r0 == 0 => 0x1000000
显然。)
但是 GDB 没有跳转到异常向量,而是报告“程序收到 SIGSEV”——我做错了什么?我没有在 MSR 中启用硬件异常位,但手册说您在任何情况下都不能屏蔽这些异常,所以这不应该是问题。
更多信息无论我是否使用调试器,我都无法执行任何异常处理代码(例如,包括未对齐异常)(除非我明确调用它)。关闭调试器后,我从 OVPsim 得到了这个输出(注意我只是改变了测试地址——上面的 0xA000000 和 0x100000 之间的区别没有意义):
Processor Exception (PC_PRX) Processor 'platform/cpu0' 0x248: sw r20, r12, r0
Processor Exception (PC_WPX) No write access at 0xa000000
这是所有代码都在特权模式下运行,所以我看不出它不调用处理程序的明显理由,除非我没有正确配置 Microblaze。我打开了这些:
icmAddStringAttr(cpu1_attr, "endian", "big");
icmAddDoubleAttr(cpu1_attr, "mips", 100.000000);
icmAddStringAttr(cpu1_attr, "variant", "V8_20");
icmAddBoolAttr(cpu1_attr, "verbose", "true");
icmAddUns32Attr(cpu1_attr, "C_PVR", 2);
icmAddUns32Attr(cpu1_attr, "C_USE_MMU", 3);
icmAddStringAttr(cpu1_attr, "C_USE_BARREL", "1");
icmAddStringAttr(cpu1_attr, "C_USE_DIV", "1");
icmAddUns32Attr(cpu1_attr, "C_USE_INTERRUPT", 1);
icmAddUns32Attr(cpu1_attr, "C_MMU_TLB_ACCESS", 3);
icmAddUns32Attr(cpu1_attr, "C_UNALIGNED_EXCEPTIONS", 1);
icmAddUns32Attr(cpu1_attr, "C_ILL_OPCODE_EXCEPTION", 1);
icmAddUns32Attr(cpu1_attr, "C_DIV_ZERO_EXCEPTION", 1);
icmAddUns32Attr(cpu1_attr, "C_OPCODE_0x0_ILLEGAL", 1);
icmAddUns32Attr(cpu1_attr, "C_DEBUG_ENABLED", 1);
没有理由相信这不会奏效,因为 OVPsim 将在 Microblaze 上运行 Linux。