From patchwork Fri Jun 29 13:11:04 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Colin Ian King X-Patchwork-Id: 168071 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id 6ACA9B6FA7 for ; Fri, 29 Jun 2012 23:11:15 +1000 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1Skayg-00009k-6Y for incoming@patchwork.ozlabs.org; Fri, 29 Jun 2012 13:11:14 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1Skayb-000081-QW for fwts-devel@lists.ubuntu.com; Fri, 29 Jun 2012 13:11:09 +0000 Received: from cpc19-craw6-2-0-cust5.croy.cable.virginmedia.com ([77.102.228.6] helo=localhost) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1Skayb-0002fC-Bl for fwts-devel@lists.ubuntu.com; Fri, 29 Jun 2012 13:11:09 +0000 From: Colin King To: fwts-devel@lists.ubuntu.com Subject: [PATCH 2/5] acpi: acpidump: dump out the ASF! table Date: Fri, 29 Jun 2012 14:11:04 +0100 Message-Id: <1340975467-23977-3-git-send-email-colin.king@canonical.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1340975467-23977-1-git-send-email-colin.king@canonical.com> References: <1340975467-23977-1-git-send-email-colin.king@canonical.com> X-BeenThere: fwts-devel@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Firmware Test Suite Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: fwts-devel-bounces@lists.ubuntu.com Errors-To: fwts-devel-bounces@lists.ubuntu.com From: Colin Ian King 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 Acked-by: Alex Hung Acked-by: Keng-Yu Lin --- 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