Home | History | Annotate | Line # | Download | only in altboot
      1 /* $NetBSD: entry.S,v 1.6 2012/01/14 20:03:12 phx Exp $ */
      2 
      3 #include <powerpc/psl.h>
      4 #include <powerpc/spr.h>
      5 #include <powerpc/oea/spr.h>
      6 #include <powerpc/oea/bat.h>
      7 #include <powerpc/oea/hid.h>
      8 
      9 	.text
     10 	.globl _start
     11 _start:
     12 	/*
     13 	 * Save possible argc and argv values from the firmware, usually
     14 	 * passed in r3 and r4.
     15 	 * When started with "bootm", as a Linux kernel module, r6 and r7
     16 	 * point to the start and end address of the bootargs.
     17 	 */
     18 	mr	30,3
     19 	mr	31,4
     20 	mr	28,6
     21 	mr	29,7
     22 
     23 	/* Disable interrupts and everything except the MMU. */
     24 	mfmsr	3
     25 	andi.	3,3,PSL_DR|PSL_IR
     26 	mtmsr	3
     27 	isync
     28 
     29 	/*
     30 	 * U-Boot/PPCBoot forgets to flush the cache when using the "bootm"
     31 	 * command, so we have to do that now.
     32 	 */
     33 	lis	11,_start@ha
     34 	addi	11,11,_start@l
     35 	li	10,-32
     36 	and	11,11,10
     37 	lis	12,(_edata+31)@ha
     38 	addi	12,12,(_edata+31)@l
     39 	bl	syncicache
     40 
     41 	mfspr	11,SPR_HID0
     42 	andi.	0,11,HID0_DCE
     43 	ori	11,11,HID0_ICE
     44 	ori	8,11,HID0_ICFI
     45 	bne	1f			/* don't invalidate the D-cache */
     46 	ori	8,8,HID0_DCFI		/* unless it wasn't enabled */
     47 1:
     48 	mfmsr	0
     49 	andi.	0,0,PSL_DR
     50 	beq	2f
     51 	lis	5,0xfec00000@ha		/* CONFIG_ADDR of PCI */
     52 	lis	6,0xfee00000@ha		/* CONFIG_DATA of PCI */
     53 	mfspr	3,SPR_DBAT0U
     54 	mfspr	4,SPR_DBAT0L
     55 	bl	dbat_sanity_check
     56 	beq	3f
     57 	mfspr	3,SPR_DBAT1U
     58 	mfspr	4,SPR_DBAT1L
     59 	bl	dbat_sanity_check
     60 	beq	3f
     61 	mfspr	3,SPR_DBAT2U
     62 	mfspr	4,SPR_DBAT2L
     63 	bl	dbat_sanity_check
     64 	beq	3f
     65 	mfspr	3,SPR_DBAT3U
     66 	mfspr	4,SPR_DBAT3L
     67 	bl	dbat_sanity_check
     68 	beq	3f
     69 
     70 2:	/* Disable D-cache */
     71 	li	0,HID0_DCE
     72 	andc	11,11,0
     73 	b	4f
     74 
     75 3:	/* Enable D-cache */
     76 	ori	11,11,HID0_DCE
     77 
     78 4:
     79 	lis	1,BAT123@ha
     80 	addi	1,1,BAT123@l
     81 	lwz	3,0(1)
     82 	lwz	4,4(1)
     83 	mtdbatl	1,3
     84 	mtdbatu	1,4
     85 	lwz	3,8(1)
     86 	lwz	4,12(1)
     87 	mtdbatl	2,3
     88 	mtdbatu	2,4
     89 	lwz	3,16(1)
     90 	lwz	4,20(1)
     91 	mtdbatl	3,3
     92 	mtdbatu	3,4
     93 
     94 	sync
     95 	mtspr	SPR_HID0,8		/* enable and invalidate caches */
     96 	sync
     97 	mtspr	SPR_HID0,11		/* enable caches */
     98 	sync
     99 	isync
    100 
    101 	/* make sure .bss gets zeroed. */
    102 	li	0,0
    103 	lis	8,edata@ha
    104 	addi	8,8,edata@l
    105 	lis	9,end@ha
    106 	addi	9,9,end@l
    107 5:	cmpw	0,8,9			/* edata & end are >= word aligned */
    108 	bge	6f
    109 	stw	0,0(8)
    110 	addi	8,8,4
    111 	b	5b
    112 
    113 6:
    114 	/* prepare stack at +1MB from _start, 16-byte aligned */
    115 	lis	1,_start@ha
    116 	addi	1,1,_start@l
    117 	addis	1,1,0x100000@ha
    118 	li	10,-16
    119 	and	1,1,10
    120 	stw	0,0(1)
    121 
    122 	bl	brdsetup
    123 #ifdef DEBUG
    124 	bl	init_vectors
    125 #endif
    126 	mr	3,30
    127 	mr	4,31
    128 	mr	5,28
    129 	mr	6,29
    130 	bl	main
    131 
    132 hang:	b	hang
    133 	/* NOTREACHED */
    134 
    135 dbat_sanity_check:
    136 	andi.	0,3,BAT_Vs
    137 	beq	2f
    138 	andi.	0,4,BAT_I|BAT_PP_RW
    139 	cmpwi	0,0,BAT_I|BAT_PP_RW
    140 	bnelr
    141 	rlwinm	0,3,15,4,14
    142 	andis.	3,3,0xfffe0000@ha	/* BAT_EPI */
    143 	andis.	4,4,BAT_RPN@ha
    144 	cmplw	0,3,4
    145 	bnelr
    146 	add	4,4,0
    147 	oris	4,4,0x0001ffff@ha
    148 	ori	4,4,0x0001ffff@l
    149 	cmplw	0,3,5
    150 	bgt	1f
    151 	cmplw	0,5,4
    152 	bgt	1f
    153 	li	5,0
    154 1:	cmplw	0,3,6
    155 	bgt	2f
    156 	cmplw	0,6,4
    157 	bgt	2f
    158 	li	6,0
    159 2:	cmplw	0,5,6
    160 	blr
    161 
    162 /*
    163  * run(startsym, endsym, howto, bootinfo, entry)
    164  */
    165 	.globl	run
    166 run:
    167 	mtctr	7			/* hat trick jump to entry point */
    168 	bctr
    169 
    170 /*
    171  * newaltboot(argc, argv, altboot_base, altboot_len)
    172  * To be executed in a safe memory region. Copies the new altboot from
    173  * altboot_base to 0x1000000 and starts it there.
    174  */
    175 	.globl	newaltboot
    176 newaltboot:
    177 	lis	7,0x1000000@h
    178 	mr	11,7
    179 	subi	7,7,4
    180 	subi	5,5,4
    181 	add	12,11,6
    182 	addi	6,6,3
    183 	srawi	6,6,2
    184 	mtctr	6
    185 1:	lwzu	8,4(5)
    186 	stwu	8,4(7)
    187 	bdnz+	1b
    188 	mtctr	11
    189 	addi	12,12,31
    190 	bl	syncicache
    191 	bctr
    192 syncicache:
    193 /* r11=start, r12=end, r10=scratch */
    194 	mr	10,11
    195 2:	dcbst	0,10
    196 	addi	10,10,32
    197 	cmplw	10,12
    198 	ble	2b
    199 	sync
    200 3:	icbi	0,11
    201 	addi	11,11,32
    202 	cmplw	11,12
    203 	ble	3b
    204 	sync
    205 	isync
    206 	blr
    207 	.globl	newaltboot_end
    208 newaltboot_end:
    209 
    210 
    211 /* 8-bit i/o access */
    212 	.globl	out8
    213 out8:
    214 	stb	4,0(3)
    215 	eieio
    216 	blr
    217 
    218 	.globl	in8
    219 in8:
    220 	lbz	3,0(3)
    221 	eieio
    222 	blr
    223 
    224 /*
    225  * reverse endian access to mimic outw/outl/inw/inl
    226  */
    227 	.globl	out16rb
    228 	.globl	iohtole16
    229 out16rb:
    230 iohtole16:
    231 	sthbrx	4,0,3
    232 	eieio
    233 	blr
    234 
    235 	.globl	out32rb
    236 	.globl	iohtole32
    237 out32rb:
    238 iohtole32:
    239 	stwbrx	4,0,3
    240 	eieio
    241 	blr
    242 
    243 	.globl	in16rb
    244 	.globl	iole16toh
    245 in16rb:
    246 iole16toh:
    247 	lhbrx	3,0,3
    248 	eieio
    249 	blr
    250 
    251 	.globl	in32rb
    252 	.globl	iole32toh
    253 in32rb:
    254 iole32toh:
    255 	lwbrx	3,0,3
    256 	eieio
    257 	blr
    258 
    259 #ifdef DEBUG
    260 	/*
    261 	 * Call an exception handler, which prints out all information
    262 	 * about the type of exception, cpu registers, stack frame
    263 	 * backtrace, etc.
    264 	 * Use a new stack at 0x2000 and make room for 32 GPRs, and 15
    265 	 * special registers. The layout will be:
    266 	 * 0x00: link area
    267 	 * 0x10: R0
    268 	 * ...
    269 	 * 0x8c: R31
    270 	 * 0x90: CR, XER, LR, CTR
    271 	 * 0xa0: SRR0, SRR1, DAR, DSISR
    272 	 * 0xb0: DMISS, DCMP, HASH1, HASH2
    273 	 * 0xc0: IMISS, ICMP, RPA
    274 	 *
    275 	 */
    276 	.globl	trap
    277 trap:
    278 	mtsprg1	1
    279 	mfmsr	1
    280 	andis.	1,1,PSL_TGPR@h
    281 	beq	1f
    282 	andi.	1,1,0xffff		/* make sure TGPR is disabled */
    283 	mtmsr	1
    284 	isync
    285 	mtsprg1	1			/* and save the real r1 again */
    286 1:	li	1,0x2000-16-(32*4+15*4)
    287 	stmw	2,24(1)			/* save r2..r31 */
    288 	stw	0,16(1)			/* save r0 */
    289 	mfsprg1	3
    290 	stw	3,20(1)			/* and finally r1 */
    291 	mfcr	3
    292 	stw	3,0x90(1)
    293 	mfxer	3
    294 	stw	3,0x94(1)
    295 	mflr	3
    296 	stw	3,0x98(1)
    297 	mfctr	3
    298 	stw	3,0x9c(1)
    299 	mfsrr0	3
    300 	stw	3,0xa0(1)
    301 	mfsrr1	3
    302 	stw	3,0xa4(1)
    303 	mfdar	3
    304 	stw	3,0xa8(1)
    305 	mfdsisr	3
    306 	stw	3,0xac(1)
    307 	mfspr	3,976
    308 	stw	3,0xb0(1)
    309 	mfspr	3,977
    310 	stw	3,0xb4(1)
    311 	mfspr	3,978
    312 	stw	3,0xb8(1)
    313 	mfspr	3,979
    314 	stw	3,0xbc(1)
    315 	mfspr	3,980
    316 	stw	3,0xc0(1)
    317 	mfspr	3,981
    318 	stw	3,0xc4(1)
    319 	mfspr	3,982
    320 	stw	3,0xc8(1)
    321 	bl	call_handler
    322 call_handler:
    323 	lis	11,exception_handler@ha
    324 	addi	11,11,exception_handler@l
    325 	mtsrr0	11
    326 	li	0,PSL_DR|PSL_IR
    327 	mtsrr1	0
    328 	mflr	3
    329 	subi	3,3,call_handler-trap
    330 	addi	4,1,16
    331 	rfi
    332 	.globl	trap_end
    333 trap_end:
    334 #endif
    335 
    336 	.data
    337 #define	xBATL(pa, wimg, pp)						\
    338 	((pa) | (wimg) | (pp))
    339 #define	xBATU(va, len, v)						\
    340 	((va) | ((len) & BAT_BL) | ((v) & BAT_V))
    341 BAT123:
    342 	.long xBATL(0x80000000, BAT_I|BAT_G, BAT_PP_RW)
    343 	.long xBATU(0x80000000, BAT_BL_256M, BAT_Vs)
    344 	.long xBATL(0xfc000000, BAT_I|BAT_G, BAT_PP_RW)
    345 	.long xBATU(0xfc000000, BAT_BL_64M, BAT_Vs)
    346 	.long xBATL(0x70000000, BAT_I|BAT_G, BAT_PP_RW)
    347 	.long xBATU(0x70000000, BAT_BL_128K, BAT_Vs)
    348