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