1
votes

I am trying to build simple and small preemptive OS for the ARM processor (for experimenting with the ARM architecture).

I have my TCB that have pointer to the proper thread's stack which I am updating/reading from in my dispatch() method - something like this (mixed C and assembly)

asm("
  ldr r5, =oldSP
  ldr sp, [r5]
");
myThread->sp = oldSP;
myThread = getNewThread();
newSP = myThread->sp
asm("
  ldr r5, =newSP
  str sp, [r5]
");

When I call this dispatch() from user mode (explicit call), everything works all right - threads are losing and getting processor as they should.

However, I am trying to build preemptive OS, so I need timer IRQ to call dispatch - and that is my problem - in irq mode, r13_usr register is hidden, so I can't access it. I can't change to the SVC mode either - it is hidden there, too.

One solution that I see is switching to the user mode (after I entered dispatch method), updating/changing sp fields and switching back to the irq mode to continue where I left. Is that possible?

Another solution is to try not to enter IRQ mode again - I just need to handle hardware things (set proper status bit in timer periphery), call dispatch() (still in irq mode) in which I will mask timer interrupt, change to the user mode, do context switch, unmask timer interrupt and continue. Resumed thread should continue where it was suspended (before entering IRQ). Is this correct? (This should be correct if on interrupt, processor pushes r4-r11 and lr into user stack, but I think I am wrong here...)

Thank you.

3

3 Answers

2
votes

I think I might have answered a similar question here: "ARM - access R13 and R14 from Supervisor Mode"

In your case, just use "IRQ mode" instead of "Supervisor mode", but I think the same principle applies.

Long & short of it, if you switch from IRQ to user mode, that's a one-way trap door, you can't simply switch back to IRQ mode under software control.

But by manipulating the CPSR and switching to system mode, you can get r13_usr and then switch back to the previous mode (in your case, IRQ mode).

0
votes

Normally you setup all of this on boot, the various stack registers, handlers, etc. If there is a reason to go to user mode and get out of it, you can use swi from user mode and have the swi handler do whatever it was you wanted to do in user mode or task switch to a svc mode handler or something like that.

0
votes

Which ARM variant do you use? On modern variants like Cortex_M3 you have the MRS/MSR instruction. This way you can access the MSP and PSP registers by moving them to/from a general purpose register.

CMSIS even defines __get_MSP() and __get_PSP() as C functions, as well as their __set[...] counterparts.

EDIT: This seems to work in Thumb-2 only. Sorry for the noise.