Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm64/acpica/acpi_iort.c
Show First 20 Lines • Show All 364 Lines • ▼ Show 20 Lines | |||||
* Walk SRAT, assign proximity to all ITS entries. | * Walk SRAT, assign proximity to all ITS entries. | ||||
*/ | */ | ||||
static void | static void | ||||
srat_resolve_its_pxm(ACPI_SUBTABLE_HEADER *entry, void *arg) | srat_resolve_its_pxm(ACPI_SUBTABLE_HEADER *entry, void *arg) | ||||
{ | { | ||||
ACPI_SRAT_GIC_ITS_AFFINITY *gicits; | ACPI_SRAT_GIC_ITS_AFFINITY *gicits; | ||||
struct iort_node *its_node; | struct iort_node *its_node; | ||||
struct iort_its_entry *its_entry; | struct iort_its_entry *its_entry; | ||||
int i, matches; | int *map_counts; | ||||
int i, matches, dom; | |||||
if (entry->Type != ACPI_SRAT_TYPE_GIC_ITS_AFFINITY) | if (entry->Type != ACPI_SRAT_TYPE_GIC_ITS_AFFINITY) | ||||
return; | return; | ||||
matches = 0; | matches = 0; | ||||
map_counts = arg; | |||||
gicits = (ACPI_SRAT_GIC_ITS_AFFINITY *)entry; | gicits = (ACPI_SRAT_GIC_ITS_AFFINITY *)entry; | ||||
dom = acpi_map_pxm_to_vm_domainid(gicits->ProximityDomain); | |||||
/* | |||||
* Catch firmware and config errors. map_counts keeps a | |||||
* count of ProximityDomain values mapping to a domain ID | |||||
*/ | |||||
#if MAXMEMDOM > 1 | |||||
if (dom == -1) | |||||
printf("Firmware Error: Proximity Domain %d could not be" | |||||
" mapped for GIC ITS ID %d!\n", | |||||
gicits->ProximityDomain, gicits->ItsId); | |||||
#endif | |||||
/* use dom + 1 as index to handle the case where dom == -1 */ | |||||
i = ++map_counts[dom + 1]; | |||||
if (i > 1) { | |||||
#ifdef NUMA | |||||
if (dom != -1) | |||||
printf("ERROR: Multiple Proximity Domains map to the" | |||||
" same NUMA domain %d!\n", dom); | |||||
#else | |||||
printf("WARNING: multiple Proximity Domains in SRAT but NUMA" | |||||
" NOT enabled!\n"); | |||||
#endif | |||||
} | |||||
TAILQ_FOREACH(its_node, &its_groups, next) { | TAILQ_FOREACH(its_node, &its_groups, next) { | ||||
its_entry = its_node->entries.its; | its_entry = its_node->entries.its; | ||||
for (i = 0; i < its_node->nentries; i++, its_entry++) { | for (i = 0; i < its_node->nentries; i++, its_entry++) { | ||||
if (its_entry->its_id == gicits->ItsId) { | if (its_entry->its_id == gicits->ItsId) { | ||||
its_entry->pxm = acpi_map_pxm_to_vm_domainid( | its_entry->pxm = dom; | ||||
gicits->ProximityDomain); | |||||
matches++; | matches++; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (matches == 0) | if (matches == 0) | ||||
printf("ACPI: IORT: ITS block %u in SRAT not found in IORT!\n", | printf("ACPI: IORT: ITS block %u in SRAT not found in IORT!\n", | ||||
gicits->ItsId); | gicits->ItsId); | ||||
} | } | ||||
/* | /* | ||||
* Cross check the ITS Id with MADT and (if available) SRAT. | * Cross check the ITS Id with MADT and (if available) SRAT. | ||||
*/ | */ | ||||
static int | static int | ||||
iort_post_process_its(void) | iort_post_process_its(void) | ||||
{ | { | ||||
ACPI_TABLE_MADT *madt; | ACPI_TABLE_MADT *madt; | ||||
ACPI_TABLE_SRAT *srat; | ACPI_TABLE_SRAT *srat; | ||||
vm_paddr_t madt_pa, srat_pa; | vm_paddr_t madt_pa, srat_pa; | ||||
int map_counts[MAXMEMDOM + 1] = { 0 }; | |||||
/* Check ITS block in MADT */ | /* Check ITS block in MADT */ | ||||
madt_pa = acpi_find_table(ACPI_SIG_MADT); | madt_pa = acpi_find_table(ACPI_SIG_MADT); | ||||
KASSERT(madt_pa != 0, ("no MADT!")); | KASSERT(madt_pa != 0, ("no MADT!")); | ||||
madt = acpi_map_table(madt_pa, ACPI_SIG_MADT); | madt = acpi_map_table(madt_pa, ACPI_SIG_MADT); | ||||
KASSERT(madt != NULL, ("can't map MADT!")); | KASSERT(madt != NULL, ("can't map MADT!")); | ||||
acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, | acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, | ||||
madt_resolve_its_xref, NULL); | madt_resolve_its_xref, NULL); | ||||
acpi_unmap_table(madt); | acpi_unmap_table(madt); | ||||
/* Get proximtiy if available */ | /* Get proximtiy if available */ | ||||
srat_pa = acpi_find_table(ACPI_SIG_SRAT); | srat_pa = acpi_find_table(ACPI_SIG_SRAT); | ||||
if (srat_pa != 0) { | if (srat_pa != 0) { | ||||
srat = acpi_map_table(srat_pa, ACPI_SIG_SRAT); | srat = acpi_map_table(srat_pa, ACPI_SIG_SRAT); | ||||
KASSERT(srat != NULL, ("can't map SRAT!")); | KASSERT(srat != NULL, ("can't map SRAT!")); | ||||
acpi_walk_subtables(srat + 1, (char *)srat + srat->Header.Length, | acpi_walk_subtables(srat + 1, (char *)srat + srat->Header.Length, | ||||
srat_resolve_its_pxm, NULL); | srat_resolve_its_pxm, map_counts); | ||||
acpi_unmap_table(srat); | acpi_unmap_table(srat); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Find, parse, and save IO Remapping Table ("IORT"). | * Find, parse, and save IO Remapping Table ("IORT"). | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 74 Lines • Show Last 20 Lines |