嵌入式xworks系统初始化(PowerPC汇编)

本文详细解析了VxWorks系统初始化的过程,包括启动关闭中断、放boottype到堆栈、清空缓存等关键步骤,使用PowerPC汇编语言实现。重点介绍了初始化特殊功能寄存器(SPR)、设备控制寄存器(DCR)、机器状态寄存器(MSR)以及外部总线控制器(EBC)的初始化方法。

 系统初始化
系统初始化对不同的CPU,基本步骤是类似的.
系统初始化的主要步骤以 下启动 关闭中断 放boot type到堆栈 清空缓存
VxWorks 系统的 PowerPC BSP,系统开机后执行的第一个函数 romInit(),在ROM的起点,这里是运用运用的PowerPC汇编语言
/* 定义内部函数 internals */
.globl romInit /* start of system code */
.globl _romInit /* start of system code */

/* 定义外部函数 externals */
.extern romStart /* system initialization routine */

.text
.align 2

/*******************************************************************************
*
* romInit ( int startType /@ only used by 2nd entry point @/ )
*/

romInit:
_romInit:
bl cold /* 冷启动 */
bl warm /* 热启动 */

cold:
li p5, BOOT_COLD  /*BOOT_COLD是否是宏定义,p5是否是SPR,li是load立即数吧?*/
bl start /* skip over next instruction */

warm:
or p5, p0, p0 /* startType to p5 */

start: /* 此处是系统启动开始 */
/* 屏蔽MSR中CE,EE位,关闭所有的外部中断
/*
* Disable external interrupts
*/

mfmsr p0 /* p0 = msr */
INT_MASK (p0, p1) /* mask EE and CE bit */
ori p1,p1,_PPC_MSR_ME /* enable machine checks */
mtmsr p1 /* msr = p1 */
isync

/* 下面两步是按照硬件定义初始化一些SPR,DCR寄存器,置0或置1
/* SPR是特殊功能寄存器,DCR为设备控制寄存器,还有MSR机器状态寄存器,这些是PowerPC内核中很重要的寄存器
/* 初始化SPR,DCR寄存器置0
* Initalize registers that need to be set to zero.
*/

addi r4,r0,0x0000
mtspr SGR,r4 /* 解锁所有存储区域 SPR 中 SGR 位置0 */
mtspr ESR, r4 /* SPR中的错误状态位 ESR 清0 */
mtspr TCR, r4 /* 关闭所有的 timers */
mtspr PIT, r4 /* 清0 PIT timer */
mtdcr UICER, r4 /* 关闭中断控制器(UIC)中的所有中断 */
mtspr XER, r4 /* 清0 integer exception 寄存器 */

/* 初始化另外一些SPR,DCR寄存器,置1
* Initalize registers that need to be cleared with 0xFFFFFFFF.
*/

addis r4,r0,0xffff
ori r4,r4,0xffff
mtspr TSR, r4 /* timer */
mtspr DBSR, r4 /* 调试状态位置1 */
mtdcr UICSR, r4 /* 清除中断控制器(UIC)中的所有 pending 中断 */
mtdcr dmasr, r4 /* DMA状态寄存器置1 */

/* PowerPC405用2个缓存,一个是16K指令缓存(ICU),一个是6K数据缓存(DCU),下面是清空着2个缓存,并根据硬件设置缓存 */
/* 清空指令缓存 */
/*BESR type regs ZZZZZZZZZZZZ
* Invalidate the entire instruction cache. This can be done
* with a single iccci instruction in the processor core.
*/

iccci r0, r0   /*清空指令cache*/

/*清空数据缓存
* Invalidate the entire data cache.
* The 405 processor core in the 405GP has 128 congruence classes.
* Each cache line in the 405 processor is 32 bytes.
*/

/*
* Turn the instruction cache on for faster boot-up.
* Also, the icache is needed to help initialize Bank 0
* of the EBC to speed up accesses to flash.
* address space 0x00000000-0x07ffffff is cached
* address space 0xf8000000-0xffffffff is cached
*/

