348 lines
5.6 KiB
ArmAsm
348 lines
5.6 KiB
ArmAsm
/* $NetBSD: entry.S,v 1.6 2012/01/14 20:03:12 phx Exp $ */
|
|
|
|
#include <powerpc/psl.h>
|
|
#include <powerpc/spr.h>
|
|
#include <powerpc/oea/spr.h>
|
|
#include <powerpc/oea/bat.h>
|
|
#include <powerpc/oea/hid.h>
|
|
|
|
.text
|
|
.globl _start
|
|
_start:
|
|
/*
|
|
* Save possible argc and argv values from the firmware, usually
|
|
* passed in r3 and r4.
|
|
* When started with "bootm", as a Linux kernel module, r6 and r7
|
|
* point to the start and end address of the bootargs.
|
|
*/
|
|
mr 30,3
|
|
mr 31,4
|
|
mr 28,6
|
|
mr 29,7
|
|
|
|
/* Disable interrupts and everything except the MMU. */
|
|
mfmsr 3
|
|
andi. 3,3,PSL_DR|PSL_IR
|
|
mtmsr 3
|
|
isync
|
|
|
|
/*
|
|
* U-Boot/PPCBoot forgets to flush the cache when using the "bootm"
|
|
* command, so we have to do that now.
|
|
*/
|
|
lis 11,_start@ha
|
|
addi 11,11,_start@l
|
|
li 10,-32
|
|
and 11,11,10
|
|
lis 12,(_edata+31)@ha
|
|
addi 12,12,(_edata+31)@l
|
|
bl syncicache
|
|
|
|
mfspr 11,SPR_HID0
|
|
andi. 0,11,HID0_DCE
|
|
ori 11,11,HID0_ICE
|
|
ori 8,11,HID0_ICFI
|
|
bne 1f /* don't invalidate the D-cache */
|
|
ori 8,8,HID0_DCFI /* unless it wasn't enabled */
|
|
1:
|
|
mfmsr 0
|
|
andi. 0,0,PSL_DR
|
|
beq 2f
|
|
lis 5,0xfec00000@ha /* CONFIG_ADDR of PCI */
|
|
lis 6,0xfee00000@ha /* CONFIG_DATA of PCI */
|
|
mfspr 3,SPR_DBAT0U
|
|
mfspr 4,SPR_DBAT0L
|
|
bl dbat_sanity_check
|
|
beq 3f
|
|
mfspr 3,SPR_DBAT1U
|
|
mfspr 4,SPR_DBAT1L
|
|
bl dbat_sanity_check
|
|
beq 3f
|
|
mfspr 3,SPR_DBAT2U
|
|
mfspr 4,SPR_DBAT2L
|
|
bl dbat_sanity_check
|
|
beq 3f
|
|
mfspr 3,SPR_DBAT3U
|
|
mfspr 4,SPR_DBAT3L
|
|
bl dbat_sanity_check
|
|
beq 3f
|
|
|
|
2: /* Disable D-cache */
|
|
li 0,HID0_DCE
|
|
andc 11,11,0
|
|
b 4f
|
|
|
|
3: /* Enable D-cache */
|
|
ori 11,11,HID0_DCE
|
|
|
|
4:
|
|
lis 1,BAT123@ha
|
|
addi 1,1,BAT123@l
|
|
lwz 3,0(1)
|
|
lwz 4,4(1)
|
|
mtdbatl 1,3
|
|
mtdbatu 1,4
|
|
lwz 3,8(1)
|
|
lwz 4,12(1)
|
|
mtdbatl 2,3
|
|
mtdbatu 2,4
|
|
lwz 3,16(1)
|
|
lwz 4,20(1)
|
|
mtdbatl 3,3
|
|
mtdbatu 3,4
|
|
|
|
sync
|
|
mtspr SPR_HID0,8 /* enable and invalidate caches */
|
|
sync
|
|
mtspr SPR_HID0,11 /* enable caches */
|
|
sync
|
|
isync
|
|
|
|
/* make sure .bss gets zeroed. */
|
|
li 0,0
|
|
lis 8,edata@ha
|
|
addi 8,8,edata@l
|
|
lis 9,end@ha
|
|
addi 9,9,end@l
|
|
5: cmpw 0,8,9 /* edata & end are >= word aligned */
|
|
bge 6f
|
|
stw 0,0(8)
|
|
addi 8,8,4
|
|
b 5b
|
|
|
|
6:
|
|
/* prepare stack at +1MB from _start, 16-byte aligned */
|
|
lis 1,_start@ha
|
|
addi 1,1,_start@l
|
|
addis 1,1,0x100000@ha
|
|
li 10,-16
|
|
and 1,1,10
|
|
stw 0,0(1)
|
|
|
|
bl brdsetup
|
|
#ifdef DEBUG
|
|
bl init_vectors
|
|
#endif
|
|
mr 3,30
|
|
mr 4,31
|
|
mr 5,28
|
|
mr 6,29
|
|
bl main
|
|
|
|
hang: b hang
|
|
/* NOTREACHED */
|
|
|
|
dbat_sanity_check:
|
|
andi. 0,3,BAT_Vs
|
|
beq 2f
|
|
andi. 0,4,BAT_I|BAT_PP_RW
|
|
cmpwi 0,0,BAT_I|BAT_PP_RW
|
|
bnelr
|
|
rlwinm 0,3,15,4,14
|
|
andis. 3,3,0xfffe0000@ha /* BAT_EPI */
|
|
andis. 4,4,BAT_RPN@ha
|
|
cmplw 0,3,4
|
|
bnelr
|
|
add 4,4,0
|
|
oris 4,4,0x0001ffff@ha
|
|
ori 4,4,0x0001ffff@l
|
|
cmplw 0,3,5
|
|
bgt 1f
|
|
cmplw 0,5,4
|
|
bgt 1f
|
|
li 5,0
|
|
1: cmplw 0,3,6
|
|
bgt 2f
|
|
cmplw 0,6,4
|
|
bgt 2f
|
|
li 6,0
|
|
2: cmplw 0,5,6
|
|
blr
|
|
|
|
/*
|
|
* run(startsym, endsym, howto, bootinfo, entry)
|
|
*/
|
|
.globl run
|
|
run:
|
|
mtctr 7 /* hat trick jump to entry point */
|
|
bctr
|
|
|
|
/*
|
|
* newaltboot(argc, argv, altboot_base, altboot_len)
|
|
* To be executed in a safe memory region. Copies the new altboot from
|
|
* altboot_base to 0x1000000 and starts it there.
|
|
*/
|
|
.globl newaltboot
|
|
newaltboot:
|
|
lis 7,0x1000000@h
|
|
mr 11,7
|
|
subi 7,7,4
|
|
subi 5,5,4
|
|
add 12,11,6
|
|
addi 6,6,3
|
|
srawi 6,6,2
|
|
mtctr 6
|
|
1: lwzu 8,4(5)
|
|
stwu 8,4(7)
|
|
bdnz+ 1b
|
|
mtctr 11
|
|
addi 12,12,31
|
|
bl syncicache
|
|
bctr
|
|
syncicache:
|
|
/* r11=start, r12=end, r10=scratch */
|
|
mr 10,11
|
|
2: dcbst 0,10
|
|
addi 10,10,32
|
|
cmplw 10,12
|
|
ble 2b
|
|
sync
|
|
3: icbi 0,11
|
|
addi 11,11,32
|
|
cmplw 11,12
|
|
ble 3b
|
|
sync
|
|
isync
|
|
blr
|
|
.globl newaltboot_end
|
|
newaltboot_end:
|
|
|
|
|
|
/* 8-bit i/o access */
|
|
.globl out8
|
|
out8:
|
|
stb 4,0(3)
|
|
eieio
|
|
blr
|
|
|
|
.globl in8
|
|
in8:
|
|
lbz 3,0(3)
|
|
eieio
|
|
blr
|
|
|
|
/*
|
|
* reverse endian access to mimic outw/outl/inw/inl
|
|
*/
|
|
.globl out16rb
|
|
.globl iohtole16
|
|
out16rb:
|
|
iohtole16:
|
|
sthbrx 4,0,3
|
|
eieio
|
|
blr
|
|
|
|
.globl out32rb
|
|
.globl iohtole32
|
|
out32rb:
|
|
iohtole32:
|
|
stwbrx 4,0,3
|
|
eieio
|
|
blr
|
|
|
|
.globl in16rb
|
|
.globl iole16toh
|
|
in16rb:
|
|
iole16toh:
|
|
lhbrx 3,0,3
|
|
eieio
|
|
blr
|
|
|
|
.globl in32rb
|
|
.globl iole32toh
|
|
in32rb:
|
|
iole32toh:
|
|
lwbrx 3,0,3
|
|
eieio
|
|
blr
|
|
|
|
#ifdef DEBUG
|
|
/*
|
|
* Call an exception handler, which prints out all information
|
|
* about the type of exception, cpu registers, stack frame
|
|
* backtrace, etc.
|
|
* Use a new stack at 0x2000 and make room for 32 GPRs, and 15
|
|
* special registers. The layout will be:
|
|
* 0x00: link area
|
|
* 0x10: R0
|
|
* ...
|
|
* 0x8c: R31
|
|
* 0x90: CR, XER, LR, CTR
|
|
* 0xa0: SRR0, SRR1, DAR, DSISR
|
|
* 0xb0: DMISS, DCMP, HASH1, HASH2
|
|
* 0xc0: IMISS, ICMP, RPA
|
|
*
|
|
*/
|
|
.globl trap
|
|
trap:
|
|
mtsprg1 1
|
|
mfmsr 1
|
|
andis. 1,1,PSL_TGPR@h
|
|
beq 1f
|
|
andi. 1,1,0xffff /* make sure TGPR is disabled */
|
|
mtmsr 1
|
|
isync
|
|
mtsprg1 1 /* and save the real r1 again */
|
|
1: li 1,0x2000-16-(32*4+15*4)
|
|
stmw 2,24(1) /* save r2..r31 */
|
|
stw 0,16(1) /* save r0 */
|
|
mfsprg1 3
|
|
stw 3,20(1) /* and finally r1 */
|
|
mfcr 3
|
|
stw 3,0x90(1)
|
|
mfxer 3
|
|
stw 3,0x94(1)
|
|
mflr 3
|
|
stw 3,0x98(1)
|
|
mfctr 3
|
|
stw 3,0x9c(1)
|
|
mfsrr0 3
|
|
stw 3,0xa0(1)
|
|
mfsrr1 3
|
|
stw 3,0xa4(1)
|
|
mfdar 3
|
|
stw 3,0xa8(1)
|
|
mfdsisr 3
|
|
stw 3,0xac(1)
|
|
mfspr 3,976
|
|
stw 3,0xb0(1)
|
|
mfspr 3,977
|
|
stw 3,0xb4(1)
|
|
mfspr 3,978
|
|
stw 3,0xb8(1)
|
|
mfspr 3,979
|
|
stw 3,0xbc(1)
|
|
mfspr 3,980
|
|
stw 3,0xc0(1)
|
|
mfspr 3,981
|
|
stw 3,0xc4(1)
|
|
mfspr 3,982
|
|
stw 3,0xc8(1)
|
|
bl call_handler
|
|
call_handler:
|
|
lis 11,exception_handler@ha
|
|
addi 11,11,exception_handler@l
|
|
mtsrr0 11
|
|
li 0,PSL_DR|PSL_IR
|
|
mtsrr1 0
|
|
mflr 3
|
|
subi 3,3,call_handler-trap
|
|
addi 4,1,16
|
|
rfi
|
|
.globl trap_end
|
|
trap_end:
|
|
#endif
|
|
|
|
.data
|
|
#define xBATL(pa, wimg, pp) \
|
|
((pa) | (wimg) | (pp))
|
|
#define xBATU(va, len, v) \
|
|
((va) | ((len) & BAT_BL) | ((v) & BAT_V))
|
|
BAT123:
|
|
.long xBATL(0x80000000, BAT_I|BAT_G, BAT_PP_RW)
|
|
.long xBATU(0x80000000, BAT_BL_256M, BAT_Vs)
|
|
.long xBATL(0xfc000000, BAT_I|BAT_G, BAT_PP_RW)
|
|
.long xBATU(0xfc000000, BAT_BL_64M, BAT_Vs)
|
|
.long xBATL(0x70000000, BAT_I|BAT_G, BAT_PP_RW)
|
|
.long xBATU(0x70000000, BAT_BL_128K, BAT_Vs)
|