From 46dd5df0a6646284ce87f5e4ade1a53c580121b7 Mon Sep 17 00:00:00 2001 From: schulz Date: Sun, 19 Apr 2015 10:55:22 +0000 Subject: [PATCH] Use new ARM instructions for interrupts, exceptions and system calls. The new instructions allows to handle all supervisor related code in supervisor mode without need for additional IRQ or UND stacks. Additionaly, we do not use the system mode to handle IRQs anymore, thus task's stacks are not involved in interrupt or exception handling at all. git-svn-id: https://svn.aros.org/svn/aros/trunk/AROS@50425 fb15a70f-31f2-0310-bbcc-cdcc74a49acc --- arch/arm-native/kernel/intr.c | 29 +++------------------- arch/arm-native/kernel/kernel_intern.h | 44 ++++++++++++++++----------------- arch/arm-native/kernel/kernel_startup.c | 8 ------ arch/arm-native/kernel/syscall.c | 10 +++----- 4 files changed, 29 insertions(+), 62 deletions(-) diff --git a/arch/arm-native/kernel/intr.c b/arch/arm-native/kernel/intr.c index bc4e5083e2..65fb7d19c2 100644 --- a/arch/arm-native/kernel/intr.c +++ b/arch/arm-native/kernel/intr.c @@ -62,13 +62,7 @@ asm ( ".type __vectorhand_undef,%function \n" "__vectorhand_undef: \n" VECTCOMMON_START - " cpsid i, #" STR(MODE_SYSTEM)"\n" // switch to system mode, with interrupts disabled.. - " str sp, [r0, #13*4] \n" - " str lr, [r0, #14*4] \n" // store lr in ctx_lr - " mov fp, #0 \n" // clear fp - " bl handle_undef \n" - VECTCOMMON_END ); @@ -107,8 +101,7 @@ asm ( ".type __vectorhand_reset,%function \n" "__vectorhand_reset: \n" " mov sp, #0x1000 - 16 \n" // re-use bootstrap tmp stack - " mov r0, sp \n" - " sub r0, r0, #" STR(BOOT_STACK_SIZE)"\n" // get the boottag's + " sub r0, sp, #" STR(BOOT_STACK_SIZE)"\n" // get the boottag's " sub r0, r0, #" STR(BOOT_TAGS_SIZE) "\n" " mov fp, #0 \n" // clear fp @@ -138,18 +131,12 @@ asm ( "__vectorhand_irq: \n" " sub lr, lr, #4 \n" // adjust lr_irq VECTCOMMON_START - " cpsid i, #MODE_SYSTEM \n" // switch to system mode, with interrupts disabled.. - " str sp, [r0, #13*4] \n" - " str lr, [r0, #14*4] \n" // store lr in ctx_lr - " mov fp, #0 \n" // clear fp - " bl handle_irq \n" - - " cpsid i, #MODE_IRQ \n" // switch to IRQ mode, with interrupts disabled.. " mov r0, sp \n" " ldr r1, [r0, #16*4] \n" // load the spr register " and r1, r1, #31 \n" // mask processor mode - " cmp r1, #16 \n" // will we go back to user mode? + " cmp r1, #0x10 \n" // will we go back to user mode? + " cmpne r1, #0x1f \n" // or system mode (falls we use it) " bne 1f \n" // no? don't call core_ExitInterrupt! " mov fp, #0 \n" // clear fp " bl core_ExitInterrupt \n" @@ -200,13 +187,7 @@ asm ( "__vectorhand_dataabort: \n" " sub lr, lr, #8 \n" // adjust lr_irq VECTCOMMON_START - " cpsid i, #MODE_SYSTEM \n" // switch to system mode, with interrupts disabled.. - " str sp, [r0, #13*4] \n" - " str lr, [r0, #14*4] \n" // store lr in ctx_lr - " mov fp, #0 \n" // clear fp - " bl handle_dataabort \n" - VECTCOMMON_END ); @@ -255,10 +236,6 @@ asm ( "__vectorhand_prefetchabort: \n" " sub lr, lr, #4 \n" // adjust lr_irq VECTCOMMON_START - " cpsid i, #MODE_SYSTEM \n" // switch to system mode, with interrupts disabled.. - " str sp, [r0, #13*4] \n" - " str lr, [r0, #14*4] \n" // store lr in ctx_lr - " mov fp, #0 \n" // clear fp " bl handle_prefetchabort \n" diff --git a/arch/arm-native/kernel/kernel_intern.h b/arch/arm-native/kernel/kernel_intern.h index cf9b20574e..b24b341744 100644 --- a/arch/arm-native/kernel/kernel_intern.h +++ b/arch/arm-native/kernel/kernel_intern.h @@ -78,31 +78,31 @@ static inline void bug(const char *format, ...) va_end(args); } -// NB - we use sizeof(ExceptionContext) on the stack - #define VECTCOMMON_START \ - " sub sp, sp, #6*4 \n" \ - " stmfd sp!, {r0-r12} \n" \ - " mov r0, sp \n" \ - " mrs r1, spsr \n" \ - " str r1, [r0, #16*4] \n" \ - " str lr, [r0, #15*4] \n" + " srsfd sp!, #0x13 \n" \ + " cpsid i, #0x13 \n" \ + " sub sp, sp, #2*4 \n" \ + " stmfd sp!, {r0-r12} \n" \ + " mov r0, sp \n" \ + " ldr ip, [r0, #16*4] \n" \ + " and ip, ip, #0x1f \n" \ + " cmp ip, #0x10 \n" \ + " cmpne ip, #0x1f \n" \ + " addeq r1, r0, #13*4 \n" \ + " stmeq r1, {sp, lr}^ \n" \ + " strne lr, [r0, #14*4] \n" #define VECTCOMMON_END \ - " ldr r1, [sp, #16*4] \n" \ - " msr spsr, r1 \n" \ - " and r1, r1, #31 \n" \ - " cmp r1, #16 \n" \ - " cmpne r1, #31 \n" \ - " bne 1f \n" \ - " add r1, sp, #13*4 \n" \ - " ldm r1, {sp}^ \n" \ - " add r1, sp, #14*4 \n" \ - " ldm r1, {lr}^ \n" \ - "1: ldr lr, [sp, #15*4] \n" \ - " ldmfd sp!, {r0-r12} \n" \ - " add sp, sp, #6*4 \n" \ - " movs pc, lr \n" + " ldr ip, [sp, #16*4] \n" \ + " and ip, ip, #0x1f \n" \ + " cmp ip, #0x10 \n" \ + " cmpne ip, #0x1f \n" \ + " addeq r1, sp, #13*4 \n" \ + " ldmeq r1, {sp, lr}^ \n" \ + " ldrne lr, [sp, #14*4] \n" \ + " ldmfd sp!, {r0-r12} \n" \ + " add sp, sp, #2*4 \n" \ + " rfefd sp! \n" #define STORE_TASKSTATE(task, regs) \ struct ExceptionContext *ctx = task->tc_UnionETask.tc_ETask->et_RegFrame; \ diff --git a/arch/arm-native/kernel/kernel_startup.c b/arch/arm-native/kernel/kernel_startup.c index 21d0f8fc3a..bc342ffc56 100644 --- a/arch/arm-native/kernel/kernel_startup.c +++ b/arch/arm-native/kernel/kernel_startup.c @@ -37,8 +37,6 @@ void __attribute__((used)) kernel_cstart(struct TagItem *msg); uint32_t stack[AROS_STACKSIZE] __attribute__((used,aligned(16))); static uint32_t stack_super[AROS_STACKSIZE] __attribute__((used,aligned(16))); -static uint32_t stack_abort[AROS_STACKSIZE] __attribute__((used,aligned(16))); -static uint32_t stack_irq[AROS_STACKSIZE] __attribute__((used,aligned(16))); asm ( ".section .aros.init,\"ax\"\n\t" @@ -50,10 +48,6 @@ asm ( " pop {r0} \n" " cps #0x1f \n" /* system mode */ " ldr sp, stack_end \n" - " cps #0x17 \n" /* abort mode */ - " ldr sp, stack_abort_end \n" - " cps #0x12 \n" /* IRQ mode */ - " ldr sp, stack_irq_end \n" " cps #0x13 \n" /* SVC (supervisor) mode */ " ldr sp, stack_super_end \n" " b kernel_cstart \n" @@ -63,8 +57,6 @@ asm ( static uint32_t * const stack_end __attribute__((used, section(".aros.init"))) = &stack[AROS_STACKSIZE - sizeof(IPTR)]; static uint32_t * const stack_super_end __attribute__((used, section(".aros.init"))) = &stack_super[AROS_STACKSIZE - sizeof(IPTR)]; -static uint32_t * const stack_abort_end __attribute__((used, section(".aros.init"))) = &stack_abort[AROS_STACKSIZE - sizeof(IPTR)]; -static uint32_t * const stack_irq_end __attribute__((used, section(".aros.init"))) = &stack_irq[AROS_STACKSIZE - sizeof(IPTR)]; struct ARM_Implementation __arm_arosintern __attribute__((aligned(4), section(".data"))) = {0,0,NULL,NULL}; struct ExecBase *SysBase __attribute__((section(".data"))) = NULL; diff --git a/arch/arm-native/kernel/syscall.c b/arch/arm-native/kernel/syscall.c index ab1b5a4778..65f8c95ecf 100644 --- a/arch/arm-native/kernel/syscall.c +++ b/arch/arm-native/kernel/syscall.c @@ -43,11 +43,6 @@ asm ( ".type __vectorhand_swi,%function \n" "__vectorhand_swi: \n" VECTCOMMON_START - " add r1, r0, #13*4 \n" // store sp^ in ctx_sp - " stm r1, {sp}^ \n" - " add r1, r0, #14*4 \n" // store lr^ in ctx_lr - " stm r1, {lr}^ \n" - " mov fp, #0 \n" // clear fp(??) " bl handle_syscall \n" VECTCOMMON_END ); @@ -173,9 +168,12 @@ void handle_syscall(void *regs) * not check this condition and could execute Cause() handler before IRQ is entirely handled. */ case SC_CAUSE: - if ((((uint32_t *)regs)[16] & 0x1f) == 0x10) + { + uint32_t mode = (((uint32_t *)regs)[16]) & 0x1f; + if (mode == 0x10 || mode == 0x1f) core_SysCall(swi_no, regs); break; + } default: core_SysCall(swi_no, regs); -- 2.11.4.GIT