Index: sys/arm64/arm64/mp_machdep.c =================================================================== --- sys/arm64/arm64/mp_machdep.c +++ sys/arm64/arm64/mp_machdep.c @@ -148,6 +148,13 @@ /* Temporary variables for init_secondary() */ void *dpcpu[MAXCPU - 1]; +static bool +is_boot_cpu(uint64_t target_cpu) +{ + + return (__pcpu[0].pc_mpidr == (target_cpu & CPU_AFF_MASK)); +} + static void release_aps(void *dummy __unused) { @@ -430,6 +437,10 @@ return (1); } +/* + * Starts a given CPU. If the CPU is already running, i.e. it is the boot CPU, + * do nothing. Returns true if the CPU is present and running. + */ static bool start_cpu(u_int cpuid, uint64_t target_cpu) { @@ -441,9 +452,11 @@ if (cpuid > mp_maxid) return (false); + /* Skip boot CPU */ + if (is_boot_cpu(target_cpu)) + return (true); + KASSERT(cpuid < MAXCPU, ("Too many CPUs")); - KASSERT(__pcpu[0].pc_mpidr != (target_cpu & CPU_AFF_MASK), - ("Start_cpu() was called on the boot CPU")); pcpup = &__pcpu[cpuid]; pcpu_init(pcpup, cpuid, sizeof(struct pcpu)); @@ -477,14 +490,14 @@ kmem_free((vm_offset_t)bootstacks[cpuid], PAGE_SIZE); bootstacks[cpuid] = NULL; mp_ncpus--; - - } else { - /* Wait for the AP to switch to its boot stack. */ - while (atomic_load_int(&aps_started) < naps + 1) - cpu_spinwait(); - CPU_SET(cpuid, &all_cpus); + return (false); } + /* Wait for the AP to switch to its boot stack. */ + while (atomic_load_int(&aps_started) < naps + 1) + cpu_spinwait(); + CPU_SET(cpuid, &all_cpus); + return (true); } @@ -500,17 +513,22 @@ case ACPI_MADT_TYPE_GENERIC_INTERRUPT: intr = (ACPI_MADT_GENERIC_INTERRUPT *)entry; cpuid = arg; - id = *cpuid; - /* Skip the boot CPU, but save its ACPI id. */ - if (__pcpu[0].pc_mpidr == (intr->ArmMpidr & CPU_AFF_MASK)) { - __pcpu[0].pc_acpi_id = intr->Uid; - break; + if (is_boot_cpu(intr->ArmMpidr)) + id = 0; + else + id = *cpuid; + + if (start_cpu(id, intr->ArmMpidr)) { + __pcpu[id].pc_acpi_id = intr->Uid; + /* + * Don't increment for the boot CPU, its CPU ID is + * reserved. + */ + if (!is_boot_cpu(intr->ArmMpidr)) + (*cpuid)++; } - start_cpu(id, intr->ArmMpidr); - __pcpu[id].pc_acpi_id = intr->Uid; - (*cpuid)++; break; default: break; @@ -533,7 +551,7 @@ printf("Unable to map the MADT, not starting APs\n"); return; } - /* Boot CPU is always 0 */ + cpuid = 1; acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, madt_handler, &cpuid); @@ -547,11 +565,10 @@ #endif #ifdef FDT -static boolean_t -cpu_init_fdt(u_int id, phandle_t node, u_int addr_size, pcell_t *reg) +static uint64_t +get_fdt_target_cpu(u_int addr_size, pcell_t *reg) { uint64_t target_cpu; - int domain; target_cpu = reg[0]; if (addr_size == 2) { @@ -559,35 +576,64 @@ target_cpu |= reg[1]; } - /* Skip boot CPU */ - if (__pcpu[0].pc_mpidr == (target_cpu & CPU_AFF_MASK)) - return (TRUE); + return (target_cpu); +} + +static boolean_t +start_cpu_fdt(u_int id, phandle_t node, u_int addr_size, pcell_t *reg) +{ + uint64_t target_cpu; + int domain; + int cpuid; + + target_cpu = get_fdt_target_cpu(addr_size, reg); - if (!start_cpu(fdt_cpuid, target_cpu)) + if (is_boot_cpu(target_cpu)) + cpuid = 0; + else + cpuid = fdt_cpuid; + + if (!start_cpu(cpuid, target_cpu)) return (FALSE); - fdt_cpuid++; /* Try to read the numa node of this cpu */ if (vm_ndomains == 1 || OF_getencprop(node, "numa-node-id", &domain, sizeof(domain)) <= 0) domain = 0; - __pcpu[fdt_cpuid].pc_domain = domain; + __pcpu[cpuid].pc_domain = domain; if (domain < MAXMEMDOM) - CPU_SET(fdt_cpuid, &cpuset_domain[domain]); + CPU_SET(cpuid, &cpuset_domain[domain]); + + /* + * Don't increment for the boot CPU, its CPU ID is reserved. + */ + if (!is_boot_cpu(target_cpu)) + fdt_cpuid++; return (TRUE); } +static void +cpu_init_fdt(void) +{ + phandle_t node; + int i; + + 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; + } + } + fdt_cpuid = 1; + ofw_cpu_early_foreach(start_cpu_fdt, true); +} #endif /* Initialize and fire up non-boot processors */ void cpu_mp_start(void) { -#ifdef FDT - phandle_t node; -#endif - int i; - mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN); /* CPU 0 is always boot CPU. */ @@ -603,15 +649,7 @@ #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; - } - } - fdt_cpuid = 1; - ofw_cpu_early_foreach(cpu_init_fdt, true); + cpu_init_fdt(); break; #endif default: