Files
2025-10-14 09:52:32 +09:00

370 lines
7.2 KiB
Plaintext

.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