[U-Boot] [PATCH] 85xx: Add support for not releasing secondary cores via 'mp_holdoff'

From: Aaron Sierra asierra@xes-inc.com
Some OSes require that secondary cores not be initialized when they are booted (eg VxWorks). By default when U-Boot is compiled with the CONFIG_MP option all secondary cores are brought out of reset and held in spinloops. Setting the "mp_holdoff" environment variable to a non-null value will cause U-Boot to leave secondary cores in their default state.
Signed-off-by: Aaron Sierra asierra@xes-inc.com Signed-off-by: Peter Tyser ptyser@xes-inc.com --- arch/powerpc/cpu/mpc85xx/mp.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c index 603baef..7ad5efb 100644 --- a/arch/powerpc/cpu/mpc85xx/mp.c +++ b/arch/powerpc/cpu/mpc85xx/mp.c @@ -51,6 +51,11 @@ int cpu_status(int nr) { u32 *table, id = get_my_id();
+ if (getenv("mp_holdoff")) { + printf("Secondary cores are disabled; mp_holdoff is set\n"); + return 0; + } + if (nr == id) { table = (u32 *)get_spin_virt_addr(); printf("table base @ 0x%p\n", table); @@ -133,6 +138,11 @@ int cpu_release(int nr, int argc, char * const argv[]) u32 i, val, *table = (u32 *)get_spin_virt_addr() + nr * NUM_BOOT_ENTRY; u64 boot_addr;
+ if (getenv("mp_holdoff")) { + printf("Secondary cores are disabled; mp_holdoff is set\n"); + return 0; + } + if (nr == get_my_id()) { printf("Invalid to release the boot core.\n\n"); return 1; @@ -353,6 +363,14 @@ void setup_mp(void) ulong fixup = (ulong)&__secondary_start_page; u32 bootpg = determine_mp_bootpg();
+ /* + * Some OSes expect the secondary cores to be held in reset when the OS + * boots. Use the optional 'mp_holdoff' environment variable to allow + * users to disable the bring up of secondary cores. + */ + if (getenv("mp_holdoff")) + return; + /* Store the bootpg's SDRAM address for use by secondary CPU cores */ __bootpg_addr = bootpg;

On Wed, 29 Sep 2010 13:44:07 -0500 Peter Tyser ptyser@xes-inc.com wrote:
From: Aaron Sierra asierra@xes-inc.com
Some OSes require that secondary cores not be initialized when they are booted (eg VxWorks). By default when U-Boot is compiled with the CONFIG_MP option all secondary cores are brought out of reset and held in spinloops. Setting the "mp_holdoff" environment variable to a non-null value will cause U-Boot to leave secondary cores in their default state.
Signed-off-by: Aaron Sierra asierra@xes-inc.com Signed-off-by: Peter Tyser ptyser@xes-inc.com
While this may not be relevant to VxWorks, we should update the device tree's enable-method if mp_holdoff is set.
-Scott

On Wed, 2010-09-29 at 14:22 -0500, Scott Wood wrote:
On Wed, 29 Sep 2010 13:44:07 -0500 Peter Tyser ptyser@xes-inc.com wrote:
From: Aaron Sierra asierra@xes-inc.com
Some OSes require that secondary cores not be initialized when they are booted (eg VxWorks). By default when U-Boot is compiled with the CONFIG_MP option all secondary cores are brought out of reset and held in spinloops. Setting the "mp_holdoff" environment variable to a non-null value will cause U-Boot to leave secondary cores in their default state.
Signed-off-by: Aaron Sierra asierra@xes-inc.com Signed-off-by: Peter Tyser ptyser@xes-inc.com
While this may not be relevant to VxWorks, we should update the device tree's enable-method if mp_holdoff is set.
I just looked at the ePAPR spec and it says valid values for enable-method are: - "spin-table" The CPU is enabled with the spin table method defined in the ePAPR.
- "[vendor],[method]" An implementation-dependent string that describes the method by which a CPU is released from a "disabled" state. The required format is: vendor,method,. where vendor is a string describing the name of the manufacturer and method is a string describing the vendor-specific mechanism. Example: "fsl,MPC8572DS"
Note: Other methods may be added to later revisions of the ePAPR specification.
Any preference on what enable-method should be set to? "fsl,holdoff"? I'll also delete the "cpu-release-addr" node when mp_holdoff is set.
Regards, Peter

On Wed, 29 Sep 2010 14:50:17 -0500 Peter Tyser ptyser@xes-inc.com wrote:
On Wed, 2010-09-29 at 14:22 -0500, Scott Wood wrote:
On Wed, 29 Sep 2010 13:44:07 -0500 Peter Tyser ptyser@xes-inc.com wrote:
From: Aaron Sierra asierra@xes-inc.com
Some OSes require that secondary cores not be initialized when they are booted (eg VxWorks). By default when U-Boot is compiled with the CONFIG_MP option all secondary cores are brought out of reset and held in spinloops. Setting the "mp_holdoff" environment variable to a non-null value will cause U-Boot to leave secondary cores in their default state.
Signed-off-by: Aaron Sierra asierra@xes-inc.com Signed-off-by: Peter Tyser ptyser@xes-inc.com
While this may not be relevant to VxWorks, we should update the device tree's enable-method if mp_holdoff is set.
I just looked at the ePAPR spec and it says valid values for enable-method are:
- "spin-table" The CPU is enabled with the spin table method defined in
the ePAPR.
- "[vendor],[method]" An implementation-dependent string
that describes the method by which a CPU is released from a "disabled" state. The required format is: vendor,method,. where vendor is a string describing the name of the manufacturer and method is a string describing the vendor-specific mechanism. Example: "fsl,MPC8572DS"
Note: Other methods may be added to later revisions of the ePAPR specification.
Any preference on what enable-method should be set to? "fsl,holdoff"?
Possibly fsl,eebpcr-holdoff (8572, p1020, etc) or fsl,brr-holdoff (p4080, etc), depending on which register is present.
-Scott

From: Aaron Sierra asierra@xes-inc.com
Some OSes require that secondary cores not be initialized when they are booted (eg VxWorks). By default when U-Boot is compiled with the CONFIG_MP option all secondary cores are brought out of reset and held in spinloops. Setting the "mp_holdoff" environment variable to 'yes' or '1' will cause U-Boot to leave secondary cores in their default state.
Signed-off-by: Aaron Sierra asierra@xes-inc.com Signed-off-by: Peter Tyser ptyser@xes-inc.com --- Changes since v1: - Update 'enable-method' in dtb appropriately - Don't set cpu-release-addr if spin-table isn't used - Add hold_cores_in_reset() function with more intelligent mp_holdoff environment variable checking
arch/powerpc/cpu/mpc85xx/fdt.c | 22 +++++++++++++++++++--- arch/powerpc/cpu/mpc85xx/mp.c | 31 +++++++++++++++++++++++++++++++ arch/powerpc/cpu/mpc85xx/mp.h | 1 + 3 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index 4540364..dee6e9b 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -48,6 +48,7 @@ void ft_fixup_cpu(void *blob, u64 memory_limit) ulong spin_tbl_addr = get_spin_phys_addr(); u32 bootpg = determine_mp_bootpg(); u32 id = get_my_id(); + const char *enable_method;
off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4); while (off != -FDT_ERR_NOTFOUND) { @@ -63,10 +64,25 @@ void ft_fixup_cpu(void *blob, u64 memory_limit) fdt_setprop_string(blob, off, "status", "disabled"); } + + if (hold_cores_in_reset(0)) { +#ifdef CONFIG_FSL_CORENET + /* Cores held in reset, use BRR to release */ + enable_method = "fsl,brr-holdoff"; +#else + /* Cores held in reset, use EEBPCR to release */ + enable_method = "fsl,eebpcr"; +#endif + } else { + /* Cores out of reset and in a spin-loop */ + enable_method = "spin-table"; + + fdt_setprop(blob, off, "cpu-release-addr", + &val, sizeof(val)); + } + fdt_setprop_string(blob, off, "enable-method", - "spin-table"); - fdt_setprop(blob, off, "cpu-release-addr", - &val, sizeof(val)); + enable_method); } else { printf ("cpu NULL\n"); } diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c index 603baef..a019b1b 100644 --- a/arch/powerpc/cpu/mpc85xx/mp.c +++ b/arch/powerpc/cpu/mpc85xx/mp.c @@ -36,6 +36,27 @@ u32 get_my_id() return mfspr(SPRN_PIR); }
+/* + * Determine if U-Boot should keep secondary cores in reset, or let them out + * of reset and hold them in a spinloop + */ +int hold_cores_in_reset(int verbose) +{ + const char *s = getenv("mp_holdoff"); + + /* Default to no, overriden by 'y', 'yes', 'Y', 'Yes', or '1' */ + if (s && (*s == 'y' || *s == 'Y' || *s == '1')) { + if (verbose) { + puts("Secondary cores are being held in reset.\n"); + puts("See 'mp_holdoff' environment variable\n"); + } + + return 1; + } + + return 0; +} + int cpu_reset(int nr) { volatile ccsr_pic_t *pic = (void *)(CONFIG_SYS_MPC8xxx_PIC_ADDR); @@ -51,6 +72,9 @@ int cpu_status(int nr) { u32 *table, id = get_my_id();
+ if (hold_cores_in_reset(1)) + return 0; + if (nr == id) { table = (u32 *)get_spin_virt_addr(); printf("table base @ 0x%p\n", table); @@ -133,6 +157,9 @@ int cpu_release(int nr, int argc, char * const argv[]) u32 i, val, *table = (u32 *)get_spin_virt_addr() + nr * NUM_BOOT_ENTRY; u64 boot_addr;
+ if (hold_cores_in_reset(1)) + return 0; + if (nr == get_my_id()) { printf("Invalid to release the boot core.\n\n"); return 1; @@ -353,6 +380,10 @@ void setup_mp(void) ulong fixup = (ulong)&__secondary_start_page; u32 bootpg = determine_mp_bootpg();
+ /* Some OSes expect secondary cores to be held in reset */ + if (hold_cores_in_reset(0)) + return; + /* Store the bootpg's SDRAM address for use by secondary CPU cores */ __bootpg_addr = bootpg;
diff --git a/arch/powerpc/cpu/mpc85xx/mp.h b/arch/powerpc/cpu/mpc85xx/mp.h index 3422cc1..87bac37 100644 --- a/arch/powerpc/cpu/mpc85xx/mp.h +++ b/arch/powerpc/cpu/mpc85xx/mp.h @@ -6,6 +6,7 @@ ulong get_spin_phys_addr(void); ulong get_spin_virt_addr(void); u32 get_my_id(void); +int hold_cores_in_reset(int verbose);
#define BOOT_ENTRY_ADDR_UPPER 0 #define BOOT_ENTRY_ADDR_LOWER 1

On Thu, 30 Sep 2010 11:14:50 -0500 Peter Tyser ptyser@xes-inc.com wrote:
if (hold_cores_in_reset(0)) {
+#ifdef CONFIG_FSL_CORENET
/* Cores held in reset, use BRR to release */
enable_method = "fsl,brr-holdoff";
+#else
/* Cores held in reset, use EEBPCR to release */
enable_method = "fsl,eebpcr";
+#endif
Seems a little odd to have "fsl,brr-holdoff" but "fsl,eebpcr" with no "-holdoff".
-Scott

On Thu, 2010-09-30 at 12:13 -0500, Scott Wood wrote:
On Thu, 30 Sep 2010 11:14:50 -0500 Peter Tyser ptyser@xes-inc.com wrote:
if (hold_cores_in_reset(0)) {
+#ifdef CONFIG_FSL_CORENET
/* Cores held in reset, use BRR to release */
enable_method = "fsl,brr-holdoff";
+#else
/* Cores held in reset, use EEBPCR to release */
enable_method = "fsl,eebpcr";
+#endif
Seems a little odd to have "fsl,brr-holdoff" but "fsl,eebpcr" with no "-holdoff".
Argh, my bad, resending...

From: Aaron Sierra asierra@xes-inc.com
Some OSes require that secondary cores not be initialized when they are booted (eg VxWorks). By default when U-Boot is compiled with the CONFIG_MP option all secondary cores are brought out of reset and held in spinloops. Setting the "mp_holdoff" environment variable to 'yes' or '1' will cause U-Boot to leave secondary cores in their default state.
Signed-off-by: Aaron Sierra asierra@xes-inc.com Signed-off-by: Peter Tyser ptyser@xes-inc.com --- Changes since v1: - Update 'enable-method' in dtb appropriately - Don't set cpu-release-addr if spin-table isn't used - Add hold_cores_in_reset() function with more intelligent mp_holdoff environment variable checking
Changes since v2: - Fixed enable-method inconsistency pointed out by Scott
arch/powerpc/cpu/mpc85xx/fdt.c | 22 +++++++++++++++++++--- arch/powerpc/cpu/mpc85xx/mp.c | 31 +++++++++++++++++++++++++++++++ arch/powerpc/cpu/mpc85xx/mp.h | 1 + 3 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index 4540364..dee6e9b 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -48,6 +48,7 @@ void ft_fixup_cpu(void *blob, u64 memory_limit) ulong spin_tbl_addr = get_spin_phys_addr(); u32 bootpg = determine_mp_bootpg(); u32 id = get_my_id(); + const char *enable_method;
off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4); while (off != -FDT_ERR_NOTFOUND) { @@ -63,10 +64,25 @@ void ft_fixup_cpu(void *blob, u64 memory_limit) fdt_setprop_string(blob, off, "status", "disabled"); } + + if (hold_cores_in_reset(0)) { +#ifdef CONFIG_FSL_CORENET + /* Cores held in reset, use BRR to release */ + enable_method = "fsl,brr-holdoff"; +#else + /* Cores held in reset, use EEBPCR to release */ + enable_method = "fsl,eebpcr-holdoff"; +#endif + } else { + /* Cores out of reset and in a spin-loop */ + enable_method = "spin-table"; + + fdt_setprop(blob, off, "cpu-release-addr", + &val, sizeof(val)); + } + fdt_setprop_string(blob, off, "enable-method", - "spin-table"); - fdt_setprop(blob, off, "cpu-release-addr", - &val, sizeof(val)); + enable_method); } else { printf ("cpu NULL\n"); } diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c index 603baef..a019b1b 100644 --- a/arch/powerpc/cpu/mpc85xx/mp.c +++ b/arch/powerpc/cpu/mpc85xx/mp.c @@ -36,6 +36,27 @@ u32 get_my_id() return mfspr(SPRN_PIR); }
+/* + * Determine if U-Boot should keep secondary cores in reset, or let them out + * of reset and hold them in a spinloop + */ +int hold_cores_in_reset(int verbose) +{ + const char *s = getenv("mp_holdoff"); + + /* Default to no, overriden by 'y', 'yes', 'Y', 'Yes', or '1' */ + if (s && (*s == 'y' || *s == 'Y' || *s == '1')) { + if (verbose) { + puts("Secondary cores are being held in reset.\n"); + puts("See 'mp_holdoff' environment variable\n"); + } + + return 1; + } + + return 0; +} + int cpu_reset(int nr) { volatile ccsr_pic_t *pic = (void *)(CONFIG_SYS_MPC8xxx_PIC_ADDR); @@ -51,6 +72,9 @@ int cpu_status(int nr) { u32 *table, id = get_my_id();
+ if (hold_cores_in_reset(1)) + return 0; + if (nr == id) { table = (u32 *)get_spin_virt_addr(); printf("table base @ 0x%p\n", table); @@ -133,6 +157,9 @@ int cpu_release(int nr, int argc, char * const argv[]) u32 i, val, *table = (u32 *)get_spin_virt_addr() + nr * NUM_BOOT_ENTRY; u64 boot_addr;
+ if (hold_cores_in_reset(1)) + return 0; + if (nr == get_my_id()) { printf("Invalid to release the boot core.\n\n"); return 1; @@ -353,6 +380,10 @@ void setup_mp(void) ulong fixup = (ulong)&__secondary_start_page; u32 bootpg = determine_mp_bootpg();
+ /* Some OSes expect secondary cores to be held in reset */ + if (hold_cores_in_reset(0)) + return; + /* Store the bootpg's SDRAM address for use by secondary CPU cores */ __bootpg_addr = bootpg;
diff --git a/arch/powerpc/cpu/mpc85xx/mp.h b/arch/powerpc/cpu/mpc85xx/mp.h index 3422cc1..87bac37 100644 --- a/arch/powerpc/cpu/mpc85xx/mp.h +++ b/arch/powerpc/cpu/mpc85xx/mp.h @@ -6,6 +6,7 @@ ulong get_spin_phys_addr(void); ulong get_spin_virt_addr(void); u32 get_my_id(void); +int hold_cores_in_reset(int verbose);
#define BOOT_ENTRY_ADDR_UPPER 0 #define BOOT_ENTRY_ADDR_LOWER 1

On Sep 30, 2010, at 12:22 PM, Peter Tyser wrote:
From: Aaron Sierra asierra@xes-inc.com
Some OSes require that secondary cores not be initialized when they are booted (eg VxWorks). By default when U-Boot is compiled with the CONFIG_MP option all secondary cores are brought out of reset and held in spinloops. Setting the "mp_holdoff" environment variable to 'yes' or '1' will cause U-Boot to leave secondary cores in their default state.
Signed-off-by: Aaron Sierra asierra@xes-inc.com Signed-off-by: Peter Tyser ptyser@xes-inc.com
Changes since v1:
- Update 'enable-method' in dtb appropriately
- Don't set cpu-release-addr if spin-table isn't used
- Add hold_cores_in_reset() function with more intelligent mp_holdoff
environment variable checking
Changes since v2:
- Fixed enable-method inconsistency pointed out by Scott
arch/powerpc/cpu/mpc85xx/fdt.c | 22 +++++++++++++++++++--- arch/powerpc/cpu/mpc85xx/mp.c | 31 +++++++++++++++++++++++++++++++ arch/powerpc/cpu/mpc85xx/mp.h | 1 + 3 files changed, 51 insertions(+), 3 deletions(-)
applied to 85xx
- k
participants (3)
-
Kumar Gala
-
Peter Tyser
-
Scott Wood