Message ID | 1340975467-23977-3-git-send-email-colin.king@canonical.com |
---|---|
State | Accepted |
Headers | show |
On 06/29/2012 09:11 PM, Colin King wrote: > From: Colin Ian King <colin.king@canonical.com> > > Kind of academic, but there are good descriptions of the ASF! and > modern firmware seems to have these tables, so lets dump these > out in an annotated form. > > Signed-off-by: Colin Ian King <colin.king@canonical.com> > --- > src/acpi/acpidump/acpidump.c | 167 +++++++++++++++++++++++++++++++++++++++++- > src/lib/include/fwts_acpi.h | 76 +++++++++++++++++++ > 2 files changed, 241 insertions(+), 2 deletions(-) > > diff --git a/src/acpi/acpidump/acpidump.c b/src/acpi/acpidump/acpidump.c > index 3b4b2d0..3ff3e75 100644 > --- a/src/acpi/acpidump/acpidump.c > +++ b/src/acpi/acpidump/acpidump.c > @@ -195,8 +195,6 @@ static void acpi_dump_raw_data(fwts_framework *fw, uint8_t *data, size_t length) > { > int n; > > - fwts_log_nl(fw); > - > for (n = 0; n < length; n+=16) { > int left = length - n; > char buffer[128]; > @@ -207,6 +205,7 @@ static void acpi_dump_raw_data(fwts_framework *fw, uint8_t *data, size_t length) > > static void acpi_dump_raw_table(fwts_framework *fw, fwts_acpi_table_info *table) > { > + fwts_log_nl(fw); > acpi_dump_raw_data(fw, (uint8_t *)table->data, table->length); > } > > @@ -363,6 +362,7 @@ static void acpidump_bert(fwts_framework *fw, fwts_acpi_table_info *table) > }; > > acpi_dump_table_fields(fw, data, fields, length, length); > + fwts_log_nl(fw); > acpi_dump_raw_data(fw, bert->generic_error_data, n); > } > > @@ -406,6 +406,7 @@ static void acpidump_ecdt(fwts_framework *fw, fwts_acpi_table_info *table) > acpi_dump_table_fields(fw, data, fields, 0, length); > > fwts_log_info_verbatum(fw, "EC_ID:"); > + fwts_log_nl(fw); > acpi_dump_raw_data(fw, ecdt->ec_id, n); > } > > @@ -1040,6 +1041,167 @@ static void acpidump_tcpa(fwts_framework *fw, fwts_acpi_table_info *table) > acpi_dump_table_fields(fw, data, fields, length, length); > } > > +/* > + * acpidump_asf() > + * dump out ASF! descruption table > + * see: http://dmtf.org/documents/asf/alert-standard-format-asf-specification-200 > + */ > +static void acpidump_asf(fwts_framework *fw, fwts_acpi_table_info *table) > +{ > + uint8_t *data = (uint8_t *)table->data; > + size_t length = table->length; > + uint8_t *ptr; > + > + ptr = data + sizeof(fwts_acpi_table_header); > + > + static fwts_acpidump_field asf_info_fields[] = { > + FIELD_UINT("Watchdog Reset Value", fwts_acpi_table_asf_info, watchdog_reset_value), > + FIELD_UINT("Min Sensor Poll Wait Time", fwts_acpi_table_asf_info, min_sensor_poll_wait_time), > + FIELD_UINT("System ID", fwts_acpi_table_asf_info, id), > + FIELD_UINT("IANA ID", fwts_acpi_table_asf_info, iana_id), > + FIELD_UINT("Feature Flags", fwts_acpi_table_asf_info, flags), > + FIELD_UINT("Reserved1", fwts_acpi_table_asf_info, reserved1), > + FIELD_UINT("Reserved2", fwts_acpi_table_asf_info, reserved2), > + FIELD_UINT("Reserved3", fwts_acpi_table_asf_info, reserved3), > + FIELD_END > + }; > + > + static fwts_acpidump_field asf_alrt_fields[] = { > + FIELD_UINT("Assertion Event Bit Mask", fwts_acpi_table_asf_alrt, assertion_mask), > + FIELD_UINT("De-assertion Event Bit Mask", fwts_acpi_table_asf_alrt, deassertion_mask), > + FIELD_UINT("Number of Alerts", fwts_acpi_table_asf_alrt, number_of_alerts), > + FIELD_UINT("Array Element Length", fwts_acpi_table_asf_alrt, array_length), > + FIELD_END > + }; > + > + static fwts_acpidump_field asf_alrt_element_fields[] = { > + FIELD_UINT("Alert Device Address", fwts_acpi_table_asf_alrt_element, device_addr), > + FIELD_UINT("Alert Command", fwts_acpi_table_asf_alrt_element, command), > + FIELD_UINT("Alert Data Mask", fwts_acpi_table_asf_alrt_element, data_mask), > + FIELD_UINT("Alert Compare Value", fwts_acpi_table_asf_alrt_element, compare_value), > + FIELD_UINT("Alert Event Sensor Type", fwts_acpi_table_asf_alrt_element, sensor_type), > + FIELD_UINT("Alert Event Type", fwts_acpi_table_asf_alrt_element, event_type), > + FIELD_UINT("Alert Event Offset", fwts_acpi_table_asf_alrt_element, event_offset), > + FIELD_UINT("Alert Event Source Type", fwts_acpi_table_asf_alrt_element, event_source_type), > + FIELD_UINT("Alert Event Severity", fwts_acpi_table_asf_alrt_element, event_severity), > + FIELD_UINT("Alert Sensor Number", fwts_acpi_table_asf_alrt_element, sensor_number), > + FIELD_UINT("Alert Entity", fwts_acpi_table_asf_alrt_element, entity), > + FIELD_UINT("Alert Entity Instance", fwts_acpi_table_asf_alrt_element, entity_instance), > + FIELD_END > + }; > + > + static fwts_acpidump_field asf_rctl_fields[] = { > + FIELD_UINT("Number of Controls", fwts_acpi_table_asf_rctl, number_of_controls), > + FIELD_UINT("Array Element Length", fwts_acpi_table_asf_rctl, array_element_length), > + FIELD_UINT("Reserved", fwts_acpi_table_asf_rctl, reserved), > + FIELD_END > + }; > + > + static fwts_acpidump_field asf_rctl_element_fields[] = { > + FIELD_UINT("Control Function", fwts_acpi_table_asf_rctl_element, control_function), > + FIELD_UINT("Control Device Address", fwts_acpi_table_asf_rctl_element, control_device_addr), > + FIELD_UINT("Control Command", fwts_acpi_table_asf_rctl_element, control_command), > + FIELD_UINT("Control Value", fwts_acpi_table_asf_rctl_element, control_value), > + FIELD_END > + }; > + > + static fwts_acpidump_field asf_rcmp_fields[] = { > + FIELD_UINT("Remote Control Capabilities", fwts_acpi_table_asf_rcmp, remote_control_capabilities), > + FIELD_UINT("RMCP Boot Options Completion Code", fwts_acpi_table_asf_rcmp, rcmp_completion_code), > + FIELD_UINT("RMCP IANA Enterprise ID", fwts_acpi_table_asf_rcmp, rcmp_iana), > + FIELD_UINT("RMCP Special Command", fwts_acpi_table_asf_rcmp, rcmp_special_command), > + FIELD_UINT("RMCP Special Command Parameter", fwts_acpi_table_asf_rcmp, rcmp_special_command_param), > + FIELD_UINT("RMCP Boot Options", fwts_acpi_table_asf_rcmp, rcmp_boot_options), > + FIELD_UINT("RMCP OEM Parameters", fwts_acpi_table_asf_rcmp, rcmp_oem_parameters), > + FIELD_END > + }; > + > + static fwts_acpidump_field asf_header_fields[] = { > + FIELD_UINT("Type", fwts_acpi_table_asf_header, type), > + FIELD_UINT("Reserved", fwts_acpi_table_asf_header, reserved), > + FIELD_UINT("Length", fwts_acpi_table_asf_header, length), > + }; > + > + static fwts_acpidump_field asf_addr_fields[] = { > + FIELD_UINT("SEEPROM Address", fwts_acpi_table_asf_addr, seeprom_addr), > + FIELD_UINT("Number of Devices", fwts_acpi_table_asf_addr, number_of_devices), > + FIELD_END > + }; > + > + static fwts_acpidump_field asf_addr_element_fields[] = { > + FIELD_UINT("Fixed SMBus Address", fwts_acpi_table_asf_addr_element, fixed_smbus_addr), > + FIELD_END > + }; > + > + while (ptr < data + length) { > + fwts_acpi_table_asf_header *hdr = (fwts_acpi_table_asf_header*)ptr; > + fwts_acpi_table_asf_alrt *alrt; > + fwts_acpi_table_asf_rctl *rctl; > + fwts_acpi_table_asf_addr *addr; > + uint8_t type = hdr->type; > + uint8_t i; > + uint8_t *asf_ptr = ptr; > + > + fwts_log_nl(fw); > + __acpi_dump_table_fields(fw, asf_ptr, asf_header_fields, asf_ptr - data); > + > + asf_ptr += sizeof(fwts_acpi_table_asf_header); > + > + switch (type & 0x7f) { > + case 0: > + /* Info fields */ > + __acpi_dump_table_fields(fw, asf_ptr, asf_info_fields, asf_ptr - data); > + break; > + case 1: > + /* Alert fields */ > + alrt = (fwts_acpi_table_asf_alrt *)asf_ptr; > + __acpi_dump_table_fields(fw, asf_ptr, asf_alrt_fields, asf_ptr - data); > + asf_ptr += sizeof(fwts_acpi_table_asf_alrt); > + for (i = 0; i < alrt->number_of_alerts; i++) { > + fwts_log_nl(fw); > + fwts_log_info_verbatum(fw, "ASF Alert Data #%d:\n", (int)i); > + __acpi_dump_table_fields(fw, asf_ptr, asf_alrt_element_fields, asf_ptr - data); > + asf_ptr += alrt->array_length; > + } > + break; > + case 2: > + /* remote control system actions */ > + rctl = (fwts_acpi_table_asf_rctl *)asf_ptr; > + __acpi_dump_table_fields(fw, asf_ptr, asf_rctl_fields, asf_ptr - data); > + asf_ptr += sizeof(fwts_acpi_table_asf_rctl); > + for (i = 0; i < rctl->number_of_controls; i++) { > + fwts_log_nl(fw); > + fwts_log_info_verbatum(fw, "ASF Control Data #%d:\n", (int)i); > + __acpi_dump_table_fields(fw, asf_ptr, asf_rctl_element_fields, asf_ptr - data); > + > + asf_ptr += rctl->array_element_length; > + } > + break; > + case 3: > + /* remote control capabilties */ > + __acpi_dump_table_fields(fw, asf_ptr, asf_rcmp_fields, asf_ptr - data); > + break; > + case 4: > + /* fixed SMBus addresses */ > + addr = (fwts_acpi_table_asf_addr *)asf_ptr; > + __acpi_dump_table_fields(fw, asf_ptr, asf_addr_fields, asf_ptr - data); > + asf_ptr += sizeof(fwts_acpi_table_asf_addr); > + for (i = 0; i < addr->number_of_devices; i++) { > + __acpi_dump_table_fields(fw, asf_ptr, asf_addr_element_fields, asf_ptr - data); > + asf_ptr += sizeof(fwts_acpi_table_asf_addr_element); > + } > + break; > + default: > + break; /* Unknown! */ > + } > + > + ptr += hdr->length; /* Jump to next header */ > + > + if (type & 0x80) /* Last record indicator, top bit of type field */ > + break; > + } > +} > + > typedef struct { > char *name; > void (*func)(fwts_framework *fw, fwts_acpi_table_info *table); > @@ -1053,6 +1215,7 @@ typedef struct { > > static acpidump_table_vec table_vec[] = { > { "APIC", acpidump_madt, 1 }, > + { "ASF!", acpidump_asf, 1 }, > { "BERT", acpidump_bert, 1 }, > { "BOOT", acpidump_boot, 1 }, > { "CPEP", acpidump_cpep, 1 }, > diff --git a/src/lib/include/fwts_acpi.h b/src/lib/include/fwts_acpi.h > index c5fe9d5..03f7c2e 100644 > --- a/src/lib/include/fwts_acpi.h > +++ b/src/lib/include/fwts_acpi.h > @@ -428,6 +428,82 @@ typedef struct { > uint64_t log_zone_addr; > } __attribute__ ((packed)) fwts_acpi_table_tcpa; > > +/* Following ASF definitions from > + http://dmtf.org/documents/asf/alert-standard-format-asf-specification-200 */ > +typedef struct { > + uint8_t type; > + uint8_t reserved; > + uint16_t length; > +} __attribute__ ((packed)) fwts_acpi_table_asf_header; > + > +typedef struct { > + uint8_t watchdog_reset_value; > + uint8_t min_sensor_poll_wait_time; > + uint16_t id; > + uint32_t iana_id; > + uint8_t flags; > + uint8_t reserved1; > + uint8_t reserved2; > + uint8_t reserved3; > +} __attribute__ ((packed)) fwts_acpi_table_asf_info; > + > +typedef struct { > + uint8_t device_addr; > + uint8_t command; > + uint8_t data_mask; > + uint8_t compare_value; > + uint8_t sensor_type; > + uint8_t event_type; > + uint8_t event_offset; > + uint8_t event_source_type; > + uint8_t event_severity; > + uint8_t sensor_number; > + uint8_t entity; > + uint8_t entity_instance; > +} __attribute__ ((packed)) fwts_acpi_table_asf_alrt_element; > + > +typedef struct { > + uint8_t assertion_mask; > + uint8_t deassertion_mask; > + uint8_t number_of_alerts; > + uint8_t array_length; > + uint8_t device_length[0]; > +} __attribute__ ((packed)) fwts_acpi_table_asf_alrt; > + > +typedef struct { > + uint8_t control_function; > + uint8_t control_device_addr; > + uint8_t control_command; > + uint8_t control_value; > +} __attribute__ ((packed)) fwts_acpi_table_asf_rctl_element; > + > +typedef struct { > + uint8_t number_of_controls; > + uint8_t array_element_length; > + uint16_t reserved; > + fwts_acpi_table_asf_rctl_element elements[0]; > +} __attribute__ ((packed)) fwts_acpi_table_asf_rctl; > + > +typedef struct { > + uint8_t remote_control_capabilities[7]; > + uint8_t rcmp_completion_code; > + uint8_t rcmp_iana[4]; > + uint8_t rcmp_special_command; > + uint8_t rcmp_special_command_param[2]; > + uint8_t rcmp_boot_options[2]; > + uint8_t rcmp_oem_parameters[2]; > +} __attribute__ ((packed)) fwts_acpi_table_asf_rcmp; > + > +typedef struct { > + uint8_t fixed_smbus_addr; > +} __attribute__ ((packed)) fwts_acpi_table_asf_addr_element; > + > +typedef struct { > + uint8_t seeprom_addr; > + uint8_t number_of_devices; > + uint8_t fwts_acpi_table_asf_addr_element[0]; > +} __attribute__ ((packed)) fwts_acpi_table_asf_addr; > + > void fwts_acpi_table_get_header(fwts_acpi_table_header *hdr, uint8_t *data); > > #endif > Acked-by: Alex Hung <alex.hung@canonical.com>
On Fri, Jun 29, 2012 at 9:11 PM, Colin King <colin.king@canonical.com> wrote: > From: Colin Ian King <colin.king@canonical.com> > > Kind of academic, but there are good descriptions of the ASF! and > modern firmware seems to have these tables, so lets dump these > out in an annotated form. > > Signed-off-by: Colin Ian King <colin.king@canonical.com> > --- > src/acpi/acpidump/acpidump.c | 167 +++++++++++++++++++++++++++++++++++++++++- > src/lib/include/fwts_acpi.h | 76 +++++++++++++++++++ > 2 files changed, 241 insertions(+), 2 deletions(-) > > diff --git a/src/acpi/acpidump/acpidump.c b/src/acpi/acpidump/acpidump.c > index 3b4b2d0..3ff3e75 100644 > --- a/src/acpi/acpidump/acpidump.c > +++ b/src/acpi/acpidump/acpidump.c > @@ -195,8 +195,6 @@ static void acpi_dump_raw_data(fwts_framework *fw, uint8_t *data, size_t length) > { > int n; > > - fwts_log_nl(fw); > - > for (n = 0; n < length; n+=16) { > int left = length - n; > char buffer[128]; > @@ -207,6 +205,7 @@ static void acpi_dump_raw_data(fwts_framework *fw, uint8_t *data, size_t length) > > static void acpi_dump_raw_table(fwts_framework *fw, fwts_acpi_table_info *table) > { > + fwts_log_nl(fw); > acpi_dump_raw_data(fw, (uint8_t *)table->data, table->length); > } > > @@ -363,6 +362,7 @@ static void acpidump_bert(fwts_framework *fw, fwts_acpi_table_info *table) > }; > > acpi_dump_table_fields(fw, data, fields, length, length); > + fwts_log_nl(fw); > acpi_dump_raw_data(fw, bert->generic_error_data, n); > } > > @@ -406,6 +406,7 @@ static void acpidump_ecdt(fwts_framework *fw, fwts_acpi_table_info *table) > acpi_dump_table_fields(fw, data, fields, 0, length); > > fwts_log_info_verbatum(fw, "EC_ID:"); > + fwts_log_nl(fw); > acpi_dump_raw_data(fw, ecdt->ec_id, n); > } > > @@ -1040,6 +1041,167 @@ static void acpidump_tcpa(fwts_framework *fw, fwts_acpi_table_info *table) > acpi_dump_table_fields(fw, data, fields, length, length); > } > > +/* > + * acpidump_asf() > + * dump out ASF! descruption table > + * see: http://dmtf.org/documents/asf/alert-standard-format-asf-specification-200 > + */ > +static void acpidump_asf(fwts_framework *fw, fwts_acpi_table_info *table) > +{ > + uint8_t *data = (uint8_t *)table->data; > + size_t length = table->length; > + uint8_t *ptr; > + > + ptr = data + sizeof(fwts_acpi_table_header); > + > + static fwts_acpidump_field asf_info_fields[] = { > + FIELD_UINT("Watchdog Reset Value", fwts_acpi_table_asf_info, watchdog_reset_value), > + FIELD_UINT("Min Sensor Poll Wait Time", fwts_acpi_table_asf_info, min_sensor_poll_wait_time), > + FIELD_UINT("System ID", fwts_acpi_table_asf_info, id), > + FIELD_UINT("IANA ID", fwts_acpi_table_asf_info, iana_id), > + FIELD_UINT("Feature Flags", fwts_acpi_table_asf_info, flags), > + FIELD_UINT("Reserved1", fwts_acpi_table_asf_info, reserved1), > + FIELD_UINT("Reserved2", fwts_acpi_table_asf_info, reserved2), > + FIELD_UINT("Reserved3", fwts_acpi_table_asf_info, reserved3), > + FIELD_END > + }; > + > + static fwts_acpidump_field asf_alrt_fields[] = { > + FIELD_UINT("Assertion Event Bit Mask", fwts_acpi_table_asf_alrt, assertion_mask), > + FIELD_UINT("De-assertion Event Bit Mask", fwts_acpi_table_asf_alrt, deassertion_mask), > + FIELD_UINT("Number of Alerts", fwts_acpi_table_asf_alrt, number_of_alerts), > + FIELD_UINT("Array Element Length", fwts_acpi_table_asf_alrt, array_length), > + FIELD_END > + }; > + > + static fwts_acpidump_field asf_alrt_element_fields[] = { > + FIELD_UINT("Alert Device Address", fwts_acpi_table_asf_alrt_element, device_addr), > + FIELD_UINT("Alert Command", fwts_acpi_table_asf_alrt_element, command), > + FIELD_UINT("Alert Data Mask", fwts_acpi_table_asf_alrt_element, data_mask), > + FIELD_UINT("Alert Compare Value", fwts_acpi_table_asf_alrt_element, compare_value), > + FIELD_UINT("Alert Event Sensor Type", fwts_acpi_table_asf_alrt_element, sensor_type), > + FIELD_UINT("Alert Event Type", fwts_acpi_table_asf_alrt_element, event_type), > + FIELD_UINT("Alert Event Offset", fwts_acpi_table_asf_alrt_element, event_offset), > + FIELD_UINT("Alert Event Source Type", fwts_acpi_table_asf_alrt_element, event_source_type), > + FIELD_UINT("Alert Event Severity", fwts_acpi_table_asf_alrt_element, event_severity), > + FIELD_UINT("Alert Sensor Number", fwts_acpi_table_asf_alrt_element, sensor_number), > + FIELD_UINT("Alert Entity", fwts_acpi_table_asf_alrt_element, entity), > + FIELD_UINT("Alert Entity Instance", fwts_acpi_table_asf_alrt_element, entity_instance), > + FIELD_END > + }; > + > + static fwts_acpidump_field asf_rctl_fields[] = { > + FIELD_UINT("Number of Controls", fwts_acpi_table_asf_rctl, number_of_controls), > + FIELD_UINT("Array Element Length", fwts_acpi_table_asf_rctl, array_element_length), > + FIELD_UINT("Reserved", fwts_acpi_table_asf_rctl, reserved), > + FIELD_END > + }; > + > + static fwts_acpidump_field asf_rctl_element_fields[] = { > + FIELD_UINT("Control Function", fwts_acpi_table_asf_rctl_element, control_function), > + FIELD_UINT("Control Device Address", fwts_acpi_table_asf_rctl_element, control_device_addr), > + FIELD_UINT("Control Command", fwts_acpi_table_asf_rctl_element, control_command), > + FIELD_UINT("Control Value", fwts_acpi_table_asf_rctl_element, control_value), > + FIELD_END > + }; > + > + static fwts_acpidump_field asf_rcmp_fields[] = { > + FIELD_UINT("Remote Control Capabilities", fwts_acpi_table_asf_rcmp, remote_control_capabilities), > + FIELD_UINT("RMCP Boot Options Completion Code", fwts_acpi_table_asf_rcmp, rcmp_completion_code), > + FIELD_UINT("RMCP IANA Enterprise ID", fwts_acpi_table_asf_rcmp, rcmp_iana), > + FIELD_UINT("RMCP Special Command", fwts_acpi_table_asf_rcmp, rcmp_special_command), > + FIELD_UINT("RMCP Special Command Parameter", fwts_acpi_table_asf_rcmp, rcmp_special_command_param), > + FIELD_UINT("RMCP Boot Options", fwts_acpi_table_asf_rcmp, rcmp_boot_options), > + FIELD_UINT("RMCP OEM Parameters", fwts_acpi_table_asf_rcmp, rcmp_oem_parameters), > + FIELD_END > + }; > + > + static fwts_acpidump_field asf_header_fields[] = { > + FIELD_UINT("Type", fwts_acpi_table_asf_header, type), > + FIELD_UINT("Reserved", fwts_acpi_table_asf_header, reserved), > + FIELD_UINT("Length", fwts_acpi_table_asf_header, length), > + }; > + > + static fwts_acpidump_field asf_addr_fields[] = { > + FIELD_UINT("SEEPROM Address", fwts_acpi_table_asf_addr, seeprom_addr), > + FIELD_UINT("Number of Devices", fwts_acpi_table_asf_addr, number_of_devices), > + FIELD_END > + }; > + > + static fwts_acpidump_field asf_addr_element_fields[] = { > + FIELD_UINT("Fixed SMBus Address", fwts_acpi_table_asf_addr_element, fixed_smbus_addr), > + FIELD_END > + }; > + > + while (ptr < data + length) { > + fwts_acpi_table_asf_header *hdr = (fwts_acpi_table_asf_header*)ptr; > + fwts_acpi_table_asf_alrt *alrt; > + fwts_acpi_table_asf_rctl *rctl; > + fwts_acpi_table_asf_addr *addr; > + uint8_t type = hdr->type; > + uint8_t i; > + uint8_t *asf_ptr = ptr; > + > + fwts_log_nl(fw); > + __acpi_dump_table_fields(fw, asf_ptr, asf_header_fields, asf_ptr - data); > + > + asf_ptr += sizeof(fwts_acpi_table_asf_header); > + > + switch (type & 0x7f) { > + case 0: > + /* Info fields */ > + __acpi_dump_table_fields(fw, asf_ptr, asf_info_fields, asf_ptr - data); > + break; > + case 1: > + /* Alert fields */ > + alrt = (fwts_acpi_table_asf_alrt *)asf_ptr; > + __acpi_dump_table_fields(fw, asf_ptr, asf_alrt_fields, asf_ptr - data); > + asf_ptr += sizeof(fwts_acpi_table_asf_alrt); > + for (i = 0; i < alrt->number_of_alerts; i++) { > + fwts_log_nl(fw); > + fwts_log_info_verbatum(fw, "ASF Alert Data #%d:\n", (int)i); > + __acpi_dump_table_fields(fw, asf_ptr, asf_alrt_element_fields, asf_ptr - data); > + asf_ptr += alrt->array_length; > + } > + break; > + case 2: > + /* remote control system actions */ > + rctl = (fwts_acpi_table_asf_rctl *)asf_ptr; > + __acpi_dump_table_fields(fw, asf_ptr, asf_rctl_fields, asf_ptr - data); > + asf_ptr += sizeof(fwts_acpi_table_asf_rctl); > + for (i = 0; i < rctl->number_of_controls; i++) { > + fwts_log_nl(fw); > + fwts_log_info_verbatum(fw, "ASF Control Data #%d:\n", (int)i); > + __acpi_dump_table_fields(fw, asf_ptr, asf_rctl_element_fields, asf_ptr - data); > + > + asf_ptr += rctl->array_element_length; > + } > + break; > + case 3: > + /* remote control capabilties */ > + __acpi_dump_table_fields(fw, asf_ptr, asf_rcmp_fields, asf_ptr - data); > + break; > + case 4: > + /* fixed SMBus addresses */ > + addr = (fwts_acpi_table_asf_addr *)asf_ptr; > + __acpi_dump_table_fields(fw, asf_ptr, asf_addr_fields, asf_ptr - data); > + asf_ptr += sizeof(fwts_acpi_table_asf_addr); > + for (i = 0; i < addr->number_of_devices; i++) { > + __acpi_dump_table_fields(fw, asf_ptr, asf_addr_element_fields, asf_ptr - data); > + asf_ptr += sizeof(fwts_acpi_table_asf_addr_element); > + } > + break; > + default: > + break; /* Unknown! */ > + } > + > + ptr += hdr->length; /* Jump to next header */ > + > + if (type & 0x80) /* Last record indicator, top bit of type field */ > + break; > + } > +} > + > typedef struct { > char *name; > void (*func)(fwts_framework *fw, fwts_acpi_table_info *table); > @@ -1053,6 +1215,7 @@ typedef struct { > > static acpidump_table_vec table_vec[] = { > { "APIC", acpidump_madt, 1 }, > + { "ASF!", acpidump_asf, 1 }, > { "BERT", acpidump_bert, 1 }, > { "BOOT", acpidump_boot, 1 }, > { "CPEP", acpidump_cpep, 1 }, > diff --git a/src/lib/include/fwts_acpi.h b/src/lib/include/fwts_acpi.h > index c5fe9d5..03f7c2e 100644 > --- a/src/lib/include/fwts_acpi.h > +++ b/src/lib/include/fwts_acpi.h > @@ -428,6 +428,82 @@ typedef struct { > uint64_t log_zone_addr; > } __attribute__ ((packed)) fwts_acpi_table_tcpa; > > +/* Following ASF definitions from > + http://dmtf.org/documents/asf/alert-standard-format-asf-specification-200 */ > +typedef struct { > + uint8_t type; > + uint8_t reserved; > + uint16_t length; > +} __attribute__ ((packed)) fwts_acpi_table_asf_header; > + > +typedef struct { > + uint8_t watchdog_reset_value; > + uint8_t min_sensor_poll_wait_time; > + uint16_t id; > + uint32_t iana_id; > + uint8_t flags; > + uint8_t reserved1; > + uint8_t reserved2; > + uint8_t reserved3; > +} __attribute__ ((packed)) fwts_acpi_table_asf_info; > + > +typedef struct { > + uint8_t device_addr; > + uint8_t command; > + uint8_t data_mask; > + uint8_t compare_value; > + uint8_t sensor_type; > + uint8_t event_type; > + uint8_t event_offset; > + uint8_t event_source_type; > + uint8_t event_severity; > + uint8_t sensor_number; > + uint8_t entity; > + uint8_t entity_instance; > +} __attribute__ ((packed)) fwts_acpi_table_asf_alrt_element; > + > +typedef struct { > + uint8_t assertion_mask; > + uint8_t deassertion_mask; > + uint8_t number_of_alerts; > + uint8_t array_length; > + uint8_t device_length[0]; > +} __attribute__ ((packed)) fwts_acpi_table_asf_alrt; > + > +typedef struct { > + uint8_t control_function; > + uint8_t control_device_addr; > + uint8_t control_command; > + uint8_t control_value; > +} __attribute__ ((packed)) fwts_acpi_table_asf_rctl_element; > + > +typedef struct { > + uint8_t number_of_controls; > + uint8_t array_element_length; > + uint16_t reserved; > + fwts_acpi_table_asf_rctl_element elements[0]; > +} __attribute__ ((packed)) fwts_acpi_table_asf_rctl; > + > +typedef struct { > + uint8_t remote_control_capabilities[7]; > + uint8_t rcmp_completion_code; > + uint8_t rcmp_iana[4]; > + uint8_t rcmp_special_command; > + uint8_t rcmp_special_command_param[2]; > + uint8_t rcmp_boot_options[2]; > + uint8_t rcmp_oem_parameters[2]; > +} __attribute__ ((packed)) fwts_acpi_table_asf_rcmp; > + > +typedef struct { > + uint8_t fixed_smbus_addr; > +} __attribute__ ((packed)) fwts_acpi_table_asf_addr_element; > + > +typedef struct { > + uint8_t seeprom_addr; > + uint8_t number_of_devices; > + uint8_t fwts_acpi_table_asf_addr_element[0]; > +} __attribute__ ((packed)) fwts_acpi_table_asf_addr; > + > void fwts_acpi_table_get_header(fwts_acpi_table_header *hdr, uint8_t *data); > > #endif > -- > 1.7.10.4 > Acked-by: Keng-Yu Lin <kengyu@canonical.com>
diff --git a/src/acpi/acpidump/acpidump.c b/src/acpi/acpidump/acpidump.c index 3b4b2d0..3ff3e75 100644 --- a/src/acpi/acpidump/acpidump.c +++ b/src/acpi/acpidump/acpidump.c @@ -195,8 +195,6 @@ static void acpi_dump_raw_data(fwts_framework *fw, uint8_t *data, size_t length) { int n; - fwts_log_nl(fw); - for (n = 0; n < length; n+=16) { int left = length - n; char buffer[128]; @@ -207,6 +205,7 @@ static void acpi_dump_raw_data(fwts_framework *fw, uint8_t *data, size_t length) static void acpi_dump_raw_table(fwts_framework *fw, fwts_acpi_table_info *table) { + fwts_log_nl(fw); acpi_dump_raw_data(fw, (uint8_t *)table->data, table->length); } @@ -363,6 +362,7 @@ static void acpidump_bert(fwts_framework *fw, fwts_acpi_table_info *table) }; acpi_dump_table_fields(fw, data, fields, length, length); + fwts_log_nl(fw); acpi_dump_raw_data(fw, bert->generic_error_data, n); } @@ -406,6 +406,7 @@ static void acpidump_ecdt(fwts_framework *fw, fwts_acpi_table_info *table) acpi_dump_table_fields(fw, data, fields, 0, length); fwts_log_info_verbatum(fw, "EC_ID:"); + fwts_log_nl(fw); acpi_dump_raw_data(fw, ecdt->ec_id, n); } @@ -1040,6 +1041,167 @@ static void acpidump_tcpa(fwts_framework *fw, fwts_acpi_table_info *table) acpi_dump_table_fields(fw, data, fields, length, length); } +/* + * acpidump_asf() + * dump out ASF! descruption table + * see: http://dmtf.org/documents/asf/alert-standard-format-asf-specification-200 + */ +static void acpidump_asf(fwts_framework *fw, fwts_acpi_table_info *table) +{ + uint8_t *data = (uint8_t *)table->data; + size_t length = table->length; + uint8_t *ptr; + + ptr = data + sizeof(fwts_acpi_table_header); + + static fwts_acpidump_field asf_info_fields[] = { + FIELD_UINT("Watchdog Reset Value", fwts_acpi_table_asf_info, watchdog_reset_value), + FIELD_UINT("Min Sensor Poll Wait Time", fwts_acpi_table_asf_info, min_sensor_poll_wait_time), + FIELD_UINT("System ID", fwts_acpi_table_asf_info, id), + FIELD_UINT("IANA ID", fwts_acpi_table_asf_info, iana_id), + FIELD_UINT("Feature Flags", fwts_acpi_table_asf_info, flags), + FIELD_UINT("Reserved1", fwts_acpi_table_asf_info, reserved1), + FIELD_UINT("Reserved2", fwts_acpi_table_asf_info, reserved2), + FIELD_UINT("Reserved3", fwts_acpi_table_asf_info, reserved3), + FIELD_END + }; + + static fwts_acpidump_field asf_alrt_fields[] = { + FIELD_UINT("Assertion Event Bit Mask", fwts_acpi_table_asf_alrt, assertion_mask), + FIELD_UINT("De-assertion Event Bit Mask", fwts_acpi_table_asf_alrt, deassertion_mask), + FIELD_UINT("Number of Alerts", fwts_acpi_table_asf_alrt, number_of_alerts), + FIELD_UINT("Array Element Length", fwts_acpi_table_asf_alrt, array_length), + FIELD_END + }; + + static fwts_acpidump_field asf_alrt_element_fields[] = { + FIELD_UINT("Alert Device Address", fwts_acpi_table_asf_alrt_element, device_addr), + FIELD_UINT("Alert Command", fwts_acpi_table_asf_alrt_element, command), + FIELD_UINT("Alert Data Mask", fwts_acpi_table_asf_alrt_element, data_mask), + FIELD_UINT("Alert Compare Value", fwts_acpi_table_asf_alrt_element, compare_value), + FIELD_UINT("Alert Event Sensor Type", fwts_acpi_table_asf_alrt_element, sensor_type), + FIELD_UINT("Alert Event Type", fwts_acpi_table_asf_alrt_element, event_type), + FIELD_UINT("Alert Event Offset", fwts_acpi_table_asf_alrt_element, event_offset), + FIELD_UINT("Alert Event Source Type", fwts_acpi_table_asf_alrt_element, event_source_type), + FIELD_UINT("Alert Event Severity", fwts_acpi_table_asf_alrt_element, event_severity), + FIELD_UINT("Alert Sensor Number", fwts_acpi_table_asf_alrt_element, sensor_number), + FIELD_UINT("Alert Entity", fwts_acpi_table_asf_alrt_element, entity), + FIELD_UINT("Alert Entity Instance", fwts_acpi_table_asf_alrt_element, entity_instance), + FIELD_END + }; + + static fwts_acpidump_field asf_rctl_fields[] = { + FIELD_UINT("Number of Controls", fwts_acpi_table_asf_rctl, number_of_controls), + FIELD_UINT("Array Element Length", fwts_acpi_table_asf_rctl, array_element_length), + FIELD_UINT("Reserved", fwts_acpi_table_asf_rctl, reserved), + FIELD_END + }; + + static fwts_acpidump_field asf_rctl_element_fields[] = { + FIELD_UINT("Control Function", fwts_acpi_table_asf_rctl_element, control_function), + FIELD_UINT("Control Device Address", fwts_acpi_table_asf_rctl_element, control_device_addr), + FIELD_UINT("Control Command", fwts_acpi_table_asf_rctl_element, control_command), + FIELD_UINT("Control Value", fwts_acpi_table_asf_rctl_element, control_value), + FIELD_END + }; + + static fwts_acpidump_field asf_rcmp_fields[] = { + FIELD_UINT("Remote Control Capabilities", fwts_acpi_table_asf_rcmp, remote_control_capabilities), + FIELD_UINT("RMCP Boot Options Completion Code", fwts_acpi_table_asf_rcmp, rcmp_completion_code), + FIELD_UINT("RMCP IANA Enterprise ID", fwts_acpi_table_asf_rcmp, rcmp_iana), + FIELD_UINT("RMCP Special Command", fwts_acpi_table_asf_rcmp, rcmp_special_command), + FIELD_UINT("RMCP Special Command Parameter", fwts_acpi_table_asf_rcmp, rcmp_special_command_param), + FIELD_UINT("RMCP Boot Options", fwts_acpi_table_asf_rcmp, rcmp_boot_options), + FIELD_UINT("RMCP OEM Parameters", fwts_acpi_table_asf_rcmp, rcmp_oem_parameters), + FIELD_END + }; + + static fwts_acpidump_field asf_header_fields[] = { + FIELD_UINT("Type", fwts_acpi_table_asf_header, type), + FIELD_UINT("Reserved", fwts_acpi_table_asf_header, reserved), + FIELD_UINT("Length", fwts_acpi_table_asf_header, length), + }; + + static fwts_acpidump_field asf_addr_fields[] = { + FIELD_UINT("SEEPROM Address", fwts_acpi_table_asf_addr, seeprom_addr), + FIELD_UINT("Number of Devices", fwts_acpi_table_asf_addr, number_of_devices), + FIELD_END + }; + + static fwts_acpidump_field asf_addr_element_fields[] = { + FIELD_UINT("Fixed SMBus Address", fwts_acpi_table_asf_addr_element, fixed_smbus_addr), + FIELD_END + }; + + while (ptr < data + length) { + fwts_acpi_table_asf_header *hdr = (fwts_acpi_table_asf_header*)ptr; + fwts_acpi_table_asf_alrt *alrt; + fwts_acpi_table_asf_rctl *rctl; + fwts_acpi_table_asf_addr *addr; + uint8_t type = hdr->type; + uint8_t i; + uint8_t *asf_ptr = ptr; + + fwts_log_nl(fw); + __acpi_dump_table_fields(fw, asf_ptr, asf_header_fields, asf_ptr - data); + + asf_ptr += sizeof(fwts_acpi_table_asf_header); + + switch (type & 0x7f) { + case 0: + /* Info fields */ + __acpi_dump_table_fields(fw, asf_ptr, asf_info_fields, asf_ptr - data); + break; + case 1: + /* Alert fields */ + alrt = (fwts_acpi_table_asf_alrt *)asf_ptr; + __acpi_dump_table_fields(fw, asf_ptr, asf_alrt_fields, asf_ptr - data); + asf_ptr += sizeof(fwts_acpi_table_asf_alrt); + for (i = 0; i < alrt->number_of_alerts; i++) { + fwts_log_nl(fw); + fwts_log_info_verbatum(fw, "ASF Alert Data #%d:\n", (int)i); + __acpi_dump_table_fields(fw, asf_ptr, asf_alrt_element_fields, asf_ptr - data); + asf_ptr += alrt->array_length; + } + break; + case 2: + /* remote control system actions */ + rctl = (fwts_acpi_table_asf_rctl *)asf_ptr; + __acpi_dump_table_fields(fw, asf_ptr, asf_rctl_fields, asf_ptr - data); + asf_ptr += sizeof(fwts_acpi_table_asf_rctl); + for (i = 0; i < rctl->number_of_controls; i++) { + fwts_log_nl(fw); + fwts_log_info_verbatum(fw, "ASF Control Data #%d:\n", (int)i); + __acpi_dump_table_fields(fw, asf_ptr, asf_rctl_element_fields, asf_ptr - data); + + asf_ptr += rctl->array_element_length; + } + break; + case 3: + /* remote control capabilties */ + __acpi_dump_table_fields(fw, asf_ptr, asf_rcmp_fields, asf_ptr - data); + break; + case 4: + /* fixed SMBus addresses */ + addr = (fwts_acpi_table_asf_addr *)asf_ptr; + __acpi_dump_table_fields(fw, asf_ptr, asf_addr_fields, asf_ptr - data); + asf_ptr += sizeof(fwts_acpi_table_asf_addr); + for (i = 0; i < addr->number_of_devices; i++) { + __acpi_dump_table_fields(fw, asf_ptr, asf_addr_element_fields, asf_ptr - data); + asf_ptr += sizeof(fwts_acpi_table_asf_addr_element); + } + break; + default: + break; /* Unknown! */ + } + + ptr += hdr->length; /* Jump to next header */ + + if (type & 0x80) /* Last record indicator, top bit of type field */ + break; + } +} + typedef struct { char *name; void (*func)(fwts_framework *fw, fwts_acpi_table_info *table); @@ -1053,6 +1215,7 @@ typedef struct { static acpidump_table_vec table_vec[] = { { "APIC", acpidump_madt, 1 }, + { "ASF!", acpidump_asf, 1 }, { "BERT", acpidump_bert, 1 }, { "BOOT", acpidump_boot, 1 }, { "CPEP", acpidump_cpep, 1 }, diff --git a/src/lib/include/fwts_acpi.h b/src/lib/include/fwts_acpi.h index c5fe9d5..03f7c2e 100644 --- a/src/lib/include/fwts_acpi.h +++ b/src/lib/include/fwts_acpi.h @@ -428,6 +428,82 @@ typedef struct { uint64_t log_zone_addr; } __attribute__ ((packed)) fwts_acpi_table_tcpa; +/* Following ASF definitions from + http://dmtf.org/documents/asf/alert-standard-format-asf-specification-200 */ +typedef struct { + uint8_t type; + uint8_t reserved; + uint16_t length; +} __attribute__ ((packed)) fwts_acpi_table_asf_header; + +typedef struct { + uint8_t watchdog_reset_value; + uint8_t min_sensor_poll_wait_time; + uint16_t id; + uint32_t iana_id; + uint8_t flags; + uint8_t reserved1; + uint8_t reserved2; + uint8_t reserved3; +} __attribute__ ((packed)) fwts_acpi_table_asf_info; + +typedef struct { + uint8_t device_addr; + uint8_t command; + uint8_t data_mask; + uint8_t compare_value; + uint8_t sensor_type; + uint8_t event_type; + uint8_t event_offset; + uint8_t event_source_type; + uint8_t event_severity; + uint8_t sensor_number; + uint8_t entity; + uint8_t entity_instance; +} __attribute__ ((packed)) fwts_acpi_table_asf_alrt_element; + +typedef struct { + uint8_t assertion_mask; + uint8_t deassertion_mask; + uint8_t number_of_alerts; + uint8_t array_length; + uint8_t device_length[0]; +} __attribute__ ((packed)) fwts_acpi_table_asf_alrt; + +typedef struct { + uint8_t control_function; + uint8_t control_device_addr; + uint8_t control_command; + uint8_t control_value; +} __attribute__ ((packed)) fwts_acpi_table_asf_rctl_element; + +typedef struct { + uint8_t number_of_controls; + uint8_t array_element_length; + uint16_t reserved; + fwts_acpi_table_asf_rctl_element elements[0]; +} __attribute__ ((packed)) fwts_acpi_table_asf_rctl; + +typedef struct { + uint8_t remote_control_capabilities[7]; + uint8_t rcmp_completion_code; + uint8_t rcmp_iana[4]; + uint8_t rcmp_special_command; + uint8_t rcmp_special_command_param[2]; + uint8_t rcmp_boot_options[2]; + uint8_t rcmp_oem_parameters[2]; +} __attribute__ ((packed)) fwts_acpi_table_asf_rcmp; + +typedef struct { + uint8_t fixed_smbus_addr; +} __attribute__ ((packed)) fwts_acpi_table_asf_addr_element; + +typedef struct { + uint8_t seeprom_addr; + uint8_t number_of_devices; + uint8_t fwts_acpi_table_asf_addr_element[0]; +} __attribute__ ((packed)) fwts_acpi_table_asf_addr; + void fwts_acpi_table_get_header(fwts_acpi_table_header *hdr, uint8_t *data); #endif