Home | History | Annotate | Line # | Download | only in booke
e500_mpsubr.S revision 1.1
      1  1.1  matt 
      2  1.1  matt /*
      3  1.1  matt  * r3 = fdt pointer (ignored)
      4  1.1  matt  * r4 = 0
      5  1.1  matt  * r5 = 0
      6  1.1  matt  * r6 = EPAPR magic (0x45505150)
      7  1.1  matt  * r7 = TLB1[0] entry size (64MB)
      8  1.1  matt  * r8 = 0
      9  1.1  matt  * r9 = 0
     10  1.1  matt  */
     11  1.1  matt _ENTRY(e500_spinup_trampoline)
     12  1.1  matt 
     13  1.1  matt 	/*
     14  1.1  matt 	 * First thing we need to do is to set SPRG0 with our cpu_info
     15  1.1  matt 	 * and get our initial stack pointer (this must be within the
     16  1.1  matt 	 * bounds of the TLB1[0] entry U-boot setup for us).
     17  1.1  matt 	 *
     18  1.1  matt 	 * cpu_hatch will return a new SP to use.
     19  1.1  matt 	 *
     20  1.1  matt 	 * All the caller-saved register are ours to use.  So we will.
     21  1.1  matt 	 */
     22  1.1  matt 	lis	%r20, _C_LABEL(cpu_hatch_data)@ha
     23  1.1  matt 	addi	%r20, %r20, _C_LABEL(cpu_hatch_data)@l
     24  1.1  matt 
     25  1.1  matt 	lwz	%r21, HATCH_CI(%r20)		/* get cpu_info */
     26  1.1  matt 	mtsprg0	%r21				/* save cpu_info */
     27  1.1  matt 	lwz	%r1, HATCH_SP(%r20)		/* get hatch SP */
     28  1.1  matt 
     29  1.1  matt 	/*
     30  1.1  matt 	 * We have to setup the IVOR SPRs since the ones u-boot setup
     31  1.1  matt 	 * don't work for us.
     32  1.1  matt 	 */
     33  1.1  matt 	bl	_C_LABEL(exception_init)	/* setup IVORs */
     34  1.1  matt 
     35  1.1  matt 	/*
     36  1.1  matt 	 * U-boot has mapped the bottom 64MB in TLB1[0].  We are going to need
     37  1.1  matt 	 * change this entry and it's not safe to do so while running out of it.
     38  1.1  matt 	 * So we copy TLB1[0] to TLB1[1] but set it for AS1.  We then switch
     39  1.1  matt 	 * to AS1 and reload TLB1[0] with its correct value, and we switch
     40  1.1  matt 	 * back to AS0.  Then we can load the rest of the TLB1 entries.
     41  1.1  matt 	 */
     42  1.1  matt 
     43  1.1  matt 	/*
     44  1.1  matt 	 * Fetch TLB1[0]
     45  1.1  matt 	 */
     46  1.1  matt 	lis	%r16, (MASX_TLBSEL_MAKE(1)|MAS0_ESEL_MAKE(0))@h
     47  1.1  matt 	mtspr	SPR_MAS0, %r16
     48  1.1  matt 	tlbre
     49  1.1  matt 
     50  1.1  matt 	/*
     51  1.1  matt 	 * Copy TLB1[0] to TLB[1] and set it to use AS1
     52  1.1  matt 	 */
     53  1.1  matt 	mfspr	%r3, SPR_MAS0
     54  1.1  matt 	addis	%r3, %r3, MAS0_ESEL@h		/* advance to next TLB entry */
     55  1.1  matt 	mtspr	SPR_MAS0, %r3			/* place into SPR */
     56  1.1  matt 	mfspr	%r4, SPR_MAS1
     57  1.1  matt 	ori	%r4, %r4, MAS1_TS@l		/* Make it use AS1 */
     58  1.1  matt 	mtspr	SPR_MAS1, %r4
     59  1.1  matt 	tlbwe					/* write the TLB entry */
     60  1.1  matt 
     61  1.1  matt 	/*
     62  1.1  matt 	 * Let's find out what TLB1[0] entry we are supposed to use.
     63  1.1  matt 	 */
     64  1.1  matt 	li	%r3, 0
     65  1.1  matt 	bl	_C_LABEL(e500_tlb1_fetch)
     66  1.1  matt 	lwz	%r28, 0(%r3)			/* load the saved TLB1 entry */
     67  1.1  matt 	mtspr	SPR_MAS0, %r28			/* place into SPRs */
     68  1.1  matt 	mtspr	SPR_MAS1, %r29
     69  1.1  matt 	mtspr	SPR_MAS2, %r30
     70  1.1  matt 	mtspr	SPR_MAS3, %r31
     71  1.1  matt 
     72  1.1  matt 	/*
     73  1.1  matt 	 * Now to switch to running in AS1
     74  1.1  matt 	 */
     75  1.1  matt 	mfmsr	%r3
     76  1.1  matt 	ori	%r4,%r3,(PSL_DS|PSL_IS)@l
     77  1.1  matt 	mtsrr1	%r4
     78  1.1  matt 
     79  1.1  matt 	bl	1f
     80  1.1  matt 1:	mflr	%r11
     81  1.1  matt 	addi	%r4,%r11,.Las1start-1b
     82  1.1  matt 	addi	%r5,%r11,.Las1end-1b
     83  1.1  matt 	mtsrr0	%r4
     84  1.1  matt 	rfi			/* switch to AS1, context synchronizing */
     85  1.1  matt 
     86  1.1  matt .Las1start:
     87  1.1  matt 	/*
     88  1.1  matt 	 * We are now running in AS1, update TLB1[0]
     89  1.1  matt 	 */
     90  1.1  matt 	tlbwe
     91  1.1  matt 
     92  1.1  matt 	mtsrr0	%r5
     93  1.1  matt 	mtsrr1	%r3
     94  1.1  matt 	rfi			/* switch back to AS0, context synchronizing */
     95  1.1  matt 
     96  1.1  matt .Las1end:
     97  1.1  matt 	/*
     98  1.1  matt 	 * We now have our TLB1[0] in place.  Now we need to load the rest of
     99  1.1  matt 	 * TLB1 with our entries.  After this is done, we should have access
    100  1.1  matt 	 * to everything.
    101  1.1  matt 	 */
    102  1.1  matt 	bl	_C_LABEL(e500_tlb1_sync)
    103  1.1  matt 
    104  1.1  matt 	/*
    105  1.1  matt 	 * We've gotten the low level stuff done.
    106  1.1  matt 	 * Now to do more advanced stuff.
    107  1.1  matt 	 */
    108  1.1  matt 	bl	_C_LABEL(cpu_hatch)
    109  1.1  matt 	mr	%r1, %r3			/* our new SP */
    110  1.1  matt 
    111  1.1  matt 	wrteei	1				/* allow interrupts */
    112  1.1  matt 
    113  1.1  matt 	b	_C_LABEL(idle_loop)
    114