svn commit: r195947 - head/usr.sbin/acpi/acpidump

John Baldwin jhb at FreeBSD.org
Wed Jul 29 19:07:25 UTC 2009


Author: jhb
Date: Wed Jul 29 19:07:24 2009
New Revision: 195947
URL: http://svn.freebsd.org/changeset/base/195947

Log:
  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

Modified:
  head/usr.sbin/acpi/acpidump/acpi.c
  head/usr.sbin/acpi/acpidump/acpidump.h

Modified: head/usr.sbin/acpi/acpidump/acpi.c
==============================================================================
--- head/usr.sbin/acpi/acpidump/acpi.c	Wed Jul 29 18:42:14 2009	(r195946)
+++ head/usr.sbin/acpi/acpidump/acpi.c	Wed Jul 29 19:07:24 2009	(r195947)
@@ -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 in
 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);

Modified: head/usr.sbin/acpi/acpidump/acpidump.h
==============================================================================
--- head/usr.sbin/acpi/acpidump/acpidump.h	Wed Jul 29 18:42:14 2009	(r195946)
+++ head/usr.sbin/acpi/acpidump/acpidump.h	Wed Jul 29 19:07:24 2009	(r195947)
@@ -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:


More information about the svn-src-all mailing list