提交 ca5555e6 编写于 作者: O openharmony_ci 提交者: Gitee

!190 fix:solve the coupling between the kernel and the structure under ARCH

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