Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/acpica/acpi_pxm.c
Show First 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
#include <dev/acpica/acpivar.h> | #include <dev/acpica/acpivar.h> | ||||
#if MAXMEMDOM > 1 | #if MAXMEMDOM > 1 | ||||
static struct cpu_info { | static struct cpu_info { | ||||
int enabled:1; | int enabled:1; | ||||
int has_memory:1; | int has_memory:1; | ||||
int domain; | int domain; | ||||
int id; | |||||
} *cpus; | } *cpus; | ||||
static int max_cpus; | static int max_cpus; | ||||
static int last_cpu; | static int last_cpu; | ||||
struct mem_affinity mem_info[VM_PHYSSEG_MAX + 1]; | struct mem_affinity mem_info[VM_PHYSSEG_MAX + 1]; | ||||
int num_mem; | int num_mem; | ||||
▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | for (i = 0; phys_avail[i] != 0 && phys_avail[i + 1] != 0; i += 2) { | ||||
if (phys_avail[i] < end) | if (phys_avail[i] < end) | ||||
return (1); | return (1); | ||||
break; | break; | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Find CPU by processor ID (APIC ID on x86). | * On x86 we can use the cpuid to index the cpus array, but on arm64 | ||||
* we have an ACPI Processor UID with a larger range. | |||||
* | |||||
* Use this variable to indicate if the cpus can be stored by index. | |||||
*/ | */ | ||||
#ifdef __aarch64__ | |||||
static const int cpus_use_indexing = 0; | |||||
#else | |||||
static const int cpus_use_indexing = 1; | |||||
#endif | |||||
/* | |||||
* Find CPU by processor ID (APIC ID on x86, Processor UID on arm64) | |||||
*/ | |||||
static struct cpu_info * | static struct cpu_info * | ||||
cpu_find(int cpuid) | cpu_find(int cpuid) | ||||
{ | { | ||||
int i; | |||||
if (cpus_use_indexing) { | |||||
if (cpuid <= last_cpu && cpus[cpuid].enabled) | if (cpuid <= last_cpu && cpus[cpuid].enabled) | ||||
return (&cpus[cpuid]); | return (&cpus[cpuid]); | ||||
} else { | |||||
for (i = 0; i <= last_cpu; i++) | |||||
if (cpus[i].id == cpuid) | |||||
return (&cpus[i]); | |||||
} | |||||
return (NULL); | return (NULL); | ||||
} | } | ||||
/* | /* | ||||
* Find CPU by pcpu pointer. | * Find CPU by pcpu pointer. | ||||
*/ | */ | ||||
static struct cpu_info * | static struct cpu_info * | ||||
cpu_get_info(struct pcpu *pc) | cpu_get_info(struct pcpu *pc) | ||||
{ | { | ||||
struct cpu_info *cpup; | struct cpu_info *cpup; | ||||
int id; | int id; | ||||
#ifdef __aarch64__ | |||||
id = pc->pc_acpi_id; | |||||
#else | |||||
id = pc->pc_apic_id; | id = pc->pc_apic_id; | ||||
#endif | |||||
cpup = cpu_find(id); | cpup = cpu_find(id); | ||||
if (cpup == NULL) | if (cpup == NULL) | ||||
panic("SRAT: CPU with APIC ID %u is not known", id); | panic("SRAT: CPU with ID %u is not known", id); | ||||
return (cpup); | return (cpup); | ||||
} | } | ||||
/* | /* | ||||
* Add proximity information for a new CPU. | * Add proximity information for a new CPU. | ||||
*/ | */ | ||||
static struct cpu_info * | static struct cpu_info * | ||||
cpu_add(int cpuid, int domain) | cpu_add(int cpuid, int domain) | ||||
{ | { | ||||
struct cpu_info *cpup; | struct cpu_info *cpup; | ||||
if (cpus_use_indexing) { | |||||
if (cpuid >= max_cpus) | if (cpuid >= max_cpus) | ||||
return (NULL); | return (NULL); | ||||
last_cpu = imax(last_cpu, cpuid); | last_cpu = imax(last_cpu, cpuid); | ||||
markj: It doesn't really matter here, but this should be imin(). | |||||
Done Inline ActionsThis is a bug (had the Linux behavior in mind) - I should use imax() here. jchandra: This is a bug (had the Linux behavior in mind) - I should use imax() here. | |||||
cpup = &cpus[cpuid]; | cpup = &cpus[cpuid]; | ||||
} else { | |||||
if (last_cpu >= max_cpus - 1) | |||||
return (NULL); | |||||
cpup = &cpus[++last_cpu]; | |||||
} | |||||
cpup->domain = domain; | cpup->domain = domain; | ||||
cpup->id = cpuid; | |||||
cpup->enabled = 1; | cpup->enabled = 1; | ||||
return (cpup); | return (cpup); | ||||
} | } | ||||
static void | static void | ||||
srat_parse_entry(ACPI_SUBTABLE_HEADER *entry, void *arg) | srat_parse_entry(ACPI_SUBTABLE_HEADER *entry, void *arg) | ||||
{ | { | ||||
ACPI_SRAT_CPU_AFFINITY *cpu; | ACPI_SRAT_CPU_AFFINITY *cpu; | ||||
ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic; | ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic; | ||||
ACPI_SRAT_MEM_AFFINITY *mem; | ACPI_SRAT_MEM_AFFINITY *mem; | ||||
ACPI_SRAT_GICC_AFFINITY *gicc; | |||||
static struct cpu_info *cpup; | static struct cpu_info *cpup; | ||||
int domain, i, slot; | int domain, i, slot; | ||||
switch (entry->Type) { | switch (entry->Type) { | ||||
case ACPI_SRAT_TYPE_CPU_AFFINITY: | case ACPI_SRAT_TYPE_CPU_AFFINITY: | ||||
cpu = (ACPI_SRAT_CPU_AFFINITY *)entry; | cpu = (ACPI_SRAT_CPU_AFFINITY *)entry; | ||||
domain = cpu->ProximityDomainLo | | domain = cpu->ProximityDomainLo | | ||||
cpu->ProximityDomainHi[0] << 8 | | cpu->ProximityDomainHi[0] << 8 | | ||||
Show All 28 Lines | case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: | ||||
if (!(x2apic->Flags & ACPI_SRAT_CPU_ENABLED)) | if (!(x2apic->Flags & ACPI_SRAT_CPU_ENABLED)) | ||||
break; | break; | ||||
KASSERT(cpu_find(x2apic->ApicId) == NULL, | KASSERT(cpu_find(x2apic->ApicId) == NULL, | ||||
("Duplicate local APIC ID %u", x2apic->ApicId)); | ("Duplicate local APIC ID %u", x2apic->ApicId)); | ||||
cpup = cpu_add(x2apic->ApicId, x2apic->ProximityDomain); | cpup = cpu_add(x2apic->ApicId, x2apic->ProximityDomain); | ||||
if (cpup == NULL) | if (cpup == NULL) | ||||
printf("SRAT: Ignoring local APIC ID %u (too high)\n", | printf("SRAT: Ignoring local APIC ID %u (too high)\n", | ||||
x2apic->ApicId); | x2apic->ApicId); | ||||
break; | |||||
case ACPI_SRAT_TYPE_GICC_AFFINITY: | |||||
gicc = (ACPI_SRAT_GICC_AFFINITY *)entry; | |||||
if (bootverbose) | |||||
printf("SRAT: Found CPU UID %u domain %d: %s\n", | |||||
Not Done Inline Actions"APIC ID" looks like the wrong term. markj: "APIC ID" looks like the wrong term. | |||||
Done Inline ActionsYes, will fix. jchandra: Yes, will fix. | |||||
gicc->AcpiProcessorUid, gicc->ProximityDomain, | |||||
(gicc->Flags & ACPI_SRAT_GICC_ENABLED) ? | |||||
"enabled" : "disabled"); | |||||
if (!(gicc->Flags & ACPI_SRAT_GICC_ENABLED)) | |||||
break; | |||||
KASSERT(cpu_find(gicc->AcpiProcessorUid) == NULL, | |||||
("Duplicate CPU UID %u", gicc->AcpiProcessorUid)); | |||||
cpup = cpu_add(gicc->AcpiProcessorUid, gicc->ProximityDomain); | |||||
if (cpup == NULL) | |||||
printf("SRAT: Ignoring CPU UID %u (too high)\n", | |||||
gicc->AcpiProcessorUid); | |||||
break; | break; | ||||
case ACPI_SRAT_TYPE_MEMORY_AFFINITY: | case ACPI_SRAT_TYPE_MEMORY_AFFINITY: | ||||
mem = (ACPI_SRAT_MEM_AFFINITY *)entry; | mem = (ACPI_SRAT_MEM_AFFINITY *)entry; | ||||
if (bootverbose) | if (bootverbose) | ||||
printf( | printf( | ||||
"SRAT: Found memory domain %d addr 0x%jx len 0x%jx: %s\n", | "SRAT: Found memory domain %d addr 0x%jx len 0x%jx: %s\n", | ||||
mem->ProximityDomain, (uintmax_t)mem->BaseAddress, | mem->ProximityDomain, (uintmax_t)mem->BaseAddress, | ||||
(uintmax_t)mem->Length, | (uintmax_t)mem->Length, | ||||
▲ Show 20 Lines • Show All 363 Lines • Show Last 20 Lines |
It doesn't really matter here, but this should be imin().