;通过设置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 ;INTOFFSET在2440addr.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