Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Aug 2015 02:41:36 +0000 (UTC)
From:      Justin Hibbits <jhibbits@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r286977 - head/sys/powerpc/booke
Message-ID:  <201508210241.t7L2faCC099729@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhibbits
Date: Fri Aug 21 02:41:35 2015
New Revision: 286977
URL: https://svnweb.freebsd.org/changeset/base/286977

Log:
  Add initial boot support for e500mc and e5500.
  
  * Since r257190 the kernel must actually be loaded at a 64MB boundary, not 16MB.
  * Don't program HID1 register on e500mc or e5500, they don't have this SPR.
  * Set proper HID0 defaults for these new architectures.
  
  There is still more work to be done for the various SoCs, and the PMAP code
  still needs to be extended to 36-bit paddr, coming soon.
  
  Obtained from:	Semihalf
  Sponsored by:	Alex Perez/Inertial Computing

Modified:
  head/sys/powerpc/booke/locore.S

Modified: head/sys/powerpc/booke/locore.S
==============================================================================
--- head/sys/powerpc/booke/locore.S	Fri Aug 21 02:22:51 2015	(r286976)
+++ head/sys/powerpc/booke/locore.S	Fri Aug 21 02:41:35 2015	(r286977)
@@ -61,11 +61,11 @@ __start:
 
 /*
  * Assumptions on the boot loader:
- *  - system memory starts from physical address 0
- *  - it's mapped by a single TBL1 entry
+ *  - System memory starts from physical address 0
+ *  - It's mapped by a single TLB1 entry
  *  - TLB1 mapping is 1:1 pa to va
- *  - kernel is loaded at 16MB boundary
- *  - all PID registers are set to the same value
+ *  - Kernel is loaded at 64MB boundary
+ *  - All PID registers are set to the same value
  *  - CPU is running in AS=0
  *
  * Registers contents provided by the loader(8):
@@ -73,14 +73,14 @@ __start:
  *	r3	: metadata pointer
  *
  * We rearrange the TLB1 layout as follows:
- *  - find TLB1 entry we started in
- *  - make sure it's protected, ivalidate other entries
- *  - create temp entry in the second AS (make sure it's not TLB[1])
- *  - switch to temp mapping
- *  - map 16MB of RAM in TLB1[1]
- *  - use AS=1, set EPN to KERNBASE and RPN to kernel load address
- *  - switch to to TLB1[1] mapping
- *  - invalidate temp mapping
+ *  - Find TLB1 entry we started in
+ *  - Make sure it's protected, invalidate other entries
+ *  - Create temp entry in the second AS (make sure it's not TLB[1])
+ *  - Switch to temp mapping
+ *  - Map 64MB of RAM in TLB1[1]
+ *  - Use AS=1, set EPN to KERNBASE and RPN to kernel load address
+ *  - Switch to to TLB1[1] mapping
+ *  - Invalidate temp mapping
  *
  * locore registers use:
  *	r1	: stack pointer
@@ -104,15 +104,44 @@ __start:
 	mtmsr	%r3
 	isync
 
-	lis	%r3, HID0_E500_DEFAULT_SET@h
-	ori	%r3, %r3, HID0_E500_DEFAULT_SET@l
-	mtspr	SPR_HID0, %r3
+	mfpvr	%r3
+	rlwinm	%r3, %r3, 16, 16, 31
+
+	lis	%r4, HID0_E500_DEFAULT_SET@h
+	ori	%r4, %r4, HID0_E500_DEFAULT_SET@l
+
+	/* Check for e500mc and e5500 */
+	cmpli	0, 0, %r3, FSL_E500mc
+	bne	2f
+
+	lis	%r4, HID0_E500MC_DEFAULT_SET@h
+	ori	%r4, %r4, HID0_E500MC_DEFAULT_SET@l
+	b	3f
+2:
+	cmpli	0, 0, %r3, FSL_E5500
+	bne	3f
+
+	lis	%r4, HID0_E5500_DEFAULT_SET@h
+	ori	%r4, %r4, HID0_E5500_DEFAULT_SET@l
+
+3:
+	mtspr	SPR_HID0, %r4
 	isync