lis p0, HIADJ(_PPC403_ICCR_DEFAULT_VAL)     /*HIADJ(_PPC403_ICCR_DEFAULT_VAL) 是否是宏定义?*/
addi p0, p0, LO(_PPC403_ICCR_DEFAULT_VAL)    /*LO(_PPC403_ICCR_DEFAULT_VAL) 是否是宏定义?*/

mtspr _PPC403_ICCR, p0
isync

/* 初始化外部总线控制器(EBC),跳转指令BL,执行extBusCntlrInit
* /

bl extBusCntlrInit

/*
* Now that the EBC Bank 0 has been set up, turn the I-cache off if
* i-cache was not specified in config.h. It is also invalidated
* again.
*/

#ifndef USER_I_CACHE_ENABLE
li p0, 0 /* clear p0 */
mtspr _PPC403_ICCR, p0 /* turn off i-cache */
isync
iccci r0, r0 /* invalidate the I-cache again */
#endif

/* 初始化与SDRAM有关的IIC(inter-integrated circut)寄存器IIC0,
* Initialize IIC0 for use in automatic SDRAM configuration
*/

#ifdef LOCAL_MEM_AUTOSIZE
bl iic0Init
#endif

/* 初始化SDRAM,BL跳转执行sdramInit
* Configure the SDRAM controller only if this is a cold boot.
* If the SDRAM controller is reinitialized on a warm boot, the
* boot line will get wiped out because of the ECC SDRAM memory
* initialization.
*/

li p0, BOOT_COLD
and. p0, p0, p5 /* p5 is saved at the entry of romInit */
beq skip    /*and与beq连用,先是用and进行位与运算,然后将位与的结果与0比较,如果为0,则跳到beq紧跟着的标记(如beq skip,则跳到skip处)。*/

bl sdramInit

skip:

/*
* Clear the CPU reservation bit
*/

li r0, 0
lwarx p0, r0, r0    /*lwarx装入指定地址的内存的内容,并且保留内存地址的内容 */
stwcx. p0, r0, r0 /*判断保留的地址是否和本指令的相同,如果相同则存入一个值到内存,否则什么都不干,根据是否存入内存设置条件寄存器*/

#ifdef PPC405GP_REVA
/* 设置中断向量表到0x0000 */
li p0, 0x2100/4    /*作用是什么?*/
mtctr p0
lis p0, WALNUT_EVPR_VAL   /*WALNUT_EVPR_VAL的值左移16位赋给p0*/
li p1, 0x0000
zeroOut:
stw p1,0x0(p0)
addi p0, p0, 4
bdnz zeroOut
#endif

/* 初始化堆栈
/* Initialize the stack pointer (r1) */

lis sp, HIADJ(STACK_ADRS)
addi sp, sp, LO(STACK_ADRS)

#if FALSE /* SDA not supported */
/* initialize r2 and r13 according to EABI standard */

lis r2, HIADJ(_SDA2_BASE_)
addi r2, r2, LO(_SDA2_BASE_)
lis r13, HIADJ(_SDA_BASE_)
addi r13, r13, LO(_SDA_BASE_)
#endif

/* 得到C代 码romStart()在ROM中的地址,保证romInit执行结束后,系统跳转执行romStart()
/* calculate C entry point: routine - entry point + ROM base */

lis p1, HIADJ(romStart) /* p1 = romstart */
addi p1, p1, LO(romStart)      /*routine地址*/

lis p2, HIADJ(romInit) /* p2 = romInit */
addi p2, p2, LO(romInit)     /*入口地址地址*/


/* ROM_TEXT_ADRS为ROM的入口地址,在文件makefile定义,为0xfff80100
lis p3, HIADJ(ROM_TEXT_ADRS) /* p3 = ROM_TEXT_ADRS */
addi p3, p3, LO(ROM_TEXT_ADRS)     /*ROM base地址*/

subf p1, p2, p1 /* p1 = p1 - p2 */
add p1, p1, p3 /* p1 = p1 + p3 */
/* p1中是romStart()的地址,这里把这个地址放到连接寄存器LR中.  

mtlr p1 /* link register = C entry point */  

or p0, p5, p5 /* p0 = startType */
addi sp, sp, -FRAMEBASESZ /* get frame stack */

/* 跳转到LR中romStart()的地址,执行romStart()
blr /* branch to link register */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值