TMS320C6678的EMIF16 NOR Flash程序自加载的实现
一.C6678的加载综述
C6678的加载实质上就是将各核的代码按段分别写到各自的L2 SRAM.这个过程的实现可以用很多种方式,于是就有了多种bootmode,比如EMIF16 boot、SRIO boot、Ethernet boot、PCI boot、SPI boot、Hyperlink boot等,这几种加载方式虽然过程不尽相同,但是目的是一样的。
在C6678的地址空间0x20B00000到0x20B1FFFF间集成了128K的内部ROM。此ROM中固化了一段叫作“boot loader”的引导代码,它的主要作用是在C6678上电时,对C6678进行必要的配置,以便辅助EMIF/PCI/SRIO等接口进行加载;另外,它还可以将代码从外部存储器读到内部L2 SRAM,以完成代码加载。
C6678有8个核,但Rom code只有一份,因此8个核统一执行Rom code的代码,Rom code 会根据核号(即DNUM)进行不同的分支。对于core0来说,它主要是读取DEVSTAT 寄存器(反映加载模式以及一些参数配置,具体是由Bootmode pin[12:0]设置)的加载模式,并根据当前加载模式进行一些接口的初始化和PLL的配置,还要根据加载模式决定是否搬移数据,若需要搬移,比如SPI boot,就要将SPI外接ROM的代码按段加载到C6678的内存中。若不需要搬移,比如EMIF16加载,就直接跳到EMIF16外接Nor Flash的起始地址开始执行。对于其它的7个核来说,它们主要是挂载IPC中断,然后进入IDLE状态等待core0发过来的中断。中断一到,就跳到入口地址开始执行程序。
二.C6678的EMIF16加载过程
1.core0加载
C6678的EMIF16加载是一种直接从Nor Flash(必须挂在CE2空间:0x70000000)加载core0的模式,不需要I2C EEPROM的参与,由Rom code初始化EMIF16接口,并且由于EMIF16外接Nor Flash是一种XIP器件(即可以在芯片内执行),因此直接跳到Nor Flash的起始地址处开始执行。
为了将Nor Flash中的代码搬移到C6678 的core0的L2 SRAM中,需要在core0的待加载工程中编写引导代码,此引导代码的作用就是将core0的代码按段加载到内存中,最后跳到入口地址处开始执行。此段引导代码用汇编语言编写,命名.bootload段,放在L2 SRAM的前1KB空间,并烧写到Nor Flash的前1KB空间,应用代码放到1KB后面,如下图所示Nor Flash代码格式:
图1 Nor Flash空间分配
2.core0加载其它核
在多核加载过程中,core0是主核,core1~core7是从核,由core0加载其它核的代码,具体步骤是:
1) 上电后,core0完成程序加载,并跳到入口地址开始执行程序。
2) 在core0主程序中,core0从Nor Flash中读取core1的代码,并按段加载到core1的L2 SRAM,然后将core1程序的入口地址写到core1的BOOT_MAGIC_ADDRESS,即L2 SRAM的最后4个字节地址:0x1187FFFC,最后向core1发送IPC中断,既写寄存器IPGR1=0x1,其它核的加载过程一样。
具体程序流程图为:
图2 EMIF16多核加载过程 各个核的Nor Flash空间分配如下:
| 起始地址 | 结束地址 | 长度 | Core0 | 0x70000000 | 0x701FFFFF | 2MB | Core1 | 0x70200000 | 0x703FFFFF | 2MB | Core2 | 0x70400000 | 0x705FFFFF | 2MB | Core3 | 0x70600000 | 0x707FFFFF | 2MB | Core4 | 0x70800000 | 0x709FFFFF | 2MB | Core5 | 0x70A00000 | 0x70BFFFFF | 2MB | Core6 | 0x70C00000 | 0x70DFFFFF | 2MB | Core7 | 0x70E00000 | 0x70FFFFFF | 2MB |
|