my buggy armv7a context switching.
Posted: Sun Feb 07, 2016 3:58 am
Hi Guys!
I was debugging my context switching code, when i realised i have made a mistake that would come to haunt me when i eventually implemented un-privilaged tasks.
On an IRQ I..
1) Push R0..R12 onto the stack.
2) Push LR onto the stack ( The PC of the interrupted task )
3) Copy the MODE flags from SPSR to CPSR and read the SP and LR registers to get the interrupted tasks SP and LR.
4) Restore CPSR mode flags.
5) Service the IRQ.
6) Call my scheduler... This coppies the CPU state from the stack, and modifies the stack with data from the task to be awakened.
7) Pop CPU state off the stack, and return from iterrups.
Point 3 is my problem!
When the interrupted task is un-privilaged, switching to unprivilaged mode to read the LR and SP would lose the ability to switch back to the IRQ mode.
I realise that there instructions to read banked registers, but they are not supported by all arm CPU's.
What is the correct, portable way of doing this in armv7a ??
The cpu state push/pop code is in _my_IRQ_handler
https://github.com/chris-stones/ShovelO ... /context.S
The very primitive *scheduler* (essentially an array of states to memcpy!):
https://github.com/chris-stones/ShovelO ... /kthread.c
Thanks for any input!
Chris.
I was debugging my context switching code, when i realised i have made a mistake that would come to haunt me when i eventually implemented un-privilaged tasks.
On an IRQ I..
1) Push R0..R12 onto the stack.
2) Push LR onto the stack ( The PC of the interrupted task )
3) Copy the MODE flags from SPSR to CPSR and read the SP and LR registers to get the interrupted tasks SP and LR.
4) Restore CPSR mode flags.
5) Service the IRQ.
6) Call my scheduler... This coppies the CPU state from the stack, and modifies the stack with data from the task to be awakened.
7) Pop CPU state off the stack, and return from iterrups.
Point 3 is my problem!
When the interrupted task is un-privilaged, switching to unprivilaged mode to read the LR and SP would lose the ability to switch back to the IRQ mode.
I realise that there instructions to read banked registers, but they are not supported by all arm CPU's.
What is the correct, portable way of doing this in armv7a ??
The cpu state push/pop code is in _my_IRQ_handler
https://github.com/chris-stones/ShovelO ... /context.S
The very primitive *scheduler* (essentially an array of states to memcpy!):
https://github.com/chris-stones/ShovelO ... /kthread.c
Thanks for any input!
Chris.