svn commit: r303614 - in head/sys/arm64: arm64 include

Andrew Turner andrew at FreeBSD.org
Mon Aug 1 12:17:46 UTC 2016


Author: andrew
Date: Mon Aug  1 12:17:44 2016
New Revision: 303614
URL: https://svnweb.freebsd.org/changeset/base/303614

Log:
  Add a kernel variable to let the user to select their preferred order
  between ACPI and FDT. This will be needed on machines with both, e.g. the
  SoftIron Overdrive 3000. The kernel will accept one or more comma separated
  values of either 'acpi' or 'fdt'. Any other values are skipped.
  
  To set it the user can either set it on the loader command line, or
  in loader.conf e.g. in loader.conf:
  kern.cfg.order=acpi,fdt
  
  This will try using ACPI then FDT. If none of the selected options work the
  kernel tries to use one to get the serial console, then panics.
  
  Reviewed by:	emaste (earlier version)
  Obtained from:	ABT Systems Ltd
  MFC after:	1 month
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D7274

Modified:
  head/sys/arm64/arm64/machdep.c
  head/sys/arm64/arm64/mp_machdep.c
  head/sys/arm64/arm64/nexus.c
  head/sys/arm64/include/machdep.h

Modified: head/sys/arm64/arm64/machdep.c
==============================================================================
--- head/sys/arm64/arm64/machdep.c	Mon Aug  1 12:14:21 2016	(r303613)
+++ head/sys/arm64/arm64/machdep.c	Mon Aug  1 12:17:44 2016	(r303614)
@@ -25,6 +25,7 @@
  *
  */
 
+#include "opt_acpi.h"
 #include "opt_platform.h"
 #include "opt_ddb.h"
 
@@ -82,11 +83,19 @@ __FBSDID("$FreeBSD$");
 #include <machine/vfp.h>
 #endif
 
+#ifdef DEV_ACPI
+#include <contrib/dev/acpica/include/acpi.h>
+#include <machine/acpica_machdep.h>
+#endif
+
 #ifdef FDT
 #include <dev/fdt/fdt_common.h>
 #include <dev/ofw/openfirm.h>
 #endif
 
+
+enum arm64_bus arm64_bus_method = ARM64_BUS_NONE;
+
 struct pcpu __pcpu[MAXCPU];
 
 static struct trapframe proc0_tf;
@@ -802,6 +811,61 @@ try_load_dtb(caddr_t kmdp)
 }
 #endif
 
