From owner-svn-src-head@FreeBSD.ORG Fri Dec 21 01:19:49 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id E290768F; Fri, 21 Dec 2012 01:19:49 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id C362F8FC12; Fri, 21 Dec 2012 01:19:49 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qBL1Jn0Q060632; Fri, 21 Dec 2012 01:19:49 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qBL1Jn1T060627; Fri, 21 Dec 2012 01:19:49 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201212210119.qBL1Jn1T060627@svn.freebsd.org> From: Neel Natu Date: Fri, 21 Dec 2012 01:19:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r244525 - head/usr.sbin/acpi/acpidump X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 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: Fri, 21 Dec 2012 01:19:50 -0000 Author: neel Date: Fri Dec 21 01:19:48 2012 New Revision: 244525 URL: http://svnweb.freebsd.org/changeset/base/244525 Log: Teach acpidump to dump the DMA Remapping Reporting table (aka DMAR). The DMAR table is documented in chapter 8 of the Intel VT-d specification. Reviewed by: jhb Obtained from: NetApp Modified: head/usr.sbin/acpi/acpidump/acpi.c head/usr.sbin/acpi/acpidump/acpidump.8 Modified: head/usr.sbin/acpi/acpidump/acpi.c ============================================================================== --- head/usr.sbin/acpi/acpidump/acpi.c Fri Dec 21 00:41:52 2012 (r244524) +++ head/usr.sbin/acpi/acpidump/acpi.c Fri Dec 21 01:19:48 2012 (r244525) @@ -123,6 +123,31 @@ static const char *TCPA_pcclient_strings "Table of Devices", }; +#define PRINTFLAG_END() printflag_end() + +static char pf_sep = '{'; + +static void +printflag_end(void) +{ + + if (pf_sep != '{') { + printf("}"); + pf_sep = '{'; + } + printf("\n"); +} + +static void +printflag(uint64_t var, uint64_t mask, const char *name) +{ + + if (var & mask) { + printf("%c%s", pf_sep, name); + pf_sep = ','; + } +} + static void acpi_print_string(char *s, size_t length) { @@ -729,6 +754,238 @@ acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp) printf(END_COMMENT); } +static const char * +devscope_type2str(int type) +{ + static char typebuf[16]; + + switch (type) { + case 1: + return ("PCI Endpoint Device"); + case 2: + return ("PCI Sub-Hierarchy"); + case 3: + return ("IOAPIC"); + case 4: + return ("HPET"); + default: + snprintf(typebuf, sizeof(typebuf), "%d", type); + return (typebuf); + } +} + +static int +acpi_handle_dmar_devscope(void *addr, int remaining) +{ + char sep; + int pathlen; + ACPI_DMAR_PCI_PATH *path, *pathend; + ACPI_DMAR_DEVICE_SCOPE *devscope = addr; + + if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE)) + return (-1); + + if (remaining < devscope->Length) + return (-1); + + printf("\n"); + printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType)); + printf("\t\tLength=%d\n", devscope->Length); + printf("\t\tEnumerationId=%d\n", devscope->EnumerationId); + printf("\t\tStartBusNumber=%d\n", devscope->Bus); + + path = (ACPI_DMAR_PCI_PATH *)(devscope + 1); + pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE); + pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH); + if (path < pathend) { + sep = '{'; + printf("\t\tPath="); + do { + printf("%c%d:%d", sep, path->Device, path->Function); + sep=','; + path++; + } while (path < pathend); + printf("}\n"); + } + + return (devscope->Length); +} + +static void +acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd) +{ + char *cp; + int remaining, consumed; + + printf("\n"); + printf("\tType=DRHD\n"); + printf("\tLength=%d\n", drhd->Header.Length); + +#define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) + + printf("\tFlags="); + PRINTFLAG(drhd->Flags, INCLUDE_ALL); + PRINTFLAG_END(); + +#undef PRINTFLAG + + printf("\tSegment=%d\n", drhd->Segment); + printf("\tAddress=0x%0jx\n", drhd->Address); + + remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT); + if (remaining > 0) + printf("\tDevice Scope:"); + while (remaining > 0) { + cp = (char *)drhd + drhd->Header.Length - remaining; + consumed = acpi_handle_dmar_devscope(cp, remaining); + if (consumed <= 0) + break; + else + remaining -= consumed; + } +} + +static void +acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr) +{ + char *cp; + int remaining, consumed; + + printf("\n"); + printf("\tType=RMRR\n"); + printf("\tLength=%d\n", rmrr->Header.Length); + printf("\tSegment=%d\n", rmrr->Segment); + printf("\tBaseAddress=0x%0jx\n", rmrr->BaseAddress); + printf("\tLimitAddress=0x%0jx\n", rmrr->EndAddress); + + remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY); + if (remaining > 0) + printf("\tDevice Scope:"); + while (remaining > 0) { + cp = (char *)rmrr + rmrr->Header.Length - remaining; + consumed = acpi_handle_dmar_devscope(cp, remaining); + if (consumed <= 0) + break; + else + remaining -= consumed; + } +} + +static void +acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr) +{ + char *cp; + int remaining, consumed; + + printf("\n"); + printf("\tType=ATSR\n"); + printf("\tLength=%d\n", atsr->Header.Length); + +#define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) + + printf("\tFlags="); + PRINTFLAG(atsr->Flags, ALL_PORTS); + PRINTFLAG_END(); + +#undef PRINTFLAG + + printf("\tSegment=%d\n", atsr->Segment); + + remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR); + if (remaining > 0) + printf("\tDevice Scope:"); + while (remaining > 0) { + cp = (char *)atsr + atsr->Header.Length - remaining; + consumed = acpi_handle_dmar_devscope(cp, remaining); + if (consumed <= 0) + break; + else + remaining -= consumed; + } +} + +static void +acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa) +{ + + printf("\n"); + printf("\tType=RHSA\n"); + printf("\tLength=%d\n", rhsa->Header.Length); + printf("\tBaseAddress=0x%0jx\n", rhsa->BaseAddress); + printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain); +} + +static int +acpi_handle_dmar_remapping_structure(void *addr, int remaining) +{ + ACPI_DMAR_HEADER *hdr = addr; + + if (remaining < (int)sizeof(ACPI_DMAR_HEADER)) + return (-1); + + if (remaining < hdr->Length) + return (-1); + + switch (hdr->Type) { + case ACPI_DMAR_TYPE_HARDWARE_UNIT: + acpi_handle_dmar_drhd(addr); + break; + case ACPI_DMAR_TYPE_RESERVED_MEMORY: + acpi_handle_dmar_rmrr(addr); + break; + case ACPI_DMAR_TYPE_ATSR: + acpi_handle_dmar_atsr(addr); + break; + case ACPI_DMAR_HARDWARE_AFFINITY: + acpi_handle_dmar_rhsa(addr); + break; + default: + printf("\n"); + printf("\tType=%d\n", hdr->Type); + printf("\tLength=%d\n", hdr->Length); + break; + } + return (hdr->Length); +} + +#ifndef ACPI_DMAR_X2APIC_OPT_OUT +#define ACPI_DMAR_X2APIC_OPT_OUT (0x2) +#endif + +static void +acpi_handle_dmar(ACPI_TABLE_HEADER *sdp) +{ + char *cp; + int remaining, consumed; + ACPI_TABLE_DMAR *dmar; + + printf(BEGIN_COMMENT); + acpi_print_sdt(sdp); + dmar = (ACPI_TABLE_DMAR *)sdp; + printf("\tHost Address Width=%d\n", dmar->Width + 1); + +#define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag) + + printf("\tFlags="); + PRINTFLAG(dmar->Flags, INTR_REMAP); + PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT); + PRINTFLAG_END(); + +#undef PRINTFLAG + + remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR); + while (remaining > 0) { + cp = (char *)sdp + sdp->Length - remaining; + consumed = acpi_handle_dmar_remapping_structure(cp, remaining); + if (consumed <= 0) + break; + else + remaining -= consumed; + } + + printf(END_COMMENT); +} + static void acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp) { @@ -854,7 +1111,6 @@ acpi_print_fadt(ACPI_TABLE_HEADER *sdp) { ACPI_TABLE_FADT *fadt; const char *pm; - char sep; fadt = (ACPI_TABLE_FADT *)sdp; printf(BEGIN_COMMENT); @@ -914,25 +1170,17 @@ acpi_print_fadt(ACPI_TABLE_HEADER *sdp) printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n", fadt->DayAlarm, fadt->MonthAlarm, fadt->Century); -#define PRINTFLAG(var, flag) do { \ - if ((var) & ACPI_FADT_## flag) { \ - printf("%c%s", sep, #flag); sep = ','; \ - } \ -} while (0) +#define PRINTFLAG(var, flag) printflag((var), ACPI_FADT_## flag, #flag) printf("\tIAPC_BOOT_ARCH="); - sep = '{'; PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES); PRINTFLAG(fadt->BootFlags, 8042); PRINTFLAG(fadt->BootFlags, NO_VGA); PRINTFLAG(fadt->BootFlags, NO_MSI); PRINTFLAG(fadt->BootFlags, NO_ASPM); - if (fadt->BootFlags != 0) - printf("}"); - printf("\n"); + PRINTFLAG_END(); printf("\tFlags="); - sep = '{'; PRINTFLAG(fadt->Flags, WBINVD); PRINTFLAG(fadt->Flags, WBINVD_FLUSH); PRINTFLAG(fadt->Flags, C1_SUPPORTED); @@ -953,8 +1201,7 @@ acpi_print_fadt(ACPI_TABLE_HEADER *sdp) PRINTFLAG(fadt->Flags, REMOTE_POWER_ON); PRINTFLAG(fadt->Flags, APIC_CLUSTER); PRINTFLAG(fadt->Flags, APIC_PHYSICAL); - if (fadt->Flags != 0) - printf("}\n"); + PRINTFLAG_END(); #undef PRINTFLAG @@ -1127,6 +1374,8 @@ acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp acpi_handle_srat(sdp); else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4)) acpi_handle_tcpa(sdp); + else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4)) + acpi_handle_dmar(sdp); else { printf(BEGIN_COMMENT); acpi_print_sdt(sdp); Modified: head/usr.sbin/acpi/acpidump/acpidump.8 ============================================================================== --- head/usr.sbin/acpi/acpidump/acpidump.8 Fri Dec 21 00:41:52 2012 (r244524) +++ head/usr.sbin/acpi/acpidump/acpidump.8 Fri Dec 21 01:19:48 2012 (r244525) @@ -97,6 +97,7 @@ flag, the utility dumps contents of the following tables: .Pp .Bl -tag -offset indent -width 12345 -compact +.It DMAR .It DSDT .It ECDT .It FACS