硬中断汇编代码注解

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    https://weharmony.gitee.io
上级 68e75446
......@@ -77,12 +77,12 @@ MRS{条件} 通用寄存器,程序状态寄存器(CPSR 或SPSR)
MRS R0,SPSR @传送SPSR 的内容到R0
@MRS指令是唯一可以直接读取CPSR和SPSR寄存器的指令
SPSR
程序状态保护寄存器,每一种模式下都有一个状态寄存器SPSR,用于保存CPSR的状态,
SPSR(saved program status register)程序状态保存寄存器.
每一种模式下都有一个状态寄存器SPSR,用于保存CPSR的状态,
以便异常返回后恢复异常发生时的工作状态。用户模式和系统模式不是异常状态,
所以没有SPSR,在这两种模式下访问SPSR,将产生不可预知的后果。
1、SPSR 为 CPSR 中断时刻的副本,退出中断后,将SPSR中数据恢复到CPSR中。
2、用户模式和系统模式下SPSR不可用
2、用户模式和系统模式下SPSR不可用,所以SPSR寄存器只有5个
******************************************************************************/
#define CPSR_INT_DISABLE 0xC0 /* Disable both FIQ and IRQ */ //禁止IRQ和FIQ中断,因为0xC0 = 0x80 + 0x40
#define CPSR_IRQ_DISABLE 0x80 /* IRQ disabled when =1 */ //禁止IRQ 中断
......@@ -99,7 +99,7 @@ SPSR
/* Define exception type ID */ //ARM处理器一共有7种工作模式,除了用户和系统模式其余都叫异常工作模式
#define OS_EXCEPT_RESET 0x00 //重置功能,例如:开机就进入CPSR_SVC_MODE模式
#define OS_EXCEPT_UNDEF_INSTR 0x01 //未定义的异常,就是others
#define OS_EXCEPT_SWI 0x02 //软件定时器中断
#define OS_EXCEPT_SWI 0x02 //软中断
#define OS_EXCEPT_PREFETCH_ABORT 0x03 //预取异常(取指异常), 指令三步骤: 取指,译码,执行,
#define OS_EXCEPT_DATA_ABORT 0x04 //数据异常
#define OS_EXCEPT_FIQ 0x05 //快中断异常
......
......@@ -109,16 +109,16 @@ ARM的指令系统中关于栈指令的内容比较容易引起迷惑,这是
.global ArchSpinUnlock /*自旋锁解锁*/
.global OsSchedToUserSpinUnlock /*尚未实现*/
/* @note_why 为何要重新定义OS_TASK_STATUS_RUNNING? */
.equ OS_TASK_STATUS_RUNNING, 0x0010U /* .equ用于把常量值设置为可以在文本段中使用的符号 #define OS_TASK_STATUS_RUNNING 0x0010U */
.equ OS_PERCPU_STRUCT_SIZE, 0x28U
.equ OS_PERCPU_TASK_LOCK_OFFSET, 0x14U
.equ OS_TASK_STATUS_RUNNING, 0x0010U /* .equ用于把常量值设置为可以在文本段中使用的符号 #define OS_TASK_STATUS_RUNNING 0x0010U */
.equ OS_PERCPU_STRUCT_SIZE, 0x28U /*宏定义 #define OS_PERCPU_STRUCT_SIZE 0x28U*/
.equ OS_PERCPU_TASK_LOCK_OFFSET, 0x14U /*宏定义 #define OS_PERCPU_TASK_LOCK_OFFSET 0x14U*/
.fpu vfpv4 /* .fpu @note_why 尚未知这句话的含义 */
/* 此宏用于对齐和不对齐8字节边界上的堆栈以符合ABI */
/* macros to align and unalign the stack on 8 byte boundary for ABI compliance */
.macro STACK_ALIGN, reg /* 栈对齐*/
MOV \reg, sp
TST SP, #4
SUBEQ SP, #4
MOV \reg, sp @reg=sp
TST SP, #4 @来检查是否设置了特定的位
SUBEQ SP, #4 @表示相等时相减
PUSH { \reg }
.endm
......@@ -226,13 +226,13 @@ OsTaskContextLoad:
ADD SP, SP, #4 @sp=sp+4
#endif
/* R0 = &g_taskSpin.rawLock */
LDR R0, =g_taskSpin
BL ArchSpinUnlock
LDR R2, =g_percpu
MRC P15, 0, R3, C0, C0, 5
UXTB R3, R3
MOV R1, #OS_PERCPU_STRUCT_SIZE
MLA R3, R1, R3, R2
LDR R0, =g_taskSpin @ R0 = &g_taskSpin.rawLock 将作为 ArchSpinUnlock的参数
BL ArchSpinUnlock @释放自旋锁g_taskSpin
LDR R2, =g_percpu
MRC P15, 0, R3, C0, C0, 5 @获取CPUIDR3
UXTB R3, R3 @字节被无符号扩展到32位(高24位清0
MOV R1, #OS_PERCPU_STRUCT_SIZE @R1 = sizeof(Percpu)
MLA R3, R1, R3, R2 @R3=R1*R3
MOV R2, #0
STR R2, [R3, #OS_PERCPU_TASK_LOCK_OFFSET]
#endif
......@@ -254,18 +254,18 @@ OsKernelTaskLoad: @内核任务的加载
ADD SP, SP, #4 @sp=SP+4
LDMFD SP!, {LR, PC}^ @返回地址赋给pc指针
OsIrqHandler: @硬中断处理
OsIrqHandler: @硬中断处理,此时已切换到硬中断栈
SUB LR, LR, #4
/* push r0-r3 to irq stack */
STMFD SP, {R0-R3} @r0-r3寄存器入栈
SUB R0, SP, #(4 * 4)
STMFD SP, {R0-R3} @r0-r3寄存器入 irq
SUB R0, SP, #(4 * 4)@r0 = sp - 16
MRS R1, SPSR @获取程序状态控制寄存器
MOV R2, LR
MOV R2, LR @r2=lr
/* disable irq, switch to svc mode */@超级用户模式(SVC 模式),主要用于 SWI(软件中断) OS(操作系统)
CPSID i, #0x13 @切换到SVC模式,此处一切换,后续指令将入SVC的栈
@CPSID i为关中断指令,对应的是CPSIE
@CPSID i为关中断指令,对应的是CPSIE
/* push spsr and pc in svc stack */
STMFD SP!, {R1, R2} @实际是将 SPSR,LR入栈,入栈顺序为 R1,R2,SP自增
STMFD SP, {LR} @LR再入栈,SP不自增
......@@ -275,14 +275,14 @@ OsIrqHandler: @硬中断处理
BNE OsIrqFromKernel @中断不发生在用户模式下则跳转到OsIrqFromKernel
/* push user sp, lr in svc stack */
STMFD SP, {R13, R14}^
STMFD SP, {R13, R14}^ @spLRsvc
OsIrqFromKernel: @从内核发起中断
/* from svc not need save sp and lr */
SUB SP, SP, #(2 * 4)
/* from svc not need save sp and lr */@svc模式下发生的中断不需要保存splr寄存器值
SUB SP, SP, #(2 * 4) @申请8个栈空间
/* pop r0-r3 form irq stack*/
LDMFD R0, {R0-R3}
/* pop r0-r3 from irq stack*/
LDMFD R0, {R0-R3} @出栈
/* push caller saved regs as trashed regs in svc stack */
STMFD SP!, {R0-R3, R12}
......@@ -295,34 +295,34 @@ OsIrqFromKernel: @从内核发起中断
* altered in interrupt handlers.
*/
PUSH_FPU_REGS R0
#ifdef LOSCFG_IRQ_USE_STANDALONE_STACK
#ifdef LOSCFG_IRQ_USE_STANDALONE_STACK @IRQ使用独立栈
PUSH {R4}
MOV R4, SP
EXC_SP_SET __svc_stack_top, OS_EXC_SVC_STACK_SIZE, R1, R2
#endif
/*BLX 带链接和状态切换的跳转*/
BLX HalIrqHandler /* 调用硬中断处理程序,无参 */
BLX HalIrqHandler /* 调用硬中断处理程序 */
#ifdef LOSCFG_IRQ_USE_STANDALONE_STACK
#ifdef LOSCFG_IRQ_USE_STANDALONE_STACK @是否使用了独立的IRQ栈
MOV SP, R4
POP {R4}
#endif
/* process pending signals */
BL OsTaskProcSignal
/* process pending signals */ @处理挂起信号
BL OsTaskProcSignal @跳转至C代码
/* check if needs to schedule */
CMP R0, #0
BLNE OsSchedPreempt
/* check if needs to schedule */@检查是否需要调度
CMP R0, #0 @是否需要调度,R0为参数保存值
BLNE OsSchedPreempt @不相等,R00,一般是 1
MOV R0,SP
MOV R1,R7
BL OsSaveSignalContextIrq
MOV R0,SP @ OsSaveSignalContextIrq 参数1来源
MOV R1,R7 @ OsSaveSignalContextIrq 参数2来源
BL OsSaveSignalContextIrq @跳转至C代码
/* restore fpu regs */
POP_FPU_REGS R0
POP_FPU_REGS R0 @恢复fpu寄存器值
ADD SP, SP, #4
ADD SP, SP, #4 @sp = sp + 4
OsIrqContextRestore: @中断环境恢复
LDR R0, [SP, #(4 * 7)] @读取 SP+28 位置数据给R0
......
......@@ -1108,7 +1108,7 @@ __attribute__((noinline)) VOID LOS_Panic(const CHAR *fmt, ...)
va_start(ap, fmt);
UartVprintf(fmt, ap);
va_end(ap);
__asm__ __volatile__("swi 0");
__asm__ __volatile__("swi 0");//触发断异常
}
/* stack protector */
......
......@@ -56,7 +56,7 @@ UINT64 g_cpuMap[LOSCFG_KERNEL_CORE_NUM] = {
LITE_OS_SEC_TEXT_INIT VOID OsTaskExit(VOID)
{// swi {cond} <immed_24>
__asm__ __volatile__("swi 0");//处理器产生软中断异常,swi指令的低24位存放的是0
}//该指令可以产生SWI异常,ARM通过该指令可以实现用户模式中对操作系统中特权模式的程序的调用,即系统调用实现的基础;
}//该指令可以产生SWI异常,ARM通过该指令从用户模式切到SVC模式.
#ifdef LOSCFG_GDB
STATIC VOID OsTaskEntrySetupLoopFrame(UINT32) __attribute__((noinline, naked));
......
......@@ -211,7 +211,7 @@ _osExceptSwiHdl: @软中断异常处理
LDMFD SP!, {PC}^ @ Return to user 弹出值给PC寄存器
OsKernelSVCHandler:
ADD R0, SP, #(4 * 16)
ADD R0, SP, #(4 * 16) @R0=sp+64
MOV R5, R0
STMFD R0!, {R4} @ Store PC
STMFD R0!, {R4}
......
......@@ -100,7 +100,7 @@ __exception_handlers:
*Assumption: ROM code has these vectors at the hardware reset address.
*A simple jump removes any address-space dependencies [i.e. safer]
*///一个简单的跳转将删除任何地址空间依赖关系
b reset_vector @所有的异常中断入口组成了reset vector
b reset_vector @开机代码
b _osExceptUndefInstrHdl @异常处理之CPU碰到不认识的指令
b _osExceptSwiHdl @异常处理之:软中断
b _osExceptPrefetchAbortHdl @异常处理之:取指异常
......@@ -136,7 +136,7 @@ reset_vector:
adr r4, __exception_handlers /* r4: base of load address */ @r4获得加载基地址
ldr r5, =SYS_MEM_BASE /* r5: base of physical address */@r5获得物理基地址
subs r12, r4, r5 /* r12: delta of load address and physical address */ @r12=r4-r5 加载地址和物理地址的增量
beq reloc_img_to_bottom_done /* if we load image at the bottom of physical address */
beq reloc_img_to_bottom_done /* if we load image at the bottom of physical address */@物理地址底部加载镜像
/* we need to relocate image at the bottom of physical address */
ldr r7, =__exception_handlers /* r7: base of linked address (or vm address) */
......@@ -229,9 +229,9 @@ warm_reset: @初始化CPU各异常工作模式环境
/* set svc stack, every cpu has OS_EXC_SVC_STACK_SIZE stack *//*设置每一个SVC,每个CPU都有独立的 SVC*/
ldr r0, =__svc_stack_top @栈底位置,注意这里虽然使用了top,但实际是栈底
mov r2, #OS_EXC_SVC_STACK_SIZE @栈大小
mul r2, r2, r12 @定位到栈位置,CPU SVC栈是连在一块的
sub r0, r0, r2 @计算栈顶位置,使用sub也说明了栈底大于栈顶
mov sp, r0 @栈顶位置
mul r2, r2, r12 @定位到栈位置,CPU SVC栈是连在一块的
sub r0, r0, r2 @计算栈顶位置,使用sub也说明了栈底大于栈顶
mov sp, r0 @栈顶位置
/* enable fpu+neon */
#ifndef LOSCFG_TEE_ENABLE
......@@ -479,7 +479,7 @@ init_flag:
*/
.section ".int_stack", "wa", %nobits
.align 3
@申请对应的内存空间
@六种特权模式申请对应的栈运行空间
__undef_stack:
.space OS_EXC_UNDEF_STACK_SIZE * CORE_NUM
__undef_stack_top:
......
......@@ -147,7 +147,11 @@ VOID OsSchedResched(VOID)
/* do the task context switch */
OsTaskSchedule(newTask, runTask);//切换任务上下文,注意OsTaskSchedule是一个汇编函数 见于 los_dispatch.s
}
//抢占式调度,调用极为频繁的函数
/******************************************************
抢占式调度函数
1.LOS_Schedule会判断是否发生硬件中断
2.硬件中断处理完成后由汇编调用: ..\arch\arm\arm\src\los_dispatch.S
******************************************************/
VOID OsSchedPreempt(VOID)
{
LosTaskCB *runTask = NULL;
......
git add -A
git commit -m '开机的第一条汇编指令在哪里? 注解开机汇编代码部分
git commit -m '硬中断汇编代码注解
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
https://weharmony.gitee.io
'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册