📄 start.s
字号:
/* * Copyright 2004 Freescale Semiconductor. * Srikanth Srinivasan <srikanth.srinivaan@freescale.com> * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA *//* U-Boot - Startup Code for 86xx PowerPC based Embedded Boards * * * The processor starts at 0xfff00100 and the code is executed * from flash. The code is organized to be at an other address * in memory, but as long we don't jump around before relocating. * board_init lies at a quite high address and when the cpu has * jumped there, everything is ok. */#include <config.h>#include <mpc86xx.h>#include <version.h>#include <ppc_asm.tmpl>#include <ppc_defs.h>#include <asm/cache.h>#include <asm/mmu.h>#ifndef CONFIG_IDENT_STRING#define CONFIG_IDENT_STRING ""#endif/* We don't want the MMU yet.*/#undef MSR_KERNEL/* Machine Check and Recoverable Interr. */#define MSR_KERNEL ( MSR_ME | MSR_RI )/* * Set up GOT: Global Offset Table * * Use r14 to access the GOT */ START_GOT GOT_ENTRY(_GOT2_TABLE_) GOT_ENTRY(_FIXUP_TABLE_) GOT_ENTRY(_start) GOT_ENTRY(_start_of_vectors) GOT_ENTRY(_end_of_vectors) GOT_ENTRY(transfer_to_handler) GOT_ENTRY(__init_end) GOT_ENTRY(_end) GOT_ENTRY(__bss_start) END_GOT/* * r3 - 1st arg to board_init(): IMMP pointer * r4 - 2nd arg to board_init(): boot flag */ .text .long 0x27051956 /* U-Boot Magic Number */ .globl version_stringversion_string: .ascii U_BOOT_VERSION .ascii " (", __DATE__, " - ", __TIME__, ")" .ascii CONFIG_IDENT_STRING, "\0" . = EXC_OFF_SYS_RESET .globl _start_start: li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH */ b boot_cold sync . = EXC_OFF_SYS_RESET + 0x10 .globl _start_warm_start_warm: li r21, BOOTFLAG_WARM /* Software reboot */ b boot_warm sync /* the boot code is located below the exception table */ .globl _start_of_vectors_start_of_vectors:/* Machine check */ STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)/* Data Storage exception. */ STD_EXCEPTION(0x300, DataStorage, UnknownException)/* Instruction Storage exception. */ STD_EXCEPTION(0x400, InstStorage, UnknownException)/* External Interrupt exception. */ STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)/* Alignment exception. */ . = 0x600Alignment: EXCEPTION_PROLOG mfspr r4,DAR stw r4,_DAR(r21) mfspr r5,DSISR stw r5,_DSISR(r21) addi r3,r1,STACK_FRAME_OVERHEAD li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ lwz r6,GOT(transfer_to_handler) mtlr r6 blrl.L_Alignment: .long AlignmentException - _start + EXC_OFF_SYS_RESET .long int_return - _start + EXC_OFF_SYS_RESET/* Program check exception */ . = 0x700ProgramCheck: EXCEPTION_PROLOG addi r3,r1,STACK_FRAME_OVERHEAD li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ lwz r6,GOT(transfer_to_handler) mtlr r6 blrl.L_ProgramCheck: .long ProgramCheckException - _start + EXC_OFF_SYS_RESET .long int_return - _start + EXC_OFF_SYS_RESET STD_EXCEPTION(0x800, FPUnavailable, UnknownException) /* I guess we could implement decrementer, and may have * to someday for timekeeping. */ STD_EXCEPTION(0x900, Decrementer, timer_interrupt) STD_EXCEPTION(0xa00, Trap_0a, UnknownException) STD_EXCEPTION(0xb00, Trap_0b, UnknownException) STD_EXCEPTION(0xc00, SystemCall, UnknownException) STD_EXCEPTION(0xd00, SingleStep, UnknownException) STD_EXCEPTION(0xe00, Trap_0e, UnknownException) STD_EXCEPTION(0xf00, Trap_0f, UnknownException) STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException) STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException) STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException) STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException) STD_EXCEPTION(0x1400, DataTLBError, UnknownException) STD_EXCEPTION(0x1500, Reserved5, UnknownException) STD_EXCEPTION(0x1600, Reserved6, UnknownException) STD_EXCEPTION(0x1700, Reserved7, UnknownException) STD_EXCEPTION(0x1800, Reserved8, UnknownException) STD_EXCEPTION(0x1900, Reserved9, UnknownException) STD_EXCEPTION(0x1a00, ReservedA, UnknownException) STD_EXCEPTION(0x1b00, ReservedB, UnknownException) STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException) STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException) STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException) STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException) .globl _end_of_vectors_end_of_vectors: . = 0x2000boot_cold:boot_warm: /* if this is a multi-core system we need to check which cpu * this is, if it is not cpu 0 send the cpu to the linux reset * vector */#if (CONFIG_NUM_CPUS > 1) mfspr r0, MSSCR0 andi. r0, r0, 0x0020 rlwinm r0,r0,27,31,31 mtspr PIR, r0 beq 1f bl secondary_cpu_setup#endif /* disable everything */1: li r0, 0 mtspr HID0, r0 sync mtmsr 0 bl invalidate_bats sync#ifdef CFG_L2 /* init the L2 cache */ addis r3, r0, L2_INIT@h ori r3, r3, L2_INIT@l mtspr l2cr, r3 /* invalidate the L2 cache */ bl l2cache_invalidate sync#endif /* * Calculate absolute address in FLASH and jump there *------------------------------------------------------*/ lis r3, CFG_MONITOR_BASE@h ori r3, r3, CFG_MONITOR_BASE@l addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET mtlr r3 blrin_flash: /* let the C-code set up the rest */ /* */ /* Be careful to keep code relocatable ! */ /*------------------------------------------------------*/ /* perform low-level init */ /* enable extended addressing */ bl enable_ext_addr /* setup the bats */ bl setup_bats sync#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR) /* setup ccsrbar */ bl setup_ccsrbar#endif /* Fix for SMP linux - Changing arbitration to round-robin */ lis r3, CFG_CCSRBAR@h ori r3, r3, 0x1000 xor r4, r4, r4 li r4, 0x1000 stw r4, 0(r3) /* setup the law entries */ bl law_entry sync /* Don't use this feature due to bug in 8641D PD4 */ /* Disable ERD_DIS */ lis r3, CFG_CCSRBAR@h ori r3, r3, 0x1008 lwz r4, 0(r3) oris r4, r4, 0x4000 stw r4, 0(r3) sync#if (EMULATOR_RUN == 1) /* On the emulator we want to adjust these ASAP */ /* otherwise things are sloooow */ /* Setup OR0 (LALE FIX)*/ lis r3, CFG_CCSRBAR@h ori r3, r3, 0x5004 li r4, 0x0FF3 stw r4, 0(r3) sync /* Setup LCRR */ lis r3, CFG_CCSRBAR@h ori r3, r3, 0x50D4 lis r4, 0x8000 ori r4, r4, 0x0002 stw r4, 0(r3) sync#endif#if 1 /* make sure timer enabled in guts register too */ lis r3, CFG_CCSRBAR@h oris r3,r3, 0xE ori r3,r3,0x0070 lwz r4, 0(r3) lis r5,0xFFFC ori r5,r5,0x5FFF and r4,r4,r5 stw r4,0(r3)#endif /* * Cache must be enabled here for stack-in-cache trick. * This means we need to enable the BATS. * Cache should be turned on after BATs, since by default * everything is write-through. */ /* enable address translation */ bl enable_addr_trans sync /* enable and invalidate the data cache *//* bl l1dcache_enable */ bl dcache_enable sync#if 1 bl icache_enable#endif#ifdef CFG_INIT_RAM_LOCK bl lock_ram_in_cache sync#endif /* set up the stack pointer in our newly created * cache-ram (r1) */ lis r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l li r0, 0 /* Make room for stack frame header and */ stwu r0, -4(r1) /* clear final stack frame so that */ stwu r0, -4(r1) /* stack backtraces terminate cleanly */ GET_GOT /* initialize GOT access */ /* run low-level CPU init code (from Flash) */ bl cpu_init_f sync#ifdef RUN_DIAG /* Sri: Code to run the diagnostic automatically */ /* Load PX_AUX register address in r4 */ lis r4, 0xf810 ori r4, r4, 0x6 /* Load contents of PX_AUX in r3 bits 24 to 31*/ lbz r3, 0(r4) /* Mask and obtain the bit in r3 */ rlwinm. r3, r3, 0, 24, 24 /* If not zero, jump and continue with u-boot */ bne diag_done /* Load back contents of PX_AUX in r3 bits 24 to 31 */ lbz r3, 0(r4) /* Set the MSB of the register value */ ori r3, r3, 0x80 /* Write value in r3 back to PX_AUX */ stb r3, 0(r4) /* Get the address to jump to in r3*/ lis r3, CFG_DIAG_ADDR@h ori r3, r3, CFG_DIAG_ADDR@l /* Load the LR with the branch address */ mtlr r3 /* Branch to diagnostic */ blrdiag_done:#endif/* bl l2cache_enable */ mr r3, r21 /* r3: BOOTFLAG */ /* run 1st part of board init code (from Flash) */ bl board_init_f sync /* NOTREACHED */ .globl invalidate_batsinvalidate_bats: /* invalidate BATs */ mtspr IBAT0U, r0 mtspr IBAT1U, r0 mtspr IBAT2U, r0 mtspr IBAT3U, r0 mtspr IBAT4U, r0 mtspr IBAT5U, r0 mtspr IBAT6U, r0 mtspr IBAT7U, r0 isync mtspr DBAT0U, r0 mtspr DBAT1U, r0 mtspr DBAT2U, r0 mtspr DBAT3U, r0 mtspr DBAT4U, r0 mtspr DBAT5U, r0 mtspr DBAT6U, r0 mtspr DBAT7U, r0 isync sync blr /* setup_bats - set them up to some initial state */ .globl setup_batssetup_bats: addis r0, r0, 0x0000 /* IBAT 0 */ addis r4, r0, CFG_IBAT0L@h ori r4, r4, CFG_IBAT0L@l addis r3, r0, CFG_IBAT0U@h ori r3, r3, CFG_IBAT0U@l mtspr IBAT0L, r4 mtspr IBAT0U, r3 isync /* DBAT 0 */ addis r4, r0, CFG_DBAT0L@h ori r4, r4, CFG_DBAT0L@l addis r3, r0, CFG_DBAT0U@h ori r3, r3, CFG_DBAT0U@l mtspr DBAT0L, r4 mtspr DBAT0U, r3 isync /* IBAT 1 */ addis r4, r0, CFG_IBAT1L@h ori r4, r4, CFG_IBAT1L@l addis r3, r0, CFG_IBAT1U@h ori r3, r3, CFG_IBAT1U@l mtspr IBAT1L, r4 mtspr IBAT1U, r3 isync /* DBAT 1 */ addis r4, r0, CFG_DBAT1L@h ori r4, r4, CFG_DBAT1L@l addis r3, r0, CFG_DBAT1U@h ori r3, r3, CFG_DBAT1U@l mtspr DBAT1L, r4 mtspr DBAT1U, r3 isync /* IBAT 2 */ addis r4, r0, CFG_IBAT2L@h ori r4, r4, CFG_IBAT2L@l addis r3, r0, CFG_IBAT2U@h ori r3, r3, CFG_IBAT2U@l mtspr IBAT2L, r4 mtspr IBAT2U, r3 isync /* DBAT 2 */ addis r4, r0, CFG_DBAT2L@h ori r4, r4, CFG_DBAT2L@l addis r3, r0, CFG_DBAT2U@h ori r3, r3, CFG_DBAT2U@l mtspr DBAT2L, r4 mtspr DBAT2U, r3 isync /* IBAT 3 */ addis r4, r0, CFG_IBAT3L@h ori r4, r4, CFG_IBAT3L@l addis r3, r0, CFG_IBAT3U@h ori r3, r3, CFG_IBAT3U@l mtspr IBAT3L, r4 mtspr IBAT3U, r3 isync /* DBAT 3 */ addis r4, r0, CFG_DBAT3L@h ori r4, r4, CFG_DBAT3L@l addis r3, r0, CFG_DBAT3U@h ori r3, r3, CFG_DBAT3U@l mtspr DBAT3L, r4 mtspr DBAT3U, r3 isync /* IBAT 4 */ addis r4, r0, CFG_IBAT4L@h ori r4, r4, CFG_IBAT4L@l addis r3, r0, CFG_IBAT4U@h ori r3, r3, CFG_IBAT4U@l mtspr IBAT4L, r4 mtspr IBAT4U, r3 isync /* DBAT 4 */ addis r4, r0, CFG_DBAT4L@h ori r4, r4, CFG_DBAT4L@l addis r3, r0, CFG_DBAT4U@h ori r3, r3, CFG_DBAT4U@l mtspr DBAT4L, r4 mtspr DBAT4U, r3 isync /* IBAT 5 */ addis r4, r0, CFG_IBAT5L@h ori r4, r4, CFG_IBAT5L@l addis r3, r0, CFG_IBAT5U@h ori r3, r3, CFG_IBAT5U@l mtspr IBAT5L, r4 mtspr IBAT5U, r3 isync /* DBAT 5 */ addis r4, r0, CFG_DBAT5L@h ori r4, r4, CFG_DBAT5L@l addis r3, r0, CFG_DBAT5U@h ori r3, r3, CFG_DBAT5U@l mtspr DBAT5L, r4 mtspr DBAT5U, r3 isync /* IBAT 6 */ addis r4, r0, CFG_IBAT6L@h ori r4, r4, CFG_IBAT6L@l addis r3, r0, CFG_IBAT6U@h ori r3, r3, CFG_IBAT6U@l mtspr IBAT6L, r4 mtspr IBAT6U, r3 isync /* DBAT 6 */ addis r4, r0, CFG_DBAT6L@h ori r4, r4, CFG_DBAT6L@l addis r3, r0, CFG_DBAT6U@h ori r3, r3, CFG_DBAT6U@l mtspr DBAT6L, r4 mtspr DBAT6U, r3 isync /* IBAT 7 */ addis r4, r0, CFG_IBAT7L@h ori r4, r4, CFG_IBAT7L@l addis r3, r0, CFG_IBAT7U@h ori r3, r3, CFG_IBAT7U@l mtspr IBAT7L, r4 mtspr IBAT7U, r3 isync /* DBAT 7 */ addis r4, r0, CFG_DBAT7L@h ori r4, r4, CFG_DBAT7L@l addis r3, r0, CFG_DBAT7U@h ori r3, r3, CFG_DBAT7U@l mtspr DBAT7L, r4 mtspr DBAT7U, r3 isync1: addis r3, 0, 0x0000 addis r5, 0, 0x4 /* upper bound of 0x00040000 for 7400/750 */ isynctlblp: tlbie r3 sync addi r3, r3, 0x1000 cmp 0, 0, r3, r5 blt tlblp blr .globl enable_addr_transenable_addr_trans: /* enable address translation */ mfmsr r5 ori r5, r5, (MSR_IR | MSR_DR) mtmsr r5 isync blr .globl disable_addr_transdisable_addr_trans: /* disable address translation */ mflr r4 mfmsr r3 andi. r0, r3, (MSR_IR | MSR_DR) beqlr andc r3, r3, r0 mtspr SRR0, r4 mtspr SRR1, r3 rfi/* * This code finishes saving the registers to the exception frame * and jumps to the appropriate handler for the exception. * Register r21 is pointer into trap frame, r1 has new stack pointer. */ .globl transfer_to_handlertransfer_to_handler: stw r22,_NIP(r21) lis r22,MSR_POW@h andc r23,r23,r22 stw r23,_MSR(r21) SAVE_GPR(7, r21) SAVE_4GPRS(8, r21) SAVE_8GPRS(12, r21) SAVE_8GPRS(24, r21) mflr r23 andi. r24,r23,0x3f00 /* get vector offset */ stw r24,TRAP(r21) li r22,0 stw r22,RESULT(r21) mtspr SPRG2,r22 /* r1 is now kernel sp */ lwz r24,0(r23) /* virtual address of handler */ lwz r23,4(r23) /* where to go when done */ mtspr SRR0,r24
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -