Adding MPU support to existing port

nburkitt wrote on Saturday, February 07, 2015:

Pardon any multiple posts - this is my third attempt.
What’s involved in adding MPU support to an existing port? It seems like it shouldn’t be a major project. Is there any documentation on what needs to be provided, and how it needs to interface to the kernel?
Thanks,

-Nick

rtel wrote on Saturday, February 07, 2015:

Which architecture are you wanting to add MPU support to?

Regards.

nburkitt wrote on Saturday, February 07, 2015:

Thanks - I’m using the Microblaze port. I figure at this point that the time I’ve spent chasing a memory overwrite bug is probably about equal to the time it would have taken to implement MPU support. At least it feels that way. :-/ I understand there’s an update to the MB port coming - any chance it includes MPU support?
Thanks again,

-Nick

rtel wrote on Sunday, February 08, 2015:

Unfortunately I’m not familiar with how the MPU works on the Microblaze,
so will give a generic reply.

‘Standard’ (non MPU) ports work by linking the FreeRTOS API functions
directly into the application code. That is the best/most efficient way
if memory protection or security are not a concern.

If memory protect or security are a concern then you will want to run
some user tasks with a low privilege levels, while leaving the RTOS code
running with a high privilege level. You then need a method of
switching from the low privilege task code to the high privilege RTOS
code when an API function is called. That is normally done by creating
a software interrupt - interrupts always running at a high privilege level.

Traditionally, in MPU restricted applications, API functions are called
by pushing the function’s parameters onto the stack, then calling a
software interrupt generating instruction with a parameter. For
example, in old DOS systems, the instruction was “INT” and you would
pass a parameter that would identify the function being called, so you
might call “INT #16”.

The software interrupt handler then looks at the parameter (that can be
tricky as it is often encoded as part of the assembly instruction) to
see which function to call. Once it knows which function to call it
knows the number of parameters to pop off the stack.

However, FreeRTOS does not normally go that far, and instead uses a
simpler but method that is fine provided for systems that only run code
of known providence. In the FreeRTOS scheme it wraps each API function
in an version that uses a software interrupt to raise the CPU privilege,
calls the API function, then sets the privilege back to whatever it was
when the special version started running. It does that uses macros (you
will find a file called mpu_wrappers.h) so is somewhat transparent to
end users.

Regards.

nburkitt wrote on Monday, February 09, 2015:

Thanks, that’s a good start. The Microblaze MMU can be configured in any of three modes, “user,” “protection,” and “virtual” (four if you count “none”). I think “protection” is probably the right choice here. It appears to be something along the lines of virtual memory minus address translation, but documentation is in short supply. The manual claims that the MMU implementation is the same as the PowerPC, but likely it is talking only about “virtual” mode.
Who’s responsible for creating and mapping memory regions? Do I need to provide a version of malloc that understands MB TLB setup, and can deal with each task having its own heap?
Thanks again,

-Nick

rtel wrote on Monday, February 09, 2015:

When I have done this I have allocated the stacks dynamically, allowing them to be placed where needed (using the linker), then used the xTaskCreateRestricted() function to pass the stack in to FreeRTOS: http://www.freertos.org/xTaskCreateRestricted.html

Regards.