📄 start.s
字号:
/* Description: Input 8 bits *//*------------------------------------------------------------------------------- */ .globl in8in8: lbz r3,0x0000(r3) blr/*------------------------------------------------------------------------------- *//* Function: out8 *//* Description: Output 8 bits *//*------------------------------------------------------------------------------- */ .globl out8out8: stb r4,0x0000(r3) blr/*------------------------------------------------------------------------------- *//* Function: out16 *//* Description: Output 16 bits *//*------------------------------------------------------------------------------- */ .globl out16out16: sth r4,0x0000(r3) blr/*------------------------------------------------------------------------------- *//* Function: out16r *//* Description: Byte reverse and output 16 bits *//*------------------------------------------------------------------------------- */ .globl out16rout16r: sthbrx r4,r0,r3 blr/*------------------------------------------------------------------------------- *//* Function: out32 *//* Description: Output 32 bits *//*------------------------------------------------------------------------------- */ .globl out32out32: stw r4,0x0000(r3) blr/*------------------------------------------------------------------------------- *//* Function: out32r *//* Description: Byte reverse and output 32 bits *//*------------------------------------------------------------------------------- */ .globl out32rout32r: stwbrx r4,r0,r3 blr/*------------------------------------------------------------------------------- *//* Function: in16 *//* Description: Input 16 bits *//*------------------------------------------------------------------------------- */ .globl in16in16: lhz r3,0x0000(r3) blr/*------------------------------------------------------------------------------- *//* Function: in16r *//* Description: Input 16 bits and byte reverse *//*------------------------------------------------------------------------------- */ .globl in16rin16r: lhbrx r3,r0,r3 blr/*------------------------------------------------------------------------------- *//* Function: in32 *//* Description: Input 32 bits *//*------------------------------------------------------------------------------- */ .globl in32in32: lwz 3,0x0000(3) blr/*------------------------------------------------------------------------------- *//* Function: in32r *//* Description: Input 32 bits and byte reverse *//*------------------------------------------------------------------------------- */ .globl in32rin32r: lwbrx r3,r0,r3 blr/*------------------------------------------------------------------------------- *//* Function: ppcDcbf *//* Description: Data Cache block flush *//* Input: r3 = effective address *//* Output: none. *//*------------------------------------------------------------------------------- */ .globl ppcDcbfppcDcbf: dcbf r0,r3 blr/*------------------------------------------------------------------------------- *//* Function: ppcDcbi *//* Description: Data Cache block Invalidate *//* Input: r3 = effective address *//* Output: none. *//*------------------------------------------------------------------------------- */ .globl ppcDcbippcDcbi: dcbi r0,r3 blr/*------------------------------------------------------------------------------- *//* Function: ppcSync *//* Description: Processor Synchronize *//* Input: none. *//* Output: none. *//*------------------------------------------------------------------------------- */ .globl ppcSyncppcSync: sync blr/*------------------------------------------------------------------------------*//* * 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_coderelocate_code: mr r1, r3 /* Set new stack pointer */ mr r9, r4 /* Save copy of Init Data pointer */ 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 lwz r5, GOT(__init_end) sub r5, r5, r4 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */ /* * 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 /* the 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 not necessary */ beq 7f /* Protect against 0 count */ 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 4f2: slwi r0,r0,2 add r8,r4,r0 add r7,r3,r03: 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. */4: cmpwi r6,0 add r5,r3,r5 beq 7f /* Always flush prefetch queue in any case */ subi r0,r6,1 andc r3,r3,r0 mr r4,r35: dcbst 0,r4 add r4,r4,r6 cmplw r4,r5 blt 5b sync /* Wait for all dcbst to complete on bus */ mr r4,r36: icbi 0,r4 add r4,r4,r6 cmplw r4,r5 blt 6b7: sync /* Wait for all icbi to complete on bus */ isync/* * 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 /* NEVER RETURNS! */in_ram: /* * Relocation Function, r14 point to got2+0x8000 * * Adjust got2 pointers, no need to check for 0, this code * already puts a few entries in the table. */ li r0,__got2_entries@sectoff@l la r3,GOT(_GOT2_TABLE_) lwz r11,GOT(_GOT2_TABLE_) mtctr r0 sub r11,r3,r11 addi r3,r3,-41: lwzu r0,4(r3) add r0,r0,r11 stw r0,0(r3) bdnz 1b /* * Now adjust the fixups and the pointers to the fixups * in case we need to move ourselves again. */2: li r0,__fixup_entries@sectoff@l lwz r3,GOT(_FIXUP_TABLE_) cmpwi r0,0 mtctr r0 addi r3,r3,-4 beq 4f3: lwzu r4,4(r3) lwzux r0,r4,r11 add r0,r0,r11 stw r10,0(r3) stw r0,0(r4) bdnz 3b4:clear_bss: /* * Now clear BSS segment */ lwz r3,GOT(__bss_start) lwz r4,GOT(_end) cmplw 0, r3, r4 beq 6f li r0, 05: stw r0, 0(r3) addi r3, r3, 4 cmplw 0, r3, r4 bne 5b6: mr r3, r9 /* Init Data pointer */ mr r4, r10 /* Destination Address */ bl board_init_r /* * Copy exception vector code to low memory * * r3: dest_addr * r7: source address, r8: end address, r9: target address */ .globl trap_inittrap_init: lwz r7, GOT(_start) lwz r8, GOT(_end_of_vectors) li r9, 0x100 /* reset vector always at 0x100 */ cmplw 0, r7, r8 bgelr /* return if r7>=r8 - just in case */ mflr r4 /* save link register */1: lwz r0, 0(r7) stw r0, 0(r9) addi r7, r7, 4 addi r9, r9, 4 cmplw 0, r7, r8 bne 1b /* * relocate `hdlr' and `int_return' entries */ li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET li r8, Alignment - _start + EXC_OFF_SYS_RESET2: bl trap_reloc addi r7, r7, 0x100 /* next exception vector */ cmplw 0, r7, r8 blt 2b li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET bl trap_reloc li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET bl trap_reloc li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET li r8, SystemCall - _start + EXC_OFF_SYS_RESET3: bl trap_reloc addi r7, r7, 0x100 /* next exception vector */ cmplw 0, r7, r8 blt 3b li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET4: bl trap_reloc addi r7, r7, 0x100 /* next exception vector */ cmplw 0, r7, r8 blt 4b mtlr r4 /* restore link register */ blr /* * Function: relocate entries for one exception vector */trap_reloc: lwz r0, 0(r7) /* hdlr ... */ add r0, r0, r3 /* ... += dest_addr */ stw r0, 0(r7) lwz r0, 4(r7) /* int_return ... */ add r0, r0, r3 /* ... += dest_addr */ stw r0, 4(r7) blr/**************************************************************************//* PPC405EP specific stuff *//**************************************************************************/#ifdef CONFIG_405EPppc405ep_init: /* !----------------------------------------------------------------------- ! Check FPGA for PCI internal/external arbitration ! If board is set to internal arbitration, update cpc0_pci !----------------------------------------------------------------------- */ addi r3,0,CPC0_PCI_HOST_CFG_EN#ifdef CONFIG_BUBINGA405EP addis r5,r0,FPGA_REG1@h /* set offset for FPGA_REG1 */ ori r5,r5,FPGA_REG1@l lbz r5,0x0(r5) /* read to get PCI arb selection */ andi. r6,r5,FPGA_REG1_PCI_INT_ARB /* using internal arbiter ?*/ beq ..pci_cfg_set /* if not set, then bypass reg write*/#endif ori r3,r3,CPC0_PCI_ARBIT_EN..pci_cfg_set: mtdcr CPC0_PCI, r3 /* Enable internal arbiter*/ /* !----------------------------------------------------------------------- ! Check to see if chip is in bypass mode. ! If so, write stored CPC0_PLLMR0 and CPC0_PLLMR1 values and perform a ! CPU reset Otherwise, skip this step and keep going. ! Note: Running BIOS in bypass mode is not supported since PLB speed ! will not be fast enough for the SDRAM (min 66MHz) !----------------------------------------------------------------------- */ mfdcr r5, CPC0_PLLMR1 rlwinm r4,r5,1,0x1 /* get system clock source (SSCS) */ cmpi cr0,0,r4,0x1 beq pll_done /* if SSCS =b'1' then PLL has */ /* already been set */ /* and CPU has been reset */ /* so skip to next section */#ifdef CONFIG_BUBINGA405EP /* !----------------------------------------------------------------------- ! Read NVRAM to get value to write in PLLMR. ! If value has not been correctly saved, write default value ! Default config values (assuming on-board 33MHz SYS_CLK) are above. ! See CPU_DEFAULT_200 and CPU_DEFAULT_266 above. ! ! WARNING: This code assumes the first three words in the nvram_t ! structure in openbios.h. Changing the beginning of ! the structure will break this code. ! !----------------------------------------------------------------------- */ addis r3,0,NVRAM_BASE@h addi r3,r3,NVRAM_BASE@l lwz r4, 0(r3) addis r5,0,NVRVFY1@h addi r5,r5,NVRVFY1@l cmp cr0,0,r4,r5 /* Compare 1st NVRAM Magic number*/ bne ..no_pllset addi r3,r3,4 lwz r4, 0(r3) addis r5,0,NVRVFY2@h addi r5,r5,NVRVFY2@l cmp cr0,0,r4,r5 /* Compare 2 NVRAM Magic number */ bne ..no_pllset addi r3,r3,8 /* Skip over conf_size */ lwz r4, 4(r3) /* Load PLLMR1 value from NVRAM */ lwz r3, 0(r3) /* Load PLLMR0 value from NVRAM */ rlwinm r5,r4,1,0x1 /* get system clock source (SSCS) */ cmpi cr0,0,r5,1 /* See if PLL is locked */ beq pll_write..no_pllset:#endif /* CONFIG_BUBINGA405EP */ addis r3,0,PLLMR0_DEFAULT@h /* PLLMR0 default value */ ori r3,r3,PLLMR0_DEFAULT@l /* */ addis r4,0,PLLMR1_DEFAULT@h /* PLLMR1 default value */ ori r4,r4,PLLMR1_DEFAULT@l /* */ b pll_write /* Write the CPC0_PLLMR with new value */pll_done: /* !----------------------------------------------------------------------- ! Clear Soft Reset Register ! This is needed to enable PCI if not booting from serial EPROM !----------------------------------------------------------------------- */ addi r3, 0, 0x0 mtdcr CPC0_SRR, r3 addis r3,0,0x0010 mtctr r3pci_wait: bdnz pci_wait blr /* return to main code *//*!-----------------------------------------------------------------------------! Function: pll_write! Description: Updates the value of the CPC0_PLLMR according to CMOS27E documentation! That is:! 1. Pll is first disabled (de-activated by putting in bypass mode)! 2. PLL is reset! 3. Clock dividers are set while PLL is held in reset and bypassed! 4. PLL Reset is cleared! 5. Wait 100us for PLL to lock! 6. A core reset is performed! Input: r3 = Value to write to CPC0_PLLMR0! Input: r4 = Value to write to CPC0_PLLMR1! Output r3 = none!-----------------------------------------------------------------------------*/pll_write: mfdcr r5, CPC0_UCR andis. r5,r5,0xFFFF ori r5,r5,0x0101 /* Stop the UART clocks */ mtdcr CPC0_UCR,r5 /* Before changing PLL */ mfdcr r5, CPC0_PLLMR1 rlwinm r5,r5,0,0x7FFFFFFF /* Disable PLL */ mtdcr CPC0_PLLMR1,r5 oris r5,r5,0x4000 /* Set PLL Reset */ mtdcr CPC0_PLLMR1,r5 mtdcr CPC0_PLLMR0,r3 /* Set clock dividers */ rlwinm r5,r4,0,0x3FFFFFFF /* Reset & Bypass new PLL dividers */ oris r5,r5,0x4000 /* Set PLL Reset */ mtdcr CPC0_PLLMR1,r5 /* Set clock dividers */ rlwinm r5,r5,0,0xBFFFFFFF /* Clear PLL Reset */ mtdcr CPC0_PLLMR1,r5 /* ! Wait min of 100us for PLL to lock. ! See CMOS 27E databook for more info. ! At 200MHz, that means waiting 20,000 instructions */ addi r3,0,20000 /* 2000 = 0x4e20 */ mtctr r3pll_wait: bdnz pll_wait oris r5,r5,0x8000 /* Enable PLL */ mtdcr CPC0_PLLMR1,r5 /* Engage */ /* * Reset CPU to guarantee timings are OK * Not sure if this is needed... */ addis r3,0,0x1000 mtspr dbcr0,r3 /* This will cause a CPU core reset, and */ /* execution will continue from the poweron */ /* vector of 0xfffffffc */#endif /* CONFIG_405EP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -