svn commit: r323070 - head/sys/arm64/arm64

Andrew Turner andrew at FreeBSD.org
Thu Aug 31 20:48:07 UTC 2017


Author: andrew
Date: Thu Aug 31 20:48:05 2017
New Revision: 323070
URL: https://svnweb.freebsd.org/changeset/base/323070

Log:
  Add support for quirks while enabling secondary CPUs. This uses the fdt
  compatible string to check if the board is compatible with a given quirk.
  It's possible this will be moved later, however as it's currently only used
  by the MP code put it there.
  
  So far the only instance of a quirk is when the list of CPUs may be
  incorrect. This can happen on virtual machines with a hard coded
  devicetree, but where the user may then set the number of CPUs as an
  argument. This is the case on the ARM models so include the model specific
  compat strings for these, including the spelling mistake found in some of
  the OpenplatformPkg dtb files.
  
  Sponsored by:	DARPA, AFRL

Modified:
  head/sys/arm64/arm64/mp_machdep.c

Modified: head/sys/arm64/arm64/mp_machdep.c
==============================================================================
--- head/sys/arm64/arm64/mp_machdep.c	Thu Aug 31 20:33:22 2017	(r323069)
+++ head/sys/arm64/arm64/mp_machdep.c	Thu Aug 31 20:48:05 2017	(r323070)
@@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$");
 #ifdef FDT
 #include <dev/ofw/openfirm.h>
 #include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
 #include <dev/ofw/ofw_cpu.h>
 #endif
 
@@ -74,6 +75,23 @@ __FBSDID("$FreeBSD$");
 
 #include "pic_if.h"
 
+#define	MP_QUIRK_CPULIST	0x01	/* The list of cpus may be wrong, */
+					/* don't panic if one fails to start */
+static uint32_t mp_quirks;
+
+#ifdef FDT
+static struct {
+	const char *compat;
+	uint32_t quirks;
+} fdt_quirks[] = {
+	{ "arm,foundation-aarch64",	MP_QUIRK_CPULIST },
+	{ "arm,fvp-base",		MP_QUIRK_CPULIST },
+	/* This is incorrect in some DTS files */
+	{ "arm,vfp-base",		MP_QUIRK_CPULIST },
+	{ NULL, 0 },
+};
+#endif
+
 typedef void intr_ipi_send_t(void *, cpuset_t, u_int);
 typedef void intr_ipi_handler_t(void *);
 
@@ -465,13 +483,16 @@ start_cpu(u_int id, uint64_t target_cpu)
 		 * start the requested CPU. If psci_cpu_on returns PSCI_MISSING
 		 * to indicate we are unable to use it to start the given CPU.
 		 */
-		KASSERT(err == PSCI_MISSING,
+		KASSERT(err == PSCI_MISSING ||
+		    (mp_quirks & MP_QUIRK_CPULIST) == MP_QUIRK_CPULIST,
 		    ("Failed to start CPU %u (%lx)\n", id, target_cpu));
 
 		pcpu_destroy(pcpup);
 		kmem_free(kernel_arena, (vm_offset_t)dpcpu[cpuid - 1],
 		    DPCPU_SIZE);
 		dpcpu[cpuid - 1] = NULL;
+		mp_ncpus--;
+
 		/* Notify the user that the CPU failed to start */
 		printf("Failed to start CPU %u (%lx)\n", id, target_cpu);
 	} else
@@ -556,6 +577,10 @@ cpu_init_fdt(u_int id, phandle_t node, u_int addr_size
 void
 cpu_mp_start(void)
 {
+#ifdef FDT
+	phandle_t node;
+	int i;
+#endif
 
 	mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
 
@@ -570,6 +595,13 @@ cpu_mp_start(void)
 #endif
 #ifdef FDT
 	case ARM64_BUS_FDT:
+		node = OF_peer(0);
+		for (i = 0; fdt_quirks[i].compat != NULL; i++) {
+			if (ofw_bus_node_is_compatible(node,
+			    fdt_quirks[i].compat) != 0) {
+				mp_quirks = fdt_quirks[i].quirks;
+			}
+		}
 		KASSERT(cpu0 >= 0, ("Current CPU was not found"));
 		ofw_cpu_early_foreach(cpu_init_fdt, true);
 		break;


More information about the svn-src-head mailing list