85xx: Update multicore boot mechanism to ePAPR v0.81 spec
authorKumar Gala <galak@kernel.crashing.org>
Wed, 26 Mar 2008 13:34:25 +0000 (08:34 -0500)
committerAndrew Fleming-AFLEMING <afleming@freescale.com>
Wed, 26 Mar 2008 16:43:04 +0000 (11:43 -0500)
The following changes are needed to be inline with ePAPR v0.81:

* r4, r5 and now always set to 0 on boot release
* r7 is used to pass the size of the initial map area (IMA)
* EPAPR_MAGIC value changed for book-e processors
* changes in the spin table layout
* spin table supports a 64-bit physical release address

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
common/cmd_mp.c
cpu/mpc85xx/fdt.c
cpu/mpc85xx/mp.c
cpu/mpc85xx/mp.h
cpu/mpc85xx/release.S
include/common.h

index d96e6a302d49d7bbb3b9f030728f0b796a0b74f9..26a57c5e96c7ae00d8cad546710f0e409d1dbdf6 100644 (file)
@@ -26,7 +26,7 @@
 int
 cpu_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
-       unsigned long cpuid, val = 0;
+       unsigned long cpuid;
 
        if (argc < 3) {
                printf ("Usage:\n%s\n", cmdtp->usage);
@@ -59,9 +59,7 @@ cpu_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                return 1;
        }
 
