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:
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to