异常分发,缺页中断 汇编部分代码注解

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    https://my.oschina.net/weharmony
上级 ad4e941c
此差异已折叠。
...@@ -117,7 +117,7 @@ STATIC UINTPTR g_minAddr; ...@@ -117,7 +117,7 @@ STATIC UINTPTR g_minAddr;
STATIC UINTPTR g_maxAddr; STATIC UINTPTR g_maxAddr;
STATIC UINT32 g_currHandleExcCpuID = INVALID_CPUID; STATIC UINT32 g_currHandleExcCpuID = INVALID_CPUID;
VOID OsExcHook(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 fsr); VOID OsExcHook(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 fsr);
UINT32 g_curNestCount[LOSCFG_KERNEL_CORE_NUM] = { 0 };// UINT32 g_curNestCount[LOSCFG_KERNEL_CORE_NUM] = { 0 };//记录当前嵌套异常的数量
BOOL g_excFromUserMode[LOSCFG_KERNEL_CORE_NUM];//记录CPU core 异常来自用户态还是内核态 TRUE为用户态,默认为内核态 BOOL g_excFromUserMode[LOSCFG_KERNEL_CORE_NUM];//记录CPU core 异常来自用户态还是内核态 TRUE为用户态,默认为内核态
STATIC EXC_PROC_FUNC g_excHook = (EXC_PROC_FUNC)OsExcHook;//全局异常处理钩子 STATIC EXC_PROC_FUNC g_excHook = (EXC_PROC_FUNC)OsExcHook;//全局异常处理钩子
#if (LOSCFG_KERNEL_SMP == YES) #if (LOSCFG_KERNEL_SMP == YES)
...@@ -239,7 +239,11 @@ STATIC INT32 OsDecodeDataFSR(UINT32 regDFSR) ...@@ -239,7 +239,11 @@ STATIC INT32 OsDecodeDataFSR(UINT32 regDFSR)
ret = OsDecodeFS(bitsFS); ret = OsDecodeFS(bitsFS);
return ret; return ret;
} }
//共享页缺失异常 /*
* 共享页缺失异常
* 异常状态寄存器(Fault Status Register -FAR)
* 异常地址寄存器(Fault Address Register -FSR)
*/
UINT32 OsArmSharedPageFault(UINT32 excType, ExcContext *frame, UINT32 far, UINT32 fsr) UINT32 OsArmSharedPageFault(UINT32 excType, ExcContext *frame, UINT32 far, UINT32 fsr)
{ {
PRINT_INFO("page fault entry!!!\n"); PRINT_INFO("page fault entry!!!\n");
...@@ -1040,7 +1044,12 @@ LITE_OS_SEC_TEXT VOID STATIC OsExcPriorDisposal(ExcContext *excBufAddr) ...@@ -1040,7 +1044,12 @@ LITE_OS_SEC_TEXT VOID STATIC OsExcPriorDisposal(ExcContext *excBufAddr)
* Description : EXC handler entry * Description : EXC handler entry
* Input : excType --- exc type * Input : excType --- exc type
* excBufAddr --- address of EXC buf * excBufAddr --- address of EXC buf
*///异常处理的执行入口,由汇编语言层调用 见于 los_hw_exc.s 文件 */
/*异常处理的执行入口,由汇编语言层调用 见于 los_hw_exc.s 文件
* 参数excBufAddr为异常发生时保存下来寄存器的值.
* 异常状态寄存器(Fault Status Register -FAR)
* 异常地址寄存器(Fault Address Register -FSR)
*/
LITE_OS_SEC_TEXT_INIT VOID OsExcHandleEntry(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 fsr) LITE_OS_SEC_TEXT_INIT VOID OsExcHandleEntry(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 fsr)
{ {
/* Task scheduling is not allowed during exception handling *///异常处理期间不允许任务调度 /* Task scheduling is not allowed during exception handling *///异常处理期间不允许任务调度
......
...@@ -170,11 +170,18 @@ _osExceptUndefInstrHdl:@出现未定义的指令处理 ...@@ -170,11 +170,18 @@ _osExceptUndefInstrHdl:@出现未定义的指令处理
B _osExceptDispatch @ Branch to global exception handler. B _osExceptDispatch @ Branch to global exception handler.
#endif #endif
/*
STMIB(地址先增而后完成操作)、STMFA(满递增堆栈);
STMIA(完成操作而后地址递增)、STMEA(空递增堆栈);
STMDB(地址先减而后完成操作)、STMFD(满递减堆栈);
STMDA(完成操作而后地址递减)、STMED(空递减堆栈)。
*/
@ Description: Software interrupt exception handler @ Description: Software interrupt exception handler
_osExceptSwiHdl: @软中断异常处理 _osExceptSwiHdl: @软中断异常处理
@保存任务上下文(TaskContext) 开始... 一定要对照TaskContext来理解
SUB SP, SP, #(4 * 16) @先申请16个栈空间用于处理本次软中断 SUB SP, SP, #(4 * 16) @先申请16个栈空间用于处理本次软中断
STMIA SP, {R0-R12} @保存R0-R12寄存器值 STMIA SP, {R0-R12} @TaskContext.R[GEN_REGS_NUM] STMIA从左到右执行,先放R0 .. R12
MRS R3, SPSR @读取本模式下的SPSR MRS R3, SPSR @读取本模式下的SPSR
MOV R4, LR @保存回跳寄存器LR MOV R4, LR @保存回跳寄存器LR
...@@ -185,18 +192,18 @@ _osExceptSwiHdl: @软中断异常处理 ...@@ -185,18 +192,18 @@ _osExceptSwiHdl: @软中断异常处理
@ we enter from user mode, we need get the values of USER mode r13(sp) and r14(lr). @ we enter from user mode, we need get the values of USER mode r13(sp) and r14(lr).
@ stmia with ^ will return the user mode registers (provided that r15 is not in the register list). @ stmia with ^ will return the user mode registers (provided that r15 is not in the register list).
MOV R0, SP @获取SP,R0将作为OsArmA32SyscallHandle的参数 MOV R0, SP @获取SP,R0将作为OsArmA32SyscallHandle的参数
STMFD SP!, {R3} @ Save the CPSR 入栈保存CPSR STMFD SP!, {R3} @ Save the CPSR 入栈保存CPSR => TaskContext.regPSR
ADD R3, SP, #(4 * 17) @ Offset to pc/cpsr storage 跳到PC/CPSR存储位置 ADD R3, SP, #(4 * 17) @ Offset to pc/cpsr storage 跳到PC/CPSR存储位置
STMFD R3!, {R4} @ Save the CPSR and r15(pc) 保存LR寄存器 STMFD R3!, {R4} @ Save the CPSR and r15(pc) 保存LR寄存器 => TaskContext.PC
STMFD R3, {R13, R14}^ @ Save user mode r13(sp) and r14(lr) 保存用户模式下的SPLR寄存器 STMFD R3, {R13, R14}^ @ Save user mode r13(sp) and r14(lr) 从右向左 保存 => TaskContext.LRSP
SUB SP, SP, #4 SUB SP, SP, #4 @ => TaskContext.resved
PUSH_FPU_REGS R1 @保存中断模式(用户模式模式) PUSH_FPU_REGS R1 @保存中断模式(用户模式模式)
@保存任务上下文(TaskContext) 结束
MOV FP, #0 @ Init frame pointer MOV FP, #0 @ Init frame pointer
CPSIE I @开中断,表明在系统调用期间可响应中断 CPSIE I @开中断,表明在系统调用期间可响应中断
BLX OsArmA32SyscallHandle /*交给C语言处理系统调用*/ BLX OsArmA32SyscallHandle /*交给C语言处理系统调用*/
CPSID I @执行后续指令前必须先关中断 CPSID I @执行后续指令前必须先关中断
@恢复任务上下文(TaskContext) 开始
POP_FPU_REGS R1 @弹出FP值给R1 POP_FPU_REGS R1 @弹出FP值给R1
ADD SP, SP,#4 @ 定位到保存旧SPSR值的位置 ADD SP, SP,#4 @ 定位到保存旧SPSR值的位置
LDMFD SP!, {R3} @ Fetch the return SPSR 弹出旧SPSR LDMFD SP!, {R3} @ Fetch the return SPSR 弹出旧SPSR
...@@ -209,23 +216,24 @@ _osExceptSwiHdl: @软中断异常处理 ...@@ -209,23 +216,24 @@ _osExceptSwiHdl: @软中断异常处理
LDMFD SP, {R13, R14}^ @ Restore user mode R13/R14 恢复用户模式的R13/R14寄存器 LDMFD SP, {R13, R14}^ @ Restore user mode R13/R14 恢复用户模式的R13/R14寄存器
ADD SP, SP, #(2 * 4) @定位到保存旧PC值的位置 ADD SP, SP, #(2 * 4) @定位到保存旧PC值的位置
LDMFD SP!, {PC}^ @ Return to user 切回用户模式运行 LDMFD SP!, {PC}^ @ Return to user 切回用户模式运行
@恢复任务上下文(TaskContext) 结束
OsKernelSVCHandler: OsKernelSVCHandler:@主要目的是保存ExcContext中除(R0~R12)的其他寄存器
ADD R0, SP, #(4 * 16) @R0=sp+64 ADD R0, SP, #(4 * 16) @跳转到保存PC,LR,SP的位置,此时R0位置刚好是SP的位置
MOV R5, R0 MOV R5, R0 @R5记录SP位置,因为R0要暂时充当SP寄存器来使用
STMFD R0!, {R4} @ Store PC STMFD R0!, {R4} @ Store PC => ExcContext.PC
STMFD R0!, {R4} STMFD R0!, {R4} @ 相当于保存了=> ExcContext.LR
STMFD R0!, {R5} STMFD R0!, {R5} @ 相当于保存了=> ExcContext.SP
STMFD SP!, {R3} @ Push task`s CPSR (i.e. exception SPSR). STMFD SP!, {R3} @ Push task`s CPSR (i.e. exception SPSR). =>ExcContext.regPSR
SUB SP, SP, #(4 * 2) @ user sp and lr SUB SP, SP, #(4 * 2) @ user sp and lr => =>ExcContext.USP,ULR
MOV R0, #OS_EXCEPT_SWI @ Set exception ID to OS_EXCEPT_SWI. MOV R0, #OS_EXCEPT_SWI @ Set exception ID to OS_EXCEPT_SWI.
@ 设置异常ID为软中断 @ 设置异常ID为软中断
B _osExceptionSwi @ Branch to global exception handler. B _osExceptionSwi @ Branch to global exception handler.
@ 跳到软中断处理 @ 跳到全局异常处理
@ Description: Prefectch abort exception handler @ Description: Prefectch abort exception handler
_osExceptPrefetchAbortHdl: _osExceptPrefetchAbortHdl: @预取异常处理
#ifdef LOSCFG_GDB #ifdef LOSCFG_GDB
#if __LINUX_ARM_ARCH__ >= 7 #if __LINUX_ARM_ARCH__ >= 7
GDB_HANDLE OsPrefetchAbortExcHandleEntry GDB_HANDLE OsPrefetchAbortExcHandleEntry
...@@ -240,7 +248,7 @@ _osExceptPrefetchAbortHdl: ...@@ -240,7 +248,7 @@ _osExceptPrefetchAbortHdl:
AND R4, R1, #CPSR_MASK_MODE @ Interrupted mode AND R4, R1, #CPSR_MASK_MODE @ Interrupted mode
CMP R4, #CPSR_USER_MODE @ User mode CMP R4, #CPSR_USER_MODE @ User mode
BEQ _osExcPageFault @ Branch if user mode BEQ _osExcPageFault @ Branch if user mode
_osKernelExceptPrefetchAbortHdl: _osKernelExceptPrefetchAbortHdl:
MOV LR, R5 MOV LR, R5
...@@ -282,10 +290,11 @@ _osExceptFiqHdl: @快中断异常处理 ...@@ -282,10 +290,11 @@ _osExceptFiqHdl: @快中断异常处理
@ 设置参数异常类型,将作为参数传给_osExceptDispatch @ 设置参数异常类型,将作为参数传给_osExceptDispatch
B _osExceptDispatch @ Branch to global exception handler. B _osExceptDispatch @ Branch to global exception handler.
_osExcPageFault: @缺页异常处理函数 _osExcPageFault: @缺页中断处理函数
SUB R3, SP, #(8 * 4) @ Save the start address of working registers. 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 MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) @ Switch to SVC mode, and disable all interrupts
MOV R2, SP MOV R2, SP
@按 ExcContext 格式开始保存现场 因为 OsArmSharedPageFault 第二个参数就是 ExcContext
STMFD SP!, {R5} @ Push original PC STMFD SP!, {R5} @ Push original PC
STMFD SP!, {LR} @ Push original svc LR STMFD SP!, {LR} @ Push original svc LR
STMFD SP!, {R2} @ Push original svc SP STMFD SP!, {R2} @ Push original svc SP
...@@ -295,31 +304,31 @@ _osExcPageFault: @缺页异常处理函数 ...@@ -295,31 +304,31 @@ _osExcPageFault: @缺页异常处理函数
STMFD SP!, {R1} STMFD SP!, {R1}
SUB SP, SP, #8 SUB SP, SP, #8
STMIA SP, {R13, R14}^ @ Save user mode r13(sp) and r14(lr) STMIA SP, {R13, R14}^ @ Save user mode r13(sp) and r14(lr)
@按ExcContext格式完成保存现场
MOV R4, SP MOV R4, SP @R4指向SP ExcContext开始位置
BIC SP, SP, #7 BIC SP, SP, #7
PUSH_FPU_REGS R1 PUSH_FPU_REGS R1
CMP R0, #OS_EXCEPT_DATA_ABORT CMP R0, #OS_EXCEPT_DATA_ABORT @从正确的地址中取数据发生异常
BNE 1f BNE 1f
MRC P15, 0, R2, C6, C0, 0 MRC P15, 0, R2, C6, C0, 0 @参数3 UINT32 far 异常地址寄存器(Fault Address Register -FSR)
MRC P15, 0, R3, C5, C0, 0 MRC P15, 0, R3, C5, C0, 0 @参数4 UINT32 fsr 异常状态寄存器(Fault Status Register -FSR)
B 2f B 2f
1: MRC P15, 0, R2, C6, C0, 2 1: MRC P15, 0, R2, C6, C0, 2
MRC P15, 0, R3, C5, C0, 1 MRC P15, 0, R3, C5, C0, 1
2: MOV R1, R4 2: MOV R1, R4 @参数R1 ExcContext开始位置
MOV R5, R0 MOV R5, R0
MOV R8, R2 MOV R8, R2
MOV R9, R3 MOV R9, R3
CPSIE I CPSIE I @禁止中断
BLX OsArmSharedPageFault BLX OsArmSharedPageFault @缺页中断处理参数(UINT32 excType, ExcContext *frame, UINT32 far, UINT32 fsr)
CPSID I CPSID I @恢复中断
POP_FPU_REGS R1 POP_FPU_REGS R1
MOV SP, R4 MOV SP, R4
CMP R0, #0 CMP R0, #0
BEQ _OsExcReturn BEQ _OsExcReturn @异常返回
MOV R0, R5 @ exc type MOV R0, R5 @ exc type
B _osExceptionSwi @跳到软中断执行,系统调用就是通过软中断实现 B _osExceptionSwi @跳到软中断执行,系统调用就是通过软中断实现
...@@ -335,17 +344,17 @@ _osExceptDispatch: @处理异常分发 ...@@ -335,17 +344,17 @@ _osExceptDispatch: @处理异常分发
MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) @ Switch to SVC mode, and disable all interrupts MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) @ Switch to SVC mode, and disable all interrupts
@ 切换到SVC模式,屏蔽掉所有中断 @ 切换到SVC模式,屏蔽掉所有中断
MOV R5, SP @ R5 = SP ,保存SP位置 MOV R5, SP @ R5 = SP ,保存SP位置
EXC_SP_SET __exc_stack_top, OS_EXC_STACK_SIZE, R6, R7 @ 切换到当前CPUSVC模式栈处理 EXC_SP_SET __exc_stack_top, OS_EXC_STACK_SIZE, R6, R7 @ 切换到当前CPUSVC模式栈处理,R6,R7用于记录CPUid和偏移量
@开始 保存异常上下文(ExcContext), 顺序是 USP,ULR,SPSR,R0~R15
STMFD SP!, {R1} @ Push Exception PC 保存上一个工作模式的PC STMFD SP!, {R1} @ Push Exception PC 保存上一个工作模式的PC => ExcContext.PC
STMFD SP!, {LR} @ Push SVC LR 保存上一个工作模式的LR STMFD SP!, {LR} @ Push SVC LR 保存上一个工作模式的LR => ExcContext.LR
STMFD SP!, {R5} @ Push SVC SP 保存上一个工作模式的SP STMFD SP!, {R5} @ Push SVC SP 保存上一个工作模式的SP => ExcContext.SP
STMFD SP!, {R8-R12} @ Push original R12-R8,保存上一个工作模式的R8-R12 STMFD SP!, {R8-R12} @ Push original R12-R8,保存上一个工作模式的R8-R12 => ExcContext.R8 - R12
LDMFD R3!, {R4-R11} @ Move original R7-R0 from exception stack to original stack. LDMFD R3!, {R4-R11} @ Move original R7-R0 from exception stack to original stack.
@ 将保存在上一个工作模式的R0~R7取出 @ 将保存在上一个工作模式的R0~R7取出
STMFD SP!, {R4-R11} @ 将上一个工作模式的R0~R7保存到新的栈中 STMFD SP!, {R4-R11} @ 将上一个工作模式的R0~R7保存到新的栈中 => ExcContext.R0 - R7
STMFD SP!, {R2} @ Push task`s CPSR (i.e. exception SPSR). STMFD SP!, {R2} @ Push task`s CPSR (i.e. exception SPSR). => ExcContext.regCPSR
@ 任务的CPSR入栈 @除了ExcContext.USP,ULR两个值,保存异常上下文(ExcContext)其他值完成.
CMP R0, #OS_EXCEPT_DATA_ABORT @是数据异常吗? CMP R0, #OS_EXCEPT_DATA_ABORT @是数据异常吗?
BNE 1f @不是跳到 锚点1 BNE 1f @不是跳到 锚点1
MRC P15, 0, R8, C6, C0, 0 @R8=C6(内存失效的地址) 0(访问数据失效) MRC P15, 0, R8, C6, C0, 0 @R8=C6(内存失效的地址) 0(访问数据失效)
...@@ -358,58 +367,58 @@ _osExceptDispatch: @处理异常分发 ...@@ -358,58 +367,58 @@ _osExceptDispatch: @处理异常分发
B 3f @直接跳到 锚点3: 处执行 B 3f @直接跳到 锚点3: 处执行
2: MOV R8, #0 @R8=0 2: MOV R8, #0 @R8=0
MOV R9, #0 @R9=0 MOV R9, #0 @R9=0
@可看出异常过后,R8,R9的值发生变化,获取协处理对应的数据.
3: AND R2, R2, #CPSR_MASK_MODE @获取当前工作模式 3: AND R2, R2, #CPSR_MASK_MODE @获取当前工作模式
CMP R2, #CPSR_USER_MODE @ User mode 是否为用户模式 CMP R2, #CPSR_USER_MODE @ User mode 是否为用户模式
BNE 4f @不是用户模式,跳到 锚点4: 处运行 BNE 4f @不是用户模式,跳到 锚点4: 处运行
STMFD SP, {R13, R14}^ @ save user mode sp and lr 保存用户模式的SPLR STMFD SP, {R13, R14}^ @ save user mode sp and lr 保存用户模式的SPLR
4: 4: @保存 => ExcContext.USP,ULR
SUB SP, SP, #(4 * 2) @sp=sp-(4*2) 指向真正的栈顶 SUB SP, SP, #(4 * 2) @非用户模式下不需要保存 USP,ULR,所以跳过2个空间
@填充好ExcContext.USP,ULR两个值,R8,R9 获得异常的信息,将接着往下执行
_osExceptionSwi: @软中断的处理,系统调用就是由软中断实现的 _osExceptionSwi: @异常软处理
MOV R1, SP @ The second argument to the exception MOV R1, SP @ The second argument to the exception
@ 异常的第二个参数,第一个参数是R0 @ 异常的第二个参数,第一个参数是R0
MRC P15, 0, R4, C0, C0, 5 @ R4获取当前cpu id MRC P15, 0, R4, C0, C0, 5 @ R4获取当前cpu id
AND R4, R4, #MPIDR_CPUID_MASK @ Get Current cpu id AND R4, R4, #MPIDR_CPUID_MASK @ Get Current cpu id
LSL R2, R4, #2 @(Logic Shift Left)逻辑左移指令 R2 = R4<<2 @note_why 没看明白这句话的含义 LSL R2, R4, #2 @(Logic Shift Left)逻辑左移指令 R2 = R4<<2 @note_why 没看明白这句话的含义
LDR R3, =g_curNestCount @ if(g_curNestCount > 0) dump to _osExceptionGetSP LDR R3, =g_curNestCount @ if(g_curNestCount > 0) dump to _osExceptionGetSP 嵌套异常
@将g_curNestCount的地址存入R3 @将g_curNestCount的地址存入R3
ADD R3, R3, R2 @ R3 = R3 + R2 ADD R3, R3, R2 @ R3 = R3 + R2,
LDR R4, [R3] @R4 = *R3 LDR R4, [R3] @ R4 = *R3
CMP R4, #0 @R4 0对比 CMP R4, #0 @R4 0对比
BNE _osExceptionGetSP @不相等则跳转 BNE _osExceptionGetSP @(g_curNestCount > 0)说明有嵌套异常,必须先处理异常
@判断异常发生在任务堆栈或系统堆栈中 @判断异常发生在任务堆栈或系统堆栈中
LDR R3, =g_intCount @ Judge the exception is occur in task stack or system stack LDR R3, =g_intCount @ Judge the exception is occur in task stack or system stack
ADD R3, R3, R2 ADD R3, R3, R2
LDR R4, [R3] LDR R4, [R3] @获取g_intCount[ArchCurrCpuid()]的值
@软中断的优先级要低于硬中断,这里判断是否有硬中断发生,有则需先处理硬中断 @软中断的优先级要低于硬中断,这里判断是否有硬中断发生,有则需先处理硬中断
CMP R4, #0 @ if (g_intCount[ArchCurrCpuid()] > 0) 当前有中断要处理 CMP R4, #0 @ if (g_intCount[ArchCurrCpuid()] > 0) 当前有中断要处理
BNE _osExceptionGetSP @ can not switch svc stack 无法切换到svc堆栈 BNE _osExceptionGetSP @ can not switch svc stack 有中断要处理,必须先处理异常
@切换到统一异常堆栈(SVC栈) @切换到SVC栈中处理未定义的异常
EXC_SP_SET __svc_stack_top, OS_EXC_SVC_STACK_SIZE, R6, R7 @ Switch to unified exception stack. EXC_SP_SET __svc_stack_top, OS_EXC_SVC_STACK_SIZE, R6, R7 @ Switch to unified exception stack.
ADD R4, R4, #1 ADD R4, R4, #1
STR R4, [R3] STR R4, [R3]
_osExceptionGetSP: _osExceptionGetSP:@处理异常 R1=sp
MOV R2, R8 @ far CP15c6获取 MOV R2, R8 @ far CP15c6获取 异常地址寄存器(Fault Address Register -FSR)
MOV R3, R9 @ fsr CP15c5获取 MOV R3, R9 @ fsr CP15c5获取 异常状态寄存器(Fault Status Register -FSR)
LDR R5, =OsExcHandleEntry @ OsExcHandleEntry(UINT32 excType, ExcContext * excBufAddr) LDR R5, =OsExcHandleEntry @ OsExcHandleEntry(UINT32 excType, ExcContext * excBufAddr,UINT32 far, UINT32 fsr)
BX R5 @LDR为加载指令把OsExcHandleEntry的地址放入R5BX为带分支的跳转指令,去执行OsExcHandleEntry BX R5 @LDR为加载指令把OsExcHandleEntry的地址放入R5BX为带分支的跳转指令,去执行OsExcHandleEntry
_OsExcReturn: _OsExcReturn:@异常返回
LDR R0, [SP, #(2 * 4)] LDR R0, [SP, #(2 * 4)]
AND R0, R0, #CPSR_MASK_MODE AND R0, R0, #CPSR_MASK_MODE
CMP R0, #CPSR_USER_MODE @ User mode CMP R0, #CPSR_USER_MODE @ User mode
BNE _OsExcReturnToKernel @非用户模式跳转执行 BNE _OsExcReturnToKernel @非用户模式跳转执行
LDMFD SP, {R13, R14}^ @ load user mode sp and lr LDMFD SP, {R13, R14}^ @ load user mode sp and lr
@恢复splr的值 < = ExcContext.USP,ULR 回到用户栈继续运行
_OsExcReturnToKernel: _OsExcReturnToKernel: @内核模式的异常返回
ADD SP, SP, #(2 * 4) ADD SP, SP, #(2 * 4) @先跳开ExcContext.USPULR
LDMFD SP!, {R1} LDMFD SP!, {R1} @取出R1 = ExcContext.SPSR
MSR SPSR_cxsf, R1 @ Set the return mode SPSR MSR SPSR_cxsf, R1 @ Set the return mode SPSR < = ExcContext.regCPSR
LDMFD SP!, {R0-R12} LDMFD SP!, {R0-R12} @依次恢复 R0~R12 < = ExcContext.R0 - R12
ADD SP, SP, #4 ADD SP, SP, #4 @跳过ExcContext.SP
LDMFD SP!, {LR, PC}^ LDMFD SP!, {LR, PC}^ @恢复LRPC的值 < = ExcContext.LR ,PC
.end .end
git add -A git add -A
git commit -m '鸿蒙内核源码分析(中断管理篇) | 硬中断的实现类似观察者模式 | 百篇博客分析鸿蒙源码 | v44.01 git commit -m '异常分发,缺页中断 汇编部分代码注解
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码 百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
https://my.oschina.net/weharmony https://my.oschina.net/weharmony
' '
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册