/* * 4.1.2.1 ASF_INFO */ static void asf_check_info( fwts_framework *fw, ssize_t length, uint8_t *data, bool *passed, bool *abort) { fwts_acpi_table_asf_info *info = (fwts_acpi_table_asf_info *)data; if (length < (ssize_t)sizeof(fwts_acpi_table_asf_info)) { fwts_failed(fw, LOG_LEVEL_HIGH, "ASF!InfoRecordTooShort", "ASF! ASF_INFO Record too short, " "expecting %zu bytes, instead got %zu bytes", sizeof(fwts_acpi_table_asf_info), length); *passed = false; *abort = true; return; } #if ASF_DUMP fwts_log_info_verbatim(fw, "ASF! ASF_INFO Record:"); fwts_log_info_verbatim(fw, " Min Watchdog Reset Value: 0x%2.2" PRIx8, info->watchdog_reset_value); fwts_log_info_verbatim(fw, " Min Poll Wait Time: 0x%2.2" PRIx8, info->min_sensor_poll_wait_time); fwts_log_info_verbatim(fw, " System ID: 0x%2.2" PRIx8, info->id); fwts_log_info_verbatim(fw, " IANA Manufacturer ID: 0x%2.2" PRIx8, info->iana_id); fwts_log_info_verbatim(fw, " Feature Flags: 0x%2.2" PRIx8, info->flags); fwts_log_info_verbatim(fw, " Reserved: 0x%2.2" PRIx8, info->reserved1); fwts_log_info_verbatim(fw, " Reserved: 0x%2.2" PRIx8, info->reserved2); fwts_log_info_verbatim(fw, " Reserved: 0x%2.2" PRIx8, info->reserved3); #endif if (info->watchdog_reset_value == 0) { *passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "ASF!InfoMinWatchDogInvalid", "ASF! ASF_INFO Minimum Watchdog Reset Value is 0x00 and " "must be in the range 0x01..0xff"); } if (info->min_sensor_poll_wait_time < 2) { *passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "ASF!InfoMinPollWaitTimeInvalid", "ASF! ASF_INFO Minimum Poll Wait Time is 0x%" PRIx8 " and must be in the range 0x02..0xff", info->min_sensor_poll_wait_time); } fwts_acpi_reserved_bits_check(fw, "ASF!", "ASF_INFO Feature Flags", info->flags, sizeof(info->flags), 1, 7, passed); fwts_acpi_reserved_zero_check(fw, "ASF!", "ASF_INFO Reserved1", info->reserved1, sizeof(info->reserved1), passed); fwts_acpi_reserved_zero_check(fw, "ASF!", "ASF_INFO Reserved2", info->reserved2, sizeof(info->reserved2), passed); fwts_acpi_reserved_zero_check(fw, "ASF!", "ASF_INFO Reserved3", info->reserved3, sizeof(info->reserved3), passed); if (*passed) fwts_passed(fw, "No issues found in ASF! ASF_INFO record."); }
static int pdtt_test1(fwts_framework *fw) { fwts_acpi_table_pdtt *pdtt = (fwts_acpi_table_pdtt*) table->data; fwts_acpi_table_pdtt_channel *entry; uint32_t offset, count, i; uint32_t reserved; bool passed = true; reserved = (uint32_t) pdtt->reserved[0] + ((uint32_t) pdtt->reserved[1] << 8) + ((uint32_t) pdtt->reserved[2] << 16); fwts_log_info_verbatim(fw, "PDTT Platform Debug Trigger Table:"); fwts_log_info_verbatim(fw, " Trigger Count: 0x%2.2" PRIx8, pdtt->trigger_count); fwts_log_info_verbatim(fw, " Reserved[3]: 0x%6.6" PRIx32, reserved); fwts_log_info_verbatim(fw, " Trigger ID Array Offset: 0x%2.2" PRIx8, pdtt->array_offset); fwts_acpi_reserved_zero_check(fw, "PDTT", "Reserved", reserved, sizeof(reserved), &passed); offset = pdtt->array_offset; entry = (fwts_acpi_table_pdtt_channel *) (table->data + offset); count = (pdtt->header.length - pdtt->array_offset) / sizeof(fwts_acpi_table_pdtt_channel); if (count != pdtt->trigger_count) { passed = false; fwts_failed(fw, LOG_LEVEL_CRITICAL, "PDTTBadIDCount", "PDTT should have %" PRId8 " ids, got %" PRId8, pdtt->trigger_count, count); return FWTS_OK; } fwts_log_info_verbatim(fw, " Platform Communication Channel IDs"); for (i = 0; i < pdtt->trigger_count; i++) { fwts_log_info_verbatim(fw, " Sub channel ID: 0x%2.2" PRIx8, entry->sub_channel_id); fwts_log_info_verbatim(fw, " Flags: 0x%2.2" PRIx8, entry->flags); fwts_acpi_reserved_bits_check(fw, "PDTT", "Flags", entry->flags, sizeof(entry->flags), 3, 7, &passed); if ((offset += sizeof(fwts_acpi_table_pdtt_channel)) > table->length) { passed = false; fwts_failed(fw, LOG_LEVEL_CRITICAL, "PDTTBadTableLength", "PDTT has more channel IDs than its size can handle"); break; } entry = (fwts_acpi_table_pdtt_channel *) (table->data + offset); } fwts_log_nl(fw); if (passed) fwts_passed(fw, "No issues found in PDTT table."); return FWTS_OK; }
/* * TPM2 table * available @ https://trustedcomputinggroup.org/tcg-acpi-specification/ */ static int tpm2_test1(fwts_framework *fw) { fwts_acpi_table_tpm2 *tpm2 = (fwts_acpi_table_tpm2*) table->data; bool passed = true; fwts_log_info_verbatim(fw, "TPM2 Table:"); fwts_log_info_verbatim(fw, " Platform Class: 0x%4.4" PRIx16, tpm2->platform_class); fwts_log_info_verbatim(fw, " Reserved: 0x%4.4" PRIx32, tpm2->reserved); fwts_log_info_verbatim(fw, " Address of Control Area: 0x%16.16" PRIx64, tpm2->address_of_control_area); fwts_log_info_verbatim(fw, " Start Method: 0x%8.8" PRIx32, tpm2->start_method); if (tpm2->platform_class != 0 && tpm2->platform_class != 1) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "TPM2BadPlatformClass", "TPM2's platform class must be zero (client) or one (server), got 0x%" PRIx16, tpm2->platform_class); } fwts_acpi_reserved_zero_check(fw, "TPM2", "Reserved", tpm2->reserved, sizeof(tpm2->reserved), &passed); if (tpm2->start_method < 1 || tpm2->start_method >= 12) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "TPM2BadStartMethod", "TPM2's Start Method must be between one to eleven, got 0x%" PRIx16, tpm2->start_method); } if (tpm2->start_method == 2 && table->length != sizeof(fwts_acpi_table_tpm2) + 4) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "TPM2BadPlatformParameters", "Table length must be 0x%" PRIx32 " if Start method equals 2, got 0x%" PRIx32, (uint32_t) sizeof(fwts_acpi_table_tpm2) + 4, (uint32_t) table->length); } if (tpm2->start_method == 11 && table->length < sizeof(fwts_acpi_table_tpm2) + 12) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "TPM2BadPlatformParameters", "Table length must be atleast 0x%" PRIx32 " if Start method equals 11, got 0x%" PRIx32, (uint32_t) sizeof(fwts_acpi_table_tpm2) + 12, (uint32_t) table->length); } if (passed) fwts_passed(fw, "No issues found in TPM2 table."); return FWTS_OK; }
/* * ASF! Hardware Error Source Table test * http://www.dmtf.org/sites/default/files/standards/documents/DSP0136.pdf */ static int asf_test1(fwts_framework *fw) { bool passed = true; bool abort = false; fwts_acpi_table_header *hdr = (fwts_acpi_table_header *)table->data; uint8_t *data = (uint8_t *)table->data; ssize_t length = (ssize_t)hdr->length; fwts_log_info_verbatim(fw, "ASF! Hardware Error Source Table"); data += sizeof(fwts_acpi_table_header); length -= sizeof(fwts_acpi_table_header); while (!abort && (length > 0)) { bool asf_passed = true; fwts_acpi_table_asf_header *asf_hdr = (fwts_acpi_table_asf_header *)data; /* Must have enough for a info header */ if (length < (ssize_t)sizeof(fwts_acpi_table_asf_header)) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "ASF!TooShort", "ASF! table too short, expecting at least %zu bytes " "for an ASF! information record header, " "instead got %zu bytes", sizeof(fwts_acpi_table_asf_header), table->length); break; } #if ASF_DUMP fwts_log_info_verbatim(fw, "Type: 0x%2.2" PRIx8, asf_hdr->type); fwts_log_info_verbatim(fw, "Reserved: 0x%2.2" PRIx8, asf_hdr->reserved); fwts_log_info_verbatim(fw, "Length: 0x%4.4" PRIx16, asf_hdr->length); #endif fwts_acpi_reserved_zero_check(fw, "ASF!", "Information Record Reserved", asf_hdr->reserved, sizeof(asf_hdr->reserved), &passed); if (asf_hdr->length > (uint32_t)length) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "ASF!InfoRecordLengthTooLong", "ASF! Information Record Reserved length is %" PRIu32 " and this is too long for the size given by " "the ASF! table. Expected at most %zu bytes.", asf_hdr->length, length); /* Since we can't trust the table, abort */ break; } switch (asf_hdr->type) { case 0x00: case 0x80: asf_check_info(fw, length - sizeof(*asf_hdr), data + sizeof(*asf_hdr), &asf_passed, &abort); data += asf_hdr->length; length -= asf_hdr->length; break; case 0x01: case 0x81: asf_check_alrt(fw, asf_hdr->length, length - sizeof(*asf_hdr), data + sizeof(*asf_hdr), &asf_passed, &abort); data += asf_hdr->length; length -= asf_hdr->length; break; case 0x02: case 0x82: asf_check_rctl(fw, asf_hdr->length, length - sizeof(*asf_hdr), data + sizeof(*asf_hdr), &asf_passed, &abort); data += asf_hdr->length; length -= asf_hdr->length; break; case 0x03: case 0x83: asf_check_rmcp(fw, length - sizeof(*asf_hdr), data + sizeof(*asf_hdr), &asf_passed, &abort); data += asf_hdr->length; length -= asf_hdr->length; break; case 0x04: case 0x84: asf_check_addr(fw, asf_hdr->length, length - sizeof(*asf_hdr), data + sizeof(*asf_hdr), &asf_passed, &abort); data += asf_hdr->length; length -= asf_hdr->length; break; default: fwts_failed(fw, LOG_LEVEL_HIGH, "ASF!InvalidType", "ASF! Information Record Type 0x%4.4" PRIx16 " is invalid, aborting check", asf_hdr->type); passed = false; length = 0; break; } passed &= asf_passed; #if ASF_DUMP fwts_log_nl(fw); #endif } #if ASF_DUMP fwts_log_nl(fw); #endif if (passed) fwts_passed(fw, "No issues found in ASF! table."); return FWTS_OK; }
static int pcct_test1(fwts_framework *fw) { fwts_acpi_table_pcct *pcct = (fwts_acpi_table_pcct*) table->data; fwts_acpi_table_pcct_subspace_header *pcct_sub; size_t offset; bool passed = true; fwts_log_info_verbatim(fw, "PCC Table:"); fwts_log_info_verbatim(fw, " Flags: 0x%8.8" PRIx32, pcct->flags); fwts_log_info_verbatim(fw, " Reserved: 0x%16.16" PRIx64, pcct->reserved); fwts_log_nl(fw); fwts_acpi_reserved_bits_check(fw, "PCCT", "Flags", pcct->flags, sizeof(pcct->flags), 1, 31, &passed); fwts_acpi_reserved_zero_check(fw, "PCCT", "Reserved", pcct->reserved, sizeof(pcct->reserved), &passed); offset = sizeof(fwts_acpi_table_pcct); pcct_sub = (fwts_acpi_table_pcct_subspace_header *) (table->data + offset); while (offset < table->length) { fwts_log_info_verbatim(fw, " PCC Subspace Structure:"); fwts_log_info_verbatim(fw, " Type: 0x%2.2" PRIx8, pcct_sub->type); fwts_log_info_verbatim(fw, " Length: 0x%2.2" PRIx8, pcct_sub->length); if (pcct_sub->type == 0) { fwts_acpi_table_pcct_subspace_type_0 *subspace = (fwts_acpi_table_pcct_subspace_type_0 *) pcct_sub; if(!subspace_length_equal(fw, 0, sizeof(fwts_acpi_table_pcct_subspace_type_0), pcct_sub->length)) { passed = false; break; } generic_comm_test(fw, subspace, &passed); } else if (pcct_sub->type == 1) { fwts_acpi_table_pcct_subspace_type_1 *subspace = (fwts_acpi_table_pcct_subspace_type_1 *) pcct_sub; if(!subspace_length_equal(fw, 0, sizeof(fwts_acpi_table_pcct_subspace_type_1), pcct_sub->length)) { passed = false; break; } hw_reduced_comm_test_type1(fw, subspace, &passed); } else if (pcct_sub->type == 2) { fwts_acpi_table_pcct_subspace_type_2 *subspace = (fwts_acpi_table_pcct_subspace_type_2 *) pcct_sub; if(!subspace_length_equal(fw, 0, sizeof(fwts_acpi_table_pcct_subspace_type_2), pcct_sub->length)) { passed = false; break; } hw_reduced_comm_test_type2(fw, subspace, &passed); } else if (pcct_sub->type == 3) { fwts_acpi_table_pcct_subspace_type_3_4 *subspace = (fwts_acpi_table_pcct_subspace_type_3_4 *) pcct_sub; if(!subspace_length_equal(fw, 0, sizeof(fwts_acpi_table_pcct_subspace_type_3_4), pcct_sub->length)) { passed = false; break; } extended_pcc_test(fw, subspace, &passed); } else if (pcct_sub->type == 4) { fwts_acpi_table_pcct_subspace_type_3_4 *subspace = (fwts_acpi_table_pcct_subspace_type_3_4 *) pcct_sub; if(!subspace_length_equal(fw, 0, sizeof(fwts_acpi_table_pcct_subspace_type_3_4), pcct_sub->length)) { passed = false; break; } if (!(pcct->flags & 0x01)) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "PCCTBadFlags", "PCCT Platform Interrupt in flags must be set when subspace " "type 4 is present, got 0x%8.8" PRIx32 " instead", pcct->flags); } extended_pcc_test(fw, subspace, &passed); } else { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "PCCTBadSubType", "PCCT Subspace Structure supports type 0..4, got " "0x%2.2" PRIx8 " instead", pcct_sub->type); break; } fwts_log_nl(fw); offset += pcct_sub->length; pcct_sub = (fwts_acpi_table_pcct_subspace_header *) (table->data + offset); } if (passed) fwts_passed(fw, "No issues found in PCC table."); return FWTS_OK; }
static int spcr_test1(fwts_framework *fw) { char *str; uint32_t reserved1; bool reserved = false; bool pci = true; bool passed = true; /* * Assuming revision 2, full list from * http://go.microsoft.com/fwlink/p/?LinkId=234837) */ switch (spcr->interface_type) { case 0x00: str = "16550 compatible"; break; case 0x01: str = "16450 compatible"; break; case 0x03: str = "ARM PL011 UART"; break; case 0x02: case 0x04 ... 0x0c: str = "Reserved (Do not Use)"; reserved = true; break; case 0x0d: str = "(deprecated) ARM SBSA"; break; case 0x0e: str = "ARM SBSA Generic UART"; break; case 0x0f: str = "ARM DCC"; break; case 0x10: str = "BCM2835"; break; default: str = "Reserved"; reserved = true; break; } fwts_log_info_verbatim(fw, "Serial Interface: %s", str); if (reserved) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "SPCRInterfaceReserved", "SPCR Serial interface type 0x%2.2" PRIx8 " is a reserved interface", spcr->interface_type); } reserved1 = spcr->reserved1[0] + (spcr->reserved1[1] << 8) + (spcr->reserved1[2] << 16); fwts_acpi_reserved_zero_check(fw, "SPCR", "Reserved1", reserved1, sizeof(reserved1), &passed); if (spcr->interrupt_type == 0) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "SPCRUnknownInterruptType", "SPCR interrupt type field is zero, expecting support bits to be set"); } if (spcr->interrupt_type & 0xf0) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "SPCRIllegalReservedInterruptType", "SPCR interrupt type reserved bits are non-zero zero, got 0x%" PRIx8, spcr->interrupt_type); } /* Check PC-AT compatible UART IRQs */ if (spcr->interrupt_type & 1) { switch (spcr->irq) { case 2 ... 7: case 9 ... 12: case 14 ... 15: break; default: passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "SPCRIllegalIRQ", "SPCR PC-AT compatible IRQ 0x%" PRIx8 " is invalid", spcr->irq); break; } } reserved = false; switch (spcr->baud_rate) { case 0x03: str = "9600"; break; case 0x04: str = "19200"; break; case 0x06: str = "57600"; break; case 0x07: str = "115200"; break; default: str = "Reserved"; reserved = true; } fwts_log_info_verbatim(fw, "Baud Rate: %s", str); if (reserved) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "SPCRBaudRateReserved", "SPCR Serial baud rate type 0x%2.2" PRIx8 " is a reserved baud rate", spcr->baud_rate); } if (spcr->parity != 0) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "SPCRReservedValueUsed", "SPCR Parity field must be zero, got 0x%2.2" PRIx8 " instead", spcr->parity); } if (spcr->stop_bits != 1) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "SPCRReservedValueUsed", "SPCR Stop field must be 1, got 0x%2.2" PRIx8 " instead", spcr->stop_bits); } fwts_acpi_reserved_bits_check(fw, "SPCR", "Flow control", spcr->flow_control, sizeof(spcr->flow_control), 3, 7, &passed); reserved = false; switch (spcr->terminal_type) { case 0x00: str = "VT100"; break; case 0x01: str = "VT100+"; break; case 0x02: str = "VT-UTF8"; break; case 0x03: str = "ANSI"; break; default: str = "Reserved"; reserved = true; } fwts_log_info_verbatim(fw, "Terminal Type: %s", str); if (reserved) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "SPCRTerminalTypeReserved", "SPCR terminal type type 0x%2.2" PRIx8 " is a reserved terminal type", spcr->terminal_type); } fwts_acpi_reserved_zero_check(fw, "SPCR", "Reserved2", spcr->reserved2, sizeof(spcr->reserved2), &passed); /* According to the spec, these values indicate NOT a PCI device */ if ((spcr->pci_device_id == 0xffff) && (spcr->pci_vendor_id == 0xffff) && (spcr->pci_bus_number == 0) && (spcr->pci_device_number == 0) && (spcr->pci_function_number == 0)) pci = false; /* Now validate all pci specific fields if not-PCI enabled */ if (pci) { if (spcr->pci_device_id == 0xffff) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "SPCRPciDeviceID", "SPCR PCI device ID is 0x%4.4" PRIx16 ", expecting non-0xffff for PCI device", spcr->pci_device_id); } if (spcr->pci_vendor_id == 0xffff) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "SPCRPciVendorID", "SPCR PCI vendor ID is 0x%4.4" PRIx16 ", expecting non-0xffff for non-PCI device", spcr->pci_vendor_id); } if ((spcr->pci_flags & 1) == 0) { passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "SPCRPciFlagsBit0", "SPCR PCI flags compatibility bit 0 is %" PRIx32 ", expecting 1 for PCI device", spcr->pci_flags & 1); } } fwts_acpi_reserved_bits_check(fw, "SPCR", "PCI Flags", spcr->pci_flags, sizeof(spcr->pci_flags), 1, 31, &passed); fwts_acpi_reserved_zero_check(fw, "SPCR", "Reserved3", spcr->reserved3, sizeof(spcr->reserved3), &passed); if (passed) fwts_passed(fw, "No issues found in SPCR table."); return FWTS_OK; }
/* * ACPI Section 18.3.2.5 PCI Express/PCI-X Bridge AER Structure */ static void hest_heck_pci_express_bridge_aer( fwts_framework *fw, ssize_t *length, uint8_t **data, bool *passed) { fwts_acpi_table_hest_pci_express_bridge_aer *aer = (fwts_acpi_table_hest_pci_express_bridge_aer *)*data; if (*length < (ssize_t)sizeof(fwts_acpi_table_hest_pci_express_bridge_aer)) { fwts_failed(fw, LOG_LEVEL_HIGH, "HESTPciExpressBridgeAerTooShort", "HEST PCI Express Bridge AER " "too short, expecting %zu bytes, " "instead got %zu bytes", sizeof(fwts_acpi_table_hest_pci_express_bridge_aer), *length); *passed = false; *length = 0; /* Forces an early abort */ return; } fwts_log_info_verbatim(fw, "HEST PCI Express Bridge AER:"); fwts_log_info_verbatim(fw, " Type: 0x%2.2" PRIx8, aer->type); fwts_log_info_verbatim(fw, " Source ID: 0x%4.4" PRIx16, aer->source_id); fwts_log_info_verbatim(fw, " Reserved: 0x%4.4" PRIx16, aer->reserved1); fwts_log_info_verbatim(fw, " Flags: 0x%2.2" PRIx8, aer->flags); fwts_log_info_verbatim(fw, " Enabled: 0x%2.2" PRIx8, aer->enabled); fwts_log_info_verbatim(fw, " Number of Records: 0x%8.8" PRIx32, aer->number_of_records_to_preallocate); fwts_log_info_verbatim(fw, " Max Sections Per Record: 0x%8.8" PRIx32, aer->max_sections_per_record); fwts_log_info_verbatim(fw, " Bus: 0x%8.8" PRIx32, aer->bus); fwts_log_info_verbatim(fw, " Device: 0x%4.4" PRIx16, aer->device); fwts_log_info_verbatim(fw, " Function: 0x%4.4" PRIx16, aer->function); fwts_log_info_verbatim(fw, " Device Control: 0x%4.4" PRIx16, aer->device_control); fwts_log_info_verbatim(fw, " Reserved: 0x%4.4" PRIx16, aer->reserved2); fwts_log_info_verbatim(fw, " Uncorrectable Mask: 0x%8.8" PRIx32, aer->uncorrectable_error_mask); fwts_log_info_verbatim(fw, " Uncorrectable Severity: 0x%8.8" PRIx32, aer->uncorrectable_error_severity); fwts_log_info_verbatim(fw, " Correctable Mask: 0x%8.8" PRIx32, aer->correctable_error_mask); fwts_log_info_verbatim(fw, " Advanced Capabilities: 0x%8.8" PRIx32, aer->advanced_error_capabilities_and_control); fwts_log_info_verbatim(fw, " 2nd Uncorrectable Mask: 0x%8.8" PRIx32, aer->secondary_uncorrectable_error_mask); fwts_log_info_verbatim(fw, " 2nd Uncurrectable Svrity: 0x%8.8" PRIx32, aer->secondary_uncorrectable_error_severity); fwts_log_info_verbatim(fw, " 2nd Advanced Capabilities:0x%8.8" PRIx32, aer->secondary_advanced_error_capabilities_and_control); fwts_log_nl(fw); fwts_acpi_reserved_zero_check(fw, "HEST", "PCI Express Bridge Reserved1", aer->reserved1, sizeof(aer->reserved1), passed); fwts_acpi_reserved_bits_check(fw, "HEST", "PCI Express Bridge Flags", aer->flags, sizeof(aer->flags), 2, 7, passed); fwts_acpi_reserved_zero_check(fw, "HEST", "PCI Express Bridge Reserved2", aer->reserved2, sizeof(aer->reserved2), passed); if (aer->number_of_records_to_preallocate < 1) { *passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "HESTInvalidRecordsToPreallocate", "HEST PCI Express Bridge Number of Records " "to Preallocate is 0x%" PRIx16 " and must be " "more than zero.", aer->number_of_records_to_preallocate); } if (aer->max_sections_per_record < 1) { *passed = false; fwts_failed(fw, LOG_LEVEL_HIGH, "HESTInvalidMaxSectionsPerRecord", "HEST PCI Express Brdige Max Sections Per " "Record is 0x%" PRIx16 " and must be " "more than zero.", aer->max_sections_per_record); } *length -= sizeof(fwts_acpi_table_hest_pci_express_bridge_aer); *data += sizeof(fwts_acpi_table_hest_pci_express_bridge_aer); }