提交 1e308db6 编写于 作者: Z zhushengle 提交者: 星e雨

fix:Fixed exception not saving stack pointer of SVC mode and abnormal signal processing issues

Close #I3OAFR

Change-Id: I25b14572809b6fabb9e9d17de89a99047c02a59b
上级 f6c4f6f5
...@@ -64,10 +64,11 @@ typedef struct { ...@@ -64,10 +64,11 @@ typedef struct {
UINT32 R10; UINT32 R10;
UINT32 R11; UINT32 R11;
UINT32 resved2; /* It has the same structure as IrqContext */
UINT32 resved1; UINT32 reserved2; /**< Multiplexing registers, used in interrupts and system calls but with different meanings */
UINT32 USP; UINT32 reserved1; /**< Multiplexing registers, used in interrupts and system calls but with different meanings */
UINT32 ULR; UINT32 USP; /**< User mode sp register */
UINT32 ULR; /**< User mode lr register */
UINT32 R0; UINT32 R0;
UINT32 R1; UINT32 R1;
UINT32 R2; UINT32 R2;
...@@ -75,14 +76,14 @@ typedef struct { ...@@ -75,14 +76,14 @@ typedef struct {
UINT32 R12; UINT32 R12;
UINT32 LR; UINT32 LR;
UINT32 PC; UINT32 PC;
UINT32 CPSR; UINT32 regCPSR;
} TaskContext; } TaskContext;
typedef struct { typedef struct {
UINT32 resved2; UINT32 reserved2; /**< Multiplexing registers, used in interrupts and system calls but with different meanings */
UINT32 resved1; UINT32 reserved1; /**< Multiplexing registers, used in interrupts and system calls but with different meanings */
UINT32 USP; UINT32 USP; /**< User mode sp register */
UINT32 ULR; UINT32 ULR; /**< User mode lr register */
UINT32 R0; UINT32 R0;
UINT32 R1; UINT32 R1;
UINT32 R2; UINT32 R2;
...@@ -90,7 +91,7 @@ typedef struct { ...@@ -90,7 +91,7 @@ typedef struct {
UINT32 R12; UINT32 R12;
UINT32 LR; UINT32 LR;
UINT32 PC; UINT32 PC;
UINT32 CPSR; UINT32 regCPSR;
} IrqContext; } IrqContext;
/* /*
...@@ -103,7 +104,7 @@ typedef struct { ...@@ -103,7 +104,7 @@ typedef struct {
extern VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack, BOOL initFlag); extern VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack, BOOL initFlag);
extern VOID OsUserCloneParentStack(VOID *childStack, UINTPTR parentTopOfStask, UINT32 parentStackSize); extern VOID OsUserCloneParentStack(VOID *childStack, UINTPTR parentTopOfStask, UINT32 parentStackSize);
extern VOID OsUserTaskStackInit(TaskContext *context, UINTPTR taskEntry, UINTPTR stack); extern VOID OsUserTaskStackInit(TaskContext *context, UINTPTR taskEntry, UINTPTR stack);
extern VOID *OsInitSignalContext(VOID *sp, UINTPTR sigHandler, UINT32 signo, UINT32 param); 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_clean_cache_range(UINTPTR start, UINTPTR end);
extern void arm_inv_cache_range(UINTPTR start, UINTPTR end); extern void arm_inv_cache_range(UINTPTR start, UINTPTR end);
......
...@@ -91,7 +91,7 @@ OsTaskSchedule: ...@@ -91,7 +91,7 @@ OsTaskSchedule:
STMFD SP!, {LR} STMFD SP!, {LR}
STMFD SP!, {R12} STMFD SP!, {R12}
/* jump R0 - R3 USP, ULR resved */ /* jump R0 - R3 USP, ULR reserved */
SUB SP, SP, #(8 * 4) SUB SP, SP, #(8 * 4)
/* push R4 - R11*/ /* push R4 - R11*/
...@@ -127,7 +127,7 @@ OsTaskContextLoad: ...@@ -127,7 +127,7 @@ OsTaskContextLoad:
BL OsSchedToUserReleaseLock BL OsSchedToUserReleaseLock
#endif #endif
/* jump sp, resved */ /* jump sp, reserved */
ADD SP, SP, #(2 * 4) ADD SP, SP, #(2 * 4)
LDMFD SP, {R13, R14}^ LDMFD SP, {R13, R14}^
ADD SP, SP, #(2 * 4) ADD SP, SP, #(2 * 4)
...@@ -142,14 +142,15 @@ OsKernelTaskLoad: ...@@ -142,14 +142,15 @@ OsKernelTaskLoad:
OsIrqHandler: OsIrqHandler:
SUB LR, LR, #4 SUB LR, LR, #4
SRSFD #0x13! @ save spsr and pc to the svc stack /* Save pc and cpsr to svc sp, ARMv6 and above support */
SRSFD #0x13!
CPSID i, #0x13 @ disable irq, switch to svc mode /* disable irq, switch to svc mode */
CPSID i, #0x13
STMFD SP!, {R0-R3, R12, LR} STMFD SP!, {R0-R3, R12, LR}
STMFD SP, {R13, R14}^ STMFD SP, {R13, R14}^
SUB SP, SP, #(4 * 4) SUB SP, SP, #(4 * 4)
STMIA SP, {R4} STR R4, [SP, #0]
/* /*
* save fpu regs in case in case those been * save fpu regs in case in case those been
...@@ -169,16 +170,20 @@ OsIrqHandler: ...@@ -169,16 +170,20 @@ OsIrqHandler:
BLX OsSchedIrqEndCheckNeedSched BLX OsSchedIrqEndCheckNeedSched
/* restore fpu regs */ /* restore fpu regs */
POP_FPU_REGS R0 POP_FPU_REGS R0
LDMFD SP, {R4} 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)] LDR R3, [SP, #(11 * 4)]
AND R1, R3, #CPSR_MASK_MODE AND R1, R3, #CPSR_MASK_MODE
CMP R1, #CPSR_USER_MODE CMP R1, #CPSR_USER_MODE
BNE 1f BNE 1f
MOV R0, SP MOV R0, SP
STMIA SP, {R7} STR R7, [SP, #0]
/* sp - sizeof(IrqContext) */
SUB SP, SP, #(12 * 4)
MOV R1, SP
BLX OsSaveSignalContext BLX OsSaveSignalContext
MOV SP, R0 MOV SP, R0
1: 1:
......
...@@ -179,7 +179,7 @@ STATIC INT32 OsDecodeDataFSR(UINT32 regDFSR) ...@@ -179,7 +179,7 @@ STATIC INT32 OsDecodeDataFSR(UINT32 regDFSR)
} }
#ifdef LOSCFG_KERNEL_VM #ifdef LOSCFG_KERNEL_VM
UINT32 OsArmSharedPageFault(UINT32 excType, PageFaultContext *frame, UINT32 far, UINT32 fsr) UINT32 OsArmSharedPageFault(UINT32 excType, ExcContext *frame, UINT32 far, UINT32 fsr)
{ {
BOOL instructionFault = FALSE; BOOL instructionFault = FALSE;
UINT32 pfFlags = 0; UINT32 pfFlags = 0;
...@@ -218,7 +218,7 @@ UINT32 OsArmSharedPageFault(UINT32 excType, PageFaultContext *frame, UINT32 far, ...@@ -218,7 +218,7 @@ UINT32 OsArmSharedPageFault(UINT32 excType, PageFaultContext *frame, UINT32 far,
/* permission fault */ /* permission fault */
case 0b01111: { case 0b01111: {
/* permission fault */ /* permission fault */
BOOL user = (frame->CPSR & CPSR_MODE_MASK) == CPSR_MODE_USR; BOOL user = (frame->regCPSR & CPSR_MODE_MASK) == CPSR_MODE_USR;
pfFlags |= write ? VM_MAP_PF_FLAG_WRITE : 0; pfFlags |= write ? VM_MAP_PF_FLAG_WRITE : 0;
pfFlags |= user ? VM_MAP_PF_FLAG_USER : 0; pfFlags |= user ? VM_MAP_PF_FLAG_USER : 0;
pfFlags |= instructionFault ? VM_MAP_PF_FLAG_INSTRUCTION : 0; pfFlags |= instructionFault ? VM_MAP_PF_FLAG_INSTRUCTION : 0;
...@@ -245,9 +245,9 @@ STATIC VOID OsExcType(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 ...@@ -245,9 +245,9 @@ STATIC VOID OsExcType(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32
{ {
/* undefinited exception handling or software interrupt */ /* undefinited exception handling or software interrupt */
if ((excType == OS_EXCEPT_UNDEF_INSTR) || (excType == OS_EXCEPT_SWI)) { if ((excType == OS_EXCEPT_UNDEF_INSTR) || (excType == OS_EXCEPT_SWI)) {
if ((excBufAddr->CPSR & INSTR_SET_MASK) == 0) { /* work status: ARM */ if ((excBufAddr->regCPSR & INSTR_SET_MASK) == 0) { /* work status: ARM */
excBufAddr->PC = excBufAddr->PC - ARM_INSTR_LEN; excBufAddr->PC = excBufAddr->PC - ARM_INSTR_LEN;
} else if ((excBufAddr->CPSR & INSTR_SET_MASK) == 0x20) { /* work status: Thumb */ } else if ((excBufAddr->regCPSR & INSTR_SET_MASK) == 0x20) { /* work status: Thumb */
excBufAddr->PC = excBufAddr->PC - THUMB_INSTR_LEN; excBufAddr->PC = excBufAddr->PC - THUMB_INSTR_LEN;
} }
} }
...@@ -397,7 +397,7 @@ STATIC VOID OsExcRegsInfo(const ExcContext *excBufAddr) ...@@ -397,7 +397,7 @@ STATIC VOID OsExcRegsInfo(const ExcContext *excBufAddr)
"R12 = 0x%x\n" "R12 = 0x%x\n"
"CPSR = 0x%x\n", "CPSR = 0x%x\n",
excBufAddr->R7, excBufAddr->R8, excBufAddr->R9, excBufAddr->R10, excBufAddr->R7, excBufAddr->R8, excBufAddr->R9, excBufAddr->R10,
excBufAddr->R11, excBufAddr->R12, excBufAddr->CPSR); excBufAddr->R11, excBufAddr->R12, excBufAddr->regCPSR);
} }
LITE_OS_SEC_TEXT_INIT UINT32 LOS_ExcRegHook(EXC_PROC_FUNC excHook) LITE_OS_SEC_TEXT_INIT UINT32 LOS_ExcRegHook(EXC_PROC_FUNC excHook)
...@@ -1026,7 +1026,7 @@ LITE_OS_SEC_TEXT VOID STATIC OsExcPriorDisposal(ExcContext *excBufAddr) ...@@ -1026,7 +1026,7 @@ LITE_OS_SEC_TEXT VOID STATIC OsExcPriorDisposal(ExcContext *excBufAddr)
UINT16 runCount; UINT16 runCount;
#endif #endif
if ((excBufAddr->CPSR & CPSR_MASK_MODE) == CPSR_USER_MODE) { if ((excBufAddr->regCPSR & CPSR_MASK_MODE) == CPSR_USER_MODE) {
g_minAddr = USER_ASPACE_BASE; g_minAddr = USER_ASPACE_BASE;
g_maxAddr = USER_ASPACE_BASE + USER_ASPACE_SIZE; g_maxAddr = USER_ASPACE_BASE + USER_ASPACE_SIZE;
g_excFromUserMode[ArchCurrCpuid()] = TRUE; g_excFromUserMode[ArchCurrCpuid()] = TRUE;
......
...@@ -83,12 +83,12 @@ LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOI ...@@ -83,12 +83,12 @@ LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOI
taskContext->PC = (UINTPTR)OsTaskEntry; taskContext->PC = (UINTPTR)OsTaskEntry;
#endif #endif
taskContext->LR = (UINTPTR)OsTaskExit; /* LR should be kept, to distinguish it's THUMB or ARM instruction */ taskContext->LR = (UINTPTR)OsTaskExit; /* LR should be kept, to distinguish it's THUMB or ARM instruction */
taskContext->R0 = taskID; /* R0 */ taskContext->R0 = taskID; /* R0 */
#ifdef LOSCFG_INTERWORK_THUMB #ifdef LOSCFG_INTERWORK_THUMB
taskContext->CPSR = 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 #else
taskContext->CPSR = 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 #endif
#if !defined(LOSCFG_ARCH_FPU_DISABLE) #if !defined(LOSCFG_ARCH_FPU_DISABLE)
...@@ -116,9 +116,9 @@ LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, UINTPTR tas ...@@ -116,9 +116,9 @@ LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, UINTPTR tas
LOS_ASSERT(context != NULL); LOS_ASSERT(context != NULL);
#ifdef LOSCFG_INTERWORK_THUMB #ifdef LOSCFG_INTERWORK_THUMB
context->CPSR = PSR_MODE_USR_THUMB; context->regCPSR = PSR_MODE_USR_THUMB;
#else #else
context->CPSR = PSR_MODE_USR_ARM; context->regCPSR = PSR_MODE_USR_ARM;
#endif #endif
context->R0 = stack; context->R0 = stack;
context->USP = TRUNCATE(stack, LOSCFG_STACK_POINT_ALIGN_SIZE); context->USP = TRUNCATE(stack, LOSCFG_STACK_POINT_ALIGN_SIZE);
...@@ -126,17 +126,13 @@ LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, UINTPTR tas ...@@ -126,17 +126,13 @@ LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, UINTPTR tas
context->PC = (UINTPTR)taskEntry; context->PC = (UINTPTR)taskEntry;
} }
VOID *OsInitSignalContext(VOID *sp, UINTPTR sigHandler, UINT32 signo, UINT32 param) VOID OsInitSignalContext(VOID *sp, VOID *signalContext, UINTPTR sigHandler, UINT32 signo, UINT32 param)
{ {
IrqContext *oldSp = (IrqContext *)sp; IrqContext *newSp = (IrqContext *)signalContext;
IrqContext *newSp = (IrqContext *)((UINTPTR)sp - sizeof(IrqContext)); (VOID)memcpy_s(signalContext, sizeof(IrqContext), sp, sizeof(IrqContext));
newSp->PC = sigHandler; newSp->PC = sigHandler;
newSp->R0 = signo; newSp->R0 = signo;
newSp->R1 = param; newSp->R1 = param;
newSp->USP = oldSp->USP;
newSp->CPSR = oldSp->CPSR;
return (VOID *)newSp;
} }
DEPRECATED VOID Dmb(VOID) DEPRECATED VOID Dmb(VOID)
......
...@@ -173,34 +173,34 @@ _osExceptUndefInstrHdl: ...@@ -173,34 +173,34 @@ _osExceptUndefInstrHdl:
#ifdef LOSCFG_GDB #ifdef LOSCFG_GDB
GDB_HANDLE OsUndefIncExcHandleEntry GDB_HANDLE OsUndefIncExcHandleEntry
#else #else
SRSFD #0x13! SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support
CPSID i, #0x13 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!, {R0-R3, R12, LR}
SUB SP, SP, #(4 * 2) STMFD SP, {R13, R14}^ @ push user sp and lr
SUB SP, SP, #(2 * 4)
MOV R2, #0 MOV R2, #0
MOV R3, #0 MOV R3, #0
STMFD SP!, {R2-R3} 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. MOV R0, #OS_EXCEPT_UNDEF_INSTR @ Set exception ID to OS_EXCEPT_UNDEF_INSTR.
B _osExceptDispatch @ Branch to global exception handler. B _osExceptDispatch @ Branch to global exception handler.
#endif #endif
@ Description: Software interrupt exception handler @ Description: Software interrupt exception handler
_osExceptSwiHdl: _osExceptSwiHdl:
SRSFD #0x13! SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support
STMFD SP!, {R0-R3, R12, LR} STMFD SP!, {R0-R3, R12, LR}
STMFD SP, {R13, R14}^ STMFD SP, {R13, R14}^
SUB SP, SP, #(4 * 4) SUB SP, SP, #(4 * 4) @ push user sp and lr and jump reserved field
STMIA SP, {R7} STR R7, [SP, #0] @ Save system call number to reserved2 filed
#ifdef LOSCFG_KERNEL_SYSCALL #ifdef LOSCFG_KERNEL_SYSCALL
LDR R3, [SP, #(11 * 4)] LDR R3, [SP, #(11 * 4)]
AND R1, R3, #CPSR_MASK_MODE @ Interrupted mode AND R1, R3, #CPSR_MASK_MODE @ Interrupted mode
CMP R1, #CPSR_USER_MODE @ User mode CMP R1, #CPSR_USER_MODE @ User mode
BNE _osKernelSVCHandler @ Branch if not user mode BNE _osKernelSVCHandler @ Branch if not user mode
CMP R7, #119 @ __NR_sigreturn CMP R7, #119 @ __NR_sigreturn
BNE _osIsSyscall BNE _osIsSyscall
MOV R0, SP MOV R0, SP
BLX OsRestorSignalContext BLX OsRestorSignalContext
...@@ -213,7 +213,7 @@ _osIsSyscall: ...@@ -213,7 +213,7 @@ _osIsSyscall:
PUSH_FPU_REGS R1 PUSH_FPU_REGS R1
MOV R0, SP MOV R0, SP
MOV FP, #0 @ Init frame pointer MOV FP, #0 @ Init frame pointer
CPSIE I CPSIE I
BLX OsArmA32SyscallHandle BLX OsArmA32SyscallHandle
CPSID I CPSID I
...@@ -221,18 +221,15 @@ _osIsSyscall: ...@@ -221,18 +221,15 @@ _osIsSyscall:
POP_FPU_REGS R1 POP_FPU_REGS R1
LDMFD SP!, {R4-R11} LDMFD SP!, {R4-R11}
LDR R3, [SP, #(11 * 4)]
AND R1, R3, #CPSR_MASK_MODE
CMP R1, #CPSR_USER_MODE
BNE _osSyscallReturn
MOV R0, SP MOV R0, SP
SUB SP, SP, #(12 * 4) @ sp - sizeof(IrqContext), reserved for signal
MOV R1, SP
BLX OsSaveSignalContext BLX OsSaveSignalContext
MOV SP, R0 MOV SP, R0
_osSyscallReturn: _osSyscallReturn:
LDMFD SP, {R7} LDR R7, [SP, #0]
ADD SP, SP, #(2 * 4) ADD SP, SP, #(2 * 4) @ jump reserved filed
LDMFD SP, {R13, R14}^ @ Restore user mode R13/R14 LDMFD SP, {R13, R14}^ @ Restore user mode R13/R14
ADD SP, SP, #(2 * 4) ADD SP, SP, #(2 * 4)
LDMFD SP!, {R0-R3, R12, LR} LDMFD SP!, {R0-R3, R12, LR}
...@@ -255,15 +252,15 @@ _osExceptPrefetchAbortHdl: ...@@ -255,15 +252,15 @@ _osExceptPrefetchAbortHdl:
#else #else
SUB LR, LR, #4 @ LR offset to return from this exception: -4. SUB LR, LR, #4 @ LR offset to return from this exception: -4.
SRSFD #0x13! SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support
CPSID i, #0x13 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!, {R0-R3, R12, LR}
STMFD SP, {R13, R14}^ STMFD SP, {R13, R14}^
SUB SP, SP, #(2 * 4) SUB SP, SP, #(2 * 4)
MRC P15, 0, R2, C6, C0, 2 MRC P15, 0, R2, C6, C0, 2
MRC P15, 0, R3, C5, C0, 1 MRC P15, 0, R3, C5, C0, 1
STMFD SP!, {R2-R3} STMFD SP!, {R2-R3} @ Save far and fsr
#ifdef LOSCFG_KERNEL_VM #ifdef LOSCFG_KERNEL_VM
LDR R0, [SP, #(11 * 4)] LDR R0, [SP, #(11 * 4)]
...@@ -275,9 +272,7 @@ _osExceptPrefetchAbortHdl: ...@@ -275,9 +272,7 @@ _osExceptPrefetchAbortHdl:
PUSH_FPU_REGS R0 PUSH_FPU_REGS R0
MOV R0, #OS_EXCEPT_PREFETCH_ABORT MOV R0, #OS_EXCEPT_PREFETCH_ABORT
CPSIE I
BLX OsArmSharedPageFault BLX OsArmSharedPageFault
CPSID I
CMP R0, #0 CMP R0, #0
POP_FPU_REGS R0 POP_FPU_REGS R0
...@@ -298,24 +293,22 @@ _osExceptDataAbortHdl: ...@@ -298,24 +293,22 @@ _osExceptDataAbortHdl:
#else #else
SUB LR, LR, #8 @ LR offset to return from this exception: -8. SUB LR, LR, #8 @ LR offset to return from this exception: -8.
SRSFD #0x13! SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support
CPSID i, #0x13 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!, {R0-R3, R12, LR}
STMFD SP, {R13, R14}^ STMFD SP, {R13, R14}^
SUB SP, SP, #(2 * 4) SUB SP, SP, #(2 * 4)
MRC P15, 0, R2, C6, C0, 0 MRC P15, 0, R2, C6, C0, 0
MRC P15, 0, R3, C5, C0, 0 MRC P15, 0, R3, C5, C0, 0
STMFD SP!, {R2-R3} STMFD SP!, {R2-R3} @ Save far and fsr
#ifdef LOSCFG_KERNEL_VM #ifdef LOSCFG_KERNEL_VM
MOV R1, SP MOV R1, SP
PUSH_FPU_REGS R0 PUSH_FPU_REGS R0
MOV R0, #OS_EXCEPT_DATA_ABORT @ Set exception ID to OS_EXCEPT_DATA_ABORT. MOV R0, #OS_EXCEPT_DATA_ABORT @ Set exception ID to OS_EXCEPT_DATA_ABORT.
CPSIE I
BLX OsArmSharedPageFault BLX OsArmSharedPageFault
CPSID I
CMP R0, #0 CMP R0, #0
POP_FPU_REGS R0 POP_FPU_REGS R0
BEQ _osExcPageFaultReturn BEQ _osExcPageFaultReturn
...@@ -329,7 +322,7 @@ _osExceptDataAbortHdl: ...@@ -329,7 +322,7 @@ _osExceptDataAbortHdl:
_osExcPageFaultReturn: _osExcPageFaultReturn:
ADD SP, SP, #(2 * 4) ADD SP, SP, #(2 * 4)
LDMFD SP, {R13, R14}^ LDMFD SP, {R13, R14}^
ADD SP, SP, #(2 * 4) ADD SP, SP, #(2 * 4) @ Jump reserved fileds
LDMFD SP!, {R0-R3, R12, LR} LDMFD SP!, {R0-R3, R12, LR}
RFEIA SP! RFEIA SP!
#endif #endif
...@@ -338,15 +331,15 @@ _osExcPageFaultReturn: ...@@ -338,15 +331,15 @@ _osExcPageFaultReturn:
_osExceptAddrAbortHdl: _osExceptAddrAbortHdl:
SUB LR, LR, #8 @ LR offset to return from this exception: -8. SUB LR, LR, #8 @ LR offset to return from this exception: -8.
SRSFD #0x13! SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support
CPSID i, #0x13 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!, {R0-R3, R12, LR}
STMFD SP, {R13, R14}^ STMFD SP, {R13, R14}^
SUB SP, SP, #(2 * 4) SUB SP, SP, #(2 * 4)
MOV R2, #0 MOV R2, #0
MOV R3, #0 MOV R3, #0
STMFD SP!, {R2-R3} 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. MOV R0, #OS_EXCEPT_ADDR_ABORT @ Set exception ID to OS_EXCEPT_ADDR_ABORT.
B _osExceptDispatch @ Branch to global exception handler. B _osExceptDispatch @ Branch to global exception handler.
...@@ -355,23 +348,27 @@ _osExceptAddrAbortHdl: ...@@ -355,23 +348,27 @@ _osExceptAddrAbortHdl:
_osExceptFiqHdl: _osExceptFiqHdl:
SUB LR, LR, #4 @ LR offset to return from this exception: -4. SUB LR, LR, #4 @ LR offset to return from this exception: -4.
SRSFD #0x13! SRSFD #CPSR_SVC_MODE! @ Save pc and cpsr to svc sp, ARMv6 and above support
CPSID i, #0x13 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!, {R0-R3, R12, LR}
STMFD SP, {R13, R14}^ STMFD SP, {R13, R14}^
SUB SP, SP, #(2 * 4) SUB SP, SP, #(2 * 4)
MOV R2, #0 MOV R2, #0
MOV R3, #0 MOV R3, #0
STMFD SP!, {R2-R3} STMFD SP!, {R2-R3} @ far and fsr fields, are 0 under this anomaly
@ Description: Exception handler @ Description: Exception handler
@ Parameter : R0 Exception Type @ Parameter : R0 Exception Type
@ Regs Hold : R3 Exception`s CPSR @ Regs Hold : R3 Exception`s CPSR
_osExceptDispatch: _osExceptDispatch:
STMFD SP!, {R4-R11} STMFD SP!, {R4-R11}
LDR R8, [SP, #(4 * 8)] LDR R8, [SP, #(8 * 4)] @ Get far
LDR R9, [SP, #(4 * 9)] LDR R9, [SP, #(9 * 4)] @ Get fsr
ADD R2, SP, #(20 * 4) @ sp + sizeof(ExcContext), position of SVC stack before exception
STR R2, [SP, #(8 * 4)] @ Save svc sp
MOV R1, SP MOV R1, SP
EXC_SP_SET __exc_stack_top, OS_EXC_STACK_SIZE, R6, R7 EXC_SP_SET __exc_stack_top, OS_EXC_STACK_SIZE, R6, R7
......
...@@ -63,6 +63,7 @@ typedef struct { ...@@ -63,6 +63,7 @@ typedef struct {
UINT64 SPSR; UINT64 SPSR;
} ExcContext; } ExcContext;
#else #else
/* It has the same structure as TaskContext */
typedef struct { typedef struct {
UINT32 R4; UINT32 R4;
UINT32 R5; UINT32 R5;
...@@ -73,8 +74,8 @@ typedef struct { ...@@ -73,8 +74,8 @@ typedef struct {
UINT32 R10; UINT32 R10;
UINT32 R11; UINT32 R11;
UINT32 SP; UINT32 SP; /**< svc sp */
UINT32 resved; UINT32 reserved; /**< Reserved, multiplexing register */
UINT32 USP; UINT32 USP;
UINT32 ULR; UINT32 ULR;
UINT32 R0; /**< Register R0 */ UINT32 R0; /**< Register R0 */
...@@ -84,7 +85,7 @@ typedef struct { ...@@ -84,7 +85,7 @@ typedef struct {
UINT32 R12; /**< Register R12 */ UINT32 R12; /**< Register R12 */
UINT32 LR; /**< Program returning address. */ UINT32 LR; /**< Program returning address. */
UINT32 PC; /**< PC pointer of the exceptional function */ UINT32 PC; /**< PC pointer of the exceptional function */
UINT32 CPSR; UINT32 regCPSR;
} ExcContext; } ExcContext;
#endif #endif
......
...@@ -1363,9 +1363,9 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT ...@@ -1363,9 +1363,9 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT
return LOS_NOK; return LOS_NOK;
} }
SCHEDULER_LOCK(intSave);
LosTaskCB *taskCB = OsCurrTaskGet(); LosTaskCB *taskCB = OsCurrTaskGet();
SCHEDULER_LOCK(intSave);
taskCB->userMapBase = mapBase; taskCB->userMapBase = mapBase;
taskCB->userMapSize = mapSize; taskCB->userMapSize = mapSize;
taskCB->taskEntry = (TSK_ENTRY_FUNC)entry; taskCB->taskEntry = (TSK_ENTRY_FUNC)entry;
...@@ -1373,8 +1373,6 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT ...@@ -1373,8 +1373,6 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT
TaskContext *taskContext = (TaskContext *)OsTaskStackInit(taskCB->taskID, taskCB->stackSize, TaskContext *taskContext = (TaskContext *)OsTaskStackInit(taskCB->taskID, taskCB->stackSize,
(VOID *)taskCB->topOfStack, FALSE); (VOID *)taskCB->topOfStack, FALSE);
OsUserTaskStackInit(taskContext, (UINTPTR)taskCB->taskEntry, sp); OsUserTaskStackInit(taskContext, (UINTPTR)taskCB->taskEntry, sp);
taskCB->stackPointer = (VOID *)taskContext;
OsTaskContextLoad(taskCB);
SCHEDULER_UNLOCK(intSave); SCHEDULER_UNLOCK(intSave);
return LOS_OK; return LOS_OK;
} }
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#define __LOS_VM_FAULT_H__ #define __LOS_VM_FAULT_H__
#include "los_typedef.h" #include "los_typedef.h"
#include "los_hw_pri.h" #include "los_exc.h"
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
...@@ -46,8 +46,6 @@ extern "C" { ...@@ -46,8 +46,6 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __cplusplus */ #endif /* __cplusplus */
typedef IrqContext PageFaultContext;
typedef struct { typedef struct {
VADDR_T excAddr; VADDR_T excAddr;
VADDR_T fixAddr; VADDR_T fixAddr;
...@@ -58,7 +56,7 @@ typedef struct { ...@@ -58,7 +56,7 @@ typedef struct {
#define VM_MAP_PF_FLAG_INSTRUCTION (1U << 2) #define VM_MAP_PF_FLAG_INSTRUCTION (1U << 2)
#define VM_MAP_PF_FLAG_NOT_PRESENT (1U << 3) #define VM_MAP_PF_FLAG_NOT_PRESENT (1U << 3)
STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, PageFaultContext *frame); STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -556,15 +556,16 @@ int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact) ...@@ -556,15 +556,16 @@ int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact)
return LOS_OK; return LOS_OK;
} }
VOID *OsSaveSignalContext(VOID *sp) VOID *OsSaveSignalContext(VOID *sp, VOID *newSp)
{ {
UINTPTR sigHandler; UINTPTR sigHandler;
UINT32 intSave; UINT32 intSave;
SCHEDULER_LOCK(intSave);
LosTaskCB *task = OsCurrTaskGet(); LosTaskCB *task = OsCurrTaskGet();
LosProcessCB *process = OsCurrProcessGet(); LosProcessCB *process = OsCurrProcessGet();
sig_cb *sigcb = &task->sig; sig_cb *sigcb = &task->sig;
SCHEDULER_LOCK(intSave);
if ((sigcb->count == 0) && ((sigcb->sigFlag != 0) || (process->sigShare != 0))) { if ((sigcb->count == 0) && ((sigcb->sigFlag != 0) || (process->sigShare != 0))) {
sigHandler = OsGetSigHandler(); sigHandler = OsGetSigHandler();
if (sigHandler == 0) { if (sigHandler == 0) {
...@@ -581,7 +582,7 @@ VOID *OsSaveSignalContext(VOID *sp) ...@@ -581,7 +582,7 @@ VOID *OsSaveSignalContext(VOID *sp)
OsProcessExitCodeSignalSet(process, signo); OsProcessExitCodeSignalSet(process, signo);
sigcb->sigContext = sp; sigcb->sigContext = sp;
VOID *newSp = OsInitSignalContext(sp, sigHandler, signo, sigVal); OsInitSignalContext(sp, newSp, sigHandler, signo, sigVal);
/* sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */ /* sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */
sigcb->sigFlag ^= 1ULL << (signo - 1); sigcb->sigFlag ^= 1ULL << (signo - 1);
...@@ -598,10 +599,10 @@ VOID *OsRestorSignalContext(VOID *sp) ...@@ -598,10 +599,10 @@ VOID *OsRestorSignalContext(VOID *sp)
{ {
UINT32 intSave; UINT32 intSave;
SCHEDULER_LOCK(intSave);
LosTaskCB *task = OsCurrTaskGet(); LosTaskCB *task = OsCurrTaskGet();
sig_cb *sigcb = &task->sig; sig_cb *sigcb = &task->sig;
SCHEDULER_LOCK(intSave);
if (sigcb->count != 1) { if (sigcb->count != 1) {
SCHEDULER_UNLOCK(intSave); SCHEDULER_UNLOCK(intSave);
PRINT_ERR("sig error count : %d\n", sigcb->count); PRINT_ERR("sig error count : %d\n", sigcb->count);
......
...@@ -75,12 +75,12 @@ STATIC STATUS_T OsVmRegionRightCheck(LosVmMapRegion *region, UINT32 flags) ...@@ -75,12 +75,12 @@ STATIC STATUS_T OsVmRegionRightCheck(LosVmMapRegion *region, UINT32 flags)
return LOS_OK; return LOS_OK;
} }
STATIC VOID OsFaultTryFixup(PageFaultContext *frame, VADDR_T excVaddr, STATUS_T *status) STATIC VOID OsFaultTryFixup(ExcContext *frame, VADDR_T excVaddr, STATUS_T *status)
{ {
INT32 tableNum = (__exc_table_end - __exc_table_start) / sizeof(LosExcTable); INT32 tableNum = (__exc_table_end - __exc_table_start) / sizeof(LosExcTable);
LosExcTable *excTable = (LosExcTable *)__exc_table_start; LosExcTable *excTable = (LosExcTable *)__exc_table_start;
if ((frame->CPSR & CPSR_MODE_MASK) != CPSR_MODE_USR) { if ((frame->regCPSR & CPSR_MODE_MASK) != CPSR_MODE_USR) {
for (int i = 0; i < tableNum; ++i, ++excTable) { for (int i = 0; i < tableNum; ++i, ++excTable) {
if (frame->PC == (UINTPTR)excTable->excAddr) { if (frame->PC == (UINTPTR)excTable->excAddr) {
frame->PC = (UINTPTR)excTable->fixAddr; frame->PC = (UINTPTR)excTable->fixAddr;
...@@ -332,7 +332,7 @@ STATIC STATUS_T OsDoFileFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault, U ...@@ -332,7 +332,7 @@ STATIC STATUS_T OsDoFileFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault, U
return ret; return ret;
} }
STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, PageFaultContext *frame) STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
{ {
LosVmSpace *space = LOS_SpaceGet(vaddr); LosVmSpace *space = LOS_SpaceGet(vaddr);
LosVmMapRegion *region = NULL; LosVmMapRegion *region = NULL;
......
...@@ -99,7 +99,7 @@ VOID OsArmA32SyscallHandle(TaskContext *regs) ...@@ -99,7 +99,7 @@ VOID OsArmA32SyscallHandle(TaskContext *regs)
UINT32 ret; UINT32 ret;
UINT8 nArgs; UINT8 nArgs;
UINTPTR handle; UINTPTR handle;
UINT32 cmd = regs->resved2; UINT32 cmd = regs->reserved2;
if (cmd >= SYS_CALL_NUM) { if (cmd >= SYS_CALL_NUM) {
PRINT_ERR("Syscall ID: error %d !!!\n", cmd); PRINT_ERR("Syscall ID: error %d !!!\n", cmd);
...@@ -134,8 +134,5 @@ VOID OsArmA32SyscallHandle(TaskContext *regs) ...@@ -134,8 +134,5 @@ VOID OsArmA32SyscallHandle(TaskContext *regs)
regs->R0 = ret; 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; return;
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册