Index: sys/conf/files.arm64 =================================================================== --- sys/conf/files.arm64 +++ sys/conf/files.arm64 @@ -188,6 +188,7 @@ dev/acpica/acpi_if.m optional acpi dev/acpica/acpi_pci_link.c optional acpi pci dev/acpica/acpi_pcib.c optional acpi pci +dev/acpica/acpi_pxm.c optional acpi dev/ahci/ahci_generic.c optional ahci dev/axgbe/if_axgbe.c optional axgbe dev/axgbe/xgbe-desc.c optional axgbe Index: sys/dev/acpica/acpi_pxm.c =================================================================== --- sys/dev/acpica/acpi_pxm.c +++ sys/dev/acpica/acpi_pxm.c @@ -182,6 +182,17 @@ return (0); } +/* + * On x86 we can use cpuid as index to cpus array, but ARM64 (which uses + * GICC entries with larged ACPI processor ID) we cannot do that. + * So, on arm64, we add by appending to the array, and lookup by iterating. + */ +#ifdef __aarch64__ +static const int cpus_use_indexing = 0; +#else +static const int cpus_use_indexing = 1; +#endif + /* * Find by CPU ACPI processor ID (on x86 apic id) */ @@ -190,8 +201,14 @@ { int i; - if (cpuid <= last_cpu && cpus[cpuid].enabled) - return (&cpus[cpuid]); + if (cpus_use_indexing) { + if (cpuid <= last_cpu && cpus[cpuid].enabled) + return (&cpus[cpuid]); + } else { + for (i = 0; i <= last_cpu; i++) + if (cpus[i].id == cpuid) + return (&cpus[i]); + } return (NULL); } @@ -204,7 +221,11 @@ struct cpu_info *cpup; int id; +#ifdef __aarch64__ + id = pc->pc_acpi_id; +#else id = pc->pc_apic_id; +#endif cpup = cpus_find(id); if (cpup == NULL) panic("SRAT: CPU with APIC ID %u is not known", id); @@ -219,10 +240,16 @@ { int pos; - if (cpuid >= max_cpus) - return (NULL); - pos = cpuid; - last_cpu = max(last_cpu, cpuid); + if (cpus_use_indexing) { + if (cpuid >= max_cpus) + return (NULL); + pos = cpuid; + last_cpu = max(last_cpu, cpuid); + } else { + if (last_cpu >= max_cpus) + return (NULL); + pos = ++last_cpu; + } /* fill cpu info, mark valid */ cpus[pos].domain = domain; @@ -237,6 +264,7 @@ ACPI_SRAT_CPU_AFFINITY *cpu; ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic; ACPI_SRAT_MEM_AFFINITY *mem; + ACPI_SRAT_GICC_AFFINITY *gicc; static struct cpu_info *cpup; int domain, i, slot; @@ -282,6 +310,22 @@ printf("SRAT: Ignoring local APIC ID %u (too high)\n", x2apic->ApicId); break; + case ACPI_SRAT_TYPE_GICC_AFFINITY: + gicc = (ACPI_SRAT_GICC_AFFINITY *)entry; + if (bootverbose) + printf("SRAT: Found CPU APIC ID %u domain %d: %s\n", + gicc->AcpiProcessorUid, gicc->ProximityDomain, + (gicc->Flags & ACPI_SRAT_GICC_ENABLED) ? + "enabled" : "disabled"); + if (!(gicc->Flags & ACPI_SRAT_GICC_ENABLED)) + break; + KASSERT(cpus_find(gicc->AcpiProcessorUid) == NULL, + ("Duplicate local APIC ID %u", gicc->AcpiProcessorUid)); + cpup = cpus_add(gicc->AcpiProcessorUid, gicc->ProximityDomain); + if (cpup == NULL) + printf("SRAT: Ignoring local APIC ID %u (too high)\n", + gicc->AcpiProcessorUid); + break; case ACPI_SRAT_TYPE_MEMORY_AFFINITY: mem = (ACPI_SRAT_MEM_AFFINITY *)entry; if (bootverbose)