diff options
author | jhb <jhb@FreeBSD.org> | 2009-07-29 19:07:24 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2009-07-29 19:07:24 +0000 |
commit | 0991e073e63d90ed3dac07a1ffbcb25463bd1cba (patch) | |
tree | 44f1ee625d3b6fbbcaffa5c7bda922abfa1463cb /usr.sbin | |
parent | 2fc68fe1d71769db4a0b55c1cd3218f891b44a93 (diff) | |
download | FreeBSD-src-0991e073e63d90ed3dac07a1ffbcb25463bd1cba.zip FreeBSD-src-0991e073e63d90ed3dac07a1ffbcb25463bd1cba.tar.gz |
Parse the System Resource Affinity Table ('SRAT') used to describe affinity
relationships between CPUs and memory.
Reviewed by: jkim
Approved by: re (kib)
MFC after: 1 week
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/acpi/acpidump/acpi.c | 106 | ||||
-rw-r--r-- | usr.sbin/acpi/acpidump/acpidump.h | 50 |
2 files changed, 148 insertions, 8 deletions
diff --git a/usr.sbin/acpi/acpidump/acpi.c b/usr.sbin/acpi/acpidump/acpi.c index 30ed43f..800655c 100644 --- a/usr.sbin/acpi/acpidump/acpi.c +++ b/usr.sbin/acpi/acpidump/acpi.c @@ -36,6 +36,7 @@ #include <fcntl.h> #include <paths.h> #include <stdio.h> +#include <stdint.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -59,6 +60,11 @@ static void acpi_print_intr(u_int32_t intr, u_int16_t mps_flags); static void acpi_print_apic(struct MADT_APIC *mp); static void acpi_handle_apic(struct ACPIsdt *sdp); static void acpi_handle_hpet(struct ACPIsdt *sdp); +static void acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, + uint32_t flags); +static void acpi_print_srat_memory(struct SRAT_memory *mp); +static void acpi_print_srat(struct SRATentry *srat); +static void acpi_handle_srat(struct ACPIsdt *sdp); static void acpi_print_sdt(struct ACPIsdt *sdp); static void acpi_print_fadt(struct ACPIsdt *sdp); static void acpi_print_facs(struct FACSbody *facs); @@ -258,7 +264,10 @@ static void acpi_print_apic(struct MADT_APIC *mp) { - printf("\tType=%s\n", apic_types[mp->type]); + if (mp->type < sizeof(apic_types) / sizeof(apic_types[0])) + printf("\tType=%s\n", apic_types[mp->type]); + else + printf("\tType=%d (unknown)\n", mp->type); switch (mp->type) { case ACPI_MADT_APIC_TYPE_LOCAL_APIC: acpi_print_local_apic(mp->body.local_apic.cpu_id, @@ -307,9 +316,6 @@ acpi_print_apic(struct MADT_APIC *mp) acpi_print_intr(mp->body.int_src.intr, mp->body.int_src.mps_flags); break; - default: - printf("\tUnknown type %d\n", (u_int)mp->type); - break; } } @@ -393,10 +399,92 @@ acpi_handle_mcfg(struct ACPIsdt *sdp) sizeof(*mcfg->s); for (i = 0; i < e; i++, mcfg++) { printf("\n"); - printf("\tBase Address= 0x%016jx\n", mcfg->s[i].baseaddr); - printf("\tSegment Group= 0x%04x\n", mcfg->s[i].seg_grp); - printf("\tStart Bus= %d\n", mcfg->s[i].start); - printf("\tEnd Bus= %d\n", mcfg->s[i].end); + printf("\tBase Address=0x%016jx\n", mcfg->s[i].baseaddr); + printf("\tSegment Group=0x%04x\n", mcfg->s[i].seg_grp); + printf("\tStart Bus=%d\n", mcfg->s[i].start); + printf("\tEnd Bus=%d\n", mcfg->s[i].end); + } + printf(END_COMMENT); +} + +static void +acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain, + uint32_t flags) +{ + + printf("\tFlags={"); + if (flags & ACPI_SRAT_CPU_ENABLED) + printf("ENABLED"); + else + printf("DISABLED"); + printf("}\n"); + printf("\tAPIC ID=%d\n", apic_id); + printf("\tProximity Domain=%d\n", proximity_domain); +} + +static void +acpi_print_srat_memory(struct SRAT_memory *mp) +{ + + printf("\tFlags={"); + if (mp->flags & ACPI_SRAT_MEM_ENABLED) + printf("ENABLED"); + else + printf("DISABLED"); + if (mp->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) + printf(",HOT_PLUGGABLE"); + if (mp->flags & ACPI_SRAT_MEM_NON_VOLATILE) + printf(",NON_VOLATILE"); + printf("}\n"); + printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->base_address); + printf("\tLength=0x%016jx\n", (uintmax_t)mp->length); + printf("\tProximity Domain=%d\n", mp->proximity_domain); +} + +const char *srat_types[] = { "CPU", "Memory", "X2APIC" }; + +static void +acpi_print_srat(struct SRATentry *srat) +{ + + if (srat->type < sizeof(srat_types) / sizeof(srat_types[0])) + printf("\tType=%s\n", srat_types[srat->type]); + else + printf("\tType=%d (unknown)\n", srat->type); + switch (srat->type) { + case ACPI_SRAT_TYPE_CPU_AFFINITY: + acpi_print_srat_cpu(srat->body.cpu.apic_id, + srat->body.cpu.proximity_domain_hi[2] << 24 | + srat->body.cpu.proximity_domain_hi[1] << 16 | + srat->body.cpu.proximity_domain_hi[0] << 0 | + srat->body.cpu.proximity_domain_lo, srat->body.cpu.flags); + break; + case ACPI_SRAT_TYPE_MEMORY_AFFINITY: + acpi_print_srat_memory(&srat->body.mem); + break; + case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: + acpi_print_srat_cpu(srat->body.x2apic.apic_id, + srat->body.x2apic.proximity_domain, + srat->body.x2apic.flags); + break; + } +} + +static void +acpi_handle_srat(struct ACPIsdt *sdp) +{ + struct SRATbody *sratp; + struct SRATentry *entry; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + sratp = (struct SRATbody *)sdp->body; + printf("\tTable Revision=%d\n", sratp->table_revision); + entry = sratp->body; + while (((uintptr_t)entry) - ((uintptr_t)sdp) < sdp->len) { + printf("\n"); + acpi_print_srat(entry); + entry = (struct SRATentry *)((char *)entry + entry->len); } printf(END_COMMENT); } @@ -710,6 +798,8 @@ acpi_handle_rsdt(struct ACPIsdt *rsdp) acpi_handle_ecdt(sdp); else if (!memcmp(sdp->signature, "MCFG", 4)) acpi_handle_mcfg(sdp); + else if (!memcmp(sdp->signature, "SRAT", 4)) + acpi_handle_srat(sdp); else { printf(BEGIN_COMMENT); acpi_print_sdt(sdp); diff --git a/usr.sbin/acpi/acpidump/acpidump.h b/usr.sbin/acpi/acpidump/acpidump.h index 8d79168..8eca6a8b 100644 --- a/usr.sbin/acpi/acpidump/acpidump.h +++ b/usr.sbin/acpi/acpidump/acpidump.h @@ -304,6 +304,56 @@ struct MCFGbody { } s[1] __packed; } __packed; +/* System Resource Affinity Table */ +struct SRAT_cpu { + uint8_t proximity_domain_lo; + uint8_t apic_id; + uint32_t flags; +#define ACPI_SRAT_CPU_ENABLED 0x00000001 + uint8_t sapic_eid; + uint8_t proximity_domain_hi[3]; + uint32_t reserved; +} __packed; + +struct SRAT_memory { + uint32_t proximity_domain; + uint16_t reserved; + uint64_t base_address; + uint64_t length; + uint32_t reserved1; + uint32_t flags; +#define ACPI_SRAT_MEM_ENABLED 0x00000001 +#define ACPI_SRAT_MEM_HOT_PLUGGABLE 0x00000002 +#define ACPI_SRAT_MEM_NON_VOLATILE 0x00000002 + uint64_t reserved2; +} __packed; + +struct SRAT_x2apic { + uint16_t reserved; + uint32_t proximity_domain; + uint32_t apic_id; + uint32_t flags; +} __packed; + +struct SRATentry { + uint8_t type; +#define ACPI_SRAT_TYPE_CPU_AFFINITY 0 +#define ACPI_SRAT_TYPE_MEMORY_AFFINITY 1 +#define ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY 2 + uint8_t len; + union { + struct SRAT_cpu cpu; + struct SRAT_memory mem; + struct SRAT_x2apic x2apic; + } body; +} __packed; + +struct SRATbody { + uint32_t table_revision; + uint64_t reserved; + struct SRATentry body[0]; +} __packed; + /* * Addresses to scan on ia32 for the RSD PTR. According to section 5.2.2 * of the ACPI spec, we only consider two regions for the base address: |