Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/acpica/acpi_pxm.c
Show First 20 Lines • Show All 259 Lines • ▼ Show 20 Lines | |||||
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; | ACPI_SRAT_GICC_AFFINITY *gicc; | ||||
static struct cpu_info *cpup; | static struct cpu_info *cpup; | ||||
uint64_t base, length; | |||||
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 | | ||||
cpu->ProximityDomainHi[1] << 16 | | cpu->ProximityDomainHi[1] << 16 | | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | KASSERT(cpu_find(gicc->AcpiProcessorUid) == NULL, | ||||
("Duplicate CPU UID %u", gicc->AcpiProcessorUid)); | ("Duplicate CPU UID %u", gicc->AcpiProcessorUid)); | ||||
cpup = cpu_add(gicc->AcpiProcessorUid, gicc->ProximityDomain); | cpup = cpu_add(gicc->AcpiProcessorUid, gicc->ProximityDomain); | ||||
if (cpup == NULL) | if (cpup == NULL) | ||||
printf("SRAT: Ignoring CPU UID %u (too high)\n", | printf("SRAT: Ignoring CPU UID %u (too high)\n", | ||||
gicc->AcpiProcessorUid); | 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; | ||||
base = mem->BaseAddress; | |||||
length = mem->Length; | |||||
domain = mem->ProximityDomain; | |||||
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, | domain, (uintmax_t)base, (uintmax_t)length, | ||||
(uintmax_t)mem->Length, | |||||
(mem->Flags & ACPI_SRAT_MEM_ENABLED) ? | (mem->Flags & ACPI_SRAT_MEM_ENABLED) ? | ||||
"enabled" : "disabled"); | "enabled" : "disabled"); | ||||
if (!(mem->Flags & ACPI_SRAT_MEM_ENABLED)) | if (!(mem->Flags & ACPI_SRAT_MEM_ENABLED)) | ||||
break; | break; | ||||
if (mem->BaseAddress >= maxphyaddr || | if (base >= maxphyaddr || | ||||
!overlaps_phys_avail(mem->BaseAddress, | !overlaps_phys_avail(base, base + length)) { | ||||
mem->BaseAddress + mem->Length)) { | |||||
printf("SRAT: Ignoring memory at addr 0x%jx\n", | printf("SRAT: Ignoring memory at addr 0x%jx\n", | ||||
(uintmax_t)mem->BaseAddress); | (uintmax_t)base); | ||||
break; | break; | ||||
} | } | ||||
if (num_mem == VM_PHYSSEG_MAX) { | if (num_mem == VM_PHYSSEG_MAX) { | ||||
printf("SRAT: Too many memory regions\n"); | printf("SRAT: Too many memory regions\n"); | ||||
*(int *)arg = ENXIO; | *(int *)arg = ENXIO; | ||||
break; | break; | ||||
} | } | ||||
slot = num_mem; | slot = num_mem; | ||||
for (i = 0; i < num_mem; i++) { | for (i = 0; i < num_mem; i++) { | ||||
if (mem_info[i].end <= mem->BaseAddress) | if (mem_info[i].domain == domain) { | ||||
/* Try to extend an existing segment. */ | |||||
if (base == mem_info[i].end) { | |||||
mem_info[i].end += length; | |||||
return; | |||||
} | |||||
if (base + length == mem_info[i].start) { | |||||
mem_info[i].start -= length; | |||||
return; | |||||
} | |||||
} | |||||
if (mem_info[i].end <= base) | |||||
continue; | continue; | ||||
if (mem_info[i].start < | if (mem_info[i].start < base + length) { | ||||
(mem->BaseAddress + mem->Length)) { | |||||
printf("SRAT: Overlapping memory entries\n"); | printf("SRAT: Overlapping memory entries\n"); | ||||
*(int *)arg = ENXIO; | *(int *)arg = ENXIO; | ||||
return; | return; | ||||
} | } | ||||
slot = i; | slot = i; | ||||
} | } | ||||
for (i = num_mem; i > slot; i--) | for (i = num_mem; i > slot; i--) | ||||
mem_info[i] = mem_info[i - 1]; | mem_info[i] = mem_info[i - 1]; | ||||
mem_info[slot].start = mem->BaseAddress; | mem_info[slot].start = base; | ||||
mem_info[slot].end = mem->BaseAddress + mem->Length; | mem_info[slot].end = base + length; | ||||
mem_info[slot].domain = mem->ProximityDomain; | mem_info[slot].domain = domain; | ||||
num_mem++; | num_mem++; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Ensure each memory domain has at least one CPU and that each CPU | * Ensure each memory domain has at least one CPU and that each CPU | ||||
* has at least one memory domain. | * has at least one memory domain. | ||||
▲ Show 20 Lines • Show All 324 Lines • Show Last 20 Lines |