start.s
来自「U-boot源码 ARM7启动代码」· S 代码 · 共 2,098 行 · 第 1/4 页
S
2,098 行
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_of_vectors) 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 + _START_OFFSET li r8, Alignment - _start + _START_OFFSET2: bl trap_reloc addi r7, r7, 0x100 /* next exception vector */ cmplw 0, r7, r8 blt 2b li r7, .L_Alignment - _start + _START_OFFSET bl trap_reloc li r7, .L_ProgramCheck - _start + _START_OFFSET bl trap_reloc#ifdef CONFIG_440 li r7, .L_FPUnavailable - _start + _START_OFFSET bl trap_reloc li r7, .L_Decrementer - _start + _START_OFFSET bl trap_reloc li r7, .L_APU - _start + _START_OFFSET bl trap_reloc li r7, .L_InstructionTLBError - _start + _START_OFFSET bl trap_reloc li r7, .L_DataTLBError - _start + _START_OFFSET bl trap_reloc#else /* CONFIG_440 */ li r7, .L_PIT - _start + _START_OFFSET bl trap_reloc li r7, .L_InstructionTLBMiss - _start + _START_OFFSET bl trap_reloc li r7, .L_DataTLBMiss - _start + _START_OFFSET bl trap_reloc#endif /* CONFIG_440 */ li r7, .L_DebugBreakpoint - _start + _START_OFFSET bl trap_reloc#if !defined(CONFIG_440) addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */ oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */ mtmsr r7 /* change MSR */#else bl __440_msr_set b __440_msr_continue__440_msr_set: addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */ oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */ mtspr srr1,r7 mflr r7 mtspr srr0,r7 rfi__440_msr_continue:#endif 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#if defined(CONFIG_440)/*----------------------------------------------------------------------------+| dcbz_area.+----------------------------------------------------------------------------*/ function_prolog(dcbz_area) rlwinm. r5,r4,0,27,31 rlwinm r5,r4,27,5,31 beq ..d_ra2 addi r5,r5,0x0001..d_ra2:mtctr r5..d_ag2:dcbz r0,r3 addi r3,r3,32 bdnz ..d_ag2 sync blr function_epilog(dcbz_area)/*----------------------------------------------------------------------------+| dflush. Assume 32K at vector address is cachable.+----------------------------------------------------------------------------*/ function_prolog(dflush) mfmsr r9 rlwinm r8,r9,0,15,13 rlwinm r8,r8,0,17,15 mtmsr r8 addi r3,r0,0x0000 mtspr dvlim,r3 mfspr r3,ivpr addi r4,r0,1024 mtctr r4..dflush_loop: lwz r6,0x0(r3) addi r3,r3,32 bdnz ..dflush_loop addi r3,r3,-32 mtctr r4..ag: dcbf r0,r3 addi r3,r3,-32 bdnz ..ag sync mtmsr r9 blr function_epilog(dflush)#endif /* CONFIG_440 */#endif /* CONFIG_NAND_SPL *//*------------------------------------------------------------------------------- *//* Function: in8 *//* 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: out32 *//* Description: Output 32 bits *//*------------------------------------------------------------------------------- */ .globl out32out32: stw r4,0x0000(r3) blr/*------------------------------------------------------------------------------- *//* Function: in32 *//* Description: Input 32 bits *//*------------------------------------------------------------------------------- */ .globl in32in32: lwz 3,0x0000(3) blrinvalidate_icache: iccci r0,r0 /* for 405, iccci invalidates the */ blr /* entire I cache */invalidate_dcache: addi r6,0,0x0000 /* clear GPR 6 */ /* Do loop for # of dcache congruence classes. */ lis r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha /* TBS for large sized cache */ ori r7, r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l /* NOTE: dccci invalidates both */ mtctr r7 /* ways in the D cache */..dcloop: dccci 0,r6 /* invalidate line */ addi r6,r6, CFG_CACHELINE_SIZE /* bump to next line */ bdnz ..dcloop blr/**************************************************************************//* PPC405EP specific stuff *//**************************************************************************/#ifdef CONFIG_405EPppc405ep_init:#ifdef CONFIG_BUBINGA /* * Initialize EBC chip selects 1 & 4 and GPIO pins (for alternate * function) to support FPGA and NVRAM accesses below. */ lis r3,GPIO0_OSRH@h /* config GPIO output select */ ori r3,r3,GPIO0_OSRH@l lis r4,CFG_GPIO0_OSRH@h ori r4,r4,CFG_GPIO0_OSRH@l stw r4,0(r3) lis r3,GPIO0_OSRL@h ori r3,r3,GPIO0_OSRL@l lis r4,CFG_GPIO0_OSRL@h ori r4,r4,CFG_GPIO0_OSRL@l stw r4,0(r3) lis r3,GPIO0_ISR1H@h /* config GPIO input select */ ori r3,r3,GPIO0_ISR1H@l lis r4,CFG_GPIO0_ISR1H@h ori r4,r4,CFG_GPIO0_ISR1H@l stw r4,0(r3) lis r3,GPIO0_ISR1L@h ori r3,r3,GPIO0_ISR1L@l lis r4,CFG_GPIO0_ISR1L@h ori r4,r4,CFG_GPIO0_ISR1L@l stw r4,0(r3) lis r3,GPIO0_TSRH@h /* config GPIO three-state select */ ori r3,r3,GPIO0_TSRH@l lis r4,CFG_GPIO0_TSRH@h ori r4,r4,CFG_GPIO0_TSRH@l stw r4,0(r3) lis r3,GPIO0_TSRL@h ori r3,r3,GPIO0_TSRL@l lis r4,CFG_GPIO0_TSRL@h ori r4,r4,CFG_GPIO0_TSRL@l stw r4,0(r3) lis r3,GPIO0_TCR@h /* config GPIO driver output enables */ ori r3,r3,GPIO0_TCR@l lis r4,CFG_GPIO0_TCR@h ori r4,r4,CFG_GPIO0_TCR@l stw r4,0(r3) li r3,pb1ap /* program EBC bank 1 for RTC access */ mtdcr ebccfga,r3 lis r3,CFG_EBC_PB1AP@h ori r3,r3,CFG_EBC_PB1AP@l mtdcr ebccfgd,r3 li r3,pb1cr mtdcr ebccfga,r3 lis r3,CFG_EBC_PB1CR@h ori r3,r3,CFG_EBC_PB1CR@l mtdcr ebccfgd,r3 li r3,pb1ap /* program EBC bank 1 for RTC access */ mtdcr ebccfga,r3 lis r3,CFG_EBC_PB1AP@h ori r3,r3,CFG_EBC_PB1AP@l mtdcr ebccfgd,r3 li r3,pb1cr mtdcr ebccfga,r3 lis r3,CFG_EBC_PB1CR@h ori r3,r3,CFG_EBC_PB1CR@l mtdcr ebccfgd,r3 li r3,pb4ap /* program EBC bank 4 for FPGA access */ mtdcr ebccfga,r3 lis r3,CFG_EBC_PB4AP@h ori r3,r3,CFG_EBC_PB4AP@l mtdcr ebccfgd,r3 li r3,pb4cr mtdcr ebccfga,r3 lis r3,CFG_EBC_PB4CR@h ori r3,r3,CFG_EBC_PB4CR@l mtdcr ebccfgd,r3#endif /* !----------------------------------------------------------------------- ! 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_BUBINGA /* !----------------------------------------------------------------------- ! 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_BUBINGA */#ifdef CONFIG_TAIHU mfdcr r4, CPC0_BOOT andi. r5, r4, CPC0_BOOT_SEP@l bne strap_1 /* serial eeprom present */ addis r5,0,CPLD_REG0_ADDR@h ori r5,r5,CPLD_REG0_ADDR@l andi. r5, r5, 0x10 bne _pci_66mhz#endif /* CONFIG_TAIHU */#if defined(CONFIG_ZEUS) mfdcr r4, CPC0_BOOT andi. r5, r4, CPC0_BOOT_SEP@l bne strap_1 /* serial eeprom present */ lis r3,0x0000 addi r3,r3,0x3030 lis r4,0x8042 addi r4,r4,0x223e b 1fstrap_1: mfdcr r3, CPC0_PLLMR0 mfdcr r4, CPC0_PLLMR1 b 1f#endif 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 /* */#ifdef CONFIG_TAIHU b 1f_pci_66mhz: addis r3,0,PLLMR0_DEFAULT_PCI66@h ori r3,r3,PLLMR0_DEFAULT_PCI66@l addis r4,0,PLLMR1_DEFAULT_PCI66@h ori r4,r4,PLLMR1_DEFAULT_PCI66@l b 1fstrap_1: mfdcr r3, CPC0_PLLMR0 mfdcr r4, CPC0_PLLMR1#endif /* CONFIG_TAIHU */1: 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 */#if defined(CONFIG_440)/*----------------------------------------------------------------------------+| mttlb3.+----------------------------------------------------------------------------*/ function_prolog(mttlb3) TLBWE(4,3,2) blr function_epilog(mttlb3)/*----------------------------------------------------------------------------+| mftlb3.+----------------------------------------------------------------------------*/ function_prolog(mftlb3) TLBRE(3,3,2) blr function_epilog(mftlb3)/*----------------------------------------------------------------------------+| mttlb2.+----------------------------------------------------------------------------*/ function_prolog(mttlb2) TLBWE(4,3,1) blr function_epilog(mttlb2)/*----------------------------------------------------------------------------+| mftlb2.+----------------------------------------------------------------------------*/ function_prolog(mftlb2) TLBRE(3,3,1) blr function_epilog(mftlb2)/*----------------------------------------------------------------------------+| mttlb1.+----------------------------------------------------------------------------*/ function_prolog(mttlb1) TLBWE(4,3,0) blr function_epilog(mttlb1)/*----------------------------------------------------------------------------+| mftlb1.+----------------------------------------------------------------------------*/ function_prolog(mftlb1) TLBRE(3,3,0) blr function_epilog(mftlb1)#endif /* CONFIG_440 */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?