Converted context switching functions in terms of setjump and longjump primitives.

Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
Anup Patel
2011-07-06 21:23:04 +05:30
parent 32fc47ef89
commit d97eac380e
3 changed files with 29 additions and 45 deletions
+1 -1
View File
@@ -171,7 +171,7 @@ int main ( void )
{ {
arm_irq_setup(); arm_irq_setup();
arm_timer_init(1000, 1); arm_timer_init((1000000 / SYSTEM_TICKS_PER_SEC), 1);
arm_uart_init(); arm_uart_init();
+16 -18
View File
@@ -40,34 +40,31 @@ archGetCPSR:
bx lr bx lr
/** /**
* int archSetJumpLowLevel(pt_regs_t *regs) * int archSetJump(pt_regs_t *regs)
*/ */
.globl archSetJumpLowLevel .globl archSetJump
archSetJumpLowLevel: archSetJump:
add r0, r0, #(4 * 16) add r0, r0, #(4 * 16)
str lr, [r0] str lr, [r0]
sub r0, r0, #(4 * 14) sub r0, r0, #(4 * 14)
stm r0, {r1-r14} stm r0, {r1-r14}
mov r0, r0 /* NOP */ mov r0, r0 /* NOP */
sub sp, sp, #4 str r2, [r1]
str r1, [sp] mov r2, #0
mov r1, #0
sub r0, r0, #4 sub r0, r0, #4
str r1, [r0] str r2, [r0]
mrs r1, cpsr_all mrs r2, cpsr_all
add r0, r0, #4 sub r0, r0, #4
str r1, [r0] str r2, [r0]
ldr r1, [sp] ldr r2, [r1]
sub sp, sp, #4
mov r0, #1 mov r0, #1
bx lr bx lr
/** /**
* void archLongJumpLowLevel(pt_regs_t *regs) * void archLongJump(pt_regs_t *regs)
*/ */
.globl archLongJumpLowLevel .globl archLongJump
archLongJumpLowLevel: archLongJump:
add r0, r0, #(4 * 17)
mrs r1, cpsr_all mrs r1, cpsr_all
SET_CURRENT_MODE CPSR_MODE_UNDEFINED SET_CURRENT_MODE CPSR_MODE_UNDEFINED
mov sp, r0 mov sp, r0
@@ -78,9 +75,10 @@ archLongJumpLowLevel:
SET_CURRENT_MODE CPSR_MODE_FIQ SET_CURRENT_MODE CPSR_MODE_FIQ
mov sp, r0 mov sp, r0
msr cpsr_all, r1 msr cpsr_all, r1
sub r0, r0, #(4 * 17)
ldr r1, [r0], #4 /* Get CPSR from stack */ ldr r1, [r0], #4 /* Get CPSR from stack */
msr spsr_all, r1
orr r1, r1, #(CPSR_IRQ_DISABLED | CPSR_FIQ_DISABLED)
msr cpsr_all, r1 msr cpsr_all, r1
ldm r0, {r0-r15} ldm r0, {r0-r15}^
mov r0, r0 /* NOP */ mov r0, r0 /* NOP */
+12 -26
View File
@@ -63,13 +63,13 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top,
for (i = 1; i < 13; i++) { for (i = 1; i < 13; i++) {
regs->gpr[i] = 0x0; regs->gpr[i] = 0x0;
} }
regs->sp = (uint32_t)stack_top - sizeof(pt_regs_t) - 2048; regs->sp = (uint32_t)stack_top - sizeof(pt_regs_t) - 1024;
regs->lr = (uint32_t)entry_point; regs->lr = (uint32_t)entry_point;
regs->pc = (uint32_t)entry_point; regs->pc = (uint32_t)entry_point;
} }
extern int archSetJumpLowLevel(pt_regs_t *regs); extern int archSetJump(pt_regs_t *regs, uint32_t *tmp);
extern void archLongJumpLowLevel(pt_regs_t *regs); extern void archLongJump(pt_regs_t *regs);
extern uint32_t archGetCPSR(void); extern uint32_t archGetCPSR(void);
/** /**
@@ -86,10 +86,9 @@ extern uint32_t archGetCPSR(void);
*/ */
void archFirstThreadRestore(ATOM_TCB *new_tcb) void archFirstThreadRestore(ATOM_TCB *new_tcb)
{ {
pt_regs_t *regs = NULL; pt_regs_t *regs = (pt_regs_t *)((uint32_t)new_tcb->sp_save_ptr
regs = (pt_regs_t *)((uint32_t)new_tcb->sp_save_ptr
- sizeof(pt_regs_t)); - sizeof(pt_regs_t));
archLongJumpLowLevel(regs); archLongJump(regs);
} }
/** /**
@@ -101,28 +100,15 @@ void archFirstThreadRestore(ATOM_TCB *new_tcb)
*/ */
void archContextSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) void archContextSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb)
{ {
uint32_t mode; uint32_t tmp = 0x0, lr = 0x0;
pt_regs_t tmp; pt_regs_t *old_regs = (pt_regs_t *)((uint32_t)old_tcb->sp_save_ptr
pt_regs_t *old_regs = NULL;
pt_regs_t *new_regs = NULL;
old_regs = (pt_regs_t *)((uint32_t)old_tcb->sp_save_ptr
- sizeof(pt_regs_t)); - sizeof(pt_regs_t));
new_regs = (pt_regs_t *)((uint32_t)new_tcb->sp_save_ptr pt_regs_t *new_regs = (pt_regs_t *)((uint32_t)new_tcb->sp_save_ptr
- sizeof(pt_regs_t)); - sizeof(pt_regs_t));
mode = archGetCPSR() & CPSR_MODE_MASK; asm volatile (" mov %0, lr\n\t" :"=r"(lr):);
if ((mode == CPSR_MODE_IRQ) || (mode == CPSR_MODE_FIQ)) { if (archSetJump(old_regs, &tmp)) {
/* Interrupt Context */ old_regs->lr = lr;
memcpy(&tmp, old_regs, sizeof(pt_regs_t)); archLongJump(new_regs);
if (archSetJumpLowLevel(old_regs)) {
archLongJumpLowLevel(new_regs);
} else {
memcpy(old_regs, &tmp, sizeof(pt_regs_t));
}
} else {
/* Thread Context */
if (archSetJumpLowLevel(old_regs)) {
archLongJumpLowLevel(new_regs);
}
} }
} }