[PATCH 3/5] acpi: acpidump: dump out the DMAR table
Colin King
colin.king at canonical.com
Fri Jun 29 13:11:05 UTC 2012
From: Colin Ian King <colin.king at canonical.com>
The DMAR table is fairly well described so lets also dump
this one out in an annotated form too.
Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
src/acpi/acpidump/acpidump.c | 117 ++++++++++++++++++++++++++++++++++++++++++
src/lib/include/fwts_acpi.h | 53 +++++++++++++++++++
2 files changed, 170 insertions(+)
diff --git a/src/acpi/acpidump/acpidump.c b/src/acpi/acpidump/acpidump.c
index 3ff3e75..79d4c4d 100644
--- a/src/acpi/acpidump/acpidump.c
+++ b/src/acpi/acpidump/acpidump.c
@@ -1202,6 +1202,122 @@ static void acpidump_asf(fwts_framework *fw, fwts_acpi_table_info *table)
}
}
+/*
+ * acpidump_dmar()
+ * dump out DMAR
+ * http://download.intel.com/technology/computing/vptech/Intel(r)_VT_for_Direct_IO.pdf
+ */
+static void acpidump_dmar(fwts_framework *fw, fwts_acpi_table_info *table)
+{
+ uint8_t *data = (uint8_t *)table->data;
+ size_t length = table->length;
+ uint8_t *ptr = data;
+ size_t device_scope_length;
+
+ static fwts_acpidump_field dmar_fields[] = {
+ FIELD_UINT("Host Address Width", fwts_acpi_table_dmar, host_addr_width),
+ FIELD_UINT("Flags", fwts_acpi_table_dmar, flags),
+ FIELD_UINT("Reserved", fwts_acpi_table_dmar, reserved),
+ FIELD_END
+ };
+
+ static fwts_acpidump_field dmar_header_fields[] = {
+ FIELD_UINT("Type", fwts_acpi_table_dmar_header, type),
+ FIELD_UINT("Length", fwts_acpi_table_dmar_header, length),
+ FIELD_END
+ };
+
+ static fwts_acpidump_field dmar_hardware_unit_fields[] = {
+ FIELD_UINT("Flags", fwts_acpi_table_dmar_hardware_unit, flags),
+ FIELD_UINT("Reserved", fwts_acpi_table_dmar_hardware_unit, reserved),
+ FIELD_UINT("Segment Number", fwts_acpi_table_dmar_hardware_unit, segment_number),
+ FIELD_UINT("Register Base Address", fwts_acpi_table_dmar_hardware_unit, register_base_addr),
+ FIELD_UINT("Device Scope", fwts_acpi_table_dmar_hardware_unit, device_scope),
+ FIELD_END
+ };
+
+ static fwts_acpidump_field dmar_reserved_memory_fields[] = {
+ FIELD_UINT("Reserved", fwts_acpi_table_dmar_reserved_memory, reserved),
+ FIELD_UINT("Segment", fwts_acpi_table_dmar_reserved_memory, segment),
+ FIELD_UINT("Base Address", fwts_acpi_table_dmar_reserved_memory, base_address),
+ FIELD_UINT("End Address", fwts_acpi_table_dmar_reserved_memory, end_address),
+
+ FIELD_END
+ };
+
+ static fwts_acpidump_field dmar_atsr_fields[] = {
+ FIELD_UINT("Flags", fwts_acpi_table_dmar_atsr, flags),
+ FIELD_UINT("Reserved", fwts_acpi_table_dmar_atsr, reserved),
+ FIELD_UINT("Segment", fwts_acpi_table_dmar_atsr, segment),
+ FIELD_END
+ };
+
+ static fwts_acpidump_field dmar_device_scope_fields[] = {
+ FIELD_UINT("Type", fwts_acpi_table_dmar_device_scope, type),
+ FIELD_UINT("Length", fwts_acpi_table_dmar_device_scope, length),
+ FIELD_UINT("Reserved", fwts_acpi_table_dmar_device_scope, reserved),
+ FIELD_UINT("Enumeration ID", fwts_acpi_table_dmar_device_scope, enumeration_id),
+ FIELD_UINT("Start Bus Number", fwts_acpi_table_dmar_device_scope, start_bus_number),
+ FIELD_END
+ };
+
+ __acpi_dump_table_fields(fw, ptr, dmar_fields, ptr - data);
+
+ ptr += sizeof(fwts_acpi_table_dmar);
+
+ while (ptr < data + length) {
+ uint8_t *tmpptr;
+ fwts_acpi_table_dmar_header *header =
+ (fwts_acpi_table_dmar_header *)ptr;
+
+ fwts_log_nl(fw);
+
+ switch (header->type) {
+ case 0:
+ fwts_log_info_verbatum(fw, "Hardware Unit Definition:");
+ __acpi_dump_table_fields(fw, ptr, dmar_header_fields, ptr - data);
+ __acpi_dump_table_fields(fw, ptr, dmar_hardware_unit_fields, ptr - data);
+ device_scope_length = (size_t)header->length - sizeof(fwts_acpi_table_dmar_hardware_unit);
+ tmpptr = ptr + sizeof(fwts_acpi_table_dmar_hardware_unit);
+
+ /* Parse through multiple device scopes */
+ while (device_scope_length > 0) {
+ int i;
+
+ fwts_acpi_table_dmar_device_scope *device_scope =
+ (fwts_acpi_table_dmar_device_scope *)tmpptr;
+ __acpi_dump_table_fields(fw, tmpptr, dmar_device_scope_fields, tmpptr - data);
+ /*
+ * The device scope has a variable length path,
+ * so just dump this raw data out for now.
+ */
+ for (i=0; i < device_scope->length - sizeof(fwts_acpi_table_dmar_device_scope); i++) {
+ uint8_t val8 = device_scope->path[i];
+ fwts_log_info_verbatum(fw, "%s 0x%2.2x [%d]", acpi_dump_field_info("Path", 1, (tmpptr - data) + sizeof(fwts_acpi_table_dmar_device_scope) + i), val8, i);
+ }
+ tmpptr += device_scope->length;
+ device_scope_length -= device_scope->length;
+ }
+ break;
+ case 1:
+ fwts_log_info_verbatum(fw, "Reserved Memory Definition:");
+ __acpi_dump_table_fields(fw, ptr, dmar_header_fields, ptr - data);
+ __acpi_dump_table_fields(fw, ptr, dmar_reserved_memory_fields, ptr - data);
+ break;
+ case 2:
+ fwts_log_info_verbatum(fw, "Root Port ATS Capability Reporting Structure:");
+ __acpi_dump_table_fields(fw, ptr, dmar_header_fields, ptr - data);
+ __acpi_dump_table_fields(fw, ptr, dmar_atsr_fields, ptr - data);
+ break;
+ default:
+ /* and anything else */
+ break;
+ }
+
+ ptr += header->length;
+ }
+}
+
typedef struct {
char *name;
void (*func)(fwts_framework *fw, fwts_acpi_table_info *table);
@@ -1220,6 +1336,7 @@ static acpidump_table_vec table_vec[] = {
{ "BOOT", acpidump_boot, 1 },
{ "CPEP", acpidump_cpep, 1 },
{ "DSDT", acpidump_amlcode, 1 },
+ { "DMAR", acpidump_dmar, 1 },
{ "ECDT", acpidump_ecdt, 1 },
{ "EINJ", acpidump_einj, 1 },
{ "ERST", acpidump_erst, 1 },
diff --git a/src/lib/include/fwts_acpi.h b/src/lib/include/fwts_acpi.h
index 03f7c2e..ef25ef5 100644
--- a/src/lib/include/fwts_acpi.h
+++ b/src/lib/include/fwts_acpi.h
@@ -504,6 +504,59 @@ typedef struct {
uint8_t fwts_acpi_table_asf_addr_element[0];
} __attribute__ ((packed)) fwts_acpi_table_asf_addr;
+/*
+ * DMAR
+ * See http://download.intel.com/technology/computing/vptech/Intel(r)_VT_for_Direct_IO.pdf
+ */
+typedef struct {
+ fwts_acpi_table_header header;
+ uint8_t host_addr_width;
+ uint8_t flags;
+ uint8_t reserved[10];
+} __attribute__ ((packed)) fwts_acpi_table_dmar;
+
+typedef struct {
+ uint16_t type;
+ uint16_t length;
+} __attribute__ ((packed)) fwts_acpi_table_dmar_header;
+
+/* DMA remapping hardware unit definition structure */
+typedef struct {
+ fwts_acpi_table_dmar_header header;
+ uint8_t flags;
+ uint8_t reserved;
+ uint16_t segment_number;
+ uint64_t register_base_addr;
+ uint8_t device_scope[0];
+} __attribute__ ((packed)) fwts_acpi_table_dmar_hardware_unit;
+
+/* Reserved Memory Defininition */
+typedef struct {
+ fwts_acpi_table_dmar_header header;
+ uint16_t reserved;
+ uint16_t segment;
+ uint64_t base_address;
+ uint64_t end_address;
+} __attribute__ ((packed)) fwts_acpi_table_dmar_reserved_memory;
+
+/* Root Port ATS capability reporting structure */
+typedef struct {
+ fwts_acpi_table_dmar_header header;
+ uint8_t flags;
+ uint8_t reserved;
+ uint16_t segment;
+} __attribute__ ((packed)) fwts_acpi_table_dmar_atsr;
+
+/* DMA remapping device scope entries */
+typedef struct {
+ uint8_t type;
+ uint8_t length;
+ uint8_t reserved[2];
+ uint8_t enumeration_id;
+ uint8_t start_bus_number;
+ uint8_t path[0];
+} __attribute__ ((packed)) fwts_acpi_table_dmar_device_scope;
+
void fwts_acpi_table_get_header(fwts_acpi_table_header *hdr, uint8_t *data);
#endif
--
1.7.10.4
More information about the fwts-devel
mailing list