mini2440启动代码分析之第六篇(DCD与二次查表判中断类型)

;通过设置CP15 C1 的位7,设置存储格式为Bigendian,三种总线方式ChangeBigEndian ,下面是改变大小端的程序,这里采用直接定义机器码的方式

  [ ENTRY_BUS_WIDTH=32 

      DCD 0xee110f10 ;0xee110f10 => mrc p15,0,r0,c1,c0,0 

      DCD 0xe3800080 ;0xe3800080 => orr r0,r0,#0x80;           //Big-endian 

      DCD 0xee010f10 ;0xee010f10 => mcr p15,0,r0,c1,c0,0 

;对存储器控制寄存器操作,指定内存模式为Big-endian 

;因为刚开始CPU 都是按照32位总线的指令格式运行的,如果采用其他的话,CPU别不了,必须转化,但当系统初始化好以后CPU能自动识别。

  ] 

  [ ENTRY_BUS_WIDTH=16 

      DCD 0x0f10ee11 

      DCD 0x0080e380 

      DCD 0x0f10ee01 

;因为采用Big-endian 模式,采用16 位总线时,物理地址的高位和数据的位对应,所以指令的机器码也相应的高低对调 

  ] 

  [ ENTRY_BUS_WIDTH=8 

      DCD 0x100f11ee 

      DCD 0x800080e3 

      DCD 0x100f01ee 

     ] 

  DCD 0xffffffff   ;swinv 0xffffff is similar with NOP and run well in both endian mode. 

  DCD 0xffffffff 

  DCD 0xffffffff 

  DCD 0xffffffff 

  DCD 0xffffffff 

  b  ResetHandler 

;如第前面所说,这里采用HANDLER宏去建立Hander***Handle***之间的联系

HandlerFIQ       HANDLER    HandleFIQ

HandlerIRQ      HANDLER    HandleIRQ

HandlerUndef    HANDLER    HandleUndef

HandlerSWI      HANDLER    HandleSWI

HandlerDabort    HANDLER    HandleDabort

HandlerPabort    HANDLER    HandlePabort

;下面这段程序就是用来进行第二次查表的过程了.如果说第一次查表是由硬件来完成的,那这一次查表就是由软件来实现的了. 为什么要查两次表?? 没有办法,ARM把所有的中断都归纳成一个IRQ中断异常和一个FIRQ中断异常,第一次查表主要是查出是什么异常,可我们总要知道是这个中断异常中的什么中断呀! 没办法了,再查一次表呗!

IsrIRQ

       sub  sp,sp,#4              ;reserved for PC,给PC寄存器保留

       stmfd  sp!,{r8-r9}       ;工作寄存器入栈保护

       ldr   r9,=INTOFFSET    ;INTOFFSET2440addr.inc中定义为0x4a000014

       ldr   r9,[r9]                      ;把中断偏移INTOFFSET的值装入r9

       ldr   r8,=HandleEINT0    ;HandleEINT0 的地址就是中断的入口地址

       add  r8,r8,r9,lsl #2       ;逻辑左移就相当于乘以4,R8=R8+(R9<<2)

       ldr   r8,[r8]                       ; 装入中断服务程序的入口

       str    r8,[sp,#8]                 ;把入口压入堆栈

       lmfd  sp!,{r8-r9,pc}    ;将地址从堆栈中弹出给PC

你可能感兴趣的:(mini2440启动代码分析之第六篇(DCD与二次查表判中断类型))