Message ID | 1340975467-23977-4-git-send-email-colin.king@canonical.com |
---|---|
State | Rejected |
Headers | show |
Hi Colin, I read DMA Remapping Table (http://download.intel.com/technology/computing/vptech/Intel(r)_VT_for_Direct_IO.pdf), and both Reserved Memory Definition and Root Port ATS capability reporting structure has a field "Device Scope []" that is only present in your DMA remapping hardware unit definition structure. Is this intentional? Best Regards, Alex Hung On 06/29/2012 09:11 PM, Colin King wrote: > From: Colin Ian King <colin.king@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@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 >
On 02/07/12 07:09, Alex Hung wrote: > Hi Colin, > > I read DMA Remapping Table > (http://download.intel.com/technology/computing/vptech/Intel(r)_VT_for_Direct_IO.pdf), > and both Reserved Memory Definition and Root Port ATS capability > reporting structure has a field "Device Scope []" that is only present > in your DMA remapping hardware unit definition structure. > > Is this intentional? My mistake. Let me fix that up and send out the correct patch later. Thanks for spotting that! Colin > > Best Regards, > Alex Hung > > On 06/29/2012 09:11 PM, Colin King wrote: >> From: Colin Ian King <colin.king@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@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 >> > > >
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