【转】P4080上电启动及uboot流程

2019-04-14 19:35发布

系统上电到执行第一条指令前,需要经过配置PLL、Local Bus控制器、LAW、MMU等操作,这些配置完全是由CPU根据芯片的默认值和RCW配置完成的。RCW的来源和读取参考RCW读取过程一文。部分RCW(共512bit)如下:
  



1)Cpu根据SYS_PLL_RAT的值决定当前CPU的平台时钟对SYS_CLK的倍频参数;
2)Cpu根据CCn_PLL_RAT等值决定e500 core的时钟频率,目前跑1.5G(CPU版本2);
3)CPU根据BOOT_LOC决定Boot ROM的位置。
4)Cpu根据BOOT_H复位时执行boot代码的Core,这里是core0。
 以上,对软件来说最重要的配置是Boot ROM位置的配置。在硬件连接无误的情况下,P4080启动的配置为:
 
core0启动,core1~core7等待(hold off);
从Local bus GPCM—8-bit ROM启动;
  
根据e500mc的硬件手册,CPU复位后执行的第一条指令的地址是0xFFFF,FFFC。因此,CPU要能正确执行U-boot代码,至少需要下面几个条件:
1) Local Access Window能正确转换U-boot代码的物理地址空间
2) Local Bus能正确转换U-boot代码的物理地址空间
3) MMU能正确转换U-boot代码的有效地址空间(e500mc核的MMU无法关闭)
首先,根据P4080手册,Local Access Window对Boot ROM的地址转换,不通过LAW寄存器配置。在复位时,映射0x0_FF80_0000到启动地址(硬件配置为Local bus GPCM),共8M空间。这样解决了第一个问题。(手册中有这么一句话: Also note that the boot window is always enabled and covers local addresses from 0x0_FF80_0000 to 0x0_FFFF_FFFF.)
接着,P4080复位时Local Bus Control寄存器BRn/ORn有默认值为全0,设定了第0个Local Bus Bank的地址空间是从0x0000_0000开始的4G空间,且MSEL=GPCM。这样,所有映射到Local Bus上的地址都会使CS0有效。
然后,MMU在复位时也有默认值。实际上,虽然e500mc的MMU有16个TLB1和512个TLB0,复位时仅TLB1的Entry0有效。Entry0将0xFFFF,F000开始的4k有效地址空间映射到0xFFFF,F000开始的4k物理地址空间中,TLB1的Entry0配置如下表所示:

有了以上的配置,P4080 CPU复位时就能够从连接在Local Bus的CS0上的Nor Flash执行第一条指令了。过程如下:
CPU从0xFFFF,FFFC有效地址开始执行,先经过MMU转换得到物理地址0xFFFF,FFFC;然后,Local Access Window的特殊转换直接将0xFFFF,FFFC转换到CPU的外围器件Local bus GPCM—8-bit ROM上;最后,由于Local Bus的CS0覆盖了4G空间,0xFFFF,FFFC直接被送到了Nor Flash(Boot Flash)的地址总线上。如果外接Boot Flash有64M BYTE,则地址总线仅26位,0xFFFF,FFFC代表了Flash 的地址0x3FF,FFFC。(若boot flash是8M的话,其地址总线有23位,0xFFFF,FFFC代表了Flash 的地址0x7F,FFFC。)所以,不管CPU发出的地址的高6位(对8MB Flash是高9位)是多少,只有低26位(对8MB Flash是低23位)有效,也就是只要CPU发出的地址是xxxx,xx11,1111,1111,1111,1111,1111,1100b,(对8MB Flash是xxxx,xxxx,x111,1111,1111,1111,1100b)就能访问到Flash 的地址0x3FF,FFFC,其他地址也一样。
系统上电到执行第一条指令前根据默认窗口和映射,不管多大容量的Flash都被映射到了4GB空间内(除非Flash容量大于4GB),具体位置(二进制)是:xxxx,xx00,0000,0000,0000,0000,0000,0000b----xxxx,xx11,1111,1111,1111,1111,1111,1111b,(对于8MB Flash是
xxxx,xxxx,x000,0000,0000,0000,0000,0000b----xxxx,xxx,x111,1111,1111,1111,1111,1111b)。
 
[注意]:系统上电到执行第一条指令前Flash的地址不要同uboot起来后的Flash地址比较或混淆,两者完全不是一回事,uboot起来后,通过设置BR/OR寄存器,看到的uboot在Flash中的起始地址是0xEFF80000。
 




P4080上电启动及uboot流程(2)
 
/board/freescale/p4080bcem/u-boot.lds文件是连接器脚本文件。
uboot.bin文件大小为512KB(0x80000),0xFFFFFFFC必须映射到他的倒数第4个字节,因此,uboot.bin的代码段要从(0xFFFFFFFF – 0x80000 + 1)处开始,即0xFFF80000,所以ADDR(.text)的值为0xFFF80000。
在本连接器脚本文件中:
.bootpg ADDR(.text) + 0x7f000 :
  {
    cpu/mpc85xx/start.o      (.bootpg)
  } :text = 0xffff
规定了/cpu/mpc85xx/start.s的_start_e500代码段放在4GB空间中的位置,0xFFF80000+0x7f000,即0xFFFFF000,整个4GB空间的倒数4KB的位置,也是Flash的倒数4K的位置。Bootpg也就是boot page,理解为引导页,即刚上电时TLB1所能映射的那4KB的空间。
.resetvec ADDR(.text) + 0x7fffc :
  {
    *(.resetvec)
  } :text = 0xffff
规定了resetvec段在4GB空间中的位置,0xFFF80000+0x7fffc,即0xFFFFFFFC。P4080复位后从0xFFFFFFFC 开始取第一条指令,即resetvec段,也就是4GB空间中的倒数第4个字节。在/cpu/mpc85xx/resetvec.s中可以看到e500mc核从倒数第4个字节处取的是一条跳转指令(32位)为:
b _start_e500       
这个指令就是所谓的放在0xFFFFFFFC处的跳转指令,跳转到了位于Flash倒数4K位置的_start_e500处。
[注意] 系统上电到执行第一条指令前,CPU看到的Flash的末地址是xxxx,xx11,1111,1111,1111,1111,1111,1111b,当然也包括0xFFFFFFFF。由上面的分析resetvec段放在了0xFFFFFFFC处,_start_e500代码段放在Flash倒数4K的位置,而整个uboot映像有512KB,所以uboot需要放在Flash的最后512KB中或做一些映射工作达到这个效果,图1示如下。

图1 uboot启动代码空间解析
系统复位后,CPU首先到0xFFFFFFFC处执行跳转指令,跳转到_start_e500处,也即0xFFFFF000,这是目前CPU MMU能够映射的最大空间,4KB,首先执行这4KB代码,期间将会把MMU进行初始化,使之能映射更大的空间,以便执行所有512KB uboot代码。       Uboot执行后,会对local bus BRn/ORn进行初始化,这以后CPU看到的Flash地址要发生变化了,最高地址是0xEFFFFFFF,uboot在Flash中的起始地址变成了0xEFF80000。
microblog.png?1 转发至微博   microblog.png?1 转发至微博