+static bool
+bus_probe(void)
+{
+	bool has_acpi, has_fdt;
+	char *order, *env;
+
+	has_acpi = has_fdt = false;
+
+#ifdef FDT
+	has_fdt = (OF_peer(0) != 0);
+#endif
+#ifdef DEV_ACPI
+	has_acpi = (acpi_find_table(ACPI_SIG_SPCR) != 0);
+#endif
+
+	env = kern_getenv("kern.cfg.order");
+	if (env != NULL) {
+		order = env;
+		while (order != NULL) {
+			if (has_acpi &&
+			    strncmp(order, "acpi", 4) == 0 &&
+			    (order[4] == ',' || order[4] == '\0')) {
+				arm64_bus_method = ARM64_BUS_ACPI;
+				break;
+			}
+			if (has_fdt &&
+			    strncmp(order, "fdt", 3) == 0 &&
+			    (order[3] == ',' || order[3] == '\0')) {
+				arm64_bus_method = ARM64_BUS_FDT;
+				break;
+			}
+			order = strchr(order, ',');
+		}
+		freeenv(env);
+
+		/* If we set the bus method it is valid */
+		if (arm64_bus_method != ARM64_BUS_NONE)
+			return (true);
+	}
+	/* If no order or an invalid order was set use the default */
+	if (arm64_bus_method == ARM64_BUS_NONE) {
+		if (has_fdt)
+			arm64_bus_method = ARM64_BUS_FDT;
+		else if (has_acpi)
+			arm64_bus_method = ARM64_BUS_ACPI;
+	}
+
+	/*
+	 * If no option was set the default is valid, otherwise we are
+	 * setting one to get cninit() working, then calling panic to tell
+	 * the user about the invalid bus setup.
+	 */
+	return (env == NULL);
+}
+
 static void
 cache_setup(void)
 {
@@ -849,6 +913,7 @@ initarm(struct arm64_bootparams *abp)
 	vm_offset_t lastaddr;
 	caddr_t kmdp;
 	vm_paddr_t mem_len;
+	bool valid;
 	int i;
 
 	/* Set the module data location */
@@ -921,8 +986,14 @@ initarm(struct arm64_bootparams *abp)
 
 	devmap_bootstrap(0, NULL);
 
+	valid = bus_probe();
+
 	cninit();
 
+	if (!valid)
+		panic("Invalid bus configuration: %s",
+		    kern_getenv("kern.cfg.order"));
+
 	init_proc0(abp->kern_stack);
 	msgbufinit(msgbufp, msgbufsize);
 	mutex_init();

Modified: head/sys/arm64/arm64/mp_machdep.c
==============================================================================
--- head/sys/arm64/arm64/mp_machdep.c	Mon Aug  1 12:14:21 2016	(r303613)
+++ head/sys/arm64/arm64/mp_machdep.c	Mon Aug  1 12:17:44 2016	(r303614)
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_kern.h>
 
 #include <machine/debug_monitor.h>
+#include <machine/machdep.h>
 #include <machine/intr.h>
 #include <machine/smp.h>
 #ifdef VFP
@@ -90,13 +91,6 @@ boolean_t ofw_cpu_reg(phandle_t node, u_
 
 extern struct pcpu __pcpu[];
 
-static enum {
-	CPUS_UNKNOWN,
-#ifdef FDT
-	CPUS_FDT,
-#endif
-} cpu_enum_method;
-
 static device_identify_t arm64_cpu_identify;
 static device_probe_t arm64_cpu_probe;
 static device_attach_t arm64_cpu_attach;
@@ -499,14 +493,14 @@ cpu_mp_start(void)
 
 	CPU_SET(0, &all_cpus);
 
-	switch(cpu_enum_method) {
+	switch(arm64_bus_method) {
 #ifdef FDT
-	case CPUS_FDT:
+	case ARM64_BUS_FDT:
 		KASSERT(cpu0 >= 0, ("Current CPU was not found"));
 		ofw_cpu_early_foreach(cpu_init_fdt, true);
 		break;
 #endif
-	case CPUS_UNKNOWN:
+	default:
 		break;
 	}
 }
@@ -544,15 +538,17 @@ cpu_mp_setmaxid(void)
 #ifdef FDT
 	int cores;
 
-	cores = ofw_cpu_early_foreach(cpu_find_cpu0_fdt, false);
-	if (cores > 0) {
-		cores = MIN(cores, MAXCPU);
-		if (bootverbose)
-			printf("Found %d CPUs in the device tree\n", cores);
-		mp_ncpus = cores;
-		mp_maxid = cores - 1;
-		cpu_enum_method = CPUS_FDT;
-		return;
+	if (arm64_bus_method == ARM64_BUS_FDT) {
+		cores = ofw_cpu_early_foreach(cpu_find_cpu0_fdt, false);
+		if (cores > 0) {
+			cores = MIN(cores, MAXCPU);
+			if (bootverbose)
+				printf("Found %d CPUs in the device tree\n",
+				    cores);
+			mp_ncpus = cores;
+			mp_maxid = cores - 1;
+			return;
+		}
 	}
 #endif
 

Modified: head/sys/arm64/arm64/nexus.c
==============================================================================
--- head/sys/arm64/arm64/nexus.c	Mon Aug  1 12:14:21 2016	(r303613)
+++ head/sys/arm64/arm64/nexus.c	Mon Aug  1 12:17:44 2016	(r303614)
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/rman.h>
 #include <sys/interrupt.h>
 
+#include <machine/machdep.h>
 #include <machine/vmparam.h>
 #include <machine/pcb.h>
 #include <vm/vm.h>
@@ -411,7 +412,7 @@ static int
 nexus_fdt_probe(device_t dev)
 {
 
-	if (OF_peer(0) == 0)
+	if (arm64_bus_method != ARM64_BUS_FDT)
 		return (ENXIO);
 
 	device_quiet(dev);
@@ -455,7 +456,7 @@ static int
 nexus_acpi_probe(device_t dev)
 {
 
-	if (acpi_identify() != 0)
+	if (arm64_bus_method != ARM64_BUS_ACPI || acpi_identify() != 0)
 		return (ENXIO);
 
 	device_quiet(dev);

Modified: head/sys/arm64/include/machdep.h
==============================================================================
--- head/sys/arm64/include/machdep.h	Mon Aug  1 12:14:21 2016	(r303613)
+++ head/sys/arm64/include/machdep.h	Mon Aug  1 12:17:44 2016	(r303614)
@@ -37,6 +37,14 @@ struct arm64_bootparams {
 	vm_offset_t	kern_l0pt;	/* L1 page table for the kernel */
 };
 
+enum arm64_bus {
+	ARM64_BUS_NONE,
+	ARM64_BUS_FDT,
+	ARM64_BUS_ACPI,
+};
+
+extern enum arm64_bus arm64_bus_method;
+
 extern vm_paddr_t physmap[];
 extern u_int physmap_idx;
 


More information about the svn-src-all mailing list