mirror of
https://github.com/kelvinlawson/atomthreads.git
synced 2026-09-17 19:07:07 +02:00
Converted context switching functions in terms of setjump and longjump primitives.
Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
@@ -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
@@ -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
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user