📄 rominit.s
字号:
/* load DBATs from table above */setDbats: mfspr r4,LR addi r4,r4,-4 lwzu r3,4(r4) mtspr DBAT0L,r3 lwzu r3,4(r4) mtspr DBAT0U,r3 lwzu r3,4(r4) mtspr DBAT1L,r3 lwzu r3,4(r4) mtspr DBAT1U,r3 lwzu r3,4(r4) mtspr DBAT2L,r3 lwzu r3,4(r4) mtspr DBAT2U,r3 lwzu r3,4(r4) mtspr DBAT3L,r3 lwzu r3,4(r4) mtspr DBAT3U,r3 /* Invalidate the data cache */ bl dCacheInval xor r0,r0,r0 sync mtspr SDR1,r0 isync /* invalidate entries within both TLBs */ li r4,128 xor r3,r3,r3 /* p0 = 0 */ mtctr r4 /* CTR = 64 */ isync /* context sync req'd before tlbie */tlbLoop: tlbie r3 sync /* sync instr req'd after tlbie */ addi r3,r3,0x1000 /* increment bits 14-19 */ bdnz tlbLoop /* decrement CTR, branch if CTR != 0 */ /* Enable the data MMU by turning on data address translation */ mfmsr r3 lis r4,HI(1<<(31-_PPC_MSR_BIT_DR)) ori r4,r4,LO(1<<(31-_PPC_MSR_BIT_DR)) or r4,r3,r4 mtmsr r4 /* Turn on data cache */ bl dCacheOn /* Initialize some memory in the cache stack */ lis r3,HI(CACHE_STACK_SIZE) ori r3,r3,LO(CACHE_STACK_SIZE) subf r3,r3,spfillLoop: dcbz r0,r3 addi r3,r3,_CACHE_ALIGN_SIZE cmplw r3,sp blt fillLoop /* * Now go calculate correct memory controller values and program * the memory controller. */ bl progMemCtlr /* Program the memory controller optimally */skipMemGo: cmpli 0,0,r31,BOOT_COLD /* check for warm boot */ bc 4,2,goCEntry /* if warm boot, skip scrub */ /* * When using any sort of error detection/correction scheme * it is necessary to scrub all of system memory on a cold boot. * * We have been using DBATs up until now. We will disable the * DBATs by turning off address translation. Cacheing will * still be operational, even with address translation turned * off. ... So disable the data MMU by turning off data address * translation. Data cache should still be turned on at this * point. */ mfmsr r3 lis r4,HI(1<<(31-_PPC_MSR_BIT_DR)) ori r4,r4,LO(1<<(31-_PPC_MSR_BIT_DR)) andc r3,r3,r4 sync isync mtmsr r3 sync /* * Scrub memory so that it is in a known state for error * correction/detection. */ xor r3,r3,r3 /* memory starting address = 0 */ add r4,r3,r29 /* memory ending address + 1 */ bl memoryScrub /* (memoryScrub) */ /* Turn off data and instruction cache */ bl dCacheInval mfspr r3,HID0 rlwinm r4,r3,0,(_PPC_HID0_BIT_ICE+1),(_PPC_HID0_BIT_ICE-1) /* ICE=0 */ mtspr HID0,r4 /* HID0 = r4 data/instr cache disabld */ /* Disable the data MMU */ mfmsr r3 rlwinm r3,r3,0,_PPC_MSR_BIT_DR+1,_PPC_MSR_BIT_DR-1 mtmsr r3#ifdef USER_I_CACHE_ENABLE /* turn the Instruction cache ON for faster ROM access */ bl iCacheOn#endifgoCEntry: /* go to C entry point */ lis sp,HI(STACK_ADRS) /* Load sp with real RAM address */ ori sp,sp,LO(STACK_ADRS) or r3,r31,r31 addi sp,sp,-FRAMEBASESZ /* get frame stack */ lis r6,HI(romStart) ori r6,r6,LO(romStart) lis r7,HI(romInit) ori r7,r7,LO(romInit) lis r8,HI(ROM_TEXT_ADRS) ori r8,r8,LO(ROM_TEXT_ADRS) sub r6,r6,r7 add r6,r6,r8 mtlr r6 blrFUNC_END(_romInit)FUNC_END(romInit)/***************************************************************************** progMemCtlr - Program memory controller with optimal values** This function calculates, if possible, optimal memory controller* values, programs the controller with these values and turns the* controller on. If it is unable to calculate the memory controller * parameters, it returns without reprogramming the controller, leaving * the controller in the default programmed state that it was in when this * function was called.** The function which is called to calculate the new memory* controller parameters is the C function sysMemParamConfig().* If sysMemParamConfig() indicates that it has successfully* calculated the new controller parameters, the memory controller* will be programmed with these new values. It is of note that* sysMemParamConfig() has been carefully written so that its* use of RAM is restricted entirely to the stack (no global variables* or other constructs which would force use of RAM outside of* the stack). At this point, the stack used by sysMemParamConfig()* is entirely confined to the L1 cache and thus no actual DRAM* is used.** r27 - used as holder for link register return address** NOMANUAL*/FUNC_BEGIN(progMemCtlr) mfspr r27,LR /* Save link register */ /* * Turn on instruction cache - this is necessary in order to * correctly calculate the bus speed (done in sysMemParamConfig()). */ bl iCacheOn /* * Read I2C to get SPD for "real" SDRAM timing values. * The I2C routines are written in 'C', so we need a stack frame. * This stack frame will exist entirely in L1 cache and will * not affect the actual RAM. */ stwu sp,-ABI_STACK_SIZE(sp) /* create an ABI stack frame */ addi r3,sp,8 /* point to register image area */ or r22,r3,r3 /* save structure address */ /* * Call the C function which will compute memory parameters * Note we must call sysMemParamConfig even if BYPASS_SPD is * #define'd since it initializes I2C interface in addition to * computing memory configuration parameters. */ bl sysMemParamConfig /* calculate memory parameters */ or r29,r3,r3 /* save size */ addi sp,sp,ABI_STACK_SIZE /* remove ABI stack frame */#ifndef BYPASS_SPD lwz r8,MCCR1(r22) /* load r8 with mem control config 1 */ cmpli 0,0,r8,0 /* check for SPD error MCCR1 = 0 */ bc 4,2,goodSpd /* test for non-0 */ b memCnfgDone /* error, leave default mem cnfg */goodSpd: /* Turn off memory controller. */ bl memCtlrOff lwz r9,MCCR2(r22) /* load mem control config 2 */ lwz r10,MCCR3(r22) /* load mem control config 3 */ lwz r11,MCCR4(r22) /* load mem control config 4 */ lwz r12,ERRENR1(r22) /* load mem control error enable 1 */ lwz r13,MSR3_2_1_0(r22) /* load mem start address 3/2/1/0 */ lwz r14,MSR7_6_5_4(r22) /* load mem start address 7/6/5/4 */ lwz r15,MSER3_2_1_0(r22) /* load ext mem start addr 3/2/1/0 */ lwz r16,MSER7_6_5_4(r22) /* load ext mem start addr 7/6/5/4 */ lwz r17,MER3_2_1_0(r22) /* load mem ending addr 3/2/1/0 */ lwz r18,MER7_6_5_4(r22) /* load mem ending addr 7/6/5/4 */ lwz r19,MEER3_2_1_0(r22) /* load ext mem end addr 3/2/1/0 */ lwz r20,MEER7_6_5_4(r22) /* load ext mem end addr 7/6/5/4 */ lbz r21,MPMR(r22) /* load mem page mode */ lbz r22,MBER(r22) /* load mem bank enable */ addis r6,r0,HIADJ(CNFG_PCI_HOST_BRDG) ori r6,r6,LO(CNFG_PCI_HOST_BRDG) addi r3,r6,MPC107_CFG_MEM_CNTL_CFG_REG1 /* add MCCR1 offset */ addis r7,r0,HIADJ(PCI_MSTR_PRIMARY_CAR) ori r7,r7,LO(PCI_MSTR_PRIMARY_CAR) stwbrx r3,r0,r7 /* write address of MCCR1 to CAR */ sync /* ensure memory access is complete */ addis r4,r0,HIADJ(PCI_MSTR_PRIMARY_CDR) ori r4,r4,LO(PCI_MSTR_PRIMARY_CDR) lwbrx r5,r0,r4 /* read MCCR1 */ addis r3,r0,HIADJ(0x00600000) /* mask R/O bits */ ori r3,r3,LO(0x00600000) and r5,r5,r3 /* reg5 &= reg3 */ or r8,r8,r5 /* reg8 |= reg5 */ stwbrx r8,r0,r4 /* write calculated value to MCCR1 */ sync /* ensure memory access is complete */ addi r3,r6,MPC107_CFG_MEM_CNTL_CFG_REG2 /* add MCCR2 offset */ stwbrx r3,r0,r7 /* write address of MCCR2 to CAR */ sync /* ensure memory access is complete */ addis r8,r0,HIADJ(PCI_MSTR_PRIMARY_CDR) ori r8,r8,LO(PCI_MSTR_PRIMARY_CDR) stwbrx r9,r0,r8 /* write calculated value to MCCR2 */ sync /* ensure memory access is complete */ addi r3,r6,MPC107_CFG_MEM_CNTL_CFG_REG3 /* add MCCR3 offset */ stwbrx r3,r0,r7 /* write address of MCCR3 to CAR */ sync /* ensure memory access is complete */ stwbrx r10,r0,r8 /* write calculated value to MCCR3 */ sync /* ensure memory access is complete */ addi r3,r6,MPC107_CFG_MEM_CNTL_CFG_REG4 /* add MCCR4 offset */ stwbrx r3,r0,r7 /* write address of MCCR4 to CAR */ sync /* ensure memory access is complete */ lwbrx r5,r0,r4 /* read MCCR4 */ addis r3,r0,HIADJ(0x00A00000) /* mask R/O bits */ ori r3,r3,LO(0x00A00000) and r5,r5,r3 /* reg5 &= reg3 */ or r11,r11,r5 /* reg11 |= reg5 */ stwbrx r11,r0,r8 /* write calculated value to MCCR4 */ sync /* ensure memory access is complete */ addi r3,r6,MPC107_CFG_ERROR_ENABLE1 /* add ERRENR1 offset */ stwbrx r3,r0,r7 /* write address of ERRENR1 to CAR */ sync /* ensure memory access is complete */ stwbrx r12,r0,r8 /* write calc'd value to ERRENR1 */ sync /* ensure memory access is complete */ addi r3,r6,MPC107_CFG_MEM_STRT_ADR_REG /* add MSR3/2/1/0 offset */ stwbrx r3,r0,r7 /* write address of MSR3/2/1/0 to CAR */ sync /* ensure memory access is complete */ stwbrx r13,r0,r8 /* write calc'd value to MSR3/2/1/0 */ sync /* ensure memory access is complete */ addi r3,r6,MPC107_CFG_MEM_STRT_UADR_REG /* add MSR7/6/5/4 offset */ stwbrx r3,r0,r7 /* write address of MSR7/6/5/4 to CAR */ sync /* ensure memory access is complete */ stwbrx r14,r0,r8 /* write calc'd value to MSR7/6/5/4 */ sync /* ensure memory access is complete */ addi r3,r6,MPC107_CFG_EXT_MEM_STRT_ADR_REG /* MSER3/2/1/0 offset */ stwbrx r3,r0,r7 /* write addr of MSER3/2/1/0 to CAR */ sync /* ensure memory access is complete */ stwbrx r15,r0,r8 /* write calc'd value to MSER3/2/1/0 */ sync /* ensure memory access is complete */ addi r3,r6,MPC107_CFG_EXT_MEM_ST_UADR_REG /* MSER7/6/5/4 offset */ stwbrx r3,r0,r7 /* write addr of MSER7/6/5/4 to CAR */ sync /* ensure memory access is complete */ stwbrx r16,r0,r8 /* write calc'd value to MSER7/6/5/4 */ sync /* ensure memory access is complete */ addi r3,r6,MPC107_CFG_MEM_END_ADR_REG /* MER3/2/1/0 offset */ stwbrx r3,r0,r7 /* write addr of MER3/2/1/0 to CAR */ sync /* ensure memory access is complete */ stwbrx r17,r0,r8 /* write calc'd value to MER3/2/1/0 */ sync /* ensure memory access is complete */ addi r3,r6,MPC107_CFG_MEM_END_UADR_REG /* MER7/6/5/4 offset */ stwbrx r3,r0,r7 /* write addr of MER7/6/5/4 to CAR */ sync /* ensure memory access is complete */ stwbrx r18,r0,r8 /* write calc'd value to MER7/6/5/4 */ sync /* ensure memory access is complete */ addi r3,r6,MPC107_CFG_EXT_MEM_END_ADR_REG /* MEER3/2/1/0 offset */ stwbrx r3,r0,r7 /* write addr of MEER3/2/1/0 to CAR */ sync /* ensure memory access is complete */ stwbrx r19,r0,r8 /* write calc'd value to MEER3/2/1/0 */ sync /* ensure memory access is complete */ addi r3,r6,MPC107_CFG_EXT_MEM_END_UADR_REG /* MEER7/6/5/4 offset */ stwbrx r3,r0,r7 /* write addr of MEER7/6/5/4 to CAR */ sync /* ensure memory access is complete */ stwbrx r20,r0,r8 /* write calc'd value to MEER7/6/5/4 */ sync /* ensure memory access is complete */ addi r3,r6,MPC107_CFG_PAGE_MODE_CTR_TIMER /* add page mode offset */ stwbrx r3,r0,r7 /* write addr of page mode to CAR */ sync /* ensure memory access is complete */ stb r21,0(r8) /* write page mode data to CDR */ sync /* ensure memory access is complete */ addi r3,r6,MPC107_CFG_MEM_BANK_ENABLE_REG /* add mem bank enable */ stwbrx r3,r0,r7 /* write config. space addr. to CAR */ sync /* ensure memory access is complete */ stb r22,0(r8) /* write data to CDR */ sync /* ensure memory access is complete */#endif /* !BYPASS_SPD */ memCnfgDone:#ifndef BYPASS_SPD /* * Once the memory controller has been configured, it is necessary * to wait 200 microseconds before turning the memory controller * back on. */ bl waitRefresh /* Turn on memory controller. */ bl memCtlrOn#endif /* !BYPASS_SPD */ mtspr LR,r27 /* restore return link address */ bclr 0x14,0x0 /* return to caller */FUNC_END(progMemCtlr)/***************************************************************************** memoryScrub - DRAM initialization.** DESCRIPTION: memoryScrub* this subroutine's purpose is to initialize (i.e., scrub)* DRAM, the Lopic ASIC protects DRAM by utilizing ECC, so* the scrub insures that the entire DRAM array's check bits* are initialized to a known state** memoryScrub(start-address, end-address);* r3 = starting address of DRAM* r4 = ending address of DRAM (plus 1)* spr8 = return program counter** NOMANUAL*/FUNC_BEGIN(memoryScrub) mfspr r16,LR /* save return instruction pointer */ or r13,r3,r3 /* save argument #1, start address */ or r14,r4,r4 /* save argument #2, end address */ xor r0,r0,r0 /* clear r0 */ /* * Enable floating point support in the processor so that * we can scrub memory using 64 bit reads and writes. */ mfmsr r3 ori r3,r3,(1<<(31-_PPC_MSR_BIT_FP)) /* 0x00002000 */ mtmsr r3 bl loadScrubData .long 0x00000000,0x00000000loadScrubData: mfspr r4,LR /* address of the above table of 0's */ lfd 0,0(r4) /* load the 0's into fpr0 */ /* Setup scrub loop specifics */ 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 CTR,r18 /* load number of doubles/words */ /* Loop through the entire DRAM array, initialize memory */scrubLoop: stfdu 0,8(r17) /* write contents of fpr0 to memory */ bc 16,0,scrubLoop /* branch until counter == 0 */ sync mtspr CTR,r18 /* load number of doubles/words */ addi r17,r13,-8 /* starting address munged */readLoop: /* * It is necessary to read the memory after writing it, to * ensure that all data has been flushed from the cache and * has been written to memory. */ lfdu 0,8(r17) /* read memory into fpr0 */ bc 16,0,readLoop /* branch until counter == 0 */ scrubExit: mtspr LR,r16 /* restore return instruction pointer */ bclr 0x14,0x0 /* return to caller */FUNC_END(memoryScrub)/***************************************************************************** mpc107RegMod - PCI configuration register modification.** This function provides modification control for mpc107's* configuration registers. It performs the necessary byte* swapping.** call:* mpc107RegMod(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)** NOMANUAL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -