[U-Boot] [PATCH 6/6] powerpc/mpc8xxx: fix core id for multicore booting
York Sun
yorksun at freescale.com
Fri Aug 17 20:20:26 CEST 2012
For the cores with multiple threads, we need to figure out which physical
core a thread belongs. To match the core ids, update PIR registers and
spin tables.
Signed-off-by: York Sun <yorksun at freescale.com>
Signed-off-by: Kumar Gala <galak at kernel.crashing.org>
---
arch/powerpc/cpu/mpc85xx/fdt.c | 5 ++-
arch/powerpc/cpu/mpc85xx/release.S | 45 +++++++++++++++++++++++++++++++++--
arch/powerpc/cpu/mpc8xxx/fdt.c | 3 +-
arch/powerpc/include/asm/mp.h | 6 ++++
4 files changed, 53 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c
index 21c3ad4..40df01c 100644
--- a/arch/powerpc/cpu/mpc85xx/fdt.c
+++ b/arch/powerpc/cpu/mpc85xx/fdt.c
@@ -57,8 +57,9 @@ void ft_fixup_cpu(void *blob, u64 memory_limit)
u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0);
if (reg) {
- u64 val = *reg * SIZE_BOOT_ENTRY + spin_tbl_addr;
- val = cpu_to_fdt32(val);
+ u32 phys_cpu_id = thread_to_core(*reg);
+ u64 val = phys_cpu_id * SIZE_BOOT_ENTRY + spin_tbl_addr;
+ val = cpu_to_fdt64(val);
if (*reg == id) {
fdt_setprop_string(blob, off, "status",
"okay");
diff --git a/arch/powerpc/cpu/mpc85xx/release.S b/arch/powerpc/cpu/mpc85xx/release.S
index 043d0ff..22e73e0 100644
--- a/arch/powerpc/cpu/mpc85xx/release.S
+++ b/arch/powerpc/cpu/mpc85xx/release.S
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ * Copyright 2008-2012 Freescale Semiconductor, Inc.
* Kumar Gala <kumar.gala at freescale.com>
*
* See file CREDITS for list of people who contributed to this
@@ -155,7 +155,27 @@ __secondary_start_page:
/* r10 has the base address for the entry */
mfspr r0,SPRN_PIR
-#ifdef CONFIG_E500MC
+#if defined(CONFIG_E6500)
+/*
+ * PIR definition for E6500
+ * 0-17 Reserved (logic 0s)
+ * 8-19 CHIP_ID, 2âb00 - SoC 1
+ * all others - reserved
+ * 20-24 CLUSTER_ID 5âb00000 - CCM 1
+ * all others - reserved
+ * 25-26 CORE_CLUSTER_ID 2âb00 - cluster 1
+ * 2âb01 - cluster 2
+ * 2âb10 - cluster 3
+ * 2âb11 - cluster 4
+ * 27-28 CORE_ID 2âb00 - core 0
+ * 2âb01 - core 1
+ * 2âb10 - core 2
+ * 2âb11 - core 3
+ * 29-31 THREAD_ID 3âb000 - thread 0
+ * 3âb001 - thread 1
+ */
+ rlwinm r4,r0,29,25,31
+#elif defined(CONFIG_E500MC)
rlwinm r4,r0,27,27,31
#else
mr r4,r0
@@ -170,6 +190,25 @@ __secondary_start_page:
mtspr L1CSR2,r8
#endif
+#ifdef CONFIG_E6500
+ mfspr r0,SPRN_PIR
+ /*
+ * core 0 thread 0: pir reset value 0x00, new pir 0
+ * core 0 thread 1: pir reset value 0x01, new pir 1
+ * core 1 thread 0: pir reset value 0x08, new pir 2
+ * core 1 thread 1: pir reset value 0x09, new pir 3
+ * core 2 thread 0: pir reset value 0x10, new pir 4
+ * core 2 thread 1: pir reset value 0x11, new pir 5
+ * etc.
+ *
+ * Only thread 0 of each core will be running, updating PIR doesn't
+ * need to deal with the thread bits.
+ */
+ rlwinm r4,r0,30,24,30
+#endif
+
+ mtspr SPRN_PIR,r4 /* write to PIR register */
+
#if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) || \
defined(CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011)
/*
@@ -253,7 +292,7 @@ __secondary_start_page:
/* setup the entry */
li r3,0
li r8,1
- stw r0,ENTRY_PIR(r10)
+ stw r4,ENTRY_PIR(r10)
stw r3,ENTRY_ADDR_UPPER(r10)
stw r8,ENTRY_ADDR_LOWER(r10)
stw r3,ENTRY_R3_UPPER(r10)
diff --git a/arch/powerpc/cpu/mpc8xxx/fdt.c b/arch/powerpc/cpu/mpc8xxx/fdt.c
index 09810be..32ab050 100644
--- a/arch/powerpc/cpu/mpc8xxx/fdt.c
+++ b/arch/powerpc/cpu/mpc8xxx/fdt.c
@@ -62,8 +62,9 @@ void ft_fixup_num_cores(void *blob) {
off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
while (off != -FDT_ERR_NOTFOUND) {
u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0);
+ u32 phys_cpu_id = thread_to_core(*reg);
- if (!is_core_valid(*reg) || is_core_disabled(*reg)) {
+ if (!is_core_valid(phys_cpu_id) || is_core_disabled(phys_cpu_id)) {
int ph = fdt_get_phandle(blob, off);
/* Delete the cpu node once there are no cpu handles */
diff --git a/arch/powerpc/include/asm/mp.h b/arch/powerpc/include/asm/mp.h
index 3ffa30b..fe490ba 100644
--- a/arch/powerpc/include/asm/mp.h
+++ b/arch/powerpc/include/asm/mp.h
@@ -28,4 +28,10 @@ void cpu_mp_lmb_reserve(struct lmb *lmb);
u32 determine_mp_bootpg(void);
int is_core_disabled(int nr);
+#ifdef CONFIG_E6500
+#define thread_to_core(x) (x >> 1)
+#else
+#define thread_to_core(x) (x)
+#endif
+
#endif
--
1.7.0.4
More information about the U-Boot
mailing list