[PATCH 2/5] acpi: acpidump: dump out the ASF! table
Colin King
colin.king at canonical.com
Fri Jun 29 13:11:04 UTC 2012
From: Colin Ian King <colin.king at 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 at 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
More information about the fwts-devel
mailing list