diff --git a/arch/arm/arm/src/include/los_hw_pri.h b/arch/arm/arm/src/include/los_hw_pri.h index 052da990..23533daa 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,43 @@ 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; + + UINT32 resved2; + UINT32 resved1; + UINT32 USP; + UINT32 ULR; + UINT32 R0; + UINT32 R1; + UINT32 R2; + UINT32 R3; + UINT32 R12; + UINT32 LR; + UINT32 PC; + UINT32 CPSR; } 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 resved2; + UINT32 resved1; + UINT32 USP; + UINT32 ULR; + UINT32 R0; + UINT32 R1; + UINT32 R2; + UINT32 R3; + UINT32 R12; + UINT32 LR; + UINT32 PC; + UINT32 CPSR; +} IrqContext; /* * Description : task stack initialization @@ -82,8 +101,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, 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 1f9c2469..ac314224 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!, {LR} - STMFD SP!, {LR} - /* jump sp */ - SUB SP, SP, #4 - - /* push r0-r12*/ - STMFD SP!, {R0-R12} STMFD SP!, {R2} + STMFD SP!, {LR} + STMFD SP!, {LR} + STMFD SP!, {R12} - /* 8 bytes stack align */ - SUB SP, SP, #4 + /* jump R0 - R3 USP, ULR resved */ + SUB SP, SP, #(8 * 4) + + /* push R4 - R11*/ + STMFD SP!, {R4-R11} /* save fpu registers */ PUSH_FPU_REGS R2 @@ -113,131 +113,81 @@ 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, resved */ + 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 + SRSFD #0x13! @ save spsr and pc to the svc stack - /* disable irq, switch to svc mode */ - CPSID i, #0x13 + CPSID i, #0x13 @ disable irq, switch to svc mode - /* 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) + STMIA SP, {R4} /* * 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 + LDMFD SP, {R4} - 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 + LDR R3, [SP, #(11 * 4)] + AND R1, R3, #CPSR_MASK_MODE + CMP R1, #CPSR_USER_MODE + BNE 1f + MOV R0, SP + STMIA SP, {R7} + 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 3197c397..7d8e9e7f 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" } }; @@ -183,7 +179,7 @@ STATIC INT32 OsDecodeDataFSR(UINT32 regDFSR) } #ifdef LOSCFG_KERNEL_VM -UINT32 OsArmSharedPageFault(UINT32 excType, ExcContext *frame, UINT32 far, UINT32 fsr) +UINT32 OsArmSharedPageFault(UINT32 excType, PageFaultContext *frame, UINT32 far, UINT32 fsr) { PRINT_INFO("page fault entry!!!\n"); BOOL instruction_fault = FALSE; @@ -211,7 +207,7 @@ UINT32 OsArmSharedPageFault(UINT32 excType, ExcContext *frame, UINT32 far, UINT3 /* permission fault */ case 0b01111: { /* permission fault */ - BOOL user = (frame->regCPSR & CPSR_MODE_MASK) == CPSR_MODE_USR; + BOOL user = (frame->CPSR & CPSR_MODE_MASK) == CPSR_MODE_USR; pfFlags |= write ? VM_MAP_PF_FLAG_WRITE : 0; pfFlags |= user ? VM_MAP_PF_FLAG_USER : 0; pfFlags |= instruction_fault ? VM_MAP_PF_FLAG_INSTRUCTION : 0; @@ -228,9 +224,9 @@ STATIC VOID OsExcType(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 { /* undefinited exception handling or software interrupt */ if ((excType == OS_EXCEPT_UNDEF_INSTR) || (excType == OS_EXCEPT_SWI)) { - if ((excBufAddr->regCPSR & INSTR_SET_MASK) == 0) { /* work status: ARM */ + if ((excBufAddr->CPSR & INSTR_SET_MASK) == 0) { /* work status: ARM */ excBufAddr->PC = excBufAddr->PC - ARM_INSTR_LEN; - } else if ((excBufAddr->regCPSR & INSTR_SET_MASK) == 0x20) { /* work status: Thumb */ + } else if ((excBufAddr->CPSR & INSTR_SET_MASK) == 0x20) { /* work status: Thumb */ excBufAddr->PC = excBufAddr->PC - THUMB_INSTR_LEN; } } @@ -380,7 +376,7 @@ STATIC VOID OsExcRegsInfo(const ExcContext *excBufAddr) "R12 = 0x%x\n" "CPSR = 0x%x\n", excBufAddr->R7, excBufAddr->R8, excBufAddr->R9, excBufAddr->R10, - excBufAddr->R11, excBufAddr->R12, excBufAddr->regCPSR); + excBufAddr->R11, excBufAddr->R12, excBufAddr->CPSR); } LITE_OS_SEC_TEXT_INIT UINT32 LOS_ExcRegHook(EXC_PROC_FUNC excHook) @@ -808,7 +804,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) @@ -1009,7 +1005,7 @@ LITE_OS_SEC_TEXT VOID STATIC OsExcPriorDisposal(ExcContext *excBufAddr) UINT16 runCount; #endif - if ((excBufAddr->regCPSR & CPSR_MASK_MODE) == CPSR_USER_MODE) { + if ((excBufAddr->CPSR & CPSR_MASK_MODE) == CPSR_USER_MODE) { g_minAddr = USER_ASPACE_BASE; g_maxAddr = USER_ASPACE_BASE + USER_ASPACE_SIZE; g_excFromUserMode[ArchCurrCpuid()] = TRUE; diff --git a/arch/arm/arm/src/los_hw.c b/arch/arm/arm/src/los_hw.c index f7b053dd..25ec5821 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->CPSR = 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->CPSR = 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,42 @@ 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)); + VOID *cloneStack = (VOID *)(((UINTPTR)parentTopOfStack + parentStackSize) - sizeof(TaskContext)); - LOS_ASSERT(parentTaskCB->taskStatus & OS_TASK_STATUS_RUNNING); - - (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->CPSR = PSR_MODE_USR_THUMB; #else - context->regPSR = PSR_MODE_USR_ARM; + context->CPSR = 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, UINTPTR sigHandler, UINT32 signo, UINT32 param) +{ + IrqContext *oldSp = (IrqContext *)sp; + IrqContext *newSp = (IrqContext *)((UINTPTR)sp - sizeof(IrqContext)); + newSp->PC = sigHandler; + newSp->R0 = signo; + newSp->R1 = param; + newSp->USP = oldSp->USP; + newSp->CPSR = oldSp->CPSR; + + return (VOID *)newSp; +} + 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 007537d1..82d64ffe 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,78 @@ _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 #0x13! + CPSID i, #0x13 + STMFD SP!, {R0-R3, R12, LR} + SUB SP, SP, #(4 * 2) + MOV R2, #0 + MOV R3, #0 + STMFD SP!, {R2-R3} 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 #0x13! + STMFD SP!, {R0-R3, R12, LR} + STMFD SP, {R13, R14}^ + SUB SP, SP, #(4 * 4) + STMIA SP, {R7} #ifdef LOSCFG_KERNEL_SYSCALL + 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 + 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 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 + LDMFD SP!, {R4-R11} - @ 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) + LDR R3, [SP, #(11 * 4)] + AND R1, R3, #CPSR_MASK_MODE + CMP R1, #CPSR_USER_MODE + BNE _osSyscallReturn - LDMFD SP!, {R0-R12} + MOV R0, SP + BLX OsSaveSignalContext + MOV SP, R0 + +_osSyscallReturn: + LDMFD SP, {R7} + ADD SP, SP, #(2 * 4) 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 +254,38 @@ _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 #0x13! + CPSID i, #0x13 + 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} #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 + CPSIE I + BLX OsArmSharedPageFault + CPSID I + 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,122 +297,87 @@ _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 + + SRSFD #0x13! + CPSID i, #0x13 + 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} + +#ifdef LOSCFG_KERNEL_VM + MOV R1, SP + PUSH_FPU_REGS R0 MOV R0, #OS_EXCEPT_DATA_ABORT @ Set exception ID to OS_EXCEPT_DATA_ABORT. -#ifdef LOSCFG_KERNEL_VM - B _osExcPageFault -#else + CPSIE I + BLX OsArmSharedPageFault + CPSID I + 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) + 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. + + SRSFD #0x13! + CPSID i, #0x13 + 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} 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. + + SRSFD #0x13! + CPSID i, #0x13 + 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} 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 - CPSIE I - BLX OsArmSharedPageFault - CPSID I - - POP_FPU_REGS R1 - MOV SP, R4 - CMP R0, #0 - BEQ _OsExcReturn - - MOV R0, R5 @ exc type - B _osExceptionSwi -#endif - @ 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. - - 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 - - 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). + LDR R8, [SP, #(4 * 8)] + LDR R9, [SP, #(4 * 9)] + MOV R1, SP - 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 + 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 @@ -414,19 +406,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 964b0137..89331692 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 7cd58d6e..5d3b5f61 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 0a265cdc..aab026ec 100644 --- a/arch/arm/include/los_exc.h +++ b/arch/arm/include/los_exc.h @@ -64,25 +64,27 @@ typedef struct { } ExcContext; #else 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; + UINT32 resved; + 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 CPSR; } ExcContext; #endif diff --git a/arch/arm/include/los_sys_stack_pri.h b/arch/arm/include/los_sys_stack_pri.h index e45e4a66..5681419b 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 a8c8130f..34ff61f2 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) { @@ -1366,14 +1364,17 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT } SCHEDULER_LOCK(intSave); - taskCB = OsCurrTaskGet(); + LosTaskCB *taskCB = OsCurrTaskGet(); 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); + taskCB->stackPointer = (VOID *)taskContext; + OsTaskContextLoad(taskCB); SCHEDULER_UNLOCK(intSave); return LOS_OK; } @@ -1555,7 +1556,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 +1572,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 +1586,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 ac0c5e12..8815a3e4 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 86b9134f..e75f5110 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/include/los_vm_fault.h b/kernel/base/include/los_vm_fault.h index d3c650a2..6bc0c2f9 100644 --- a/kernel/base/include/los_vm_fault.h +++ b/kernel/base/include/los_vm_fault.h @@ -38,7 +38,7 @@ #define __LOS_VM_FAULT_H__ #include "los_typedef.h" -#include "los_exc.h" +#include "los_hw_pri.h" #ifdef __cplusplus #if __cplusplus @@ -46,6 +46,8 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ +typedef IrqContext PageFaultContext; + typedef struct { VADDR_T excAddr; VADDR_T fixAddr; @@ -56,7 +58,7 @@ typedef struct { #define VM_MAP_PF_FLAG_INSTRUCTION (1U << 2) #define VM_MAP_PF_FLAG_NOT_PRESENT (1U << 3) -STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame); +STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, PageFaultContext *frame); #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/base/ipc/los_signal.c b/kernel/base/ipc/los_signal.c index 8edd8db4..c2b45f9c 100644 --- a/kernel/base/ipc/los_signal.c +++ b/kernel/base/ipc/los_signal.c @@ -556,131 +556,64 @@ int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact) return LOS_OK; } -void OsSaveSignalContext(unsigned int *sp) +VOID *OsSaveSignalContext(VOID *sp) { 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); - - 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))) { + LosTaskCB *task = OsCurrTaskGet(); + LosProcessCB *process = OsCurrProcessGet(); + sig_cb *sigcb = &task->sig; + 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; + + VOID *newSp = OsInitSignalContext(sp, 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++; - } - - SCHEDULER_UNLOCK(intSave); -} - -void OsSaveSignalContextIrq(unsigned int *sp, unsigned int r7) -{ - 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)); - - 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++; - } - 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) { + sigcb->count++; SCHEDULER_UNLOCK(intSave); - PRINT_ERR("sig error count : %d\n", sigcb->context.count); - return; + return newSp; } - 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--; + SCHEDULER_UNLOCK(intSave); + return sp; +} + +VOID *OsRestorSignalContext(VOID *sp) +{ + UINT32 intSave; + + SCHEDULER_LOCK(intSave); + LosTaskCB *task = OsCurrTaskGet(); + sig_cb *sigcb = &task->sig; + + if (sigcb->count != 1) { + SCHEDULER_UNLOCK(intSave); + PRINT_ERR("sig error count : %d\n", sigcb->count); + return sp; + } + + LosProcessCB *process = OsCurrProcessGet(); + VOID *saveContext = sigcb->sigContext; + sigcb->count--; process->sigShare = 0; OsProcessExitCodeSignalClear(process); SCHEDULER_UNLOCK(intSave); + return saveContext; } diff --git a/kernel/base/vm/los_vm_fault.c b/kernel/base/vm/los_vm_fault.c index d8f61b27..b805d253 100644 --- a/kernel/base/vm/los_vm_fault.c +++ b/kernel/base/vm/los_vm_fault.c @@ -75,12 +75,12 @@ STATIC STATUS_T OsVmRegionRightCheck(LosVmMapRegion *region, UINT32 flags) return LOS_OK; } -STATIC VOID OsFaultTryFixup(ExcContext *frame, VADDR_T excVaddr, STATUS_T *status) +STATIC VOID OsFaultTryFixup(PageFaultContext *frame, VADDR_T excVaddr, STATUS_T *status) { INT32 tableNum = (__exc_table_end - __exc_table_start) / sizeof(LosExcTable); LosExcTable *excTable = (LosExcTable *)__exc_table_start; - if ((frame->regCPSR & CPSR_MODE_MASK) != CPSR_MODE_USR) { + if ((frame->CPSR & CPSR_MODE_MASK) != CPSR_MODE_USR) { for (int i = 0; i < tableNum; ++i, ++excTable) { if (frame->PC == (UINTPTR)excTable->excAddr) { frame->PC = (UINTPTR)excTable->fixAddr; @@ -332,7 +332,7 @@ STATIC STATUS_T OsDoFileFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault, U return ret; } -STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame) +STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, PageFaultContext *frame) { LosVmSpace *space = LOS_SpaceGet(vaddr); LosVmMapRegion *region = NULL; diff --git a/syscall/los_syscall.c b/syscall/los_syscall.c index 29218159..c2d6e3eb 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->resved2; 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,31 @@ 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; }