Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Dec 2012 01:19:49 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r244525 - head/usr.sbin/acpi/acpidump
Message-ID:  <201212210119.qBL1Jn1T060627@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201212210119.qBL1Jn1T060627>