diff --git a/arch/arm/arm/src/include/los_hw_pri.h b/arch/arm/arm/src/include/los_hw_pri.h index 052da990a59ae488b59246c6592c4a51e6c39eeb..d4f5a88076402db9630af8f4cce786ae7c30013f 100644 --- a/arch/arm/arm/src/include/los_hw_pri.h +++ b/arch/arm/arm/src/include/los_hw_pri.h @@ -34,8 +34,7 @@ #include "los_base.h" #include "los_hw.h" -#include "los_process_pri.h" -#include "los_signal.h" + #ifdef __cplusplus #if __cplusplus extern "C" { @@ -56,23 +55,44 @@ typedef struct { UINT32 regFPSCR; /* FPSCR */ UINT32 regFPEXC; /* FPEXC */ #endif - UINT32 resved; /* It's stack 8 aligned */ - UINT32 regPSR; - UINT32 R[GEN_REGS_NUM]; /* R0-R12 */ - UINT32 SP; /* R13 */ - UINT32 LR; /* R14 */ - UINT32 PC; /* R15 */ + UINT32 R4; + UINT32 R5; + UINT32 R6; + UINT32 R7; + UINT32 R8; + UINT32 R9; + UINT32 R10; + UINT32 R11; + + /* It has the same structure as IrqContext */ + UINT32 reserved2; /**< Multiplexing registers, used in interrupts and system calls but with different meanings */ + UINT32 reserved1; /**< Multiplexing registers, used in interrupts and system calls but with different meanings */ + UINT32 USP; /**< User mode sp register */ + UINT32 ULR; /**< User mode lr register */ + UINT32 R0; + UINT32 R1; + UINT32 R2; + UINT32 R3; + UINT32 R12; + UINT32 LR; + UINT32 PC; + UINT32 regCPSR; } TaskContext; typedef struct { -#if !defined(LOSCFG_ARCH_FPU_DISABLE) - UINT64 D[FP_REGS_NUM]; /* D0-D31 */ - UINT32 regFPSCR; /* FPSCR */ - UINT32 regFPEXC; /* FPEXC */ -#endif - UINT32 resved; - TASK_IRQ_CONTEXT -} TaskIrqContext; + UINT32 reserved2; /**< Multiplexing registers, used in interrupts and system calls but with different meanings */ + UINT32 reserved1; /**< Multiplexing registers, used in interrupts and system calls but with different meanings */ + UINT32 USP; /**< User mode sp register */ + UINT32 ULR; /**< User mode lr register */ + UINT32 R0; + UINT32 R1; + UINT32 R2; + UINT32 R3; + UINT32 R12; + UINT32 LR; + UINT32 PC; + UINT32 regCPSR; +} IrqContext; /* * Description : task stack initialization @@ -82,8 +102,9 @@ typedef struct { * Return : pointer to the task context */ extern VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack, BOOL initFlag); -extern VOID OsUserCloneParentStack(LosTaskCB *childTaskCB, LosTaskCB *parentTaskCB); -extern VOID OsUserTaskStackInit(TaskContext *context, TSK_ENTRY_FUNC taskEntry, UINTPTR stack); +extern VOID OsUserCloneParentStack(VOID *childStack, UINTPTR parentTopOfStask, UINT32 parentStackSize); +extern VOID OsUserTaskStackInit(TaskContext *context, UINTPTR taskEntry, UINTPTR stack); +extern VOID OsInitSignalContext(VOID *sp, VOID *signalContext, UINTPTR sigHandler, UINT32 signo, UINT32 param); extern void arm_clean_cache_range(UINTPTR start, UINTPTR end); extern void arm_inv_cache_range(UINTPTR start, UINTPTR end); diff --git a/arch/arm/arm/src/los_dispatch.S b/arch/arm/arm/src/los_dispatch.S index 1f9c24697564c51472c7ba8e09a671918b8a262e..66a719e161bbab3c0e1b6c045a015b255c583b70 100644 --- a/arch/arm/arm/src/los_dispatch.S +++ b/arch/arm/arm/src/los_dispatch.S @@ -32,6 +32,7 @@ #include "asm.h" #include "arch_config.h" + .extern OsSaveSignalContext .extern OsSchedToUserReleaseLock .global OsTaskSchedule .global OsTaskContextLoad @@ -85,17 +86,16 @@ */ OsTaskSchedule: MRS R2, CPSR + STMFD SP!, {R2} STMFD SP!, {LR} STMFD SP!, {LR} - /* jump sp */ - SUB SP, SP, #4 + STMFD SP!, {R12} - /* push r0-r12*/ - STMFD SP!, {R0-R12} - STMFD SP!, {R2} + /* jump R0 - R3 USP, ULR reserved */ + SUB SP, SP, #(8 * 4) - /* 8 bytes stack align */ - SUB SP, SP, #4 + /* push R4 - R11*/ + STMFD SP!, {R4-R11} /* save fpu registers */ PUSH_FPU_REGS R2 @@ -113,131 +113,86 @@ OsTaskContextLoad: /* restore fpu registers */ POP_FPU_REGS R2 - /* 8 bytes stack align */ - ADD SP, SP, #4 - - LDMFD SP!, {R0} - MOV R4, R0 - AND R0, R0, #CPSR_MASK_MODE + LDMFD SP!, {R4-R11} + LDR R3, [SP, #(11 * 4)] + AND R0, R3, #CPSR_MASK_MODE CMP R0, #CPSR_USER_MODE BNE OsKernelTaskLoad + MVN R2, #CPSR_INT_DISABLE + AND R3, R3, R2 + STR R3, [SP, #(11 * 4)] + #ifdef LOSCFG_KERNEL_SMP - /* 8 bytes stack align */ - SUB SP, SP, #4 BL OsSchedToUserReleaseLock - ADD SP, SP, #4 #endif - MVN R3, #CPSR_INT_DISABLE - AND R4, R4, R3 - MSR SPSR_cxsf, R4 - - /* restore r0-r12, lr */ - LDMFD SP!, {R0-R12} + /* jump sp, reserved */ + ADD SP, SP, #(2 * 4) LDMFD SP, {R13, R14}^ ADD SP, SP, #(2 * 4) - LDMFD SP!, {PC}^ + LDMFD SP!, {R0-R3, R12, LR} + RFEIA SP! OsKernelTaskLoad: - MSR SPSR_cxsf, R4 - /* restore r0-r12, lr */ - LDMFD SP!, {R0-R12} - ADD SP, SP, #4 - LDMFD SP!, {LR, PC}^ + ADD SP, SP, #(4 * 4) + LDMFD SP!, {R0-R3, R12, LR} + RFEIA SP! OsIrqHandler: SUB LR, LR, #4 - /* push r0-r3 to irq stack */ - STMFD SP, {R0-R3} - SUB R0, SP, #(4 * 4) - MRS R1, SPSR - MOV R2, LR - + /* Save pc and cpsr to svc sp, ARMv6 and above support */ + SRSFD #0x13! /* disable irq, switch to svc mode */ CPSID i, #0x13 - /* push spsr and pc in svc stack */ - STMFD SP!, {R1, R2} - STMFD SP, {LR} - - AND R3, R1, #CPSR_MASK_MODE - CMP R3, #CPSR_USER_MODE - BNE OsIrqFromKernel - - /* push user sp, lr in svc stack */ + STMFD SP!, {R0-R3, R12, LR} STMFD SP, {R13, R14}^ - -OsIrqFromKernel: - /* from svc not need save sp and lr */ - SUB SP, SP, #(2 * 4) - - /* pop r0-r3 form irq stack*/ - LDMFD R0, {R0-R3} - - /* push caller saved regs as trashed regs in svc stack */ - STMFD SP!, {R0-R3, R12} - - /* 8 bytes stack align */ - SUB SP, SP, #4 + SUB SP, SP, #(4 * 4) + STR R4, [SP, #0] /* * save fpu regs in case in case those been * altered in interrupt handlers. */ PUSH_FPU_REGS R0 -#ifdef LOSCFG_IRQ_USE_STANDALONE_STACK - PUSH {R4} + MOV R4, SP EXC_SP_SET __svc_stack_top, OS_EXC_SVC_STACK_SIZE, R1, R2 -#endif BLX HalIrqHandler -#ifdef LOSCFG_IRQ_USE_STANDALONE_STACK MOV SP, R4 - POP {R4} -#endif /* process pending signals */ - BL OsTaskProcSignal - - BL OsSchedIrqEndCheckNeedSched - - MOV R0,SP - MOV R1,R7 - BL OsSaveSignalContextIrq + BLX OsTaskProcSignal + BLX OsSchedIrqEndCheckNeedSched /* restore fpu regs */ - POP_FPU_REGS R0 - - ADD SP, SP, #4 - -OsIrqContextRestore: - LDR R0, [SP, #(4 * 7)] - MSR SPSR_cxsf, R0 - AND R0, R0, #CPSR_MASK_MODE - CMP R0, #CPSR_USER_MODE - - LDMFD SP!, {R0-R3, R12} - - BNE OsIrqContextRestoreToKernel - + POP_FPU_REGS R0 + LDR R4, [SP, #0] + + /* Obtain the CPSR to determine the mode the system is in when the interrupt is triggered */ + LDR R3, [SP, #(11 * 4)] + AND R1, R3, #CPSR_MASK_MODE + CMP R1, #CPSR_USER_MODE + BNE 1f + + MOV R0, SP + STR R7, [SP, #0] + /* sp - sizeof(IrqContext) */ + SUB SP, SP, #(12 * 4) + MOV R1, SP + BLX OsSaveSignalContext + MOV SP, R0 +1: + ADD SP, SP, #(2 * 4) /* load user sp and lr, and jump cpsr */ LDMFD SP, {R13, R14}^ - ADD SP, SP, #(3 * 4) - - /* return to user mode */ - LDMFD SP!, {PC}^ - -OsIrqContextRestoreToKernel: - /* svc mode not load sp */ - ADD SP, SP, #4 - LDMFD SP!, {LR} - /* jump cpsr and return to svc mode */ - ADD SP, SP, #4 - LDMFD SP!, {PC}^ + ADD SP, SP, #(2 * 4) + LDMFD SP!, {R0-R3, R12, LR} + RFEIA SP! FUNCTION(ArchSpinLock) mov r1, #1 diff --git a/arch/arm/arm/src/los_exc.c b/arch/arm/arm/src/los_exc.c index 7b047fcd7f433a25ad4e2ea1b48d3f3fc8a0974b..e7a1a87c8cf97698658da5c9a12e702040baed10 100644 --- a/arch/arm/arm/src/los_exc.c +++ b/arch/arm/arm/src/los_exc.c @@ -104,11 +104,7 @@ STATIC UINT32 g_nextExcWaitCpu = INVALID_CPUID; (IS_ALIGNED((ptr), sizeof(CHAR *)))) STATIC const StackInfo g_excStack[] = { - { &__undef_stack, OS_EXC_UNDEF_STACK_SIZE, "udf_stack" }, - { &__abt_stack, OS_EXC_ABT_STACK_SIZE, "abt_stack" }, - { &__fiq_stack, OS_EXC_FIQ_STACK_SIZE, "fiq_stack" }, { &__svc_stack, OS_EXC_SVC_STACK_SIZE, "svc_stack" }, - { &__irq_stack, OS_EXC_IRQ_STACK_SIZE, "irq_stack" }, { &__exc_stack, OS_EXC_STACK_SIZE, "exc_stack" } }; @@ -829,7 +825,7 @@ VOID OsTaskBackTrace(UINT32 taskID) } PRINTK("TaskName = %s\n", taskCB->taskName); PRINTK("TaskID = 0x%x\n", taskCB->taskID); - BackTrace(((TaskContext *)(taskCB->stackPointer))->R[11]); /* R11 : FP */ + BackTrace(((TaskContext *)(taskCB->stackPointer))->R11); /* R11 : FP */ } VOID OsBackTrace(VOID) diff --git a/arch/arm/arm/src/los_hw.c b/arch/arm/arm/src/los_hw.c index f7b053dd6e116982f839cf86b3a44689ec282c99..5af4068c6a850af39a1a591476c9d3c163c7d909 100644 --- a/arch/arm/arm/src/los_hw.c +++ b/arch/arm/arm/src/los_hw.c @@ -32,7 +32,6 @@ #include "los_hw_pri.h" #include "los_task_pri.h" - /* support cpu vendors */ CpuVendor g_cpuTable[] = { /* armv7-a */ @@ -72,13 +71,10 @@ VOID OsTaskEntrySetupLoopFrame(UINT32 arg0) LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack, BOOL initFlag) { - UINT32 index = 1; - TaskContext *taskContext = NULL; - if (initFlag == TRUE) { OsStackInit(topStack, stackSize); } - taskContext = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + TaskContext *taskContext = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); /* initialize the task context */ #ifdef LOSCFG_GDB @@ -87,22 +83,17 @@ LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOI taskContext->PC = (UINTPTR)OsTaskEntry; #endif taskContext->LR = (UINTPTR)OsTaskExit; /* LR should be kept, to distinguish it's THUMB or ARM instruction */ - taskContext->resved = 0x0; - taskContext->R[0] = taskID; /* R0 */ - taskContext->R[index++] = 0x01010101; /* R1, 0x01010101 : reg initialed magic word */ - for (; index < GEN_REGS_NUM; index++) { - taskContext->R[index] = taskContext->R[index - 1] + taskContext->R[1]; /* R2 - R12 */ - } + taskContext->R0 = taskID; /* R0 */ #ifdef LOSCFG_INTERWORK_THUMB - taskContext->regPSR = PSR_MODE_SVC_THUMB; /* CPSR (Enable IRQ and FIQ interrupts, THUMNB-mode) */ + taskContext->regCPSR = PSR_MODE_SVC_THUMB; /* CPSR (Enable IRQ and FIQ interrupts, THUMNB-mode) */ #else - taskContext->regPSR = PSR_MODE_SVC_ARM; /* CPSR (Enable IRQ and FIQ interrupts, ARM-mode) */ + taskContext->regCPSR = PSR_MODE_SVC_ARM; /* CPSR (Enable IRQ and FIQ interrupts, ARM-mode) */ #endif #if !defined(LOSCFG_ARCH_FPU_DISABLE) /* 0xAAA0000000000000LL : float reg initialed magic word */ - for (index = 0; index < FP_REGS_NUM; index++) { + for (UINT32 index = 0; index < FP_REGS_NUM; index++) { taskContext->D[index] = 0xAAA0000000000000LL + index; /* D0 - D31 */ } taskContext->regFPSCR = 0; @@ -112,32 +103,38 @@ LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOI return (VOID *)taskContext; } -LITE_OS_SEC_TEXT VOID OsUserCloneParentStack(LosTaskCB *childTaskCB, LosTaskCB *parentTaskCB) +LITE_OS_SEC_TEXT VOID OsUserCloneParentStack(VOID *childStack, UINTPTR parentTopOfStack, UINT32 parentStackSize) { - TaskContext *context = (TaskContext *)childTaskCB->stackPointer; - VOID *cloneStack = (VOID *)(((UINTPTR)parentTaskCB->topOfStack + parentTaskCB->stackSize) - sizeof(TaskContext)); - - LOS_ASSERT(parentTaskCB->taskStatus & OS_TASK_STATUS_RUNNING); + VOID *cloneStack = (VOID *)(((UINTPTR)parentTopOfStack + parentStackSize) - sizeof(TaskContext)); - (VOID)memcpy_s(childTaskCB->stackPointer, sizeof(TaskContext), cloneStack, sizeof(TaskContext)); - context->R[0] = 0; + (VOID)memcpy_s(childStack, sizeof(TaskContext), cloneStack, sizeof(TaskContext)); + ((TaskContext *)childStack)->R0 = 0; } -LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, TSK_ENTRY_FUNC taskEntry, UINTPTR stack) +LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, UINTPTR taskEntry, UINTPTR stack) { LOS_ASSERT(context != NULL); #ifdef LOSCFG_INTERWORK_THUMB - context->regPSR = PSR_MODE_USR_THUMB; + context->regCPSR = PSR_MODE_USR_THUMB; #else - context->regPSR = PSR_MODE_USR_ARM; + context->regCPSR = PSR_MODE_USR_ARM; #endif - context->R[0] = stack; - context->SP = TRUNCATE(stack, LOSCFG_STACK_POINT_ALIGN_SIZE); - context->LR = 0; + context->R0 = stack; + context->USP = TRUNCATE(stack, LOSCFG_STACK_POINT_ALIGN_SIZE); + context->ULR = 0; context->PC = (UINTPTR)taskEntry; } +VOID OsInitSignalContext(VOID *sp, VOID *signalContext, UINTPTR sigHandler, UINT32 signo, UINT32 param) +{ + IrqContext *newSp = (IrqContext *)signalContext; + (VOID)memcpy_s(signalContext, sizeof(IrqContext), sp, sizeof(IrqContext)); + newSp->PC = sigHandler; + newSp->R0 = signo; + newSp->R1 = param; +} + DEPRECATED VOID Dmb(VOID) { __asm__ __volatile__ ("dmb" : : : "memory"); diff --git a/arch/arm/arm/src/los_hw_exc.S b/arch/arm/arm/src/los_hw_exc.S index a1d7d2e9b016d577cde4d43b11b13225ca1e34b5..82dad4f8e0bff1df7a66869b782b72d26b865c30 100644 --- a/arch/arm/arm/src/los_hw_exc.S +++ b/arch/arm/arm/src/los_hw_exc.S @@ -47,9 +47,10 @@ .extern OsDataAbortExcHandleEntry #endif #endif + .extern OsSaveSignalContext + .extern OsRestorSignalContext .extern OsArmSharedPageFault .extern OsArmA32SyscallHandle - .extern LOS_Exit .global _osExceptFiqHdl .global _osExceptAddrAbortHdl @@ -63,7 +64,6 @@ .global __stack_chk_guard_setup #endif - .fpu vfpv4 .macro PUSH_FPU_REGS reg1 @@ -173,69 +173,75 @@ _osExceptUndefInstrHdl: #ifdef LOSCFG_GDB GDB_HANDLE OsUndefIncExcHandleEntry #else - @ LR offset to return from this exception: 0. - STMFD SP, {R0-R7} @ Push working registers, but don`t change SP. + SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support + MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) @ Switch to svc mode, and disable all interrupt + STMFD SP!, {R0-R3, R12, LR} + STMFD SP, {R13, R14}^ @ push user sp and lr + SUB SP, SP, #(2 * 4) + MOV R2, #0 + MOV R3, #0 + STMFD SP!, {R2-R3} @ far and fsr fields, are 0 under this anomaly MOV R0, #OS_EXCEPT_UNDEF_INSTR @ Set exception ID to OS_EXCEPT_UNDEF_INSTR. - B _osExceptDispatch @ Branch to global exception handler. - #endif @ Description: Software interrupt exception handler _osExceptSwiHdl: - SUB SP, SP, #(4 * 16) - STMIA SP, {R0-R12} - MRS R3, SPSR - MOV R4, LR + SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support + STMFD SP!, {R0-R3, R12, LR} + STMFD SP, {R13, R14}^ + SUB SP, SP, #(4 * 4) @ push user sp and lr and jump reserved field + STR R7, [SP, #0] @ Save system call number to reserved2 filed #ifdef LOSCFG_KERNEL_SYSCALL - AND R1, R3, #CPSR_MASK_MODE @ Interrupted mode - CMP R1, #CPSR_USER_MODE @ User mode - BNE OsKernelSVCHandler @ Branch if not user mode + LDR R3, [SP, #(11 * 4)] + AND R1, R3, #CPSR_MASK_MODE @ Interrupted mode + CMP R1, #CPSR_USER_MODE @ User mode + BNE _osKernelSVCHandler @ Branch if not user mode - @ we enter from user mode, we need get the values of USER mode r13(sp) and r14(lr). - @ stmia with ^ will return the user mode registers (provided that r15 is not in the register list). + CMP R7, #119 @ __NR_sigreturn + BNE _osIsSyscall MOV R0, SP - STMFD SP!, {R3} @ Save the CPSR - ADD R3, SP, #(4 * 17) @ Offset to pc/cpsr storage - STMFD R3!, {R4} @ Save the CPSR and r15(pc) - STMFD R3, {R13, R14}^ @ Save user mode r13(sp) and r14(lr) - SUB SP, SP, #4 + BLX OsRestorSignalContext + MOV SP, R0 + B _osSyscallReturn + +_osIsSyscall: + STMFD SP!, {R4-R11} + PUSH_FPU_REGS R1 - MOV FP, #0 @ Init frame pointer + MOV R0, SP + MOV FP, #0 @ Init frame pointer CPSIE I BLX OsArmA32SyscallHandle CPSID I POP_FPU_REGS R1 - ADD SP, SP,#4 - LDMFD SP!, {R3} @ Fetch the return SPSR - MSR SPSR_cxsf, R3 @ Set the return mode SPSR - - @ we are leaving to user mode, we need to restore the values of USER mode r13(sp) and r14(lr). - @ ldmia with ^ will return the user mode registers (provided that r15 is not in the register list) + LDMFD SP!, {R4-R11} - LDMFD SP!, {R0-R12} + MOV R0, SP + SUB SP, SP, #(12 * 4) @ sp - sizeof(IrqContext), reserved for signal + MOV R1, SP + BLX OsSaveSignalContext + MOV SP, R0 + +_osSyscallReturn: + LDR R7, [SP, #0] + ADD SP, SP, #(2 * 4) @ jump reserved filed LDMFD SP, {R13, R14}^ @ Restore user mode R13/R14 ADD SP, SP, #(2 * 4) - LDMFD SP!, {PC}^ @ Return to user + LDMFD SP!, {R0-R3, R12, LR} + RFEIA SP! @ Return to user -OsKernelSVCHandler: +_osKernelSVCHandler: #endif - ADD R0, SP, #(4 * 16) - MOV R5, R0 - STMFD R0!, {R4} @ Store PC - STMFD R0!, {R4} - STMFD R0!, {R5} - - STMFD SP!, {R3} @ Push task`s CPSR (i.e. exception SPSR). - SUB SP, SP, #(4 * 2) @ user sp and lr - + MOV R0, #0 + STR R0, [SP, #0] + STR R0, [SP, #4] MOV R0, #OS_EXCEPT_SWI @ Set exception ID to OS_EXCEPT_SWI. - - B _osExceptionSwi @ Branch to global exception handler. + B _osExceptDispatch @ Branch to global exception handler. @ Description: Prefectch abort exception handler _osExceptPrefetchAbortHdl: @@ -245,20 +251,36 @@ _osExceptPrefetchAbortHdl: #endif #else SUB LR, LR, #4 @ LR offset to return from this exception: -4. - STMFD SP, {R0-R7} @ Push working registers, but don`t change SP. - MOV R5, LR - MRS R1, SPSR - MOV R0, #OS_EXCEPT_PREFETCH_ABORT @ Set exception ID to OS_EXCEPT_PREFETCH_ABORT. + SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support + MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) @ Switch to svc mode, and disable all interrupt + STMFD SP!, {R0-R3, R12, LR} + STMFD SP, {R13, R14}^ + SUB SP, SP, #(2 * 4) + + MRC P15, 0, R2, C6, C0, 2 + MRC P15, 0, R3, C5, C0, 1 + STMFD SP!, {R2-R3} @ Save far and fsr #ifdef LOSCFG_KERNEL_VM - AND R4, R1, #CPSR_MASK_MODE @ Interrupted mode - CMP R4, #CPSR_USER_MODE @ User mode - BEQ _osExcPageFault @ Branch if user mode + LDR R0, [SP, #(11 * 4)] + AND R0, R0, #CPSR_MASK_MODE @ Interrupted mode + CMP R0, #CPSR_USER_MODE @ User mode + BNE _osKernelExceptPrefetchAbortHdl + + MOV R1, SP + PUSH_FPU_REGS R0 + + MOV R0, #OS_EXCEPT_PREFETCH_ABORT + BLX OsArmSharedPageFault + CMP R0, #0 + + POP_FPU_REGS R0 + BEQ _osExcPageFaultReturn #endif _osKernelExceptPrefetchAbortHdl: - MOV LR, R5 + MOV R0, #OS_EXCEPT_PREFETCH_ABORT B _osExceptDispatch @ Branch to global exception handler. #endif @@ -270,120 +292,86 @@ _osExceptDataAbortHdl: #endif #else SUB LR, LR, #8 @ LR offset to return from this exception: -8. - STMFD SP, {R0-R7} @ Push working registers, but don`t change SP. - MOV R5, LR - MRS R1, SPSR - MOV R0, #OS_EXCEPT_DATA_ABORT @ Set exception ID to OS_EXCEPT_DATA_ABORT. + SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support + MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) @ Switch to svc mode, and disable all interrupt + STMFD SP!, {R0-R3, R12, LR} + STMFD SP, {R13, R14}^ + SUB SP, SP, #(2 * 4) + + MRC P15, 0, R2, C6, C0, 0 + MRC P15, 0, R3, C5, C0, 0 + STMFD SP!, {R2-R3} @ Save far and fsr + #ifdef LOSCFG_KERNEL_VM - B _osExcPageFault -#else + MOV R1, SP + PUSH_FPU_REGS R0 + + MOV R0, #OS_EXCEPT_DATA_ABORT @ Set exception ID to OS_EXCEPT_DATA_ABORT. + BLX OsArmSharedPageFault + CMP R0, #0 + POP_FPU_REGS R0 + BEQ _osExcPageFaultReturn +#endif + + MOV R0, #OS_EXCEPT_DATA_ABORT B _osExceptDispatch #endif + +#ifdef LOSCFG_KERNEL_VM +_osExcPageFaultReturn: + ADD SP, SP, #(2 * 4) + LDMFD SP, {R13, R14}^ + ADD SP, SP, #(2 * 4) @ Jump reserved fileds + LDMFD SP!, {R0-R3, R12, LR} + RFEIA SP! #endif @ Description: Address abort exception handler _osExceptAddrAbortHdl: SUB LR, LR, #8 @ LR offset to return from this exception: -8. - STMFD SP, {R0-R7} @ Push working registers, but don`t change SP. - MOV R0, #OS_EXCEPT_ADDR_ABORT @ Set exception ID to OS_EXCEPT_ADDR_ABORT. + SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support + MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) @ Switch to svc mode, and disable all interrupt + STMFD SP!, {R0-R3, R12, LR} + STMFD SP, {R13, R14}^ + SUB SP, SP, #(2 * 4) + MOV R2, #0 + MOV R3, #0 + STMFD SP!, {R2-R3} @ far and fsr fields, are 0 under this anomaly + + MOV R0, #OS_EXCEPT_ADDR_ABORT @ Set exception ID to OS_EXCEPT_ADDR_ABORT. B _osExceptDispatch @ Branch to global exception handler. @ Description: Fast interrupt request exception handler _osExceptFiqHdl: SUB LR, LR, #4 @ LR offset to return from this exception: -4. - STMFD SP, {R0-R7} @ Push working registers. - - MOV R0, #OS_EXCEPT_FIQ @ Set exception ID to OS_EXCEPT_FIQ. - - B _osExceptDispatch @ Branch to global exception handler. - -#ifdef LOSCFG_KERNEL_VM -_osExcPageFault: - SUB R3, SP, #(8 * 4) @ Save the start address of working registers. - MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) @ Switch to SVC mode, and disable all interrupts - MOV R2, SP - STMFD SP!, {R5} @ Push original PC - STMFD SP!, {LR} @ Push original svc LR - STMFD SP!, {R2} @ Push original svc SP - STMFD SP!, {R8-R12} @ Push original R12-R8, - LDMFD R3!, {R4-R11} @ Move original R7-R0 from exception stack to original stack. - STMFD SP!, {R4-R11} - STMFD SP!, {R1} - SUB SP, SP, #8 - STMIA SP, {R13, R14}^ @ Save user mode r13(sp) and r14(lr) - - MOV R4, SP - BIC SP, SP, #7 - PUSH_FPU_REGS R1 - - CMP R0, #OS_EXCEPT_DATA_ABORT - BNE 1f - MRC P15, 0, R2, C6, C0, 0 - MRC P15, 0, R3, C5, C0, 0 - B 2f -1: MRC P15, 0, R2, C6, C0, 2 - MRC P15, 0, R3, C5, C0, 1 -2: MOV R1, R4 - MOV R5, R0 - MOV R8, R2 - MOV R9, R3 - BLX OsArmSharedPageFault - - POP_FPU_REGS R1 - MOV SP, R4 - CMP R0, #0 - BEQ _OsExcReturn + SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support + MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) @ Switch to svc mode, and disable all interrupt + STMFD SP!, {R0-R3, R12, LR} + STMFD SP, {R13, R14}^ + SUB SP, SP, #(2 * 4) - MOV R0, R5 @ exc type - B _osExceptionSwi -#endif + MOV R2, #0 + MOV R3, #0 + STMFD SP!, {R2-R3} @ far and fsr fields, are 0 under this anomaly @ Description: Exception handler @ Parameter : R0 Exception Type @ Regs Hold : R3 Exception`s CPSR _osExceptDispatch: - MRS R2, SPSR @ Save CPSR before exception. - MOV R1, LR @ Save PC before exception. - SUB R3, SP, #(8 * 4) @ Save the start address of working registers. + STMFD SP!, {R4-R11} + LDR R8, [SP, #(8 * 4)] @ Get far + LDR R9, [SP, #(9 * 4)] @ Get fsr - MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) @ Switch to SVC mode, and disable all interrupts - MOV R5, SP - EXC_SP_SET __exc_stack_top, OS_EXC_STACK_SIZE, R6, R7 + ADD R2, SP, #(20 * 4) @ sp + sizeof(ExcContext), position of SVC stack before exception + STR R2, [SP, #(8 * 4)] @ Save svc sp - STMFD SP!, {R1} @ Push Exception PC - STMFD SP!, {LR} @ Push SVC LR - STMFD SP!, {R5} @ Push SVC SP - STMFD SP!, {R8-R12} @ Push original R12-R8, - LDMFD R3!, {R4-R11} @ Move original R7-R0 from exception stack to original stack. - STMFD SP!, {R4-R11} - STMFD SP!, {R2} @ Push task`s CPSR (i.e. exception SPSR). - - CMP R0, #OS_EXCEPT_DATA_ABORT - BNE 1f - MRC P15, 0, R8, C6, C0, 0 - MRC P15, 0, R9, C5, C0, 0 - B 3f -1: CMP R0, #OS_EXCEPT_PREFETCH_ABORT - BNE 2f - MRC P15, 0, R8, C6, C0, 2 - MRC P15, 0, R9, C5, C0, 1 - B 3f -2: MOV R8, #0 - MOV R9, #0 - -3: AND R2, R2, #CPSR_MASK_MODE - CMP R2, #CPSR_USER_MODE @ User mode - BNE 4f - STMFD SP, {R13, R14}^ @ save user mode sp and lr -4: - SUB SP, SP, #(4 * 2) - -_osExceptionSwi: - MOV R1, SP @ The second argument to the exception + MOV R1, SP + + EXC_SP_SET __exc_stack_top, OS_EXC_STACK_SIZE, R6, R7 MRC P15, 0, R4, C0, C0, 5 AND R4, R4, #MPIDR_CPUID_MASK @ Get Current cpu id @@ -412,19 +400,4 @@ _osExceptionGetSP: LDR R5, =OsExcHandleEntry @ OsExcHandleEntry(UINT32 excType, ExcContext * excBufAddr) BX R5 -_OsExcReturn: - LDR R0, [SP, #(2 * 4)] - AND R0, R0, #CPSR_MASK_MODE - CMP R0, #CPSR_USER_MODE @ User mode - BNE _OsExcReturnToKernel - LDMFD SP, {R13, R14}^ @ load user mode sp and lr - -_OsExcReturnToKernel: - ADD SP, SP, #(2 * 4) - LDMFD SP!, {R1} - MSR SPSR_cxsf, R1 @ Set the return mode SPSR - LDMFD SP!, {R0-R12} - ADD SP, SP, #4 - LDMFD SP!, {LR, PC}^ - .end diff --git a/arch/arm/arm/src/startup/reset_vector_mp.S b/arch/arm/arm/src/startup/reset_vector_mp.S index 4889b16578e9822f9aabd8b786b56a9da2c2a5c0..2ac92e1a77e10085fad2207a13da88d93afa677e 100644 --- a/arch/arm/arm/src/startup/reset_vector_mp.S +++ b/arch/arm/arm/src/startup/reset_vector_mp.S @@ -37,17 +37,9 @@ .global __exc_stack_top - .global __irq_stack_top - .global __fiq_stack_top .global __svc_stack_top - .global __abt_stack_top - .global __undef_stack_top .global __exc_stack - .global __irq_stack - .global __fiq_stack .global __svc_stack - .global __abt_stack - .global __undef_stack .extern __bss_start .extern __bss_end @@ -219,35 +211,14 @@ reloc_img_to_bottom_done: bl mmu_setup /* set up the mmu */ #endif /* clear out the interrupt and exception stack and set magic num to check the overflow */ - ldr r0, =__undef_stack + ldr r0, =__svc_stack ldr r1, =__exc_stack_top bl stack_init - STACK_MAGIC_SET __undef_stack, #OS_EXC_UNDEF_STACK_SIZE, OS_STACK_MAGIC_WORD - STACK_MAGIC_SET __abt_stack, #OS_EXC_ABT_STACK_SIZE, OS_STACK_MAGIC_WORD - STACK_MAGIC_SET __irq_stack, #OS_EXC_IRQ_STACK_SIZE, OS_STACK_MAGIC_WORD - STACK_MAGIC_SET __fiq_stack, #OS_EXC_FIQ_STACK_SIZE, OS_STACK_MAGIC_WORD STACK_MAGIC_SET __svc_stack, #OS_EXC_SVC_STACK_SIZE, OS_STACK_MAGIC_WORD STACK_MAGIC_SET __exc_stack, #OS_EXC_STACK_SIZE, OS_STACK_MAGIC_WORD warm_reset: - /* initialize interrupt/exception environments */ - mov r0, #(CPSR_IRQ_DISABLE |CPSR_FIQ_DISABLE|CPSR_IRQ_MODE) - msr cpsr, r0 - EXC_SP_SET __irq_stack_top, #OS_EXC_IRQ_STACK_SIZE - - mov r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_UNDEF_MODE) - msr cpsr, r0 - EXC_SP_SET __undef_stack_top, #OS_EXC_UNDEF_STACK_SIZE - - mov r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_ABT_MODE) - msr cpsr, r0 - EXC_SP_SET __abt_stack_top, #OS_EXC_ABT_STACK_SIZE - - mov r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_FIQ_MODE) - msr cpsr, r0 - EXC_SP_SET __fiq_stack_top, #OS_EXC_FIQ_STACK_SIZE - /* initialize CPSR (machine state register) */ mov r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SVC_MODE) msr cpsr, r0 @@ -498,22 +469,6 @@ init_flag: .section ".int_stack", "wa", %nobits .align 3 -__undef_stack: - .space OS_EXC_UNDEF_STACK_SIZE * CORE_NUM -__undef_stack_top: - -__abt_stack: - .space OS_EXC_ABT_STACK_SIZE * CORE_NUM -__abt_stack_top: - -__irq_stack: - .space OS_EXC_IRQ_STACK_SIZE * CORE_NUM -__irq_stack_top: - -__fiq_stack: - .space OS_EXC_FIQ_STACK_SIZE * CORE_NUM -__fiq_stack_top: - __svc_stack: .space OS_EXC_SVC_STACK_SIZE * CORE_NUM __svc_stack_top: diff --git a/arch/arm/arm/src/startup/reset_vector_up.S b/arch/arm/arm/src/startup/reset_vector_up.S index 7cd58d6ee1552f2febd483cd3cf80b2b2166a30e..5d3b5f6152dc1ad2e96b2d17d1645a666ba20f19 100644 --- a/arch/arm/arm/src/startup/reset_vector_up.S +++ b/arch/arm/arm/src/startup/reset_vector_up.S @@ -38,17 +38,9 @@ .global __exc_stack_top - .global __irq_stack_top - .global __fiq_stack_top .global __svc_stack_top - .global __abt_stack_top - .global __undef_stack_top .global __exc_stack - .global __irq_stack - .global __fiq_stack .global __svc_stack - .global __abt_stack - .global __undef_stack .extern __bss_start .extern __bss_end @@ -201,36 +193,15 @@ reloc_img_to_bottom_done: excstatck_loop: /* clear out the interrupt and exception stack and set magic num to check the overflow */ - ldr r0, =__undef_stack + ldr r0, =__svc_stack ldr r1, =__exc_stack_top bl stack_init - STACK_MAGIC_SET __undef_stack, #OS_EXC_UNDEF_STACK_SIZE, OS_STACK_MAGIC_WORD - STACK_MAGIC_SET __abt_stack, #OS_EXC_ABT_STACK_SIZE, OS_STACK_MAGIC_WORD - STACK_MAGIC_SET __irq_stack, #OS_EXC_IRQ_STACK_SIZE, OS_STACK_MAGIC_WORD - STACK_MAGIC_SET __fiq_stack, #OS_EXC_FIQ_STACK_SIZE, OS_STACK_MAGIC_WORD STACK_MAGIC_SET __svc_stack, #OS_EXC_SVC_STACK_SIZE, OS_STACK_MAGIC_WORD STACK_MAGIC_SET __exc_stack, #OS_EXC_STACK_SIZE, OS_STACK_MAGIC_WORD excstatck_loop_done: warm_reset: - /* initialize interrupt/exception environments */ - mov r0, #(CPSR_IRQ_DISABLE |CPSR_FIQ_DISABLE|CPSR_IRQ_MODE) - msr cpsr, r0 - EXC_SP_SET __irq_stack_top, #OS_EXC_IRQ_STACK_SIZE - - mov r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_UNDEF_MODE) - msr cpsr, r0 - EXC_SP_SET __undef_stack_top, #OS_EXC_UNDEF_STACK_SIZE - - mov r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_ABT_MODE) - msr cpsr, r0 - EXC_SP_SET __abt_stack_top, #OS_EXC_ABT_STACK_SIZE - - mov r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_FIQ_MODE) - msr cpsr, r0 - EXC_SP_SET __fiq_stack_top, #OS_EXC_FIQ_STACK_SIZE - /* initialize CPSR (machine state register) */ mov r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SVC_MODE) msr cpsr, r0 @@ -464,22 +435,6 @@ init_flag: .section ".int_stack", "wa", %nobits .align 3 -__undef_stack: - .space OS_EXC_UNDEF_STACK_SIZE * CORE_NUM -__undef_stack_top: - -__abt_stack: - .space OS_EXC_ABT_STACK_SIZE * CORE_NUM -__abt_stack_top: - -__irq_stack: - .space OS_EXC_IRQ_STACK_SIZE * CORE_NUM -__irq_stack_top: - -__fiq_stack: - .space OS_EXC_FIQ_STACK_SIZE * CORE_NUM -__fiq_stack_top: - __svc_stack: .space OS_EXC_SVC_STACK_SIZE * CORE_NUM __svc_stack_top: diff --git a/arch/arm/include/los_exc.h b/arch/arm/include/los_exc.h index 0a265cdcc16fbdc818bf2de3520cf8af32822c07..893f06e00ca1397724b34e331efd937ef5906e8c 100644 --- a/arch/arm/include/los_exc.h +++ b/arch/arm/include/los_exc.h @@ -63,26 +63,29 @@ typedef struct { UINT64 SPSR; } ExcContext; #else +/* It has the same structure as TaskContext */ typedef struct { - UINT32 USP; /**< User mode stack pointer */ - UINT32 ULR; /**< User mode program returning address */ - UINT32 regCPSR; /**< Current program status register (CPSR) */ + UINT32 R4; + UINT32 R5; + UINT32 R6; + UINT32 R7; + UINT32 R8; + UINT32 R9; + UINT32 R10; + UINT32 R11; + + UINT32 SP; /**< svc sp */ + UINT32 reserved; /**< Reserved, multiplexing register */ + UINT32 USP; + UINT32 ULR; UINT32 R0; /**< Register R0 */ UINT32 R1; /**< Register R1 */ UINT32 R2; /**< Register R2 */ UINT32 R3; /**< Register R3 */ - UINT32 R4; /**< Register R4 */ - UINT32 R5; /**< Register R5 */ - UINT32 R6; /**< Register R6 */ - UINT32 R7; /**< Register R7 */ - UINT32 R8; /**< Register R8 */ - UINT32 R9; /**< Register R9 */ - UINT32 R10; /**< Register R10 */ - UINT32 R11; /**< Register R11 */ UINT32 R12; /**< Register R12 */ - UINT32 SP; /**< Stack pointer */ UINT32 LR; /**< Program returning address. */ UINT32 PC; /**< PC pointer of the exceptional function */ + UINT32 regCPSR; } ExcContext; #endif diff --git a/arch/arm/include/los_sys_stack_pri.h b/arch/arm/include/los_sys_stack_pri.h index e45e4a66f50ec1ec2777663b0ff64daca6a1b580..5681419b242e3c7aae9a508037d0fe3673ac2e4a 100644 --- a/arch/arm/include/los_sys_stack_pri.h +++ b/arch/arm/include/los_sys_stack_pri.h @@ -44,19 +44,11 @@ extern "C" { extern UINTPTR __stack_startup; extern UINTPTR __stack_startup_top; #else -extern UINTPTR __fiq_stack_top; extern UINTPTR __svc_stack_top; -extern UINTPTR __abt_stack_top; -extern UINTPTR __undef_stack_top; extern UINTPTR __exc_stack_top; -extern UINTPTR __fiq_stack; extern UINTPTR __svc_stack; -extern UINTPTR __abt_stack; -extern UINTPTR __undef_stack; extern UINTPTR __exc_stack; #endif -extern UINTPTR __irq_stack_top; -extern UINTPTR __irq_stack; #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index a8c8130f6db5e45c188b8c06401be3af94290cb0..7ea277e8b407bd2e51728772c3245aec1af2efb8 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -1349,8 +1349,6 @@ LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize) { - LosTaskCB *taskCB = NULL; - TaskContext *taskContext = NULL; UINT32 intSave; if (entry == NULL) { @@ -1365,15 +1363,16 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT return LOS_NOK; } - SCHEDULER_LOCK(intSave); - taskCB = OsCurrTaskGet(); + LosTaskCB *taskCB = OsCurrTaskGet(); + SCHEDULER_LOCK(intSave); taskCB->userMapBase = mapBase; taskCB->userMapSize = mapSize; taskCB->taskEntry = (TSK_ENTRY_FUNC)entry; - taskContext = (TaskContext *)OsTaskStackInit(taskCB->taskID, taskCB->stackSize, (VOID *)taskCB->topOfStack, FALSE); - OsUserTaskStackInit(taskContext, taskCB->taskEntry, sp); + TaskContext *taskContext = (TaskContext *)OsTaskStackInit(taskCB->taskID, taskCB->stackSize, + (VOID *)taskCB->topOfStack, FALSE); + OsUserTaskStackInit(taskContext, (UINTPTR)taskCB->taskEntry, sp); SCHEDULER_UNLOCK(intSave); return LOS_OK; } @@ -1555,7 +1554,7 @@ STATIC VOID OsInitCopyTaskParam(LosProcessCB *childProcessCB, const CHAR *name, STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR *name, UINTPTR entry, UINT32 size) { - LosTaskCB *childTaskCB = NULL; + LosTaskCB *runTask = OsCurrTaskGet(); TSK_INIT_PARAM_S childPara = { 0 }; UINT32 ret; UINT32 intSave; @@ -1571,8 +1570,8 @@ STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR return LOS_ENOMEM; } - childTaskCB = OS_TCB_FROM_TID(taskID); - childTaskCB->taskStatus = OsCurrTaskGet()->taskStatus; + LosTaskCB *childTaskCB = OS_TCB_FROM_TID(taskID); + childTaskCB->taskStatus = runTask->taskStatus; if (childTaskCB->taskStatus & OS_TASK_STATUS_RUNNING) { childTaskCB->taskStatus &= ~OS_TASK_STATUS_RUNNING; } else { @@ -1585,7 +1584,7 @@ STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR if (OsProcessIsUserMode(childProcessCB)) { SCHEDULER_LOCK(intSave); - OsUserCloneParentStack(childTaskCB, OsCurrTaskGet()); + OsUserCloneParentStack(childTaskCB->stackPointer, runTask->topOfStack, runTask->stackSize); SCHEDULER_UNLOCK(intSave); } return LOS_OK; diff --git a/kernel/base/core/los_task.c b/kernel/base/core/los_task.c index ac0c5e120c673f769af2b1e8ef54287c9b608826..8815a3e453038746e0084ad80dcb4c9effe4c462 100644 --- a/kernel/base/core/los_task.c +++ b/kernel/base/core/los_task.c @@ -571,7 +571,7 @@ STATIC UINT32 OsTaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam, taskCB->userArea = initParam->userParam.userArea; taskCB->userMapBase = initParam->userParam.userMapBase; taskCB->userMapSize = initParam->userParam.userMapSize; - OsUserTaskStackInit(taskCB->stackPointer, taskCB->taskEntry, initParam->userParam.userSP); + OsUserTaskStackInit(taskCB->stackPointer, (UINTPTR)taskCB->taskEntry, initParam->userParam.userSP); } if (!processCB->threadNumber) { diff --git a/kernel/base/include/los_signal.h b/kernel/base/include/los_signal.h index 86b9134f094e0b3e43f04cbe766176ef7232deed..e75f5110627b21efd947f80f03d360e3613bfc42 100644 --- a/kernel/base/include/los_signal.h +++ b/kernel/base/include/los_signal.h @@ -48,9 +48,6 @@ extern "C" { #define LOS_BIT_CLR(val, bit) ((val) = (val) & ~(1ULL << (UINT32)(bit))) #define LOS_IS_BIT_SET(val, bit) (bool)((((val) >> (UINT32)(bit)) & 1ULL)) -#define OS_SYSCALL_SET_CPSR(regs, cpsr) (*((unsigned long *)((UINTPTR)(regs) - 4)) = (cpsr)) -#define OS_SYSCALL_SET_SR(regs, cpsr) (*((unsigned long *)((UINTPTR)(regs))) = (cpsr)) -#define OS_SYSCALL_GET_CPSR(regs) (*((unsigned long *)((UINTPTR)(regs) - 4))) #define SIG_STOP_VISIT 1 #define OS_KERNEL_KILL_PERMISSION 0U @@ -135,27 +132,6 @@ struct sq_queue_s { }; typedef struct sq_queue_s sq_queue_t; -#define TASK_IRQ_CONTEXT \ - unsigned int R0; \ - unsigned int R1; \ - unsigned int R2; \ - unsigned int R3; \ - unsigned int R12; \ - unsigned int USP; \ - unsigned int ULR; \ - unsigned int CPSR; \ - unsigned int PC; - -typedef struct { - TASK_IRQ_CONTEXT -} TaskIrqDataSize; - -typedef struct { - TASK_IRQ_CONTEXT - unsigned int R7; - unsigned int count; -} sig_switch_context; - typedef struct { sigset_t sigFlag; sigset_t sigPendFlag; @@ -164,7 +140,8 @@ typedef struct { LOS_DL_LIST waitList; sigset_t sigwaitmask; /* Waiting for pending signals */ siginfo_t sigunbinfo; /* Signal info when task unblocked */ - sig_switch_context context; + void *sigContext; + unsigned int count; } sig_cb; #define SIGEV_THREAD_ID 4 @@ -180,8 +157,6 @@ int OsPthreadKill(UINT32 tid, int signo); int OsSigEmptySet(sigset_t *); int OsSigAddSet(sigset_t *, int); int OsSigIsMember(const sigset_t *, int); -void OsSaveSignalContext(unsigned int *sp); -void OsRestorSignalContext(unsigned int *sp); int OsKill(pid_t pid, int sig, int permission); int OsDispatch(pid_t pid, siginfo_t *info, int permission); int OsSigTimedWait(sigset_t *set, siginfo_t *info, unsigned int timeout); diff --git a/kernel/base/ipc/los_signal.c b/kernel/base/ipc/los_signal.c index 8edd8db467a214b652f2b0336625cda86cae3e29..566b8a6ba79d12fc5f2a85b384a65a1e194216f4 100644 --- a/kernel/base/ipc/los_signal.c +++ b/kernel/base/ipc/los_signal.c @@ -556,131 +556,65 @@ int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact) return LOS_OK; } -void OsSaveSignalContext(unsigned int *sp) +VOID *OsSaveSignalContext(VOID *sp, VOID *newSp) { UINTPTR sigHandler; UINT32 intSave; - LosTaskCB *task = NULL; - LosProcessCB *process = NULL; - sig_cb *sigcb = NULL; - unsigned long cpsr; - OS_RETURN_IF_VOID(sp == NULL); - cpsr = OS_SYSCALL_GET_CPSR(sp); + LosTaskCB *task = OsCurrTaskGet(); + LosProcessCB *process = OsCurrProcessGet(); + sig_cb *sigcb = &task->sig; - OS_RETURN_IF_VOID(((cpsr & CPSR_MASK_MODE) != CPSR_USER_MODE)); SCHEDULER_LOCK(intSave); - task = OsCurrTaskGet(); - process = OsCurrProcessGet(); - sigcb = &task->sig; - - if ((sigcb->context.count == 0) && ((sigcb->sigFlag != 0) || (process->sigShare != 0))) { + if ((sigcb->count == 0) && ((sigcb->sigFlag != 0) || (process->sigShare != 0))) { sigHandler = OsGetSigHandler(); if (sigHandler == 0) { sigcb->sigFlag = 0; process->sigShare = 0; SCHEDULER_UNLOCK(intSave); PRINT_ERR("The signal processing function for the current process pid =%d is NULL!\n", task->processID); - return; + return sp; } /* One pthread do the share signal */ sigcb->sigFlag |= process->sigShare; - unsigned int signo = (unsigned int)FindFirstSetedBit(sigcb->sigFlag) + 1; + UINT32 signo = (UINT32)FindFirstSetedBit(sigcb->sigFlag) + 1; + UINT32 sigVal = (UINT32)(UINTPTR)(sigcb->sigunbinfo.si_value.sival_ptr); OsProcessExitCodeSignalSet(process, signo); - sigcb->context.CPSR = cpsr; - sigcb->context.PC = sp[REG_PC]; - sigcb->context.USP = sp[REG_SP]; - sigcb->context.ULR = sp[REG_LR]; - sigcb->context.R0 = sp[REG_R0]; - sigcb->context.R1 = sp[REG_R1]; - sigcb->context.R2 = sp[REG_R2]; - sigcb->context.R3 = sp[REG_R3]; - sigcb->context.R7 = sp[REG_R7]; - sigcb->context.R12 = sp[REG_R12]; - sp[REG_PC] = sigHandler; - sp[REG_R0] = signo; - sp[REG_R1] = (unsigned int)(UINTPTR)(sigcb->sigunbinfo.si_value.sival_ptr); + sigcb->sigContext = sp; + + OsInitSignalContext(sp, newSp, sigHandler, signo, sigVal); + /* sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */ sigcb->sigFlag ^= 1ULL << (signo - 1); - sigcb->context.count++; + sigcb->count++; + SCHEDULER_UNLOCK(intSave); + return newSp; } SCHEDULER_UNLOCK(intSave); + return sp; } -void OsSaveSignalContextIrq(unsigned int *sp, unsigned int r7) +VOID *OsRestorSignalContext(VOID *sp) { - UINTPTR sigHandler; - LosTaskCB *task = NULL; - LosProcessCB *process = NULL; - sig_cb *sigcb = NULL; - unsigned long cpsr; UINT32 intSave; - TaskIrqContext *context = (TaskIrqContext *)(sp); - OS_RETURN_IF_VOID(sp == NULL); - cpsr = context->CPSR; - OS_RETURN_IF_VOID(((cpsr & CPSR_MASK_MODE) != CPSR_USER_MODE)); + LosTaskCB *task = OsCurrTaskGet(); + sig_cb *sigcb = &task->sig; SCHEDULER_LOCK(intSave); - task = OsCurrTaskGet(); - process = OsCurrProcessGet(); - sigcb = &task->sig; - if ((sigcb->context.count == 0) && ((sigcb->sigFlag != 0) || (process->sigShare != 0))) { - sigHandler = OsGetSigHandler(); - if (sigHandler == 0) { - sigcb->sigFlag = 0; - process->sigShare = 0; - SCHEDULER_UNLOCK(intSave); - PRINT_ERR("The current process pid =%d starts fail!\n", task->processID); - return; - } - sigcb->sigFlag |= process->sigShare; - unsigned int signo = (unsigned int)FindFirstSetedBit(sigcb->sigFlag) + 1; - OsProcessExitCodeSignalSet(process, signo); - (VOID)memcpy_s(&sigcb->context.R0, sizeof(TaskIrqDataSize), &context->R0, sizeof(TaskIrqDataSize)); - sigcb->context.R7 = r7; - context->PC = sigHandler; - context->R0 = signo; - context->R1 = (UINT32)(UINTPTR)sigcb->sigunbinfo.si_value.sival_ptr; - /* sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */ - sigcb->sigFlag ^= 1ULL << (signo - 1); - sigcb->context.count++; + if (sigcb->count != 1) { + SCHEDULER_UNLOCK(intSave); + PRINT_ERR("sig error count : %d\n", sigcb->count); + return sp; } - SCHEDULER_UNLOCK(intSave); -} -void OsRestorSignalContext(unsigned int *sp) -{ - LosTaskCB *task = NULL; /* Do not adjust this statement */ - LosProcessCB *process = NULL; - sig_cb *sigcb = NULL; - UINT32 intSave; - - SCHEDULER_LOCK(intSave); - task = OsCurrTaskGet(); - sigcb = &task->sig; - - if (sigcb->context.count != 1) { - SCHEDULER_UNLOCK(intSave); - PRINT_ERR("sig error count : %d\n", sigcb->context.count); - return; - } - - process = OsCurrProcessGet(); - sp[REG_PC] = sigcb->context.PC; - OS_SYSCALL_SET_CPSR(sp, sigcb->context.CPSR); - sp[REG_SP] = sigcb->context.USP; - sp[REG_LR] = sigcb->context.ULR; - sp[REG_R0] = sigcb->context.R0; - sp[REG_R1] = sigcb->context.R1; - sp[REG_R2] = sigcb->context.R2; - sp[REG_R3] = sigcb->context.R3; - sp[REG_R7] = sigcb->context.R7; - sp[REG_R12] = sigcb->context.R12; - sigcb->context.count--; + LosProcessCB *process = OsCurrProcessGet(); + VOID *saveContext = sigcb->sigContext; + sigcb->count--; process->sigShare = 0; OsProcessExitCodeSignalClear(process); SCHEDULER_UNLOCK(intSave); + return saveContext; } diff --git a/syscall/los_syscall.c b/syscall/los_syscall.c index 292181598dc3e4b0718447f58d5e0dfbf2f27701..3b6e5098b63129df7888fb4729b0d96dceef2c42 100644 --- a/syscall/los_syscall.c +++ b/syscall/los_syscall.c @@ -38,6 +38,7 @@ #include "los_syscall.h" #include "los_task_pri.h" #include "los_process_pri.h" +#include "los_hw_pri.h" #include "los_printf.h" #include "time.h" #include "utime.h" @@ -93,21 +94,16 @@ void SyscallHandleInit(void) } /* The SYSCALL ID is in R7 on entry. Parameters follow in R0..R6 */ -LITE_OS_SEC_TEXT UINT32 *OsArmA32SyscallHandle(UINT32 *regs) +VOID OsArmA32SyscallHandle(TaskContext *regs) { UINT32 ret; UINT8 nArgs; UINTPTR handle; - UINT32 cmd = regs[REG_R7]; + UINT32 cmd = regs->reserved2; if (cmd >= SYS_CALL_NUM) { PRINT_ERR("Syscall ID: error %d !!!\n", cmd); - return regs; - } - - if (cmd == __NR_sigreturn) { - OsRestorSignalContext(regs); - return regs; + return; } handle = g_syscallHandle[cmd]; @@ -115,35 +111,28 @@ LITE_OS_SEC_TEXT UINT32 *OsArmA32SyscallHandle(UINT32 *regs) nArgs = (cmd & 1) ? (nArgs >> NARG_BITS) : (nArgs & NARG_MASK); if ((handle == 0) || (nArgs > ARG_NUM_7)) { PRINT_ERR("Unsupport syscall ID: %d nArgs: %d\n", cmd, nArgs); - regs[REG_R0] = -ENOSYS; - return regs; + regs->R0 = -ENOSYS; + return; } switch (nArgs) { case ARG_NUM_0: case ARG_NUM_1: - ret = (*(SyscallFun1)handle)(regs[REG_R0]); + ret = (*(SyscallFun1)handle)(regs->R0); break; case ARG_NUM_2: case ARG_NUM_3: - ret = (*(SyscallFun3)handle)(regs[REG_R0], regs[REG_R1], regs[REG_R2]); + ret = (*(SyscallFun3)handle)(regs->R0, regs->R1, regs->R2); break; case ARG_NUM_4: case ARG_NUM_5: - ret = (*(SyscallFun5)handle)(regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], - regs[REG_R4]); + ret = (*(SyscallFun5)handle)(regs->R0, regs->R1, regs->R2, regs->R3, regs->R4); break; default: - ret = (*(SyscallFun7)handle)(regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], - regs[REG_R4], regs[REG_R5], regs[REG_R6]); + ret = (*(SyscallFun7)handle)(regs->R0, regs->R1, regs->R2, regs->R3, regs->R4, regs->R5, regs->R6); } - regs[REG_R0] = ret; - - OsSaveSignalContext(regs); + regs->R0 = ret; - /* Return the last value of curent_regs. This supports context switches on return from the exception. - * That capability is only used with theSYS_context_switch system call. - */ - return regs; + return; }