+
+/*
+ * E500mc and E5500 do not have HID1 register, so skip HID1 setup on
+ * this core.
+ */
+	cmpli	0, 0, %r3, FSL_E500mc
+	beq	1f
+	cmpli	0, 0, %r3, FSL_E5500
+	beq	1f
+
 	lis	%r3, HID1_E500_DEFAULT_SET@h
 	ori	%r3, %r3, HID1_E500_DEFAULT_SET@l
 	mtspr	SPR_HID1, %r3
 	isync
-
+1:
 	/* Invalidate all entries in TLB0 */
 	li	%r3, 0
 	bl	tlb_inval_all
@@ -153,10 +182,10 @@ __start:
 /*
  * Setup final mapping in TLB1[1] and switch to it
  */
-	/* Final kernel mapping, map in 16 MB of RAM */
+	/* Final kernel mapping, map in 64 MB of RAM */
 	lis	%r3, MAS0_TLBSEL1@h	/* Select TLB1 */
 	li	%r4, 0			/* Entry 0 */
-	rlwimi	%r3, %r4, 16, 12, 15
+	rlwimi	%r3, %r4, 16, 10, 15
 	mtspr	SPR_MAS0, %r3
 	isync
 
@@ -176,10 +205,12 @@ __start:
 	/* Discover phys load address */
 	bl	3f
 3:	mflr	%r4			/* Use current address */
-	rlwinm	%r4, %r4, 0, 0, 7	/* 16MB alignment mask */
+	rlwinm	%r4, %r4, 0, 0, 5	/* 64MB alignment mask */
 	ori	%r4, %r4, (MAS3_SX | MAS3_SW | MAS3_SR)@l
 	mtspr	SPR_MAS3, %r4		/* Set RPN and protection */
 	isync
+	bl	zero_mas7
+	bl	zero_mas8
 	tlbwe
 	isync
 	msync
@@ -281,15 +312,40 @@ bp_tlb1_end:
 1:	mflr	%r31		/* r31 hold the address of bp_ntlb1s */
 
 	/* Set HIDs */
-	lis	%r3, HID0_E500_DEFAULT_SET@h
-	ori	%r3, %r3, HID0_E500_DEFAULT_SET@l
-	mtspr	SPR_HID0, %r3
-	isync
+	mfpvr	%r3
+	rlwinm	%r3, %r3, 16, 16, 31
+
+	/* HID0 for E500 is default */
+	lis	%r4, HID0_E500_DEFAULT_SET@h
+	ori	%r4, %r4, HID0_E500_DEFAULT_SET@l
+
+	cmpli	0, 0, %r3, FSL_E500mc
+	bne	2f
+	lis	%r4, HID0_E500MC_DEFAULT_SET@h
+	ori	%r4, %r4, HID0_E500MC_DEFAULT_SET@l
+	b	3f
+2:
+	cmpli	0, 0, %r3, FSL_E5500
+	bne	3f
+	lis	%r4, HID0_E5500_DEFAULT_SET@h
+	ori	%r4, %r4, HID0_E5500_DEFAULT_SET@l
+3:
+	mtspr	SPR_HID0, %r4
+	isync
+/*
+ * E500mc and E5500 do not have HID1 register, so skip HID1 setup on
+ * this core.
+ */
+	cmpli	0, 0, %r3, FSL_E500mc
+	beq	1f
+	cmpli	0, 0, %r3, FSL_E5500
+	beq	1f
+
 	lis	%r3, HID1_E500_DEFAULT_SET@h
 	ori	%r3, %r3, HID1_E500_DEFAULT_SET@l
 	mtspr	SPR_HID1, %r3
 	isync
