📄 rominit.s
字号:
/******************************************************************************
*
* mpc8240Scrub - PCI configuration register modification.
*
* DESCRIPTION: mpc8240Scrub
* this subroutine's purpose is to initialize (i.e., scrub)
* DRAM, the MPC8240 ASIC protects DRAM by utilizing ECC, so
* the scrub insures that the entire DRAM array's check bits
* are initialized to a known state
*
* mpc8240Scrub(start-address, end-address, control-flag);
* r1 = don't care, no stack is needed
* r3 = starting address of DRAM
* r4 = ending address of DRAM (plus 1)
* spr8 = return program counter
*
* RETURNS:
* r3 = 1, DRAM ECC error detected
* = 0, no DRAM ECC errors occurred
*/
.data
.align 3
.globl mpc8240ScrubData
mpc8240ScrubData:
.long 0x00000000, 0x00000000
.text
.align 3
.globl mpc8240Scrub
mpc8240Scrub:
mfspr r16,8 /* save return instruction pointer */
or r13,r3,r3 /* save argument #1 */
or r14,r4,r4 /* save argument #2 */
addis r0,r0,0 /* insure r0 is zero */
ori r0,r0,0 /* insure r0 is zero */
/* load 64-bit number to initialize memory with */
addis r6,r0,HI(mpc8240ScrubData)
ori r6,r6,LO(mpc8240ScrubData)
/*
* setup loop specifics
*
* attempt a fpu register access only if mpc8240 has fpu enabled,
* based on HID1 bit 0 being a 1 or 0. 0 = FPU enabled, 1 = FPU disabled
*/
mfspr r5,1009 /* load hid1 contents */
andi. r5,r5,0x0001 /* extract FPU available bit and test */
bc 4,2,mpc8240FpuDisabled /* if 1, don't load FPU register */
lfdu 0,0(r6)
subf r18,r13,r14 /* calculate number of bytes */
rlwinm r18,r18,29,3,31 /* calculate number of doubles */
addi r17,r13,-8 /* starting address munged */
mtspr 9,r18 /* load number of doubles/words */
b mpc8240ScrubLoopFpu
mpc8240FpuDisabled:
lwz r8,0(r6)
subf r18,r13,r14 /* calculate number of bytes */
rlwinm r18,r18,30,2,31 /* calculate number of words */
addi r17,r13,-4 /* starting address munged */
mtspr 9,r18 /* load number of doubles/words */
b mpc8240ScrubLoopNoFpu /* branch to loop */
/* Loop through the entire DRAM array, initialize memory */
mpc8240ScrubLoopFpu:
stfdu 0,8(r17)
bc 16,0,mpc8240ScrubLoopFpu /* branch till counter == 0 */
sync /* synchronize the data stream */
b mpc8240ScrubExit
mpc8240ScrubLoopNoFpu:
/*
* Flicker fail LED while scrubbing (demonstrates how slow
* (~5 secs) this is.
*/
#ifdef DEBUG_STARTUP
addis r3,r0,HIADJ(PRPMC600_SYS_STAT_REG2)
ori r3,r3,LO(PRPMC600_SYS_STAT_REG2)
addis r4,r0,HIADJ(PRPMC600_BD_FAIL)
ori r4,r4,LO(PRPMC600_BD_FAIL)
andc r5,r5,r4 /* and in complement of BD_FAIL */
stwbrx r5,r0,r3 /* write new STAT */
sync /* ensure memory access is complete */
#endif /* DEBUG_STARTUP */
stw r8,4(r17)
#ifdef DEBUG_STARTUP
addis r3,r0,HIADJ(PRPMC600_SYS_STAT_REG2)
ori r3,r3,LO(PRPMC600_SYS_STAT_REG2)
addis r4,r0,HIADJ(PRPMC600_BD_FAIL)
ori r4,r4,LO(PRPMC600_BD_FAIL)
stwbrx r4,r0,r3 /* write new STAT */
sync /* ensure memory access is complete */
#endif /* DEBUG_STARTUP */
bc 16,0,mpc8240ScrubLoopNoFpu /* branch till counter == 0 */
sync /* synchronize the data stream */
/* exit */
mpc8240ScrubExit:
addi r3,r0,0 /* initialize error indicator, none */
mtspr 8,r16 /* restore return instruction pointer */
bclr 0x14,0x0 /* return to caller */
/******************************************************************************
*
* mpc8240RegMod - PCI configuration register modification.
*
* This function provides modification control for Mpc8240's
* configuration registers. It performs the necessary byte
* swapping.
*
* call:
* mpc8240RegMod(regOffset, regSize, mask, data)
*
* regOffset = (r3) address of device register to be modified
* regSize = (r4) register size
* 1, byte (8 bit) register
* 2, half word (16 bit/2 byte) register
* 4, word (32 bit/4 byte) register
* mask = (r5) mask for current register value
* data = (r6) data to be inserted into register
* spr8 = return program counter
*
* registers used (and not saved):
* r3, r4, r5, r6, r7, r8, r9, r20
*
* RETURNS:
* (r3) data read from register if read operation (otherwise return 0)
*/
.text
.align 2
.globl mpc8240RegMod
mpc8240RegMod:
sync /* ensure instructions are complete */
eieio /* ensures memory access is complete */
xor r0,r0,r0 /* clear r0 */
/* load register addresses to device-register, PCI_CAR, and PCI_CDR */
addis r7,r0,HIADJ(CNFG_PCI_HOST_BRDG)
ori r7,r7,LO(CNFG_PCI_HOST_BRDG)
add r7,r7,r3 /* add register offset */
addis r8,r0,HIADJ(PCI_MSTR_PRIMARY_CAR)
ori r8,r8,LO(PCI_MSTR_PRIMARY_CAR)
addis r9,r0,HIADJ(PCI_MSTR_PRIMARY_CDR)
ori r9,r9,LO(PCI_MSTR_PRIMARY_CDR)
/* adjust the addresses to CDR and device-register */
andi. r12,r3,0x3 /* mask register offset */
add r9,r9,r12 /* adjust it */
addi r12,r0,0x3 /* load mask (lower 2-bits) */
andc r7,r7,r12 /* mask of lower 2-bits */
/* write register value to CAR */
stwbrx r7,r0,r8 /* write register value to CAR */
eieio /* ensure memory access is complete */
sync /* ensure memory access is complete */
/* determine the size of the data operation */
cmpli 0,0,r4,0x04 /* is this a word i/o operation? */
bc 0x0c,0x02,andor32 /* branch to word i/o code */
cmpli 0,0,r4,0x02 /* is this a half-word i/o operation? */
bc 0x0c,0x02,andor16 /* branch to half-word i/o code */
cmpli 0,0,r4,0x01 /* is this a byte i/o operation? */
bc 0x0c,0x02,andor8 /* branch to byte i/o code */
bclr 0x14,0x0 /* return to caller */
/* word size data operations */
andor32: /* READ/MODIFY(AND/OR)/WRITE */
lwbrx r7,r0,r9 /* load(read) device data into r7 */
and r7,r7,r5 /* reg7 &= reg5 */
or r7,r7,r6 /* reg7 |= reg6 */
stwbrx r7,r0,r9 /* store(write) r7 to device reg */
eieio /* ensure memory access is complete */
sync /* ensure memory access is complete */
bclr 0x14,0x0 /* return to caller */
/* half-word size data operations */
andor16: /* READ/MODIFY(AND/OR)/WRITE */
lhbrx r7,r0,r9 /* load(read) device data into r7 */
eieio /* ensure memory access is complete */
sync /* ensure memory access is complete */
and r7,r7,r5 /* reg7 &= reg5 */
or r7,r7,r6 /* reg7 |= reg6 */
sthbrx r7,r0,r9 /* store(write) r7 to device reg */
eieio /* ensure memory access is complete */
sync /* ensure memory access is complete */
bclr 0x14,0x0 /* return to caller */
/* byte data size operations */
andor8: /* READ/MODIFY(AND/OR)/WRITE */
lbz r7,0(r9) /* load(read) device data into r7 */
eieio /* ensure memory access is complete */
sync /* ensure memory access is complete */
and r7,r7,r5 /* reg7 &= reg5 */
or r7,r7,r6 /* reg7 |= reg6 */
stb r7,0(r9) /* store(write) r7 to device reg */
eieio /* ensure memory access is complete */
sync /* ensure memory access is complete */
bclr 0x14,0x0 /* return to caller */
/******************************************************************************
*
* mpc8240DefInit - configure memory controller with default memory settings.
*
* This function initializes the Mpc8240 memory controller
* to bank 0, 32Mg and assumes a 83.3MHz clock.
*
* registers used (and not saved):
* r3, r4, r5, r6, r7, r8, r9, r20
*
* RETURNS:
* none
*/
.text
.align 3
.globl mpc8240DefInit
mpc8240DefInit:
addis r0,r0,0 /* insure r0 is zero */
ori r0,r0,0 /* insure r0 is zero */
or r22,r0,r0 /* preset to no memory available */
mfspr r20,8 /* save return instruction pointer */
bl mpc8240InitTableBasicPtr /* branch around tables */
/*
* register data table (initialization values)
*
* this table places the Mpc8240 into a known state, other tables
* exist for specific memory configurations
*/
mpc8240InitTableBasic:
/*
* reg size data mask
* === ==== ==== ====
*/
.long MPC8240_CFG_COMMAND, 2, 0x0006, 0x0000
.long MPC8240_CFG_CACHE_LINE_SIZE, 1, 0x08, 0x00
.long MPC8240_CFG_PCI_ARBITER_CNTL, 2, 0x8000, 0x1B60
.long MPC8240_CFG_PERF_MON_CMND_REG, 4, 0x00000000, 0x00000000
.long MPC8240_CFG_PERF_MON_CNTL_REG, 2, 0x0020, 0x3F0E
.long MPC8240_CFG_PERF_MON_COUNTER0, 4, 0x00000000, 0x00000000
.long MPC8240_CFG_PERF_MON_COUNTER1, 4, 0x00000000, 0x00000000
.long MPC8240_CFG_PERF_MON_COUNTER2, 4, 0x00000000, 0x00000000
.long MPC8240_CFG_PERF_MON_COUNTER3, 4, 0x00000000, 0x00000000
.long MPC8240_CFG_PWR_MGT_CFG_REG, 2, 0x0001, 0x2B40 /*donot change, maybe 0x2b40*/
.long MPC8240_CFG_PWR_MGT_CFG_REG2, 1, 0x80, 0x08
.long MPC8240_CFG_OUTPUT_DRIVER_REG, 1, 0x05, 0x00 /*changed*/
.long MPC8240_CFG_CLOCK_DRIVER_REG, 2, 0x0000, 0x0306
.long MPC8240_CFG_EUMBBAR, 4, MPC8240_EUMB_BASE, 0x0
.long MPC8240_CFG_MISC_REG1, 4, 0x000000c0, 0xFFFFFF1F
.long MPC8240_CFG_MISC_REG1, 4, 0x000000e0, 0xFFFFFF1F
.long MPC8240_CFG_MISC_REG1, 4, 0x000000c0, 0xFFFFFF1F
/*
* The 66.66 and 83.33 boards will
* work with the following memory controller settings.
*
* reg size data mask
* === ==== ==== ====
*/
/* .long MPC8240_CFG_MEM_CNTL_CFG_REG1, 4, 0x8f600002, 0x00600000 */ /*for 128M*/
.long MPC8240_CFG_MEM_CNTL_CFG_REG1, 4, 0x8f600000, 0x00600000 /*for 64M*/
.long MPC8240_CFG_MEM_CNTL_CFG_REG2, 4, 0x000006b8, 0x00000000
.long MPC8240_CFG_MEM_CNTL_CFG_REG3, 4, 0x78400000, 0x00000000
.long MPC8240_CFG_MEM_CNTL_CFG_REG4, 4, 0x35323239, 0x00A00000
.long MPC8240_CFG_MEM_STRT_ADR_REG, 4, 0x00000000, 0x00000000
.long MPC8240_CFG_MEM_STRT_UADR_REG, 4, 0x00000000, 0x00000000
.long MPC8240_CFG_EXT_MEM_STRT_ADR_REG, 4, 0x00000000, 0xFCFCFCFC
.long MPC8240_CFG_EXT_MEM_ST_UADR_REG, 4, 0x00000000, 0xFCFCFCFC
/* .long MPC8240_CFG_MEM_END_ADR_REG, 4, 0xFFFFFF7F, 0x00000000 */ /*for 128M*/
.long MPC8240_CFG_MEM_END_ADR_REG, 4, 0x7F5F3F1F, 0x00000000 /*for 32M*/
.long MPC8240_CFG_MEM_END_UADR_REG, 4, 0xFFFFFFFF, 0x00000000
.long MPC8240_CFG_EXT_MEM_END_ADR_REG, 4, 0x00000000, 0xFCFCFCFC
.long MPC8240_CFG_EXT_MEM_END_UADR_REG, 4, 0x00000000, 0xFCFCFCFC
.long MPC8240_CFG_PAGE_MODE_CTR_TIMER, 1, 0x50, 0x00
.long MPC8240_CFG_MEM_BANK_ENABLE_REG, 1, 0x01, 0x00
.long MPC8240_CFG_PROC_IF_CFG1, 4, 0xff141b88, 0xFF39E483
.long MPC8240_CFG_PROC_IF_CFG2, 4, 0x00040604, 0xD1F3FFF3
.long MPC8240_CFG_ECC_ERROR_CTR, 1, 0x00, 0x00
.long MPC8240_CFG_ECC_ERROR_TRIG, 1, 0x00, 0x00
.long MPC8240_CFG_ERROR_ENABLE1, 1, 0x01, 0x00 /* modified by zoutl for test: 0x01--> 0xff */
.long MPC8240_CFG_ERROR_DETECT1, 1, 0x0, 0x00
.long MPC8240_CFG_CPU_BUS_ERR_STAT, 1, 0x10, 0x00
.long MPC8240_CFG_ERROR_ENABLE2, 1, 0x00, 0x72 /* modified by zoutl for test: 0x00--> 0xcf */
.long MPC8240_CFG_ERROR_DETECT2, 1, 0x0, 0x72
.long MPC8240_CFG_PCI_BUS_ERR_STAT, 1, 0x0, 0xE0
.long MPC8240_CFG_MEM_CNTL_CFG_REG1, 4, MPC8240_MCC1_MEMGO, 0xFFF7FFFF
.long -1, -1, -1, -1 /* table end marker */
mpc8240InitTableBasicPtr:
mfspr r21,8 /* load pointer to table */
mpc8240InitBLoop:
lwz r3,0(r21) /* load offset */
lwz r4,4(r21) /* load size */
lwz r5,12(r21) /* load mask (and-data) */
lwz r6,8(r21) /* load data (or-data) */
cmpi 0,0,r5,-1 /* table end? */
bc 12,2,mpc8240InitDone /* if equal, yes, branch */
bl mpc8240RegMod /* perform register mod operation */
addi r21,r21,16 /* bump to next entry */
b mpc8240InitBLoop /* play it again sam */
mpc8240InitDone:
/* exit routine, return to caller (probably start.s) */
or r3,r22,r22 /* return memory size in bytes */
mtspr 8,r20 /* restore return instruction pointer */
bclr 20,0 /* return to caller */
.align 3
/******************************************************************************
*
* waitRefresh - delays for at least 100 microseconds.
*
* This subroutine's purpose is delay execution for at least
* 100 micro seconds to allow a memory refresh to occur
* The routine assumes the fastest prpmc600 clock (83.33MHz).
* 83.33MHz = 83,333,333 Hz or clock cycles/sec
* Decrementer counts down 1 value in 4 clock cycles.
* Want to wait 100 usecs or .0001 seconds.
*
* 83,333,333 * .0001 = 8333 clock cycles.
* 8333/4 = 2083 clocks.
*
* registers used (and not saved):
* r3
*
* RETURNS:
* none
*/
.text
.align 3
.globl waitRefresh
waitRefresh:
sync /* ensure instructions are complete */
eieio /* ensures memory access is complete */
li r4, 8000
mtctr r4
eieio
sync
PPMC8240wait8ref:
eieio
bdnz PPMC8240wait8ref
/* addis r6,0,0x0000
ori r6,r6,0x1f40
mtctr r6
eieio
sync
PPMC8240wait8ref:
eieio
bc 16,0,PPMC8240wait8ref*/
sync
bclr 20,0
.align 3
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -