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
This commit is contained in:
parent
5a31465d50
commit
698c14e189
@ -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();
|
||||
|
@ -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_int, cell_t *);
|
||||
|
||||
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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user