summaryrefslogtreecommitdiffstats
path: root/usr.sbin/acpi
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2009-07-29 19:07:24 +0000
committerjhb <jhb@FreeBSD.org>2009-07-29 19:07:24 +0000
commit0991e073e63d90ed3dac07a1ffbcb25463bd1cba (patch)
tree44f1ee625d3b6fbbcaffa5c7bda922abfa1463cb /usr.sbin/acpi
parent2fc68fe1d71769db4a0b55c1cd3218f891b44a93 (diff)
downloadFreeBSD-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/acpi')
-rw-r--r--usr.sbin/acpi/acpidump/acpi.c106
-rw-r--r--usr.sbin/acpi/acpidump/acpidump.h50
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:
OpenPOWER on IntegriCloud