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