I was thinking you'd use VP to flip in a different mapping for supervisor mode. The bank 0 in supervisor mode, and the other details of the address map for that mode, don't need to have any particular commonality with the address map for user mode tasks.
That was something I had considered. However:
Because the CPU fetches vectors after the PBR, PC, and P registers have been pushed onto the stack, VP# is asserted after the user task state has been saved. This state is saved on the user-mode stack.
The obvious problem, as highlighted by Samuel, is if a kernel call via BRK is being processed, the data (register values) needed to restore the MPU state upon exit will be on the wrong stack. Ditto for processing other interrupts. The machine would go off into deep space, never to be heard from again—at least until the reset button is pressed.
This isn't necessarily an issue if your kernel code shares the stack with the user code (a logical design choice if BRK or COP is used to invoke system services). But, for handling ABORT, this can be a possible cause for live-lock, because if the abort happened while stacking something in user code, you'll put the CPU into an endless loop (as the CPU attempts to stack the process state after receiving ABORT, it'll receive another ABORT) without some kind of "double fault" detection hardware.
Exactly. The only way to avoid this issue is to have individual stacks for each process, with each stack located in RAM that cannot be accessed by any other process—even the kernel.
It should be kept in mind that although the kernel would, upon context switch, load the stack pointer with the correct address for the currently running process and thus initially ensure the process is working with the correct stack, there's nothing to prevent that process from changing the stack pointer to anything, including the address of a different process' stack (ditto for the DP register). Succinctly stated, there are no privileged instructions in the '816, ergo no wired-in method to prevent a process from trying to access arbitrary locations in RAM. It would take very sophisticated hardware management to prevent something like that from occurring.
This is a good use for the NMI input, frankly. But it is something to be aware of.
Using NMI wouldn't help with memory protection, as the NMI isn't processed until the completion of the current instruction. By then, the illegal memory access will have taken place.
(Sorry -- am I showing my QA Engineering side too much again? Wink )
What's the old saying: quality is engineered in, not inspected in?