-       val = simple_strtoul(argv[3], NULL, 16);
-
-       if (cpu_release(cpuid, val, argc - 4, argv + 4)) {
+       if (cpu_release(cpuid, argc - 3, argv + 3)) {
                printf ("Usage:\n%s\n", cmdtp->usage);
                return 1;
        }
@@ -71,17 +69,16 @@ cpu_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 
 #ifdef CONFIG_PPC
 #define CPU_ARCH_HELP \
-       "                         [args] : <pir> <r3> <r4> <r6> <r7>\n" \
+       "                         [args] : <pir> <r3> <r6>\n" \
        "                                   pir - processor id (if writeable)\n" \
        "                                    r3 - value for gpr 3\n" \
-       "                                    r4 - value for gpr 4\n" \
        "                                    r6 - value for gpr 6\n" \
-       "                                    r7 - value for gpr 7\n" \
        "\n" \
        "     Use '-' for any arg if you want the default value.\n" \
-       "     Default for r3, r4, r7 is 0, r6 is 0x65504150\n" \
+       "     Default for r3 is <num> and r6 is 0\n" \
        "\n" \
-       "     When cpu <num> is released r5 = 0 per the ePAPR spec.\n"
+       "     When cpu <num> is released r4 and r5 = 0.\n" \
+       "     r7 will contain the size of the initial mapped area\n"
 #endif
 
 U_BOOT_CMD(
index 43df1c70b2b282958bab41c49fe34e7d6eb1f9b1..bde6d1e9630a876a5141f54748e3b48825771f2d 100644 (file)
@@ -52,7 +52,7 @@ void ft_fixup_cpu(void *blob, u64 memory_limit)
                        if (*reg == id) {
                                fdt_setprop_string(blob, off, "status", "okay");
                        } else {
-                               u32 val = *reg * 24 + spin_tbl_addr;
+                               u32 val = *reg * SIZE_BOOT_ENTRY + spin_tbl_addr;
                                val = cpu_to_fdt32(val);
                                fdt_setprop_string(blob, off, "status",
                                                                "disabled");
index aa91cea170b81a5c9654813379c22c8c4140b0ef..d3727b0b2c03f2c5ab8819a944b5a0d1d4f8747f 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define BOOT_ENTRY_ADDR        0
-#define BOOT_ENTRY_PIR 1
-#define BOOT_ENTRY_R3  2
-#define BOOT_ENTRY_R4  3
-#define BOOT_ENTRY_R6  4
-#define BOOT_ENTRY_R7  5
-#define NUM_BOOT_ENTRY 6
-
 u32 get_my_id()
 {
        return mfspr(SPRN_PIR);
@@ -63,40 +55,54 @@ int cpu_status(int nr)
                printf("Running on cpu %d\n", id);
                printf("\n");
                printf("table @ 0x%08x:\n", table);
-               printf("   addr - 0x%08x\n", table[BOOT_ENTRY_ADDR]);
+               printf("   addr - 0x%08x\n", table[BOOT_ENTRY_ADDR_LOWER]);
                printf("   pir  - 0x%08x\n", table[BOOT_ENTRY_PIR]);
-               printf("   r3   - 0x%08x\n", table[BOOT_ENTRY_R3]);
-               printf("   r4   - 0x%08x\n", table[BOOT_ENTRY_R4]);
-               printf("   r6   - 0x%08x\n", table[BOOT_ENTRY_R6]);
-               printf("   r7   - 0x%08x\n", table[BOOT_ENTRY_R7]);
+               printf("   r3   - 0x%08x\n", table[BOOT_ENTRY_R3_LOWER]);
+               printf("   r6   - 0x%08x\n", table[BOOT_ENTRY_R6_LOWER]);
        }
 
        return 0;
 }
 
-int cpu_release(int nr, unsigned long boot_addr, int argc, char *argv[])
+static u8 boot_entry_map[4] = {
+       0,
+       BOOT_ENTRY_PIR,
+       BOOT_ENTRY_R3_LOWER,
+       BOOT_ENTRY_R6_LOWER,
+};
+
+int cpu_release(int nr, int argc, char *argv[])
 {
        u32 i, val, *table = (u32 *)get_spin_addr() + nr * NUM_BOOT_ENTRY;
+       u64 boot_addr;
 
        if (nr == get_my_id()) {
                printf("Invalid to release the boot core.\n\n");
                return 1;
        }
 
-       if (argc != 5) {
+       if (argc != 4) {
                printf("Invalid number of arguments to release.\n\n");
                return 1;
        }
 
-       /* handle pir, r3, r4, r6, r7 */
-       for (i = 0; i < 5; i++) {
+#ifdef CFG_64BIT_STRTOUL
+       boot_addr = simple_strtoull(argv[0], NULL, 16);
+#else
+       boot_addr = simple_strtoul(argv[0], NULL, 16);
+#endif
+
+       /* handle pir, r3, r6 */
+       for (i = 1; i < 4; i++) {
                if (argv[i][0] != '-') {
+                       u8 entry = boot_entry_map[i];
                        val = simple_strtoul(argv[i], NULL, 16);
-                       table[i+BOOT_ENTRY_PIR] = val;
+                       table[entry] = val;
                }
        }
 
-       table[BOOT_ENTRY_ADDR] = boot_addr;
+       table[BOOT_ENTRY_ADDR_UPPER] = (u32)(boot_addr >> 32);
+       table[BOOT_ENTRY_ADDR_LOWER] = (u32)(boot_addr & 0xffffffff);
 
        return 0;
 }
index d9fbb825e5dc4f216e56a1311dc060d35fef6ac7..b762ee2d76cc27c0672403935a61c41188212025 100644 (file)
@@ -5,4 +5,15 @@ ulong get_spin_addr(void);
 void setup_mp(void);
 u32 get_my_id(void);
 
+#define BOOT_ENTRY_ADDR_UPPER  0
+#define BOOT_ENTRY_ADDR_LOWER  1
+#define BOOT_ENTRY_R3_UPPER    2
+#define BOOT_ENTRY_R3_LOWER    3
+#define BOOT_ENTRY_RESV                4
+#define BOOT_ENTRY_PIR         5
+#define BOOT_ENTRY_R6_UPPER    6
+#define BOOT_ENTRY_R6_LOWER    7
+#define NUM_BOOT_ENTRY         8
+#define SIZE_BOOT_ENTRY                (NUM_BOOT_ENTRY * sizeof(u32))
+
 #endif
index fe1775cdc881d3e7f6a8852651e4d74c80326ebb..3b7366ff692c1dbbddd36ac1e3b4382a114bb0f6 100644 (file)
@@ -57,61 +57,91 @@ __secondary_start_page:
        lis     r3,toreset(__spin_table)@h
        ori     r3,r3,toreset(__spin_table)@l
 
-       /* r9 has the base address for the entry */
+       /* r10 has the base address for the entry */
        mfspr   r0,SPRN_PIR
        mr      r4,r0
-       slwi    r8,r4,4
-       slwi    r9,r4,3
-       add     r8,r8,r9
-       add     r9,r3,r8
-
-#define EPAPR_MAGIC    (0x65504150)
-#define ENTRY_ADDR     0
-#define ENTRY_PIR      4
-#define ENTRY_R3       8
-#define ENTRY_R4       12
-#define ENTRY_R6       16
-#define ENTRY_R7       20
+       slwi    r8,r4,5
+       add     r10,r3,r8
+
+#define EPAPR_MAGIC            (0x45504150)
+#define ENTRY_ADDR_UPPER       0
+#define ENTRY_ADDR_LOWER       4
+#define ENTRY_R3_UPPER         8
+#define ENTRY_R3_LOWER         12
+#define ENTRY_RESV             16
+#define ENTRY_PIR              20
+#define ENTRY_R6_UPPER         24
+#define ENTRY_R6_LOWER         28
+#define ENTRY_SIZE             32
 
        /* setup the entry */
-       li      r4,0
+       li      r3,0
        li      r8,1
-       lis     r6,EPAPR_MAGIC@h
-       ori     r6,r6,EPAPR_MAGIC@l
-       stw     r0,ENTRY_PIR(r9)
-       stw     r8,ENTRY_ADDR(r9)
-       stw     r4,ENTRY_R3(r9)
-       stw     r4,ENTRY_R4(r9)
-       stw     r6,ENTRY_R6(r9)
-       stw     r4,ENTRY_R7(r9)
+       stw     r0,ENTRY_PIR(r10)
+       stw     r3,ENTRY_ADDR_UPPER(r10)
+       stw     r8,ENTRY_ADDR_LOWER(r10)
+       stw     r3,ENTRY_R3_UPPER(r10)
+       stw     r4,ENTRY_R3_LOWER(r10)
+       stw     r3,ENTRY_R6_UPPER(r10)
+       stw     r3,ENTRY_R6_LOWER(r10)
+
+       /* setup mapping for AS = 1, and jump there */
+       lis     r11,(MAS0_TLBSEL(1)|MAS0_ESEL(1))@h
+       mtspr   SPRN_MAS0,r11
+       lis     r11,(MAS1_VALID|MAS1_IPROT)@h
+       ori     r11,r11,(MAS1_TS|MAS1_TSIZE(BOOKE_PAGESZ_4K))@l
+       mtspr   SPRN_MAS1,r11
+       lis     r11,(0xfffff000|MAS2_I)@h
+       ori     r11,r11,(0xfffff000|MAS2_I)@l
+       mtspr   SPRN_MAS2,r11
+       lis     r11,(0xfffff000|MAS3_SX|MAS3_SW|MAS3_SR)@h
+       ori     r11,r11,(0xfffff000|MAS3_SX|MAS3_SW|MAS3_SR)@l
+       mtspr   SPRN_MAS3,r11
+       tlbwe
+
+       bl      1f
+1:     mflr    r11
+       addi    r11,r11,28
+       mfmsr   r13
+       ori     r12,r13,MSR_IS|MSR_DS@l
+
+       mtspr   SPRN_SRR0,r11
+       mtspr   SPRN_SRR1,r12
+       rfi
 
        /* spin waiting for addr */
-1:     lwz     r4,ENTRY_ADDR(r9)
+2:
+       lwz     r4,ENTRY_ADDR_LOWER(r10)
        andi.   r11,r4,1
-       bne     1b
+       bne     2b
+
+       /* get the upper bits of the addr */
+       lwz     r11,ENTRY_ADDR_UPPER(r10)
 
        /* setup branch addr */
-       mtctr   r4
+       mtspr   SPRN_SRR0,r4
 
        /* mark the entry as released */
        li      r8,3
-       stw     r8,ENTRY_ADDR(r9)
+       stw     r8,ENTRY_ADDR_LOWER(r10)
 
        /* mask by ~64M to setup our tlb we will jump to */
-       rlwinm  r8,r4,0,0,5
+       rlwinm  r12,r4,0,0,5
 
-       /* setup r3, r5, r6, r7 */
-       lwz     r3,ENTRY_R3(r9)
-       lwz     r4,ENTRY_R4(r9)
+       /* setup r3, r4, r5, r6, r7, r8, r9 */
+       lwz     r3,ENTRY_R3_LOWER(r10)
+       li      r4,0
        li      r5,0
-       lwz     r6,ENTRY_R6(r9)
-       lwz     r7,ENTRY_R7(r9)
+       lwz     r6,ENTRY_R6_LOWER(r10)
+       lis     r7,(64*1024*1024)@h
+       li      r8,0
+       li      r9,0
 
        /* load up the pir */
-       lwz     r0,ENTRY_PIR(r9)
+       lwz     r0,ENTRY_PIR(r10)
        mtspr   SPRN_PIR,r0
        mfspr   r0,SPRN_PIR
-       stw     r0,ENTRY_PIR(r9)
+       stw     r0,ENTRY_PIR(r10)
 
 /*
  * Coming here, we know the cpu has one TLB mapping in TLB1[0]
@@ -119,26 +149,30 @@ __secondary_start_page:
  * second mapping that maps addr 1:1 for 64M, and then we jump to
  * addr
  */
-       lis     r9,(MAS0_TLBSEL(1)|MAS0_ESEL(1))@h
-       mtspr   SPRN_MAS0,r9
-       lis     r9,(MAS1_VALID|MAS1_IPROT)@h
-       ori     r9,r9,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l
-       mtspr   SPRN_MAS1,r9
+       lis     r10,(MAS0_TLBSEL(1)|MAS0_ESEL(0))@h
+       mtspr   SPRN_MAS0,r10
+       lis     r10,(MAS1_VALID|MAS1_IPROT)@h
+       ori     r10,r10,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l
+       mtspr   SPRN_MAS1,r10
        /* WIMGE = 0b00000 for now */
-       mtspr   SPRN_MAS2,r8
-       ori     r8,r8,(MAS3_SX|MAS3_SW|MAS3_SR)
-       mtspr   SPRN_MAS3,r8
+       mtspr   SPRN_MAS2,r12
+       ori     r12,r12,(MAS3_SX|MAS3_SW|MAS3_SR)
+       mtspr   SPRN_MAS3,r12
+#ifdef CONFIG_ENABLE_36BIT_PHYS
+       mtspr   SPRN_MAS7,r11
+#endif
        tlbwe
 
 /* Now we have another mapping for this page, so we jump to that
  * mapping
  */
-       bctr
+       mtspr   SPRN_SRR1,r13
+       rfi
 
        .align 3
        .globl __spin_table
 __spin_table:
-       .space CONFIG_NR_CPUS*24
+       .space CONFIG_NR_CPUS*ENTRY_SIZE
 
        /* Fill in the empty space.  The actual reset vector is
         * the last word of the page */
index f49607376aaad0520b53fe5a42a7ba5cf878ae14..39bcd307b58ab9d72df47b3be75b393d36798eaa 100644 (file)
@@ -673,7 +673,7 @@ void inline show_boot_progress (int val);
 #ifdef CONFIG_MP
 int cpu_status(int nr);
 int cpu_reset(int nr);
-int cpu_release(int nr, unsigned long boot_addr, int argc, char *argv[]);
+int cpu_release(int nr, int argc, char *argv[]);
 #endif
 
 #endif /* __COMMON_H_ */