fix:Fixed exception not saving stack pointer of SVC mode and abnormal signal processing issues
Close #I3OAFR Change-Id: I25b14572809b6fabb9e9d17de89a99047c02a59b
This commit is contained in:
parent
f6c4f6f5da
commit
1e308db64e
|
@ -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 {
|
||||||
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 {
|
||||||
UINT32 R12;
|
UINT32 R12;
|
||||||
UINT32 LR;
|
UINT32 LR;
|
||||||
UINT32 PC;
|
UINT32 PC;
|
||||||
UINT32 CPSR;
|
UINT32 regCPSR;
|
||||||
} IrqContext;
|
} IrqContext;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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:
|
||||||
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:
|
||||||
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:
|
||||||
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:
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
#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,
|
||||||
/* 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
|
||||||
{
|
{
|
||||||
/* 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)
|
||||||
"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)
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
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:
|
||||||
#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:
|
||||||
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:
|
||||||
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:
|
||||||
#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:
|
||||||
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:
|
||||||
#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:
|
||||||
_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:
|
||||||
_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:
|
||||||
_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 {
|
||||||
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 {
|
||||||
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 {
|
||||||
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
|
||||||
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
|
||||||
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 @@
|
||||||
#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" {
|
||||||
#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 {
|
||||||
#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)
|
||||||
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)
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue