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

Peter Tyser ptyser at xes-inc.com
Thu Sep 30 18:14:50 CEST 2010


From: Aaron Sierra <asierra at 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 at xes-inc.com>
Signed-off-by: Peter Tyser <ptyser at 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
-- 
1.7.0.4



More information about the U-Boot mailing list