Page MenuHomeFreeBSD

D13863.1777533442.diff
No OneTemporary

Size
5 KB
Referenced Files
None
Subscribers
None

D13863.1777533442.diff

Index: sys/arm64/arm64/mp_machdep.c
===================================================================
--- sys/arm64/arm64/mp_machdep.c
+++ sys/arm64/arm64/mp_machdep.c
@@ -125,15 +125,12 @@
struct mtx ap_boot_mtx;
struct pcb stoppcbs[MAXCPU];
+uint64_t cpu_mpidrs[MAXCPU];
static device_t cpu_list[MAXCPU];
-
-/*
- * Not all systems boot from the first CPU in the device tree. To work around
- * this we need to find which CPU we have booted from so when we later
- * enable the secondary CPUs we skip this one.
- */
-static int cpu0 = -1;
+#ifdef FDT
+static u_int fdt_cpuid;
+#endif
void mpentry(unsigned long cpuid);
void init_secondary(uint64_t);
@@ -442,33 +439,21 @@
}
static bool
-start_cpu(u_int id, uint64_t target_cpu)
+start_cpu(u_int cpuid, uint64_t target_cpu)
{
struct pcpu *pcpup;
vm_paddr_t pa;
- u_int cpuid;
int err;
/* Check we are able to start this cpu */
- if (id > mp_maxid)
+ if (cpuid > mp_maxid)
return (false);
- KASSERT(id < MAXCPU, ("Too many CPUs"));
+ KASSERT(cpuid < MAXCPU, ("Too many CPUs"));
+ KASSERT(cpu_mpidrs[cpuid] != (target_cpu & 0xff00fffffful),
+ ("Start_cpu() was called on the boot CPU"));
- /* We are already running on cpu 0 */
- if (id == cpu0)
- return (true);
-
- /*
- * Rotate the CPU IDs to put the boot CPU as CPU 0. We keep the other
- * CPUs ordered as the are likely grouped into clusters so it can be
- * useful to keep that property, e.g. for the GICv3 driver to send
- * an IPI to all CPUs in the cluster.
- */
- cpuid = id;
- if (cpuid < cpu0)
- cpuid += mp_maxid + 1;
- cpuid -= cpu0;
+ cpu_mpidrs[cpuid] = target_cpu & 0xff00fffffful;
pcpup = &__pcpu[cpuid];
pcpu_init(pcpup, cpuid, sizeof(struct pcpu));
@@ -483,13 +468,13 @@
err = psci_cpu_on(target_cpu, pa, cpuid);
if (err != PSCI_RETVAL_SUCCESS) {
/*
- * Panic here if INVARIANTS are enabled and PSCI failed to
+ * Panic here if INVARIANTS are enabled and PSCI failed to
* start the requested CPU. If psci_cpu_on returns PSCI_MISSING
* to indicate we are unable to use it to start the given CPU.
*/
KASSERT(err == PSCI_MISSING ||
(mp_quirks & MP_QUIRK_CPULIST) == MP_QUIRK_CPULIST,
- ("Failed to start CPU %u (%lx)\n", id, target_cpu));
+ ("Failed to start CPU %u (%lx)\n", cpuid, target_cpu));
pcpu_destroy(pcpup);
kmem_free(kernel_arena, (vm_offset_t)dpcpu[cpuid - 1],
@@ -498,7 +483,7 @@
mp_ncpus--;
/* Notify the user that the CPU failed to start */
- printf("Failed to start CPU %u (%lx)\n", id, target_cpu);
+ printf("Failed to start CPU %u (%lx)\n", cpuid, target_cpu);
} else
CPU_SET(cpuid, &all_cpus);
@@ -517,6 +502,10 @@
intr = (ACPI_MADT_GENERIC_INTERRUPT *)entry;
cpuid = arg;
+ /* Skip boot CPU */
+ if (cpu_mpidrs[0] == (intr->ArmMpidr & 0xff00fffffful))
+ break;
+
start_cpu((*cpuid), intr->ArmMpidr);
(*cpuid)++;
break;
@@ -551,6 +540,7 @@
#endif
#ifdef FDT
+
static boolean_t
cpu_init_fdt(u_int id, phandle_t node, u_int addr_size, pcell_t *reg)
{
@@ -563,14 +553,18 @@
target_cpu |= reg[1];
}
- if (!start_cpu(id, target_cpu))
+ if (cpu_mpidrs[0] == (target_cpu & 0xff00fffffful))
+ return (TRUE);
+
+ if (!start_cpu(fdt_cpuid, target_cpu))
return (FALSE);
+ fdt_cpuid++;
/* Try to read the numa node of this cpu */
if (OF_getencprop(node, "numa-node-id", &domain, sizeof(domain)) > 0) {
- __pcpu[id].pc_domain = domain;
+ __pcpu[fdt_cpuid].pc_domain = domain;
if (domain < MAXMEMDOM)
- CPU_SET(id, &cpuset_domain[domain]);
+ CPU_SET(fdt_cpuid, &cpuset_domain[domain]);
}
return (TRUE);
@@ -583,17 +577,23 @@
{
#ifdef FDT
phandle_t node;
- int i;
#endif
+ int i;
mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
+
+ /* Initialize MPIDR table with impossible MPIDR. */
+ for (i = 0; i < MAXCPU; i++)
+ cpu_mpidrs[i] = ~0;
+
+ /* CPU 0 is alwaus boot CPU. */
CPU_SET(0, &all_cpus);
+ cpu_mpidrs[0] = READ_SPECIALREG(mpidr_el1) & 0xff00fffffful;
switch(arm64_bus_method) {
#ifdef DEV_ACPI
case ARM64_BUS_ACPI:
- KASSERT(cpu0 >= 0, ("Current CPU was not found"));
cpu_init_acpi();
break;
#endif
@@ -606,7 +606,7 @@
mp_quirks = fdt_quirks[i].quirks;
}
}
- KASSERT(cpu0 >= 0, ("Current CPU was not found"));
+ fdt_cpuid = 1;
ofw_cpu_early_foreach(cpu_init_fdt, true);
break;
#endif
@@ -632,11 +632,6 @@
switch(entry->Type) {
case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
intr = (ACPI_MADT_GENERIC_INTERRUPT *)entry;
- if (cpu0 < 0) {
- mpidr_reg = READ_SPECIALREG(mpidr_el1);
- if ((mpidr_reg & 0xff00fffffful) == intr->ArmMpidr)
- cpu0 = *cores;
- }
(*cores)++;
break;
default:
@@ -671,29 +666,6 @@
}
#endif
-#ifdef FDT
-static boolean_t
-cpu_find_cpu0_fdt(u_int id, phandle_t node, u_int addr_size, pcell_t *reg)
-{
- uint64_t mpidr_fdt, mpidr_reg;
-
- if (cpu0 < 0) {
- mpidr_fdt = reg[0];
- if (addr_size == 2) {
- mpidr_fdt <<= 32;
- mpidr_fdt |= reg[1];
- }
-
- mpidr_reg = READ_SPECIALREG(mpidr_el1);
-
- if ((mpidr_reg & 0xff00fffffful) == mpidr_fdt)
- cpu0 = id;
- }
-
- return (TRUE);
-}
-#endif
-
void
cpu_mp_setmaxid(void)
{
@@ -718,7 +690,7 @@
#endif
#ifdef FDT
case ARM64_BUS_FDT:
- cores = ofw_cpu_early_foreach(cpu_find_cpu0_fdt, false);
+ cores = ofw_cpu_early_foreach(NULL, false);
if (cores > 0) {
cores = MIN(cores, MAXCPU);
if (bootverbose)
Index: sys/arm64/include/smp.h
===================================================================
--- sys/arm64/include/smp.h
+++ sys/arm64/include/smp.h
@@ -51,5 +51,6 @@
/* global data in mp_machdep.c */
extern struct pcb stoppcbs[];
+extern uint64_t cpu_mpidrs[];
#endif /* !_MACHINE_SMP_H_ */

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 30, 7:17 AM (14 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28495018
Default Alt Text
D13863.1777533442.diff (5 KB)

Event Timeline