;通过设置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
|