I want to write my code that will handle TLB misses on the Microblaze and through that, of course, the page tables etc. This is all being done on OVPsim.
As I am learning as I go I wrote this little piece of assembly to reference an unmapped location (0x1000000) - I am running this as privileged code with VM on:
ori r20, r0, 0
ori r12, r0, 0x1000000
/* next line should break it */
sw r20, r12, r0
(I.e., write the contents of r20 == 0
out to the address formed by ORing r12 == 0x1000000
and r0 == 0 => 0x1000000
obviously.)
But instead of jumping to the exception vector, GDB reports "Program received SIGSEV" - what did I get wrong? I haven't got the enable hardware exceptions bit on in the MSR but the manual says you cannot mask these exceptions in any case so that shouldn't be the issue.
Further information I cannot get any (eg, including misalignment exceptions) of the exception handling code to execute, (unless I explicitly call it), whether or not I am using the debugger. With the debugger off I get this output from OVPsim (NB I merely changed the test address - there is no significance in the difference between 0xA000000 and 0x100000 above):
Processor Exception (PC_PRX) Processor 'platform/cpu0' 0x248: sw r20, r12, r0
Processor Exception (PC_WPX) No write access at 0xa000000
This is all code being run in privileged mode, so I can see no overt reason for it not to call the handlers, unless I have not configured the Microblaze properly. I have these turned on:
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);
There is no reason to believe this won't work as OVPsim will run Linux on the Microblaze.
With thanks to Jamie Garside at the York University Real-Time Systems group: the OVP simulator's default setting is to trap exceptions and exit the simulation, this is why no sort of exception was being executed in the way I expected - instead they were simply being reported as some sort of error and the simulation was being halted.
However, if
ICM_ATTR_SIMEX
is defined for the simulation then the simulation will execute the exception handlers in just the way the real processor would - so addingICM_ATTR_SIMEX
to my instance's attributes - e.g., by ORing it in as shown below, puts everything in its rightful place: