OK6410A 开发板 (三) 16 u-boot-2021.01 boot 解析 U-boot 镜像运行部分 irq

硬件
When an IRQ is detected, the following actions are performed:
	R14_irq = address of next instruction to be executed + 4
	SPSR_irq = CPSR
	CPSR[4:0] = 0b10010 /* Enter IRQ mode */
	CPSR[5] = 0 /* Execute in ARM state */
	/* CPSR[6] is unchanged */
	CPSR[7] = 1 /* Disable normal interrupts */
	CPSR[8] = 1 /* Disable Imprecise Data Aborts (v6 only) */
	CPSR[9] = CP15_reg1_EEbit /* Endianness on exception entry */
	
	if high vectors configured then
		PC = 0xFFFF0018
	else
		PC = 0x00000018

软件建议
	To return after servicing the interrupt, use:
	SUBS PC,R14,#4

软件
 ldr pc, _irq
 _irq: .word irq


.globl IRQ_STACK_START_IN
IRQ_STACK_START_IN:
 .word 0x0badc0de

 irq:
	 get_bad_stack

	 	 ---- irq mode

		 ldr r13, IRQ_STACK_START_IN @ setup our mode stack

		 // 压栈 lr_irq
		 str lr, [r13] @ save caller lr in position 0 of saved stack

		 // 压栈 spsr_irq
		 mrs lr, spsr @ get the spsr
		 str lr, [r13, #4] @ save spsr in position 1 of saved stack
		 
		 // 准备切换到 Supervisor mode
		 mov r13, #0x13 @ prepare SVC-Mode
		 @ msr spsr_c, r13

		 // 在 irq mode 模式下 切换到 Supervisor mode
		 msr spsr, r13 @ switch modes, make sure moves will execute

		 ----- Supervisor mode
		 
		 // 将pc放到 lr_svc 中,以便 可以返回 irq mode 下 执行的最后一条指令的下一条指令
		 mov lr, pc @ capture return pc
		 // 将 lr_svc 放到 pc,转回执行 irq mode 下 执行的最后一条指令的下一条指令
		 movs pc, lr @ jump to next instruction & switch modes.

	 bad_save_user_regs
		 .macro bad_save_user_regs
		 @ carve out a frame on current user stack
		 
		 // sp_svc = sp_svc - 72,用来保存 13个寄存器,13*4=52 byte ,还有20个byte,可以存5个寄存器
		 sub sp, sp, #72
		 
		 // 将 r0-r12 保存到 sp_svc 中
		 stmia sp, {
    
    r0 - r12} @ Save user registers (now in svc mode) r0-r12
		 //  将 之前保存在 IRQ_STACK_START_IN 的 lr_irq spsr_irq  分别弹到 r2 和 r3 中
		 
		 // 再保存4个到 之前13个的上面
		 
		 ldr r2, IRQ_STACK_START_IN
		 @ get values for "aborted" pc and cpsr (into parm regs)
		 ldmia r2, {
    
    r2 - r3}
		 
		 // r0 = sp_svc + 72  ,r0保存的是地址,地址中是 sp_SVC
		 add r0, sp, #72 @ grab pointer to old stack
		 // r5 = sp_svc + 52  ,r5保存的是地址,地址中是 ???
		 add r5, sp, #52
		 // r1 保存的是 lr_SVC
		 mov r1, lr

		 // 将 r0 r1 r2 r3 保存到 r5 的地址中去
		 stmia r5, {
    
    r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
		 
		
		 // 保存当前的栈到r0,做为第一个参数
		 mov r0, sp @ save current stack into r0 (param register)
		 .endm
		
		/*
		此时的状态是 r0保存了一个地址,这个地址是栈顶
		在栈顶之上,有17个之前保存的寄存器,排序依次为
		--------
		|      |
		--------
		|      |
		--------
		|      |
		--------
		|      |
		--------
		|      |
		--------
		|      |
		--------
		|      |
		--------
		|      |
		--------
		|      |
		--------
		|      |
		--------
		|      |
		--------
		|      |
		--------
		|      |
		--------
		|      |
		--------
		|      |
		--------
		|      |
		--------
		|      |
		--------------r0中的地址 , 即 栈顶

		*/

	 bl do_irq


// arch/arm/include/asm/proc-armv/ptrace.h 中有 struct pt_regs 的定义

/* this struct defines the way the registers are stored on the
   stack during a system call. */

struct pt_regs {
    
    
	long uregs[18];
};

#define ARM_cpsr	uregs[16]
#define ARM_pc		uregs[15]
#define ARM_lr		uregs[14]
#define ARM_sp		uregs[13]
#define ARM_ip		uregs[12]
#define ARM_fp		uregs[11]
#define ARM_r10		uregs[10]
#define ARM_r9		uregs[9]
#define ARM_r8		uregs[8]
#define ARM_r7		uregs[7]
#define ARM_r6		uregs[6]
#define ARM_r5		uregs[5]
#define ARM_r4		uregs[4]
#define ARM_r3		uregs[3]
#define ARM_r2		uregs[2]
#define ARM_r1		uregs[1]
#define ARM_r0		uregs[0]
#define ARM_ORIG_r0	uregs[17]

void do_irq (struct pt_regs *pt_regs)
{
    
    
 efi_restore_gd();
 	// null
 	
 printf ("interrupt request\n");
	// 这句话应该被替换,调用 ok6410 注册 的中断处理函数
	// 而且 这个 do_irq 函数也不是 被 __weak 修饰
	// 看起来 这个do_irq 函数就是 必走的一步了
	// 但是没有去 读 gic 相关的寄存器 去判断中断源 ,而是打印了一句,看起来,中断机制在 u-boot 中还不完善
	
 // 返回, 类似于 软件推荐的  SUBS PC,R14,#4
 fixup_pc(pt_regs, -8);
 	uint32_t pc = ((((regs)->uregs[15]) & ~0)) + offset;
 	regs->uregs[15] = pc | (regs->uregs[15] & 0);
 show_regs (pt_regs);
 show_efi_loaded_images(pt_regs);
 	// null
 bad_mode ();
 	panic ("Resetting CPU ...\n");
 	reset_cpu(0);
}



猜你喜欢

转载自blog.csdn.net/u011011827/article/details/115263545