.globl _start .globl _exit #ifdef BOOT_FROM_FLASH .text .section .rhcw,"a" # Reset configuration half word (RCHW) # ifdef __PPC_VLE__ .long 0x015a0000 # Magic BOOT_ID for Freescale VLE code # else .long 0x005a0000 # Magic BOOT_ID for Power Architecture code # endif .long _start #endif .macro li32 reg,imm lis \reg,\imm@h ori \reg,\reg,\imm@l .endm .macro ivor spr,reg,imm lis \reg,0 ori \reg,\reg,\imm@l # "li reg,\imm@l" should work too mtspr \spr,\reg .endm .text .section .start,"xa" _start: li %r0,0 li %r1,0 li %r2,0 li %r3,0 li %r4,0 li %r5,0 li %r6,0 li %r7,0 li %r8,0 li %r9,0 li %r10,0 li %r11,0 li %r12,0 li %r13,0 li %r14,0 li %r15,0 li %r16,0 li %r17,0 li %r18,0 li %r19,0 li %r20,0 li %r21,0 li %r22,0 li %r23,0 li %r24,0 li %r25,0 li %r26,0 li %r27,0 li %r28,0 li %r29,0 li %r30,0 li %r31,0 init_stackpointer: li32 %sp,__stack_end init_int_vector_prefix: lis %r3,IVOR0_entry@h mtspr 63,%r3 # IVPR # ifdef __PPC_VLE__ check_cpu: mfspr %r7,287 # read Processor Version Register (PVR) srwi %r7,%r7,20 # get only upper 12 bit, which contain Manuf.ID and processor type fields cmpwi %r7,0x817 # check if its an Freescale e200z0 core (0b100000010111) beq end_mmu # for e200z0 branch over initialization of Interrupt Vector Offset table (hardwired) and MMU (MMU not available) #endif init_int_vector_offsets: ivor 400,%r3,IVOR0_entry # IVOR0 ivor 401,%r3,IVOR1_entry # IVOR1 ivor 402,%r3,IVOR2_entry # IVOR2 ivor 403,%r3,IVOR3_entry # IVOR3 ivor 404,%r3,IVOR4_entry # IVOR4 ivor 405,%r3,IVOR5_entry # IVOR5 ivor 406,%r3,IVOR6_entry # IVOR6 ivor 407,%r3,IVOR7_entry # IVOR7 ivor 408,%r3,IVOR8_entry # IVOR8 ivor 409,%r3,IVOR9_entry # IVOR9 ivor 410,%r3,IVOR10_entry # IVOR10 ivor 411,%r3,IVOR11_entry # IVOR11 ivor 412,%r3,IVOR12_entry # IVOR12 ivor 413,%r3,IVOR13_entry # IVOR13 ivor 414,%r3,IVOR14_entry # IVOR14 ivor 415,%r3,IVOR15_entry # IVOR15 ivor 528,%r3,IVOR32_entry # IVOR32 ivor 529,%r3,IVOR33_entry # IVOR33 #ifndef QORIQ ivor 530,%r3,IVOR34_entry # IVOR34 #endif #ifdef BOOT_FROM_FLASH init_mmu: li32 %r4,__tlbdata_size mtctr %r4 li32 %r4,__tlbdata_start subi %r4,%r4,4 init_mmu_loop: lwzu %r3, 4(%r4) mtspr 624,%r3 # MAS0 lwzu %r3, 4(%r4) mtspr 625,%r3 # MAS1 lwzu %r3, 4(%r4) mtspr 626,%r3 # MAS2 lwzu %r3, 4(%r4) mtspr 627,%r3 # MAS3 tlbwe isync bdnz init_mmu_loop #endif end_mmu: #ifndef QORIQ disable_watchdog: li32 %r4,0xFFF38000 #Software Watchdog Timer (SWT) base address li32 %r3,0xC520 stw %r3,0x10(%r4) # SWT_SR : 1st magic word to clear the soft lock bit li32 %r3,0xD928 stw %r3,0x10(%r4) # SWT_SR : 2nd magic word to clear the soft lock bit li32 %r3,0xC000011A stw %r3,0x00(%r4) # SWT_CR : disable watchdog and set soft lock bit #endif #ifdef BOOT_FROM_FLASH init_sram: # Init ECC of SRAM (and clear BSS section at the same time) # For ECC we wouldn't care about the content of the registers, # but for the BSS section we're lucky that we've set r16-r31 to zero before li32 %r3,__SRAM_start li32 %r4,__SRAM_size srwi %r4,%r4,6 # divide size of SRAM by 64=16*4 (16-Registers with 4 Bytes) mtctr %r4 init_sram_loop: stmw %r16,0(%r3) # write r16-r31 to SRAM to initialize ECC addi %r3,%r3,64 bdnz init_sram_loop init_data: li32 %r3,__data_vaddr li32 %r4,__data_laddr li32 %r5,__data_size bl memcpy #else init_stack: li %r0,0 stw %r0,0(%sp) # clear Back Chain Word bss_clear: li32 %r3,__bss_start li32 %r4,__bss_size cmpwi %r4,0 beq gomain srwi %r4,%r4,2 mtctr %r4 subi %r3,%r3,4 bss_clear_loop: stwu %r0,4(%r3) bdnz bss_clear_loop #endif gomain: li %r3,0 li %r4,0 li %r5,0 bl main _exit: b _exit _start_background: # very reduced start-sequence for secondary core of a Bolero3M li32 %r0,_sp_background lwz %sp,0(%r0) # load initial value of stack pointer from memory li %r0,0 stw %r0,0(%sp) # clear Back Chain Word bl background b _exit .align 2 _sp_background: .long 0x40020000 #ifdef BOOT_FROM_FLASH .rodata .section .mmudata,"a" __tlbdata_start: /*** TLB1 entry 0 -> FLASH ***/ .long 0x10000000 # MAS0: ESL 0 .long 0x80000600 # MAS1: valid, no-protect, global, 4 MB # ifdef __PPC_VLE__ .long 0x00000020 # MAS2: log.addr.0x00000000, big-endian, VLE # else .long 0x00000000 # MAS2: log.addr.0x00000000, big-endian # endif .long 0x0000003F # MAS3: phy.addr.0x00000000, full-access /*** TLB1 entry 1 -> SRAM ***/ .long 0x10010000 # MAS0: ESL 1 .long 0x80000400 # MAS1: valid, no-protect, global, 256 KBytes .long 0x40000000 # MAS2: log.addr.0x40000000, big-endian .long 0x4000003F # MAS3: phy.addr.0x40000000, full-access /*** TLB1 entry 2 -> Flash configuration ***/ .long 0x10020000 # MAS0: ESL 2 .long 0xC0000500 # MAS1: valid, no-protect, global, 1 MB .long 0xC3F0000A # MAS2: log.addr.0xC3F00000, cache-inhibited, guarded (no speculative access), big-endian .long 0xC3F0003F # MAS3: phy.addr.0xC3F00000, full-access /*** TLB1 entry 3 -> Peripherals ***/ .long 0x10030000 # MAS0: ESL 3 .long 0xC0000500 # MAS1: valid, no-protect, global, 1 MB .long 0xFFF0000A # MAS2: log.addr.0xFFF00000, cache-inhibited, guarded (no speculative access), big-endian .long 0xFFF0003F # MAS3: phy.addr.0xFFF00000, full-access /*** TLB1 entry 4 -> disable default entry of SPC564A80-V2 ***/ .long 0x10040000 # MAS0: ESL 4 .long 0x00000000 # MAS1: invalid .long 0x00000000 # MAS2 .long 0x00000000 # MAS3 __tlbdata_end: .set __tlbdata_size, (__tlbdata_end-__tlbdata_start)/16 #endif .section .ivec,"xa" # for e200z0 cores this section must be aligned to 4096 bytes (since this e200z0 has a hardwired Interrupt Vector Offset table) .align 4 IVOR0_entry: #Critical Input nop nop nop b IVOR0_entry .align 4 IVOR1_entry: #Machine Check nop nop nop b IVOR1_entry .align 4 IVOR2_entry: #Data Storage nop nop nop b IVOR2_entry .align 4 IVOR3_entry: #Instruction Storage nop nop nop b IVOR3_entry .align 4 IVOR4_entry: #External Input nop nop nop b IVOR4_entry .align 4 IVOR5_entry: #Alignment nop nop nop b IVOR5_entry .align 4 IVOR6_entry: #Program nop nop nop b IVOR6_entry .align 4 IVOR7_entry: #Floating-Point Unavailable nop nop nop b IVOR7_entry .align 4 IVOR8_entry: #System Call nop nop nop b IVOR8_entry .align 4 IVOR9_entry: #Auxiliary Processor Unavailable nop nop nop b IVOR9_entry .align 4 IVOR10_entry: #Decrementer nop nop nop b IVOR10_entry .align 4 IVOR11_entry: #Fixed Interval Timer nop nop nop b IVOR11_entry .align 4 IVOR12_entry: #Watchdog nop nop nop b IVOR12_entry .align 4 IVOR13_entry: #Data TLB Error nop nop nop b IVOR13_entry .align 4 IVOR14_entry: #Instruction TLB Error nop nop nop b IVOR14_entry .align 4 IVOR15_entry: #Debug nop nop nop b IVOR15_entry .align 4 IVOR32_entry: #SPE APU unavailable nop nop nop b IVOR15_entry .align 4 IVOR33_entry: #SPE Floating-point Data nop nop nop b IVOR15_entry .align 4 IVOR34_entry: #SPE Floating-point Round nop nop nop b IVOR15_entry