Index: head/sys/arm64/arm64/machdep.c =================================================================== --- head/sys/arm64/arm64/machdep.c +++ head/sys/arm64/arm64/machdep.c @@ -25,6 +25,7 @@ * */ +#include "opt_acpi.h" #include "opt_platform.h" #include "opt_ddb.h" @@ -82,11 +83,19 @@ #include #endif +#ifdef DEV_ACPI +#include +#include +#endif + #ifdef FDT #include #include #endif + +enum arm64_bus arm64_bus_method = ARM64_BUS_NONE; + struct pcpu __pcpu[MAXCPU]; static struct trapframe proc0_tf; @@ -802,6 +811,61 @@ } #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 @@ 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 @@ 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(); Index: head/sys/arm64/arm64/mp_machdep.c =================================================================== --- head/sys/arm64/arm64/mp_machdep.c +++ head/sys/arm64/arm64/mp_machdep.c @@ -52,6 +52,7 @@ #include #include +#include #include #include #ifdef VFP @@ -90,13 +91,6 @@ 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_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 @@ #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 Index: head/sys/arm64/arm64/nexus.c =================================================================== --- head/sys/arm64/arm64/nexus.c +++ head/sys/arm64/arm64/nexus.c @@ -55,6 +55,7 @@ #include #include +#include #include #include #include @@ -411,7 +412,7 @@ 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 @@ 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); Index: head/sys/arm64/include/machdep.h =================================================================== --- head/sys/arm64/include/machdep.h +++ head/sys/arm64/include/machdep.h @@ -37,6 +37,14 @@ 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;