From owner-svn-src-head@FreeBSD.ORG Wed Jul 29 19:07:24 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E7E48106566B; Wed, 29 Jul 2009 19:07:24 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id CB4658FC1B; Wed, 29 Jul 2009 19:07:24 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n6TJ7OTF079715; Wed, 29 Jul 2009 19:07:24 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n6TJ7OTL079712; Wed, 29 Jul 2009 19:07:24 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <200907291907.n6TJ7OTL079712@svn.freebsd.org> From: John Baldwin Date: Wed, 29 Jul 2009 19:07:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r195947 - head/usr.sbin/acpi/acpidump X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Jul 2009 19:07:25 -0000 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 #include #include +#include #include #include #include @@ -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: