两种实现PPC地址重映射的方案,uboot powerpc
来源:互联网 发布:guitar rig5 mac 破解 编辑:程序博客网 时间:2024/04/30 23:22
两种实现PPC地址重映射的方案
sailor_forever sailing_9806#163.comhttp://blog.csdn.net/sailor_8318/archive/2009/09/03/4513710.aspx1 General
本文介绍了powerpc架构下两种典型的地址重映射方案,详细描述了其实现过程。
2 HCWR/BRx/ORx
MPC8270共有11个bank,即共有11个CS。在硬件设计上,每一个存储器对应一个CS。对于每一个bank,有两个重要的寄存器即BRx和ORx。当CPU发出读写请求时,首先进行地址空间的检查及匹配,匹配因素就是BR决定的基地址和OR的地址匹配屏蔽码。当匹配成功时,才由对应的CS产生相关控制信号,进行实际的内存访问。
////////////
11.2.1 Address and Address Space Checking
The defined base address is written to the BRx. The banksize is written to the ORx. Each time a bus cycle access is requested onthe 60x or local bus, addresses are compared with each bank. If a match isfound on a memory controller bank, the attributes defined in the BRx andORx for that bank are used to control the memory access. If a match isfound in more than one bank, the lowest-numbered bank handles the memory access(that is, bank 0 has priority over bank 1).
11.3.1 Base Registers (BRx)
The base registers (BR0–BR11) contain the base address andaddress types that the memory controller uses to compare the address bus valuewith the current address accessed. Each register also includes a memory attributeand selects the machine for memory operation handling
//////////////
由此可见,每个bank的基地址是可灵活配置的。这是PPC区别于ARM系统的一个重点。在ARM中,每个bank的地址空间是固定,和CPU自身相关,和存储器无关。
既然地址是由软件配置的,那么上电时软件还没运行时,是如何确定启动Flash的地址呢?CS0一般连接的是Flash或EEPROM之类的存储设备,因此上电时BR0和OR0有默认值。BR0的默认基地址是由硬件配置字决定的。
CIP1 Core initial prefix. Defines the initial value of MSR[IP].
Exception prefix. The setting of this bit specifies whether anexception vector offset is prepended with Fs or 0s. In the following description,nnnnn is the offset of the exception vector.
0 MSR[IP] = 1 (default). Exceptions are vectored to the physicaladdress 0xFFFn_nnnn
1 MSR[IP] = 0 Exceptions are vectored to the physical address0x000n_nnnn.
BMS Boot memory space. Defines the initial value for BR0[BA].There are two possible boot memory regions: HIMEM and LOMEM.
0 0xFE00_0000—0xFFFF_FFFF
1 0x0000_0000—0x01FF_FFFF
只有OR0在上电时的值是有效的,AM域决定了哪些位用于地址匹配
0–16 AM Address mask. Masks corresponding BRx bits. Maskingaddress bits independently allows external devices of different size addressranges to be used.
0 Corresponding address bits are masked.
1 The corresponding address bits are used in the comparison withaddress pins. Address mask bits can be set or cleared in any order in thefield, allowing a resource to reside in more than one area of the address map.AM can be read or written at any time.
Note: After system reset, OR0[AM] is 1111_1110_0000_0000_0.
PPC有高端地址启动和低端地址启动。高端时Flash基地址为0xFE00_0000,而OR0的高7位需要进行地址匹配,因此复位向量的地址必须为0xFFF00100,这就意味着代码存储位置相对于Flash的偏移量为0x01F00000,即31M,因此高端启动时Flash至少32M。
同理低端启动时,复位向量的地址必须为0x0000 0100,Flash基地址为0,程序的烧录地址相对于Flash的偏移量为0。
通常中断向量表的基地址为0,为了更快的响应中断,SDRAM的地址需要最终映射到0地址。若上电时Flash的首地址为0,那么如何切换才能保证能够正常取指呢?
3 利用OR0的地址屏蔽位
/* When booting from ROM (Flash or EPROM), clear the */
/* Address Mask in OR0 so ROM appears everywhere */
/*--------------------------------------------------------------*/
lis r3, (CFG_IMMR+IM_REGBASE)@h
lwz r4, IM_OR0@l(r3)
li r5, 0x7fff
and r4, r4, r5
stw r4, IM_OR0@l(r3)
/* Calculate absolute address in FLASH and jump there */
/*--------------------------------------------------------------*/
lis r3, CFG_MONITOR_BASE@h
ori r3, r3, CFG_MONITOR_BASE@l
addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
mtlr r3
blr
in_flash:
清除OR0的地址匹配位,则不进行匹配的单位是32K,即任何地址访问只有末15位地址信息有效,因此都将从Flash的0---32k内取指。当跳转到编译链接的Flash地址处时,由于CFG_MONITOR_BASE被屏蔽,只有in_flash- _start + EXC_OFF_SYS_RESET是有效的,因此实际的取指位置相对于Flash的偏移量为in_flash- _start + EXC_OFF_SYS_RESET,正好为in_flash标号所在的代码位置,这样就实现了无缝切换。
在未改变OR0之前,程序将只能在32k内取指。当软件将BR0和OR0更改为实际设计的值时,指令访问的地址经过匹配后,仍将从Flash取指。而此时0地址经过匹配后将不再是Flash中的地址。便可将SDRAM所在的bank的基地址设置为0,拷贝中断向量表至SDRAM,即可快速响应中断。
因为程序的编译链接地址是基于flash首地址的,因为启动过程中用到了函数指针这些静态符号表,因此flash中的代码是位置相关的,也就是说运行地址和链接地址必须一致。
但程序当前仍然在flash中运行,那么是怎么跳转到SDRAM中的呢?跳转之前需要将代码先拷贝到SDRAM中去,那拷贝到SDRAM的何位置呢?这个是动态计算出来的,通常是SDRAM高端地址减去印象大小的位置。这和ARM的代码重定位有很大的区别,ARM映像的链接地址即是最终拷贝到SDRAM中的位置,拷贝代码之前flash中运行的代码是位置无关的,SDRAM中运行的代码是位置相关的,必须拷贝到程序的链接地址。
/*
* void relocate_code (addr_sp, gd, addr_moni)
*
* This "function" does not return, instead it continues in RAM
* after relocating the monitor code.
*
* r3 = dest
* r4 = src
* r5 = length in bytes
* r6 = cachelinesize
*/
.globl relocate_code
relocate_code:
mr r1, r3 /* Set new stack pointer */
mr r9, r4 /* Save copy of Global Datapointer */
mr r10, r5 /* Save copy of Destination Address */
mr r3, r5 /* Destination Address */
lis r4,CFG_MONITOR_BASE@h /* Source Address */
ori r4, r4, CFG_MONITOR_BASE@l
lis r5,CFG_MONITOR_LEN@h /* Length inBytes */
ori r5, r5, CFG_MONITOR_LEN@l
li r6,CFG_CACHELINE_SIZE /* Cache LineSize */
/*
* Fix GOT pointer:
*
* New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
*
* Offset:
*/
sub r15, r10, r4
/* First our own GOT */
add r14, r14, r15
/* then the one used by the C code */
add r30, r30, r15
/*
* Now relocate code
*/
cmplw cr1,r3,r4
addi r0,r5,3
srwi. r0,r0,2
beq cr1,4f /* In place copy is notnecessary */
beq 7f /* Protect against 0count */
mtctr r0
bge cr1,2f
la r8,-4(r4)
la r7,-4(r3)
1: lwzu r0,4(r8)
stwu r0,4(r7)
bdnz 1b
b 4f
2: slwi r0,r0,2
add r8,r4,r0
add r7,r3,r0
3: lwzu r0,-4(r8)
stwu r0,-4(r7)
bdnz 3b
/*
* Now flush the cache: note that we must start from a cache aligned
* address. Otherwise we might miss one cache line.
*/
。。。。
/*
* We are done. Do not return, instead branch to second part of board
* initialization, now running from RAM.
*/
addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
mtlr r0
blr
in_ram:
r10为 SDRAM中代码预拷贝的位置, blr功能是将 lr赋值给 PC指针,即实现了跳转,正好为 SDRAM中 in_ram标号的位置。对于 ppc ,在 SDRAM 中运行的代码由于运行地址和链接地址不一致,对于函数指针 /数组首地址这些静态符号表必须进行重定位以便能够正确解析相关符号。
/************************************************************************
* This is the next part if the initialization sequence: we are now
* running from RAM and have a "normal" C environment, i. e. global
* data can be written, BSS has been cleared, the stack size in not
* that critical any more, etc.
*
************************************************************************
*/
void board_init_r (gd_t *id, ulong dest_addr)
{
gd->reloc_off = dest_addr - CFG_MONITOR_BASE;
/*
* We have to relocate the command table manually
*/
for (cmdtp = &cmd_tbl[0]; cmdtp->name; cmdtp++) {
ulong addr;
addr = (ulong) (cmdtp->cmd) + gd->reloc_off;
。。。
}
之后拷贝中断向量表至 SDARM 首地址,因此中断处理中用到了静态的函数指针,因此需要重定位,以便中断响应时能跳转到 SDRAM 中的中断处理函数中去
/*
* Setup trap handlers
*/
trap_init (dest_addr);
至此,整个运行环境就搭建起来了。
4 利用DPRAM切换Flash和SDRAM
切换过程中如何保证取指的正确性是关键,若切换时程序既不运行在Flash中也未运行在SDRAM中,则可随意切换。PPC正是利用了内部DPRAM来实现的。
启动阶段,Flash基地址为0,SDRAM地址为非0的某值,将代码拷贝至SDRAM首地址,然后将切换代码拷贝至DPRAM,跳转至DPRAM运行,此时便可随意更改Flash和SDRAM的BR,即实现了Flash和SDRAM地址空间的重映射,Flash映射到非0地址,SDRAM映射到0地址。
程序编译链接地址为flash的0地址,跳转时的绝对符号表地址是基于flash的0地址的,因为代码在SDRAM和Flash中有同样的备份,因此跳转至0地址的SDRAM运行的第一条语句总是可以正常取指。
/**@***********************************************************/
/* FUNCTION: copy_and_start_monitor0. */
/* */
/* PURPOSE: Copy and start monitor0: */
/* - Copy all Boot0 Section into Global SDRAM. */
/* - Copy address_swap routine into DPRAM. */
/* - Call address_swap routine. */
/* */
/**@***********************************************************/
void copy_and_start_monitor0(void)
{
Uint32 *flash_addr, *ram_addr;
/* Copy all Boot0 Section into Global SDRAM*/
for(flash_addr = (Uint32 *)STARTUP_FLASH_START, ram_addr = (Uint32 *)STARTUP_GLOBAL_SDRAM_START;
flash_addr < (Uint32 *)BOOT0_SECTION_LENGTH;)
{
*ram_addr++ = *flash_addr++;
}
/* Copy address_swap routine into DPRAM */
for(flash_addr = (Uint32 *)address_swap, ram_addr = (Uint32 *)DPRAM_SWAP_RESERVED;
ram_addr < (Uint32 *)(DPRAM_SWAP_RESERVED + DPRAM_SWAP_RESERVED_LENGTH);)
{
*ram_addr++ = *flash_addr++;
}
/* Call address_swap routine (never returns!)*/
((void(*)(void(*)(void)))DPRAM_SWAP_RESERVED)(monitor0_entry);
}
/**@*************************************************************/
/* FUNCTION: address_swap. */
/* */
/* PURPOSE: Swap address to/from SDRAM and FLASH. */
/* */
/**@**************************************************************/
void address_swap(void(*sdram_entry_point)(void))
{
/* Set Base Address of Chip Select 1 (SDRAM) to SWAP_GLOBAL_SDRAM_START */
set16_reg(BR1, SWAP_GLOBAL_SDRAM_START >> 16);
SYNC;
/* Set Base Address of Chip Select 0 (FLASH) to SWAP_FLASH_START */
set16_reg(BR0, SWAP_FLASH_START >> 16);
ISYNC;
/* Jump to program in SDRAM */
(* sdram_entry_point)();
} /* address_swap */
- 两种实现PPC地址重映射的方案,uboot powerpc
- 两种实现PPC地址重映射的方案
- powerpc外设内存映射,关于uboot的讨论非常到位
- 移植uboot到powerpc(1)--配置头文件,u-boot,ppc ,mpc85 mpc83
- 移植uboot到powerpc(2)--start.s跟踪,u-boot,ppc ,mpc85 mpc83
- 移植uboot到powerpc(1)--配置头文件,u-boot,ppc ,mpc85 mpc83
- 移植uboot到powerpc(2)--start.s跟踪,u-boot,ppc ,mpc85 mpc83 【转】
- hibernate映射详解:一对一映射的两种实现方式
- uboot引导powerpc,bootm的用法
- 实现Apache虚拟主机的两种方案
- Javascript Callback的两种实现方案
- 离散傅里叶变换的两种实现方案
- ARM芯片的地址重映射
- ARM地址重映射的通俗解释
- ARM芯片的地址重映射
- ARM地址重映射的通俗解释
- ARM芯片的地址重映射
- ARM地址重映射的通俗解释
- 诺基亚标准:Does your Scrum team pass the Scrum test used at Nokia
- 一些工具函数--Xml 序列化
- flex 小技巧
- 敏捷生态系统:2009敏捷中国大会上的演讲稿
- c# + Flash上传控件
- 两种实现PPC地址重映射的方案,uboot powerpc
- Sortable Table 可排序表格JS收集
- Joomla!扩展制作实例教程-模板展示组件-增加后台上传图片功能 【转】
- OnNcCalcSize改变标题栏等的高度
- ListBox绑定数据
- 自己手动创建dataset的方法(不用从数据库倒入)
- oracle和DB2递归的例子
- 使用一次性密码解决方案更安全地验证身份
- ASP.net错误:Control 'ctl00_ctl00_ContentPlaceHolder2_ContentPlaceHolderRight_ListView1_ctrl0_DeleteButton' of type 'Button' must b