/* Searches ACPI tables by signature. */ fwts_acpi_table_info *sbbr_search_acpi_tables(fwts_framework *fw, const char *signature) { uint32_t i; fwts_acpi_table_info *info; i = 0; while (fwts_acpi_get_table(fw, i, &info) == FWTS_OK) { if (info != NULL && strncmp(info->name, signature, sizeof(uint32_t)) == 0) { return info; } i++; } return NULL; }
static int acpidump_test1(fwts_framework *fw) { int i; fwts_infoonly(fw); if (fwts_iasl_init(fw) != FWTS_OK) { fwts_aborted(fw, "Failure to initialise iasl, aborting."); return FWTS_ERROR; } for (i = 0; i < ACPI_MAX_TABLES; i++) { fwts_acpi_table_info *table; fwts_list *output; char *provenance; if (fwts_acpi_get_table(fw, i, &table) != FWTS_OK) break; if (table == NULL) break; switch (table->provenance) { case FWTS_ACPI_TABLE_FROM_FILE: provenance = " (loaded from file)"; break; case FWTS_ACPI_TABLE_FROM_FIXUP: provenance = " (generated by fwts)"; break; default: provenance = ""; break; } fwts_log_info_verbatim(fw, "%s @ %lx (%zd bytes)%s", table->name, (unsigned long)table->addr, table->length, provenance); fwts_log_info_verbatim(fw, "----"); if (!strcmp(table->name, "RSDP")) { /* RSDP is a special case */ acpidump_rsdp(fw, table); } else if (table->has_aml) { /* Disassembling the AML bloats the output, so ignore */ uint8_t *data = (uint8_t *)table->data; fwts_acpi_table_header hdr; fwts_acpi_table_get_header(&hdr, data); acpidump_hdr(fw, &hdr, table->length); fwts_log_info_verbatim(fw, "Contains AML Object Code."); } else if (fwts_iasl_disassemble(fw, table, true, &output) != FWTS_OK) { /* Cannot find, assume standard table header */ uint8_t *data = (uint8_t *)table->data; fwts_acpi_table_header hdr; fwts_acpi_table_get_header(&hdr, data); acpidump_hdr(fw, &hdr, table->length); acpi_dump_raw_table(fw, table); } else { /* Successfully disassembled, so parse */ fwts_list_link *line; bool skip = false; bool unknown = false; fwts_list_foreach(line, output) { char *text = fwts_text_list_text(line); bool ignore = (strstr(text, "Raw Table Data:") != NULL); /* We don't want to emit this line */ if (strstr(text, "Unknown ACPI table signature") != NULL) { unknown = true; ignore = true; } /* and we want to ignore text in comments */ if (!strncmp(text, "/*", 2)) skip = true; if (!(ignore | skip | unknown)) fwts_log_info_verbatim(fw, "%s", fwts_text_list_text(line)); if (!strncmp(text, " */", 3)) skip = false; } fwts_text_list_free(output); if (unknown) acpi_dump_raw_table(fw, table); } fwts_log_nl(fw); }
static int acpi_table_sbbr_check_test2(fwts_framework *fw) { int i; bool checked = false; bool dsdt_checked = false; bool ssdt_checked = false; for (i = 0; ; i++) { fwts_acpi_table_info *info; if (fwts_acpi_get_table(fw, i, &info) != FWTS_OK) break; if (info == NULL) continue; checked = true; if (!strcmp(info->name, "DSDT") || !strcmp(info->name, "SSDT")) { fwts_acpi_table_header *hdr; char name[TABLE_NAME_LEN]; bool passed = false; if (!strcmp(info->name, "DSDT")) { dsdt_checked = true; } if (!strcmp(info->name, "SSDT")) { ssdt_checked = true; } hdr = (fwts_acpi_table_header *)info->data; if (acpi_table_check_field(hdr->signature, MIN_SIG)) { snprintf(name, sizeof(name), "%4.4s", hdr->signature); } else { /* Table name not printable, so identify it by the address */ snprintf(name, sizeof(name), "at address 0x%" PRIx64, info->addr); } /* * Tables shouldn't be short, however, they do have at * least 4 bytes with their signature else they would not * have been loaded by this stage. */ if (hdr->length < sizeof(fwts_acpi_table_header)) { fwts_failed(fw, LOG_LEVEL_HIGH, "ACPITableHdrShort", "ACPI Table %s is too short, only %d bytes long. Further " "header checks will be omitted.", name, hdr->length); continue; } /* Warn about empty tables */ if (hdr->length == sizeof(fwts_acpi_table_header)) { fwts_warning(fw, "ACPI Table %s is empty and just contains a table header. Further " "header checks will be omitted.", name); continue; } passed = acpi_table_check_field_test(fw, name, "Signature", hdr->signature, MIN_SIG) & acpi_table_check_field_test(fw, name, "OEM ID", hdr->oem_id, OEM_ID) & acpi_table_check_field_test(fw, name, "OEM Table ID", hdr->oem_tbl_id, OEM_TABLE_ID) & acpi_table_check_field_test(fw, name, "OEM Creator ID", hdr->creator_id, OEM_CREATOR_ID); if (passed) fwts_passed(fw, "Table %s has valid signature and ID strings.", name); } } if (!checked) { fwts_aborted(fw, "Cannot find any ACPI tables."); return FWTS_ABORTED; } if (!dsdt_checked) fwts_failed(fw, LOG_LEVEL_HIGH, "acpi_table_check_test4", "Test DSDT table is NOT implemented."); if (!ssdt_checked) fwts_warning(fw, "SSDT table is NOT implemented."); return FWTS_OK; }
static int acpi_table_check_test1(fwts_framework *fw) { int i; bool checked = false; for (i = 0; ; i++) { fwts_acpi_table_info *info; fwts_acpi_table_header *hdr; char name[50]; bool passed; if (fwts_acpi_get_table(fw, i, &info) != FWTS_OK) break; if (info == NULL) continue; checked = true; /* RSDP and FACS are special cases, skip these */ if (!strcmp(info->name, "RSDP") || !strcmp(info->name, "FACS")) continue; hdr = (fwts_acpi_table_header *)info->data; if (acpi_table_check_field(hdr->signature, 4)) { snprintf(name, sizeof(name), "%4.4s", hdr->signature); } else { /* Table name not printable, so identify it by the address */ snprintf(name, sizeof(name), "at address 0x%" PRIx64, info->addr); } /* * Tables shouldn't be short, however, they do have at * least 4 bytes with their signature else they would not * have been loaded by this stage. */ if (hdr->length < sizeof(fwts_acpi_table_header)) { fwts_failed(fw, LOG_LEVEL_HIGH, "ACPITableHdrShort", "ACPI Table %s is too short, only %d bytes long. Further " "header checks will be omitted.", name, hdr->length); continue; } /* Warn about empty tables */ if (hdr->length == sizeof(fwts_acpi_table_header)) { fwts_warning(fw, "ACPI Table %s is empty and just contains a table header. Further " "header checks will be omitted.", name); continue; } passed = acpi_table_check_field_test(fw, name, "Signature", hdr->signature, 4) & acpi_table_check_field_test(fw, name, "OEM ID", hdr->oem_id, 6) & acpi_table_check_field_test(fw, name, "OEM Table ID", hdr->oem_tbl_id, 8) & acpi_table_check_field_test(fw, name, "OEM Creator ID", hdr->creator_id, 4); if (passed) fwts_passed(fw, "Table %s has valid signature and ID strings.", name); } if (!checked) fwts_aborted(fw, "Cannot find any ACPI tables."); return FWTS_OK; }