-
+1:
 	/* Enable branch prediction */
 	li	%r3, BUCSR_BPEN
 	mtspr	SPR_BUCSR, %r3
@@ -429,8 +485,8 @@ bp_tlb1_end:
  * r3	TLBSEL
  */
 tlb_inval_all:
-	rlwinm	%r3, %r3, 3, 0x18	/* TLBSEL */
-	ori	%r3, %r3, 0x4		/* INVALL */
+	rlwinm	%r3, %r3, 3, (1 << 3)	/* TLBSEL */
+	ori	%r3, %r3, (1 << 2)	/* INVALL */
 	tlbivax	0, %r3
 	isync
 	msync
@@ -472,7 +528,7 @@ tlb1_find_current:
  */
 tlb1_inval_entry:
 	lis	%r4, MAS0_TLBSEL1@h	/* Select TLB1 */
-	rlwimi	%r4, %r3, 16, 12, 15	/* Select our entry */
+	rlwimi	%r4, %r3, 16, 10, 15	/* Select our entry */
 	mtspr	SPR_MAS0, %r4
 	isync
 	tlbre
@@ -495,14 +551,14 @@ tlb1_temp_mapping_as1:
 
 	/* Read our current translation */
 	lis	%r3, MAS0_TLBSEL1@h	/* Select TLB1 */
-	rlwimi	%r3, %r29, 16, 12, 15	/* Select our current entry */
+	rlwimi	%r3, %r29, 16, 10, 15	/* Select our current entry */
 	mtspr	SPR_MAS0, %r3
 	isync
 	tlbre
 
 	/* Prepare and write temp entry */
 	lis	%r3, MAS0_TLBSEL1@h	/* Select TLB1 */
-	rlwimi	%r3, %r28, 16, 12, 15	/* Select temp entry */
+	rlwimi	%r3, %r28, 16, 10, 15	/* Select temp entry */
 	mtspr	SPR_MAS0, %r3
 	isync
 	mfspr	%r5, SPR_MAS1
@@ -513,6 +569,10 @@ tlb1_temp_mapping_as1:
 	oris	%r5, %r5, (MAS1_VALID | MAS1_IPROT)@h
 	mtspr	SPR_MAS1, %r5
 	isync
+	mflr	%r3
+	bl	zero_mas7
+	bl	zero_mas8
+	mtlr	%r3
 	tlbwe
 	isync
 	msync
@@ -531,7 +591,7 @@ tlb1_inval_all_but_current:
 	andi.	%r3, %r3, TLBCFG_NENTRY_MASK@l
 	li	%r4, 0			/* Start from Entry 0 */
 1:	lis	%r5, MAS0_TLBSEL1@h
-	rlwimi	%r5, %r4, 16, 12, 15
+	rlwimi	%r5, %r4, 16, 10, 15
 	mtspr	SPR_MAS0, %r5
 	isync
 	tlbre
@@ -549,6 +609,38 @@ tlb1_inval_all_but_current:
 	bne	1b
 	blr
 
+/*
+ * MAS7 and MAS8 conditional zeroing.
+ */
+.globl zero_mas7
+zero_mas7:
+	mfpvr	%r20
+	rlwinm	%r20, %r20, 16, 16, 31
+	cmpli	0, 0, %r20, FSL_E500v1
+	beq	1f
+
+	li	%r20, 0
+	mtspr	SPR_MAS7, %r20
+	isync
+1:
+	blr
+
+.globl zero_mas8
+zero_mas8:
+	mfpvr	%r20
+	rlwinm	%r20, %r20, 16, 16, 31
+	cmpli	0, 0, %r20, FSL_E500mc
+	beq	1f
+	cmpli	0, 0, %r20, FSL_E5500
+	beq	1f
+
+	blr
+1:
+	li	%r20, 0
+	mtspr	SPR_MAS8, %r20
+	isync
+	blr
+
 #ifdef SMP
 __boot_page_padding:
 	/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508210241.t7L2faCC099729>