-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix register restoration #50
Conversation
* I don't think this current isolation technique will work for bss, so I've enabled user read/write of all bss code | ||
* If we made a real OS, we would have a different binary for each program, but because this is a mini os, we didn't bother. | ||
* | ||
* Because of this reason (and discovering it during finals week), I have disabled the MPU |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree
asm volatile("ldr pc, [sp, #-84]"); | ||
void Scheduler::restore_current_task_regs(exception_stack_registers* regs) | ||
{ | ||
__set_PSP(reinterpret_cast<unsigned>(®s[1]) + 4); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exception_stack_regs already contains reserved regs due to alignment. I don't know why this is +4. It works though. lol
@@ -11,7 +11,8 @@ class GPIOPinEvent { | |||
GPIOPinEvent( | |||
uint8_t pin, GPIOConfiguration resistance, | |||
aidan::GPIOEventController::GPIOEventCallback callback | |||
) : pin(pin) | |||
) : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think ur nvim formatter is clashing with make format
Previously, I tried to be clever. After returning from an async callback, it would restore registers from the stack in userspace. This made it fast (not that it really matters), but also left it vulnerable to an interrupt during register restoration, which would cause corruption of the stack.
This is a crude diagram of the stack with the new design
After yield(), assuming callback is ready
-- original stack ptr (before yield) --
-- regs pushed to stack on SVC entry from yield --
-- new regs that we created so we go to async callback on return --
-- new stack ptr (right before we return from kernel during exception) --
During callback
-- original stack ptr (before yield) --
-- regs pushed to stack on SVC entry from yield --
-- stack allocations during async callback --
-- new stack ptr --
After we return from callback, which triggers a REG_RESTORE SVC call, and brings us to kernel
-- original stack ptr (before yield) --
-- regs pushed to stack on SVC entry from yield --
-- regs pushed to stack on REG_RESTORE svc call --
-- new stack ptr --
After we return from kernel space, we will pop the regs on the stack. We can increment the stack ptr and skip over the regs pushed to stack on REG_RESTORE call (we don't care about the async callback regs at this point, we are returning from it), which will return us to the original location.