diff options
-rw-r--r-- | sys/arm64/arm64/machdep.c | 71 | ||||
-rw-r--r-- | sys/arm64/arm64/mp_machdep.c | 34 | ||||
-rw-r--r-- | sys/arm64/arm64/nexus.c | 5 | ||||
-rw-r--r-- | sys/arm64/include/machdep.h | 8 |
4 files changed, 97 insertions, 21 deletions
diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c index 19d398192924..90b5f3d47e05 100644 --- a/sys/arm64/arm64/machdep.c +++ b/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 @@ __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(); diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c index b8e0394d2611..b0e182796461 100644 --- a/sys/arm64/arm64/mp_machdep.c +++ b/sys/arm64/arm64/mp_machdep.c @@ -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 diff --git a/sys/arm64/arm64/nexus.c b/sys/arm64/arm64/nexus.c index 2cd36ad68006..2495c4d91eff 100644 --- a/sys/arm64/arm64/nexus.c +++ b/sys/arm64/arm64/nexus.c @@ -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); diff --git a/sys/arm64/include/machdep.h b/sys/arm64/include/machdep.h index 0b1feaeab46e..b1554e98a921 100644 --- a/sys/arm64/include/machdep.h +++ b/sys/arm64/include/machdep.h @@ -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; |