示例#1
0
文件: hest.c 项目: 9elements/fwts
/*
 *  ACPI Section 18.3.2.2.1, IA-32 Architecture Non-Maskable Interrupt
 *    - note, this should be a higher section number, the ACPI 6.0
 *	specification seems to have numbered this incorrectly.
 */
static void hest_check_acpi_table_hest_nmi_error(
	fwts_framework *fw,
	ssize_t *length,
	uint8_t **data,
	bool *passed)
{
	fwts_acpi_table_hest_nmi_error *err =
		(fwts_acpi_table_hest_nmi_error *)*data;

	if (*length < (ssize_t)sizeof(fwts_acpi_table_hest_nmi_error)) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"HESTIA-32ArchitectureNmiTooShort",
			"HEST IA-32 Architecture Non-Mastable Interrupt "
			"too short, expecting %zu bytes, "
			"instead got %zu bytes",
			sizeof(fwts_acpi_table_hest_nmi_error), *length);
		*passed = false;
		*length = 0;	/* Forces an early abort */
		return;
	}

	fwts_log_info_verbatim(fw, "HEST IA-32 Architecture Non-Maskable Interrupt:");
	fwts_log_info_verbatim(fw, "  Type:                     0x%2.2" PRIx8, err->type);
	fwts_log_info_verbatim(fw, "  Source ID:                0x%4.4" PRIx16, err->source_id);
	fwts_log_info_verbatim(fw, "  Reserved:                 0x%4.4" PRIx16, err->reserved1);
	fwts_log_info_verbatim(fw, "  Number of Records:        0x%8.8" PRIx32, err->number_of_records_to_preallocate);
	fwts_log_info_verbatim(fw, "  Max Sections Per Record:  0x%8.8" PRIx32, err->max_sections_per_record);
	fwts_log_info_verbatim(fw, "  Max Raw Data Length:      0x%8.8" PRIx32, err->max_raw_data_length);
	fwts_log_nl(fw);

	if (err->reserved1) {
		*passed = false;
		fwts_failed(fw, LOG_LEVEL_LOW,
			"HESTInvalidRecordsToPreallocate",
			"HEST IA-32 Architecture NMI Reserved field "
			"at offset 4 must be zero, instead got 0x%" PRIx16,
			err->reserved1);
	}
	if (err->number_of_records_to_preallocate < 1) {
		*passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"HESTInvalidRecordsToPreallocate",
			"HEST IA-32 Architecture NMI Number of Records "
			"to Preallocate is 0x%" PRIx16 " and must be "
			"more than zero.",
			err->number_of_records_to_preallocate);
	}
	if (err->max_sections_per_record < 1) {
		*passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"HESTInvalidMaxSectionsPerRecord",
			"HEST A-32 Architecture NMI Max Sections Per "
			"Record is 0x%" PRIx16 " and must be "
			"more than zero.",
			err->max_sections_per_record);
	}

	*length -= sizeof(fwts_acpi_table_hest_nmi_error);
	*data += sizeof(fwts_acpi_table_hest_nmi_error);
}
示例#2
0
文件: wsmt.c 项目: 9elements/fwts
/*
 *  WSMT Windows Platform Binary Table
 */
static int wsmt_test1(fwts_framework *fw)
{
	fwts_acpi_table_wsmt *wsmt = (fwts_acpi_table_wsmt*) table->data;
	bool passed = true;

	fwts_log_info_verbatim(fw, "WSMT Windows SMM Security Mitigations Table:");
	fwts_log_info_verbatim(fw, "  Protection Flags:      0x%8.8" PRIx32, wsmt->protection_flags);

	fwts_acpi_reserved_bits_check(fw, "WSMT", "Protection Flags", wsmt->protection_flags, sizeof(wsmt->protection_flags), 3, 31, &passed);

	if ((wsmt->protection_flags & 0x2) && !(wsmt->protection_flags & 0x1)) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_MEDIUM,
			"WSMTBadFlagsValue",
			"WSMT Protection Flags bit[1] must be "
			"set when bit[2] is set");
	}

	fwts_log_nl(fw);

	if (passed)
		fwts_passed(fw, "No issues found in WSMT table.");

	return FWTS_OK;
}
示例#3
0
文件: pdtt.c 项目: ColinIanKing/fwts
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;
}
示例#4
0
文件: srat.c 项目: ahs3/fwts-sbbr
static void srat_check_gicc_affinity(
	fwts_framework *fw,
	ssize_t		*length,
	uint8_t		**data,
	bool		*passed)
{
	fwts_acpi_table_gicc_affinity *affinity =
		(fwts_acpi_table_gicc_affinity *)*data;

	if ((ssize_t)sizeof(fwts_acpi_table_gicc_affinity) > *length) {
		fwts_failed(fw, LOG_LEVEL_MEDIUM,
			"SRATGICCAffinityShort",
			"SRAT GICC Affinity structure too short, got "
			"%zu bytes, expecting %zu bytes",
			*length, sizeof(fwts_acpi_table_gicc_affinity));
		*passed = false;
		goto done;
	}

	if (affinity->length != sizeof(fwts_acpi_table_gicc_affinity)) {
		fwts_failed(fw, LOG_LEVEL_MEDIUM,
			"SRATGICCAffinityLength",
			"SRAT GICC Affinity Length incorrect, got "
			"%" PRIu8 ", expecting %zu",
			affinity->length, sizeof(fwts_acpi_table_gicc_affinity));
		*passed = false;
		goto done;
	}

	fwts_log_info_verbatum(fw, "SRAT GICC Affinity Structure:");
	fwts_log_info_verbatum(fw, "  Type:                     0x%2.2" PRIx8, affinity->type);
	fwts_log_info_verbatum(fw, "  Length:                   0x%2.2" PRIx8, affinity->length);
	fwts_log_info_verbatum(fw, "  Proximity Domain:         0x%4.4" PRIx32, affinity->proximity_domain);
	fwts_log_info_verbatum(fw, "  ACPI Processor UID:       0x%8.8" PRIx32, affinity->acpi_processor_uid);
	fwts_log_info_verbatum(fw, "  Flags:                    0x%8.8" PRIx32, affinity->flags);
	fwts_log_info_verbatum(fw, "  Clock Domain              0x%8.8" PRIx32, affinity->clock_domain);
	fwts_log_nl(fw);

	if (affinity->flags & ~0x1UL) {
		fwts_failed(fw, LOG_LEVEL_MEDIUM,
			"SRATGICCAffinityFlags",
			"SRAT GICC Affinity Flags field reserved bits 1..31 should be zero, got "
			"0x%" PRIx32,
			affinity->flags);
		*passed = false;
	}
	/*
	 *  Clock domain probably needs deeper sanity checking, for now
	 *  skip this.
	 */

done:
	*length -= sizeof(fwts_acpi_table_gicc_affinity);
	*data += sizeof(fwts_acpi_table_gicc_affinity);
}
示例#5
0
文件: srat.c 项目: ahs3/fwts-sbbr
static void srat_check_memory_affinity(
	fwts_framework *fw,
	ssize_t		*length,
	uint8_t		**data,
	bool		*passed)
{
	fwts_acpi_table_memory_affinity *affinity =
		(fwts_acpi_table_memory_affinity *)*data;

	if ((ssize_t)sizeof(fwts_acpi_table_memory_affinity) > *length) {
		fwts_failed(fw, LOG_LEVEL_MEDIUM,
			"SRATMemoryAffinityShort",
			"SRAT Memory Affinity structure too short, got "
			"%zu bytes, expecting %zu bytes",
			*length, sizeof(fwts_acpi_table_memory_affinity));
		*passed = false;
		goto done;
	}

	if (affinity->length != sizeof(fwts_acpi_table_memory_affinity)) {
		fwts_failed(fw, LOG_LEVEL_MEDIUM,
			"SRATMemoryAffinityLength",
			"SRAT Memory Affinity Length incorrect, got "
			"%" PRIu8 ", expecting %zu",
			affinity->length, sizeof(fwts_acpi_table_memory_affinity));
		*passed = false;
		goto done;
	}

	fwts_log_info_verbatum(fw, "SRAT Memory Affinity Structure:");
	fwts_log_info_verbatum(fw, "  Type:                     0x%2.2" PRIx8, affinity->type);
	fwts_log_info_verbatum(fw, "  Length:                   0x%2.2" PRIx8, affinity->length);
	fwts_log_info_verbatum(fw, "  Proximity Domain:         0x%8.8" PRIx32, affinity->proximity_domain);
	fwts_log_info_verbatum(fw, "  Reserved:                 0x%4.4" PRIx16, affinity->reserved1);
	fwts_log_info_verbatum(fw, "  Base Address:             0x%8.8" PRIx32 "%8.8" PRIx32,
		affinity->base_addr_hi, affinity->base_addr_lo);
	fwts_log_info_verbatum(fw, "  Length:                   0x%8.8" PRIx32 "%8.8" PRIx32,
		affinity->length_hi, affinity->length_lo);
	fwts_log_info_verbatum(fw, "  Reserved:                 0x%8.8" PRIx32, affinity->reserved2);
	fwts_log_info_verbatum(fw, "  Flags:                    0x%8.8" PRIx32, affinity->flags);
	fwts_log_info_verbatum(fw, "  Reserved:                 0x%16.16" PRIx64, affinity->reserved3);
	fwts_log_nl(fw);

	if (affinity->flags & ~0x7UL) {
		fwts_failed(fw, LOG_LEVEL_MEDIUM,
			"SRATMemoryAffinityFlags",
			"SRAT Memory Affinity Flags field reserved bits 3..31 should be zero, got "
			"0x%" PRIx32,
			affinity->flags);
		*passed = false;
	}
done:
	*length -= sizeof(fwts_acpi_table_memory_affinity);
	*data += sizeof(fwts_acpi_table_memory_affinity);
}
示例#6
0
文件: aspt.c 项目: ahs3/fwts-sbbr
/*
 *  ASPT Table
 *    (reverse engineered, table is common on AMD machines)
 */
static int aspt_test1(fwts_framework *fw)
{
	bool passed = true;
	fwts_acpi_table_aspt *aspt = (fwts_acpi_table_aspt *)table->data;

	if (table->length < sizeof(fwts_acpi_table_aspt)) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"ASPTTooShort",
			"ASPT table too short, expecting %zu bytes, "
			"instead got %zu bytes",
			sizeof(fwts_acpi_table_aspt), table->length);
		goto done;
	}

	fwts_log_info_verbatum(fw, "ASPT Table:");
	fwts_log_info_verbatum(fw, "  SPTT Start Address: 0x%8.8" PRIx32,
		aspt->sptt_addr_start);
	fwts_log_info_verbatum(fw, "  SPTT End Address:   0x%8.8" PRIx32,
		aspt->sptt_addr_end);
	fwts_log_info_verbatum(fw, "  AMRT Start Address: 0x%8.8" PRIx32,
		aspt->amrt_addr_start);
	fwts_log_info_verbatum(fw, "  AMRT End Address:   0x%8.8" PRIx32,
		aspt->amrt_addr_end);
	fwts_log_nl(fw);

	/*
	 * Without a specification to work with there is very
	 * little we can do to validate this apart from the
	 * simplest sanity check
	 */
	if (aspt->sptt_addr_end < aspt->sptt_addr_start) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"ASPTSpttEndError",
			"ASPT SPTT end address is less than the APTT start "
			"address.");
		passed = false;
	}
	if (aspt->amrt_addr_end < aspt->amrt_addr_start) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"ASPTAmrtEndError",
			"ASPT AMRT end address is less than the AMRT start "
			"address.");
		passed = false;
	}
done:
	if (passed)
		fwts_passed(fw, "No issues found in ASPT table.");

	return FWTS_OK;
}
示例#7
0
static void acpi_dump_raw_table(
	fwts_framework *fw,
	const fwts_acpi_table_info *table)
{
	const uint8_t *data = (uint8_t *)table->data;
	const size_t length = table->length;
        size_t n;

	fwts_log_nl(fw);

        for (n = 0; n < length; n += 16) {
                int left = length - n;
		char buffer[128];
		fwts_dump_raw_data(buffer, sizeof(buffer), data + n, n, left > 16 ? 16 : left);
		fwts_log_info_verbatim(fw, "%s", buffer);
        }
}
示例#8
0
文件: romdump.c 项目: 9elements/fwts
static int romdump_test1(fwts_framework *fw)
{
	uint8_t *mem;
	int i;

        if ((mem = fwts_mmap(BIOS_ROM_REGION_START, BIOS_ROM_REGION_SIZE)) == FWTS_MAP_FAILED) {
		fwts_log_error(fw, "Cannot mmap BIOS ROM region.");
		return FWTS_ERROR;
	}

	for (i = 0; i < BIOS_ROM_REGION_SIZE; i += 512) {
		/* Ensure we can safely read the memory */
		if (fwts_safe_memread(mem + i, 512) != FWTS_OK)
			continue;

		if ((*(mem+i) == 0x55) && (*(mem+i+1) == 0xaa)) {
			int length = *(mem+i+2) << 9;

			fwts_log_info(fw,
				"Found ROM: %x..%x (%d bytes)",
				BIOS_ROM_REGION_START+i,
				BIOS_ROM_REGION_START+i+length,
				length);
			romdump_data(fw, mem+i, BIOS_ROM_REGION_START+i, length);
			fwts_log_nl(fw);
		}
	}

	fwts_log_info(fw,
		"BIOS ROM: %x..%x (%d bytes)",
		BIOS_ROM_START,
		BIOS_ROM_END,
		BIOS_ROM_SIZE);

	romdump_data(fw, mem+BIOS_ROM_OFFSET, BIOS_ROM_START, BIOS_ROM_SIZE);

	fwts_infoonly(fw);

        (void)fwts_munmap(mem, BIOS_ROM_REGION_SIZE);

	return FWTS_OK;
}
示例#9
0
文件: waet.c 项目: alex1818/fwts
/*
 *  WAET Windows ACPI Emulated Devices Table
 *   see http://msdn.microsoft.com/en-us/windows/hardware/gg487524.aspx
 */
static int waet_test1(fwts_framework *fw)
{
	bool passed = true;
	fwts_acpi_table_waet *waet = (fwts_acpi_table_waet *)table->data;

	/* Enough length for the initial waet header? */
	if (table->length < sizeof(fwts_acpi_table_waet)) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"WAETTooShort",
			"WAET table too short, expecting %zu bytes, "
			"instead got %zu bytes",
			sizeof(fwts_acpi_table_waet), table->length);
		goto done;
	}

	fwts_log_info_verbatum(fw, "WAET Table:");
	fwts_log_info_verbatum(fw, "  Emulated Device Flags:    0x%8.8" PRIx32, waet->flags);
	fwts_log_info_verbatum(fw, "    Bit [0] RTC Good:       %1" PRIu32, waet->flags & 1);
	fwts_log_info_verbatum(fw, "    Bit [1] PM Timer Good:  %1" PRIu32, (waet->flags >> 1) & 1);
	fwts_log_nl(fw);

	if (waet->flags & ~3) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"WAETFlagReservedNotZero",
			"WAET Emulated Device Flags was 0x%" PRIx32
			" and so some of reserved bits [31:2] are not zero "
			" as expected.", waet->flags);
	}
done:
	if (passed)
		fwts_passed(fw, "No issues found in WAET table.");

	return FWTS_OK;
}
示例#10
0
文件: pcct.c 项目: ColinIanKing/fwts
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;
}
示例#11
0
文件: mcfg.c 项目: 9elements/fwts
static int mcfg_test1(fwts_framework *fw)
{
	int nr, i;
	fwts_acpi_table_mcfg *mcfg = (fwts_acpi_table_mcfg*)mcfg_table->data;
	fwts_acpi_mcfg_configuration *config;
	bool failed = false;
	ssize_t mcfg_size;
	const char *memory_map_name;

	memory_map_name = fwts_memory_map_name(fw->firmware_type);

	fwts_log_info(fw,
		"This test tries to validate the MCFG table by comparing the first "
		"16 bytes in the MMIO mapped config space with the 'traditional' config "
		"space of the first PCI device (root bridge). The MCFG data is only "
		"trusted if it is marked reserved in the %s",
		memory_map_name);
	fwts_log_nl(fw);

	if ((memory_map_list = fwts_memory_map_table_load(fw)) == NULL) {
		/* Not fatal, just means test will be less comprehensive */
		fwts_log_warning(fw, "No memory map table found");
	} else {
		fwts_memory_map_table_dump(fw, memory_map_list);
		fwts_log_nl(fw);
	}

	mcfg_size = mcfg_table->length;
	mcfg_size -= sizeof(fwts_acpi_table_mcfg);

	if (mcfg_size < 0) {
		fwts_failed(fw, LOG_LEVEL_HIGH, "MCFGInvalidSize",
			"Invalid MCFG ACPI table size: got %zd bytes expecting more",
			mcfg_size + sizeof(fwts_acpi_table_mcfg));
		fwts_advice(fw,
			"MCFG table must be least %zd bytes (header size) with "
			"multiples of %zd bytes for each MCFG entry.",
			sizeof(fwts_acpi_table_mcfg),
			sizeof(fwts_acpi_mcfg_configuration));
		return FWTS_ERROR;
	}
	nr = mcfg_size / sizeof(fwts_acpi_mcfg_configuration);

	if (!nr) {
		fwts_failed(fw, LOG_LEVEL_MEDIUM, "MCFGNoEntries",
			"No MCFG ACPI table entries");
		return FWTS_ERROR;
	}

	if (mcfg_size != (ssize_t)(nr * sizeof(fwts_acpi_mcfg_configuration))) {
		fwts_failed(fw, LOG_LEVEL_HIGH, "MCFGInvalidSize2",
			"MCFG table is not a multiple of record size");
		return FWTS_ERROR;
	}

	fwts_log_info(fw,
		"MCFG table found, size is %zd bytes (excluding header) (%i entries).",
		mcfg_size, nr);

	if (mcfg == NULL) {
		fwts_failed(fw, LOG_LEVEL_HIGH, "MCFGInvalidTable",
			"Invalid MCFG ACPI table");
		return FWTS_ERROR;
	}

	if (memory_map_list == NULL)
		fwts_failed(fw, LOG_LEVEL_MEDIUM, "MMapUnreadable",
			"Cannot check MCFG MMIO space against memory map table: could not read memory map table.");

	config = &mcfg->configuration[0];
	for (i = 0; i < nr; i++, config++) {
		fwts_log_info_verbatim(fw, "Configuration Entry #%d:", i);
		fwts_log_info_verbatim(fw, "  Base Address  : 0x%" PRIx64, config->base_address);
		fwts_log_info_verbatim(fw, "  Segment       : %" PRIu8, config->pci_segment_group_number);
		fwts_log_info_verbatim(fw, "  Start bus     : %" PRIu8, config->start_bus_number);
		fwts_log_info_verbatim(fw, "  End bus       : %" PRIu8, config->end_bus_number);

		if ((memory_map_list != NULL) &&
		    (!fwts_memory_map_is_reserved(memory_map_list, config->base_address))) {

			fwts_failed(fw, LOG_LEVEL_LOW, "MCFGMMIONotReserved",
				"MCFG MMIO config space at 0x%" PRIx64
				" is not reserved in the memory map table",
				config->base_address);
			fwts_advice(fw,
				"The PCI Express specification states that the "
				"PCI Express configuration space should "
				"be defined in the MCFG table and *maybe* "
				"optionally defined in the %s if ACPI MCFG is "
				"present. Linux checks if the region is reserved "
				"in the memory map table and will reject the "
				"MMCONFIG if there is a discrepency between MCFG "
				"and the memory map table for the PCI Express region. "
				"[See arch/x86/pci/mmconfig-shared.c pci_mmcfg_reject_broken()]. "
				"It is recommended that this is defined in the "
				"%s table for Linux.",
				memory_map_name, memory_map_name);
			failed = true;
		}
	}
	if (!failed)
		fwts_passed(fw, "MCFG MMIO config space is reserved in memory map table.");

	return FWTS_OK;
}
示例#12
0
static int dt_sysinfo_check_ref_plat_compatible(fwts_framework *fw)
{
	int node, compat_len, model_len;

	node = fdt_path_offset(fw->fdt, "/");
	if (node < 0) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"DTRootNodeMissing",
			"root device tree node is missing");
		return FWTS_ERROR;
	}
	if (fdt_node_check_compatible(fw->fdt, node, op_powernv)) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"DTCompatibleMissing",
			"DeviceTree failed validation, could not find"
			" the \"compatible\" property of \"%s\" in the "
			"root of the device tree", "ibm,powernv");
		return FWTS_ERROR;
	} else {
		const char *model_buf, *compat_buf;
		char *orig_model_buf, *tmp_model_buf;

		compat_buf = fdt_getprop(fw->fdt, node,
				"compatible", &compat_len);
		model_buf = fdt_getprop(fw->fdt, node,
				"model", &model_len);

		if (!model_buf || !compat_buf) {
			fwts_failed(fw,LOG_LEVEL_HIGH,
				"DTSysInfoCheck",
				"Cannot read the properties for OpenPOWER"
				" Reference Compatible check");
			return FWTS_ERROR;
		}

		/* need modifiable memory    */
		/* save original ptr to free */
		tmp_model_buf = orig_model_buf = strdup(model_buf);
		if (!tmp_model_buf) {
			fwts_failed(fw, LOG_LEVEL_HIGH,
				"DTSysInfoCheck",
				"Unable to get memory for model"
				" compare for OpenPOWER"
				" Reference Compatible check");
			return FWTS_ERROR;
		}

		tmp_model_buf = hidewhitespace(tmp_model_buf);
		if (!(strcmp(model_buf, tmp_model_buf) == 0)) {
			fwts_warning(fw,
				"DTSysInfoCheck"
				" See further advice in the log.");
			fwts_log_nl(fw);
			fwts_log_info_verbatim(fw,
				"DTSysInfoCheck"
				" Check the root \"model\" property"
				" from the device tree %s \"%s\".",
				DT_FS_PATH,
				model_buf);
			fwts_advice(fw,
				"Check the root \"model\" property"
				" from the device tree %s, "
				"there are whitespace inconsistentencies"
				" between the \"model\" property and "
				" the trimmed value of \"%s\", report"
				" this as a possible bug."
				"  Run \"hexdump -C model\""
				" from the \"%s\" directory to view"
				" the raw contents of the property.",
				DT_FS_PATH,
				tmp_model_buf,
				DT_FS_PATH);
		}
		if (machine_matches_reference_model(fw,
				compat_buf,
				compat_len,
				tmp_model_buf)) {
			fwts_passed(fw, "OpenPOWER Reference "
				"Compatible passed");
		} else {
			fwts_failed(fw, LOG_LEVEL_HIGH,
				"DTOpenPOWERReferenceFailed",
				"Unable to find an OpenPOWER supported"
				" match");
			/* adding verbatim to show proper string */
			fwts_log_info_verbatim(fw,
			"Unable to find an OpenPOWER reference"
			" match for \"%s\"", tmp_model_buf);
			free(orig_model_buf);
			return FWTS_ERROR;
		}
		free(orig_model_buf);
	}

	return FWTS_OK;
}
示例#13
0
文件: drtm.c 项目: ColinIanKing/fwts
/*
 *  DRTM D-RTM Resources Table
 */
static int drtm_test1(fwts_framework *fw)
{
	fwts_acpi_table_drtm *drtm = (fwts_acpi_table_drtm*) table->data;
	fwts_acpi_table_drtm_vtl *drtm_vtl;
	fwts_acpi_table_drtm_rtl *drtm_rtl;
	fwts_acpi_table_drtm_dps *drtm_dps;
	bool passed = true;
	uint32_t offset;
	uint32_t i;

	fwts_log_info_verbatim(fw, "DRTM D-RTM Resources Table:");
	fwts_log_info_verbatim(fw, "  DL_Entry_Base:            0x%16.16" PRIx64, drtm->entry_base_address);
	fwts_log_info_verbatim(fw, "  DL_Entry_Length:          0x%16.16" PRIx64, drtm->entry_length);
	fwts_log_info_verbatim(fw, "  DL_Entry32:               0x%8.8" PRIx32, drtm->entry_address32);
	fwts_log_info_verbatim(fw, "  DL_Entry64:               0x%16.16" PRIx64, drtm->entry_address64);
	fwts_log_info_verbatim(fw, "  DLME_Exit:                0x%16.16" PRIx64, drtm->exit_address);
	fwts_log_info_verbatim(fw, "  Log_Area_Start:           0x%16.16" PRIx64, drtm->log_area_address);
	fwts_log_info_verbatim(fw, "  Log_Area_Length:          0x%8.8" PRIx32, drtm->log_area_length);
	fwts_log_info_verbatim(fw, "  Architecture_Dependent:   0x%16.16" PRIx64, drtm->arch_dependent_address);
	fwts_log_info_verbatim(fw, "  DRT_Flags:                0x%8.8" PRIx32, drtm->flags);

	fwts_acpi_reserved_bits_check(fw, "DRTM", "DRT_Flags", drtm->flags, sizeof(drtm->flags), 4, 31, &passed);
	fwts_log_nl(fw);

	offset = sizeof(fwts_acpi_table_drtm);
	drtm_vtl = (fwts_acpi_table_drtm_vtl *) (table->data + offset);
	fwts_log_info_verbatim(fw, "  VTL_Length:               0x%8.8" PRIx32, drtm_vtl->validated_table_count);
	offset += sizeof(drtm_vtl->validated_table_count);

	if (drtm->header.length < offset + sizeof(uint64_t) * drtm_vtl->validated_table_count) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"DRTMOutOfBound",
			"DRTM's length is too small to contain all fields");
		goto error;
	}

	for (i = 0; i < drtm_vtl->validated_table_count; i++) {
		fwts_log_info_verbatim(fw, "  Validated_Tables:         0x%16.16" PRIx64, drtm_vtl->validated_tables[i]);
		offset += sizeof(drtm_vtl->validated_tables[i]);
	}

	fwts_log_nl(fw);

	drtm_rtl = (fwts_acpi_table_drtm_rtl *) (table->data + offset);
	fwts_log_info_verbatim(fw, "  RL_Length:                0x%8.8" PRIx32, drtm_rtl->resource_count);
	offset += sizeof(drtm_rtl->resource_count);

	if (drtm->header.length < offset + sizeof(fwts_acpi_drtm_resource) * drtm_rtl->resource_count) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"DRTMOutOfBound",
			"DRTM's length is too small to contain all fields");
		goto error;
	}

	for (i = 0; i < drtm_rtl->resource_count; i++) {
		fwts_acpi_drtm_resource *resource = (fwts_acpi_drtm_resource *) (table->data + offset);
		uint64_t size;
		size = resource->size[0] + ((uint64_t) resource->size[1] << 8) +
					   ((uint64_t) resource->size[2] << 16) + ((uint64_t) resource->size[3] << 24) +
					   ((uint64_t) resource->size[4] << 32) + ((uint64_t) resource->size[5] << 40) +
					   ((uint64_t) resource->size[6] << 48);

		fwts_log_info_verbatim(fw, "  Resource Size:            0x%16.16" PRIx64, size);
		fwts_log_info_verbatim(fw, "  Resource Type:            0x%2.2" PRIx8, resource->type);
		fwts_log_info_verbatim(fw, "  Resource Address:         0x%16.16" PRIx64, resource->address);

		if (resource->type & 0x7C) {
			passed = false;
			fwts_failed(fw, LOG_LEVEL_MEDIUM,
				"DRTMBadResourceType",
				"DRTM Resource Type Bits [6:2] are reserved, got 0x%2.2" PRIx8
				" instead",	resource->type);
		}

		offset += sizeof(fwts_acpi_drtm_resource);
		fwts_log_nl(fw);
	}

	drtm_dps = (fwts_acpi_table_drtm_dps *) (table->data + offset);
	fwts_log_info_verbatim(fw, "  DPS_Length:               0x%8.8" PRIx32, drtm_dps->dps_id_length);

	if (drtm->header.length < offset + sizeof(fwts_acpi_table_drtm_dps)) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"DRTMOutOfBound",
			"DRTM's length is too small to contain all fields");
		goto error;
	}

	for (i = 0; i < sizeof(drtm_dps->dps_id); i++) {
		fwts_log_info_verbatim(fw, "  DLME Platform Id:         0x%2.2" PRIx8, drtm_dps->dps_id[i]);
	}

	fwts_log_nl(fw);

	if (passed)
		fwts_passed(fw, "No issues found in DRTM table.");

 error:
	return FWTS_OK;
}
示例#14
0
文件: hest.c 项目: 9elements/fwts
/*
 *  ACPI Section 18.3.2.1 IA-32 Architecture Machine Check Exception
 */
static void hest_check_ia32_arch_machine_check_exception(
	fwts_framework *fw,
	ssize_t *length,
	uint8_t **data,
	bool *passed)
{
	ssize_t i, total_size;

	fwts_acpi_table_hest_ia32_machine_check_exception *exception =
		(fwts_acpi_table_hest_ia32_machine_check_exception *)*data;

	if (*length < (ssize_t)sizeof(fwts_acpi_table_hest_ia32_machine_check_exception)) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"HESTIA32MachineCheckTooShort",
			"HEST IA-32 Architecture Machine Check Exception "
			"too short, expecting %zu bytes, "
			"instead got %zu bytes",
			sizeof(fwts_acpi_table_hest_ia32_machine_check_exception), *length);
		*passed = false;
		*length = 0;	/* Forces an early abort */
		return;
	}

	total_size = sizeof(fwts_acpi_table_hest_ia32_machine_check_exception) +
		(exception->number_of_hardware_banks *
		sizeof(fwts_acpi_table_hest_machine_check_bank));

	if (*length < total_size) {
		*passed = false;
		*length = 0;	/* Forces an early abort */
		return;
	}

	fwts_log_info_verbatim(fw, "HEST IA-32 Architecture Machine Check Exception:");
	fwts_log_info_verbatim(fw, "  Type:                     0x%2.2" PRIx8, exception->type);
	fwts_log_info_verbatim(fw, "  Source ID:                0x%4.4" PRIx16, exception->source_id);
	fwts_log_info_verbatim(fw, "  Reserved:                 0x%4.4" PRIx16, exception->reserved1);
	fwts_log_info_verbatim(fw, "  Flags:                    0x%2.2" PRIx8, exception->flags);
	fwts_log_info_verbatim(fw, "  Enabled:                  0x%2.2" PRIx8, exception->enabled);
	fwts_log_info_verbatim(fw, "  Number of Records:        0x%8.8" PRIx32, exception->number_of_records_to_preallocate);
	fwts_log_info_verbatim(fw, "  Max Sections Per Record:  0x%8.8" PRIx32, exception->max_sections_per_record);
	fwts_log_info_verbatim(fw, "  Global Capability Data:   0x%16.16" PRIx64, exception->global_capability_init_data);
	fwts_log_info_verbatim(fw, "  Global Control Data:      0x%16.16" PRIx64, exception->global_control_init_data);
	fwts_log_info_verbatim(fw, "  Number of Hardware Banks: 0x%8.8" PRIx32, exception->number_of_hardware_banks);
	fwts_log_info_verbatim(fw, "  Reserved:                 0x%2.2" PRIx8, exception->reserved2[0]);
	fwts_log_info_verbatim(fw, "  Reserved:                 0x%2.2" PRIx8, exception->reserved2[1]);
	fwts_log_info_verbatim(fw, "  Reserved:                 0x%2.2" PRIx8, exception->reserved2[2]);
	fwts_log_info_verbatim(fw, "  Reserved:                 0x%2.2" PRIx8, exception->reserved2[3]);
	fwts_log_info_verbatim(fw, "  Reserved:                 0x%2.2" PRIx8, exception->reserved2[4]);
	fwts_log_info_verbatim(fw, "  Reserved:                 0x%2.2" PRIx8, exception->reserved2[5]);
	fwts_log_info_verbatim(fw, "  Reserved:                 0x%2.2" PRIx8, exception->reserved2[6]);
	fwts_log_nl(fw);

	if (exception->flags & ~0x5) {
		fwts_failed(fw, LOG_LEVEL_MEDIUM,
			"HESTIA32FlagsReserved",
			"HEST IA-32 Architecture MCE Flags Reserved bits "
			"[1] & [3:7] must be zero, instead got 0x%" PRIx8,
			exception->flags);
		*passed = false;
	} else if (exception->flags == 0x5) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"HESTIA32BadFlags",
			"HEST IA-32 Architecture MCE Flags bits [0] & [2] "
			"are mutually exclusive, instead got 0x%" PRIx8,
			exception->flags);
		*passed = false;
	}

	for (i = 0; i < exception->number_of_hardware_banks; i++) {
		fwts_acpi_table_hest_machine_check_bank *bank = &exception->bank[i];

		fwts_log_info_verbatim(fw, "  HEST IA-32 Architecture Machine Check Exception Bank %zd", i);
		fwts_log_info_verbatim(fw, "    Bank Number:            0x%2.2" PRIx8, bank->bank_number);
		fwts_log_info_verbatim(fw, "    Clear Status On Init.:  0x%2.2" PRIx8, bank->clear_status_on_initialization);
		fwts_log_info_verbatim(fw, "    Status Data Format:     0x%2.2" PRIx8, bank->status_data_format);
		fwts_log_info_verbatim(fw, "    Reserved:               0x%2.2" PRIx8, bank->reserved);
		fwts_log_info_verbatim(fw, "    Control Reg. MSR Addr:  0x%8.8" PRIx32, bank->control_register_msr_address);
		fwts_log_info_verbatim(fw, "    Control Init Data:      0x%16.16" PRIx64, bank->control_init_data);
		fwts_log_info_verbatim(fw, "    Status Reg. MSR Addr:   0x%8.8" PRIx32, bank->status_register_msr_address);
		fwts_log_info_verbatim(fw, "    Addr Reg. MSR Addr:     0x%8.8" PRIx32, bank->address_register_msr_address);
		fwts_log_info_verbatim(fw, "    Misc Reg. MSR Addr:     0x%8.8" PRIx32, bank->misc_register_msr_address);
		fwts_log_nl(fw);

		if (bank->clear_status_on_initialization > 1) {
			*passed = false;
			fwts_failed(fw, LOG_LEVEL_HIGH,
				"HESTIA32InvalidClearStatusOnInit",
				"HEST Machine Check Exception Bank Clear Status On Initialization "
				"has value 0x%" PRIx8 " and only valid values are "
				"0x00 (Clear) or 0x01 (Don't Clear)",
				bank->clear_status_on_initialization);
		}
		if (bank->status_data_format > 2) {
			*passed = false;
			fwts_failed(fw, LOG_LEVEL_HIGH,
				"HESTIA32InvalidBankStatusDataFormat",
				"HEST Machine Check Exception Bank Status Data Format "
				"has value 0x%" PRIx8 " and only valid values are "
				"0x00 (IA-32 MCA), 0x01 (Intel 64 MCA) or "
				"0x02 (AMD64 MCA).",
				bank->status_data_format);
		}
	}

	*length -= total_size;
	*data += total_size;
}
示例#15
0
文件: cmosdump.c 项目: ahs3/fwts-sbbr
static int cmosdump_test1(fwts_framework *fw)
{
	int i;
	unsigned long tmp;

	static char *cmos_shutdown_status[] = {
		"Power on or soft reset",
		"Memory size pass",
		"Memory test pass",
		"Memory test fail",

		"INT 19h reboot",
		"Flush keyboard and jmp via 40h:67h",
		"Protected mode tests pass",
		"Protected mode tests fail",

		"Used by POST during protected-mode RAM test",
		"Int 15h (block move)",
		"Jmp via 40h:67h",
		"Used by 80386",
	};

	static char *floppy_disk[] = {
		"None",
		"360KB 5.25\" Drive",
		"1.2MB 5.25\" Drive",
		"720KB 3.5\" Drive",
		"1.44MB 3.5\" Drive",
		"2.88MB 3.5\" Drive",
		"Unknown",
		"Unknown"
	};

	static char *hard_disk[] = {
		"None",
		"Type 1",
		"Unknown",
		"Unknown",
		"Unknown",
		"Unknown",
		"Unknown",
		"Unknown",
		"Unknown",
		"Unknown",
		"Unknown",
		"Unknown",
		"Unknown",
		"Unknown",
		"Type 14",
		"Type 16-47"
	};

	static char *primary_display[] = {
		"BIOS selected",
		"CGA 40 column",
		"CGA 80 column",
		"Monochrome"
	};

	static char *divider[8] = {
		"4.194 MHz",
		"1.049 MHz",
		"32.768 KHz (default)",
		"unknown",
		"test mode",
		"test mode",
		"reset / disable",
		"reset / disable",
	};

	static char *rate_selection[16] = {
		"none",
		"3.90625 millseconds",
		"7.8215 milliseconds",
		"122.070 microseconds",
		"244.141 microseconds",
		"488.281 microseconds",
		"976.562 microseconds (default)",
		"1.953125 milliseconds",
		"3.90625 milliseconds",
		"7.8215 milliseconds",
		"15.625 milliseconds",
		"31.25 milliseconds",
		"62.5 milliseconds",
		"125 milliseconds",
		"250 milliseconds",
		"500 milliseconds"
	};

	unsigned char data[0x80];

	/* Read CMOS Data */
	for (i = 0;i < (int)sizeof(data); i++) {
		if (fwts_cmos_read(i, &data[i]) != FWTS_OK) {
			fwts_log_error(fw, "Cannot get read/write permission on I/O ports.");
			return FWTS_ERROR;
		}
	}

	fwts_log_info_verbatum(fw, "CMOS Memory Dump:");
	for (i = 0; i < (int)sizeof(data); i += 16) {
		char buffer[128];
		fwts_dump_raw_data(buffer, sizeof(buffer), data + i, i, 16);
		fwts_log_info_verbatum(fw, "%s", buffer);
	}
	fwts_log_nl(fw);

	fwts_log_info_verbatum(fw, "RTC Current Time: (CMOS 0x00..0x09)");
	fwts_log_info_verbatum(fw, "  RTC seconds:            %2.2x", data[0]);
	fwts_log_info_verbatum(fw, "  RTC minutes:            %2.2x", data[2]);
	fwts_log_info_verbatum(fw, "  RTC hours:              %2.2x", data[4]);
	fwts_log_info_verbatum(fw, "  RTC day of week:        %2.2x", data[6]);
	fwts_log_info_verbatum(fw, "  RTC date day:           %2.2x", data[7]);
	fwts_log_info_verbatum(fw, "  RTC date month:         %2.2x", data[8]);
	fwts_log_info_verbatum(fw, "  RTC date year:          %2.2x", data[9]);
	fwts_log_nl(fw);

	fwts_log_info_verbatum(fw, "RTC Alarm:");
	fwts_log_info_verbatum(fw, "  RTC seconds:            %2.2x", data[1]);
	fwts_log_info_verbatum(fw, "  RTC minutes:            %2.2x", data[3]);
	fwts_log_info_verbatum(fw, "  RTC hours:              %2.2x", data[5]);
	fwts_log_nl(fw);

	fwts_log_info_verbatum(fw, "Status Register A: (CMOS 0x0a): 0x%2.2x",
		data[10]);
	fwts_log_info_verbatum(fw, "  Rate freq:              %1.1x (%s)",
		data[10] & 0xf, rate_selection[data[10] & 0xf]);
	fwts_log_info_verbatum(fw, "  Timer freq divider:     %1.1x (%s)",
		(data[10] >> 4) & 0x7, divider[(data[10] >> 4) & 0x7]);
	fwts_log_info_verbatum(fw, "  Update in progress:     %1.1x",
		(data[10] >> 7) & 1);
	fwts_log_nl(fw);

	fwts_log_info_verbatum(fw, "Status Register B: (CMOS 0x0b): 0x%2.2x",
		data[11]);
	fwts_log_info_verbatum(fw, "  Daylight savings:       %1.1x (%s)",
		data[11] & 1,
		(data[11] & 1) ? "Enabled" : "Disabled");
	fwts_log_info_verbatum(fw, "  24 Hour Clock:          %1.1x (%s)",
		(data[11] >> 1) & 1,
		((data[11] >> 1) & 1) ? "24 Hour" : "12 Hour");
	fwts_log_info_verbatum(fw, "  Data Mode (DM):         %1.1x (%s)",
		(data[11] >> 2) & 1,
		((data[11] >> 2) & 1) ? "Binary" : "BCD");
	fwts_log_info_verbatum(fw, "  Square Wave:            %1.1x (%s)",
		(data[11] >> 3) & 1,
		((data[11] >> 3) & 1) ? "Enabled" : "Disabled");
	fwts_log_info_verbatum(fw, "  Update ended IRQ:       %1.1x (%s)",
		(data[11] >> 4) & 1,
		((data[11] >> 4) & 1) ? "Enabled" : "Disabled");
	fwts_log_info_verbatum(fw, "  Alarm IRQ:              %1.1x (%s)",
		(data[11] >> 5) & 1,
		((data[11] >> 5) & 1) ? "Enabled" : "Disabled");
	fwts_log_info_verbatum(fw, "  Periodic IRQ:           %1.1x (%s)",
		(data[11] >> 6) & 1,
		((data[11] >> 6) & 1) ? "Enabled" : "Disabled");
	fwts_log_info_verbatum(fw, "  Clock update cycle:     %1.1x (%s)",
		(data[11] >> 7) & 1,
		((data[11] >> 7) & 1) ? "Abort update in progress" : "Update normally");
	fwts_log_nl(fw);

	fwts_log_info_verbatum(fw, "Status Register C: (CMOS 0x0c): 0x%2.2x",
		data[12]);
	fwts_log_info_verbatum(fw, "  UF flag:                0x%1.1x",
		(data[12] >> 4) & 1);
	fwts_log_info_verbatum(fw, "  AF flag:                0x%1.1x",
		(data[12] >> 5) & 1);
	fwts_log_info_verbatum(fw, "  PF flag:                0x%1.1x",
		(data[12] >> 6) & 1);
	fwts_log_info_verbatum(fw, "  IRQF flag:              0x%1.1x",
		(data[12] >> 7) & 1);
	fwts_log_nl(fw);

	fwts_log_info_verbatum(fw, "Status Register D: (CMOS 0x0d): 0x%2.2x",
		data[13]);
	fwts_log_info_verbatum(fw, "  Valid CMOS RAM flag:    0x%1.1x (%s)",
		(data[13] >> 7) & 1,
		((data[13] >> 7) & 1) ? "Battery Good": "Battery Dead");
	fwts_log_nl(fw);

	fwts_log_info_verbatum(fw, "Diagnostic Status: (CMOS 0x0e): 0x%2.2x",
		data[14]);
	fwts_log_info_verbatum(fw, "  CMOS time status:       0x%1.1x (%s)",
		(data[14] >> 2) & 1,
		((data[14] >> 2) & 1) ? "Invalid": "Valid");
	fwts_log_info_verbatum(fw, "  Fixed disk init:        0x%1.1x (%s)",
		(data[14] >> 3) & 1,
		((data[14] >> 3) & 1) ? "Bad": "Good");
	fwts_log_info_verbatum(fw, "  Memory size check:      0x%1.1x (%s)",
		(data[14] >> 4) & 1,
		((data[14] >> 4) & 1) ? "Bad": "Good");
	fwts_log_info_verbatum(fw, "  Config info status:     0x%1.1x (%s)",
		(data[14] >> 5) & 1,
		((data[14] >> 5) & 1) ? "Invalid": "Valid");
	fwts_log_info_verbatum(fw, "  CMOS checksum status:   0x%1.1x (%s)",
		(data[14] >> 6) & 1,
		((data[14] >> 6) & 1) ? "Bad": "Good");
	fwts_log_info_verbatum(fw, "  CMOS power loss:        0x%1.1x (%s)",
		(data[14] >> 7) & 1,
		((data[14] >> 7) & 1) ? "Lost power": "Not lost power");
	fwts_log_nl(fw);

	fwts_log_info_verbatum(fw, "CMOS Shutdown Status: (CMOS 0x0f): 0x%2.2x (%s)",
		data[15],
		data[15] < 0xb ? cmos_shutdown_status[data[15]] : "Perform power-on reset");
	fwts_log_nl(fw);

	fwts_log_info_verbatum(fw, "Floppy Disk Type: (CMOS 0x10): 0x%2.2x",
		data[16]);
	fwts_log_info_verbatum(fw, "  Drive 0: %s",
		floppy_disk[((data[16] >> 4) & 0xf)]);
	fwts_log_info_verbatum(fw, "  Drive 1: %s",
		floppy_disk[((data[16] >> 0) & 0xf)]);
	fwts_log_nl(fw);

	fwts_log_info_verbatum(fw, "Hard Disk Type: (CMOS 0x12, Obsolete): 0x%2.2x", data[18]);
	fwts_log_info_verbatum(fw, "  Drive 0: %s",
		hard_disk[((data[18] >> 4) & 0xf)]);
	fwts_log_info_verbatum(fw, "  Drive 1: %s",
		hard_disk[((data[18] >> 0) & 0xf)]);
	fwts_log_nl(fw);

	fwts_log_info_verbatum(fw, "Installed H/W: (CMOS 0x14): 0x%2.2x",
		data[20]);
	fwts_log_info_verbatum(fw, "  Maths Coprocessor:      0x%1.1x (%s)",
		(data[20] >> 1) & 1,
		((data[20] >> 1) & 1) ? "Installed": "Not Installed");
	fwts_log_info_verbatum(fw, "  Keyboard:               0x%1.1x (%s)",
		(data[20] >> 2) & 1,
		((data[20] >> 2) & 1) ? "Installed": "Not Installed");
	fwts_log_info_verbatum(fw, "  Display Adaptor:        0x%1.1x (%s)",
		(data[20] >> 3) & 1,
		((data[20] >> 3) & 1) ? "Installed": "Not Installed");
	fwts_log_info_verbatum(fw, "  Primary Display:        0x%1.1x (%s)",
		(data[20] >> 4) & 3,
		primary_display[(data[20] >> 4) & 3]);
	if (data[20] & 1) {
		int drives = (data[20] >> 6) & 3;
		fwts_log_info_verbatum(fw, "  Floppy Drives:          0x%2.2x (%d drive%s)",
			drives, drives + 1, drives > 0 ? "s" : "");
	} else {
示例#16
0
文件: hest.c 项目: 9elements/fwts
/*
 *  HEST Hardware Error Source Table test
 *     ACPI section 18.3.2 "ACPI Error Source"
 */
static int hest_test1(fwts_framework *fw)
{
	bool passed = true;
	fwts_acpi_table_hest *hest = (fwts_acpi_table_hest *)table->data;
        uint8_t *data = (uint8_t *)table->data;
        ssize_t length = (ssize_t)hest->header.length;
	uint32_t hest_type_00_count = 0,
		 hest_type_01_count = 0,
		 hest_type_02_count = 0,
		 hest_type_11_count = 0;


	if (table->length < sizeof(fwts_acpi_table_hest)) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"HESTTooShort",
			"HEST table too short, expecting %zu bytes, "
			"instead got %zu bytes",
			sizeof(fwts_acpi_table_hest), table->length);
		goto done;
	}

	fwts_log_info_verbatim(fw, "HEST Hardware Error Source Table test");
	fwts_log_info_verbatim(fw, "  Error Source Count:       0x%2.2" PRIx8, hest->error_source_count);
	fwts_log_nl(fw);

        data += sizeof(fwts_acpi_table_hest);
        length -= sizeof(fwts_acpi_table_hest);

	while (length > 0) {
		uint16_t *type = (uint16_t *)data;

		switch (*type) {
		case 0:
			hest_check_ia32_arch_machine_check_exception(fw, &length, &data, &passed);
			hest_type_00_count++;
			break;
		case 1:
			hest_check_ia32_arch_corrected_machine_check(fw, &length, &data, &passed);
			hest_type_01_count++;
			break;
		case 2:
			hest_check_acpi_table_hest_nmi_error(fw, &length, &data, &passed);
			hest_type_02_count++;
			break;
		case 6:
			hest_check_pci_express_root_port_aer(fw, &length, &data, &passed);
			break;
		case 7:
			hest_check_pci_express_device_aer(fw, &length, &data, &passed);
			break;
		case 8:
			hest_heck_pci_express_bridge_aer(fw, &length, &data, &passed);
			break;
		case 9:
			hest_check_generic_error_source(fw, &length, &data, &passed);
			break;
		case 10:
			hest_check_generic_error_source_v2(fw, &length, &data, &passed);
			break;
		case 11:
			/* the structure of type 11 is the same as type 1 */
			hest_check_ia32_arch_corrected_machine_check(fw, &length, &data, &passed);
			hest_type_11_count++;
			break;
		default:
			fwts_failed(fw, LOG_LEVEL_HIGH,
				"HESTInvalidType",
				"HEST Type 0x%4.4" PRIx16 " is invalid, aborting check",
				*type);
			passed = false;
			length = 0;
			break;
		}
	}
	if (hest_type_00_count > 1) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"HESTTooManyIA32ArchMachineCheckExceptions",
			"HEST Contained %" PRIu32 " IA32 Architecture "
			"Machine Check Exception Entries, maximum allowed "
			"per HEST is just 1.",
			hest_type_00_count);
	}
	if (hest_type_01_count > 1) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"HESTTooManyIA32CorrectedMachineChecks",
			"HEST Contained %" PRIu32 " IA32 Architecture "
			"Corrected Machine Check Exception Entries, maximum allowed "
			"per HEST is just 1.",
			hest_type_01_count);
	}
	if (hest_type_02_count > 1) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"HESTTooManyNmiErrors",
			"HEST Contained %" PRIu32 " NMI Error Entries, "
			"maximum allowed per HEST is just 1.",
			hest_type_02_count);
	}

	if (passed)
		fwts_passed(fw, "No issues found in HEST table.");

done:
	return FWTS_OK;
}
示例#17
0
文件: hest.c 项目: 9elements/fwts
/*
 *  ACPI Section 18.3.2.8 Generic Error Source version 2
 */
static void hest_check_generic_error_source_v2(
	fwts_framework *fw,
	ssize_t *length,
	uint8_t **data,
	bool *passed)
{
	fwts_acpi_table_hest_generic_hardware_error_source_v2 *source =
		(fwts_acpi_table_hest_generic_hardware_error_source_v2 *)*data;

	/* Enough data for an empty machine check exceptions structure? */
	if (*length < (ssize_t)sizeof(fwts_acpi_table_hest_generic_hardware_error_source_v2)) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"HESTGenericHardwareErrorSourceTooShort",
			"HEST Generic Hardware Error Source Too Short "
			"too short, expecting %zu bytes, "
			"instead got %zu bytes",
			sizeof(fwts_acpi_table_hest_generic_hardware_error_source_v2), *length);
		*passed = false;
		*length = 0;	/* Forces an early abort */
		return;
	}

	fwts_log_info_verbatim(fw, "HEST Generic Hardware Error Source version 2");
	fwts_log_info_verbatim(fw, "  Type:                     0x%2.2" PRIx8, source->type);
	fwts_log_info_verbatim(fw, "  Source ID:                0x%4.4" PRIx16, source->source_id);
	fwts_log_info_verbatim(fw, "  Related Source ID:        0x%4.4" PRIx16, source->related_source_id);
	fwts_log_info_verbatim(fw, "  Flags:                    0x%2.2" PRIx8, source->flags);
	fwts_log_info_verbatim(fw, "  Enabled:                  0x%2.2" PRIx8, source->enabled);
	fwts_log_info_verbatim(fw, "  Num. Records. Prealloc.:  0x%8.8" PRIx32, source->number_of_records_to_preallocate);
	fwts_log_info_verbatim(fw, "  Max. Sections Per Rec.:   0x%8.8" PRIx32, source->max_sections_per_record);
	fwts_log_info_verbatim(fw, "  Max. Raw Data Length:     0x%8.8" PRIx32, source->max_raw_data_length);

        fwts_log_info_verbatim(fw, "  Error Status Address:");
        fwts_log_info_verbatim(fw, "    Address Space ID:       0x%2.2" PRIx8,
		source->error_status_address.address_space_id);
        fwts_log_info_verbatim(fw, "    Register Bit Width      0x%2.2" PRIx8,
		source->error_status_address.register_bit_width);
        fwts_log_info_verbatim(fw, "    Register Bit Offset     0x%2.2" PRIx8,
		source->error_status_address.register_bit_offset);
        fwts_log_info_verbatim(fw, "    Access Size             0x%2.2" PRIx8,
		source->error_status_address.access_width);
        fwts_log_info_verbatim(fw, "    Address                 0x%16.16" PRIx64,
			source->error_status_address.address);
        fwts_log_info_verbatim(fw, "  Hardware Error Notification:");
        fwts_log_info_verbatim(fw, "    Type:                   0x%2.2" PRIx8, source->notification.type);
        fwts_log_info_verbatim(fw, "    Length:                 0x%2.2" PRIx8, source->notification.length);
        fwts_log_info_verbatim(fw, "    Config. Write. Enable:  0x%4.4" PRIx16,
		source->notification.configuration_write_enable);
        fwts_log_info_verbatim(fw, "    Poll Interval:          0x%4.4" PRIx16,
		source->notification.poll_interval);
        fwts_log_info_verbatim(fw, "    Interrupt Vector:       0x%4.4" PRIx16,
		source->notification.vector);
        fwts_log_info_verbatim(fw, "    Sw. to Polling Value:   0x%4.4" PRIx16,
		source->notification.switch_to_polling_threshold_value);
        fwts_log_info_verbatim(fw, "    Sw. to Polling Window:  0x%4.4" PRIx16,
		source->notification.switch_to_polling_threshold_window);
        fwts_log_info_verbatim(fw, "    Error: Thresh. Value:   0x%4.4" PRIx16,
		source->notification.error_threshold_value);
        fwts_log_info_verbatim(fw, "    Error: Thresh. Window:  0x%4.4" PRIx16,
		source->notification.error_threshold_window);
	fwts_log_info_verbatim(fw, "  Error Status Blk. Length: 0x%8.8" PRIx32, source->error_status_block_length);
        fwts_log_info_verbatim(fw, "  Read Ack Register:");
        fwts_log_info_verbatim(fw, "    Address Space ID:       0x%2.2" PRIx8,
		source->read_ack_register.address_space_id);
        fwts_log_info_verbatim(fw, "    Register Bit Width      0x%2.2" PRIx8,
		source->read_ack_register.register_bit_width);
        fwts_log_info_verbatim(fw, "    Register Bit Offset     0x%2.2" PRIx8,
		source->read_ack_register.register_bit_offset);
        fwts_log_info_verbatim(fw, "    Access Size             0x%2.2" PRIx8,
		source->read_ack_register.access_width);
        fwts_log_info_verbatim(fw, "    Address                 0x%16.16" PRIx64,
			source->read_ack_register.address);
	fwts_log_info_verbatim(fw, "  Read Ack Preserve:        0x%16.16" PRIx64, source->read_ack_preserve);
	fwts_log_info_verbatim(fw, "  Read Ack Write:           0x%16.16" PRIx64, source->read_ack_write);
	fwts_log_nl(fw);

	if (source->number_of_records_to_preallocate < 1) {
		*passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"HESTInvalidRecordsToPreallocate",
			"HEST Hardware Error Source Number of Records "
			"to Preallocate is 0x%" PRIx16 " and must be "
			"more than zero.",
			source->number_of_records_to_preallocate);
	}
	if (source->max_sections_per_record < 1) {
		*passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"HESTInvalidMaxSectionsPerRecord",
			"HEST Hardware Error Source Max Sections Per "
			"Record is 0x%" PRIx16 " and must be "
			"more than zero.",
			source->max_sections_per_record);
	}
	if (source->notification.type > 11) {
		*passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"HESTInvalidHardwareErrorNotificationType",
			"HEST Hardware Error Notification Type is "
			"an invalid reserved value of %2.2" PRIu8 ","
			"expecting value 0 to 11",
			source->notification.type);
	}

	fwts_acpi_reserved_bits_check(fw, "HEST", "HEST Configuration Write Enabled",
		source->notification.configuration_write_enable,
		sizeof(source->notification.configuration_write_enable), 6, 31, passed);

	*length -= sizeof(fwts_acpi_table_hest_generic_hardware_error_source_v2);
	*data += sizeof(fwts_acpi_table_hest_generic_hardware_error_source_v2);
}
示例#18
0
文件: hest.c 项目: 9elements/fwts
/*
 *  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);
}
示例#19
0
文件: asf.c 项目: 9elements/fwts
/*
 *  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;
}
示例#20
0
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);
	}
示例#21
0
文件: hest.c 项目: 9elements/fwts
/*
 *  ACPI Section 18.3.2.2 IA-32 Architecture Corrected Machine Check
 */
static void hest_check_ia32_arch_corrected_machine_check(
	fwts_framework *fw,
	ssize_t *length,
	uint8_t **data,
	bool *passed)
{
	ssize_t i, total_size;

	fwts_acpi_table_hest_ia32_corrected_machine_check *check =
		(fwts_acpi_table_hest_ia32_corrected_machine_check *)*data;

	if (*length < (ssize_t)sizeof(fwts_acpi_table_hest_ia32_corrected_machine_check)) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"HESTIA32CorrectedMachineCheckTooShort",
			"HEST IA-32 Architecture Corrected Machine Check "
			"too short, expecting %zu bytes, "
			"instead got %zu bytes",
			sizeof(fwts_acpi_table_hest_ia32_corrected_machine_check), *length);
		*passed = false;
		*length = 0;	/* Forces an early abort */
		return;
	}

	total_size = sizeof(fwts_acpi_table_hest_ia32_corrected_machine_check) +
		(check->number_of_hardware_banks *
		sizeof(fwts_acpi_table_hest_machine_check_bank));

	if (*length < total_size) {
		*passed = false;
		*length = 0;	/* Forces an early abort */
		return;
	}

	fwts_log_info_verbatim(fw, "HEST IA-32 Architecture Machine Check:");
	fwts_log_info_verbatim(fw, "  Type:                     0x%2.2" PRIx8, check->type);
	fwts_log_info_verbatim(fw, "  Source ID:                0x%4.4" PRIx16, check->source_id);
	fwts_log_info_verbatim(fw, "  Reserved:                 0x%4.4" PRIx16, check->reserved1);
	fwts_log_info_verbatim(fw, "  Flags:                    0x%2.2" PRIx8, check->flags);
	fwts_log_info_verbatim(fw, "  Enabled:                  0x%2.2" PRIx8, check->enabled);
	fwts_log_info_verbatim(fw, "  Number of Records:        0x%8.8" PRIx32, check->number_of_records_to_preallocate);
	fwts_log_info_verbatim(fw, "  Max Sections Per Record:  0x%8.8" PRIx32, check->max_sections_per_record);
	fwts_log_info_verbatim(fw, "  Hardware Error Notification:");
	fwts_log_info_verbatim(fw, "    Type:                   0x%2.2" PRIx8, check->notification.type);
	fwts_log_info_verbatim(fw, "    Length:                 0x%2.2" PRIx8, check->notification.length);
	fwts_log_info_verbatim(fw, "    Config. Write. Enable:  0x%4.4" PRIx16,
		check->notification.configuration_write_enable);
	fwts_log_info_verbatim(fw, "    Poll Interval:          0x%4.4" PRIx16,
		check->notification.poll_interval);
	fwts_log_info_verbatim(fw, "    Interrupt Vector:       0x%4.4" PRIx16,
		check->notification.vector);
	fwts_log_info_verbatim(fw, "    Sw. to Polling Value:   0x%4.4" PRIx16,
		check->notification.switch_to_polling_threshold_value);
	fwts_log_info_verbatim(fw, "    Sw. to Polling Window:  0x%4.4" PRIx16,
		check->notification.switch_to_polling_threshold_window);
	fwts_log_info_verbatim(fw, "    Error: Thresh. Value:   0x%4.4" PRIx16,
		check->notification.error_threshold_value);
	fwts_log_info_verbatim(fw, "    Error: Thresh. Window:  0x%4.4" PRIx16,
		check->notification.error_threshold_window);
	fwts_log_info_verbatim(fw, "  Number of Hardware Banks: 0x%8.8" PRIx32, check->number_of_hardware_banks);
	fwts_log_info_verbatim(fw, "  Reserved:                 0x%2.2" PRIx8, check->reserved2[0]);
	fwts_log_info_verbatim(fw, "  Reserved:                 0x%2.2" PRIx8, check->reserved2[1]);
	fwts_log_info_verbatim(fw, "  Reserved:                 0x%2.2" PRIx8, check->reserved2[2]);
	fwts_log_nl(fw);

	if (check->flags & ~0x5) {
		fwts_failed(fw, LOG_LEVEL_MEDIUM,
			"HESTIA32CorrectedMachineCheckFlagsReserved",
			"HEST IA-32 Architecture MC Flags Reserved bits "
			"[1] & [3:7] must be zero, instead got 0x%" PRIx8,
			check->flags);
		*passed = false;
	} else if (check->flags == 0x5) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"HESTIA32CorrectedMachineCheckBadFlags",
			"HEST IA-32 Architecture MC Flags bits [0] & [2] "
			"are mutually exclusive, instead got 0x%" PRIx8,
			check->flags);
		*passed = false;
	}

	if (check->notification.type > 11) {
		*passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"HESTInvalidHardwareErrorNotificationType",
			"HEST Hardware Error Notification Type is "
			"an invalid reserved value of %2.2" PRIu8 ","
			"expecting value 0 to 11",
			check->notification.type);
	}

	for (i = 0; i < check->number_of_hardware_banks; i++) {
		fwts_acpi_table_hest_machine_check_bank *bank = &check->bank[i];

		fwts_log_info_verbatim(fw, "  HEST IA-32 Architecture Machine Check Bank %zd", i);
		fwts_log_info_verbatim(fw, "    Bank Number:            0x%2.2" PRIx8, bank->bank_number);
		fwts_log_info_verbatim(fw, "    Clear Status On Init.:  0x%2.2" PRIx8, bank->clear_status_on_initialization);
		fwts_log_info_verbatim(fw, "    Status Data Format:     0x%2.2" PRIx8, bank->status_data_format);
		fwts_log_info_verbatim(fw, "    Reserved:               0x%2.2" PRIx8, bank->reserved);
		fwts_log_info_verbatim(fw, "    Control Reg. MSR Addr:  0x%8.8" PRIx32, bank->control_register_msr_address);
		fwts_log_info_verbatim(fw, "    Control Init Data:      0x%16.16" PRIx64, bank->control_init_data);
		fwts_log_info_verbatim(fw, "    Status Reg. MSR Addr:   0x%8.8" PRIx32, bank->status_register_msr_address);
		fwts_log_info_verbatim(fw, "    Addr Reg. MSR Addr:     0x%8.8" PRIx32, bank->address_register_msr_address);
		fwts_log_info_verbatim(fw, "    Misc Reg. MSR Addr:     0x%8.8" PRIx32, bank->misc_register_msr_address);
		fwts_log_nl(fw);

		if (bank->clear_status_on_initialization > 1) {
			*passed = false;
			fwts_failed(fw, LOG_LEVEL_HIGH,
				"HESTIA32InvalidClearStatusOnInit",
				"HEST IA-32 Architecture Machine Check Bank Clear Status On Initialization "
				"has value 0x%" PRIx8 " and only valid values are "
				"0x00 (Clear) or 0x01 (Don't Clear)",
				bank->clear_status_on_initialization);
		}
		if (bank->status_data_format > 2) {
			*passed = false;
			fwts_failed(fw, LOG_LEVEL_HIGH,
				"HESTIA32InvalidBankStatusDataFormat",
				"HEST IA-32 Architecture Machine Check Bank Status Data Format "
				"has value 0x%" PRIx8 " and only valid values are "
				"0x00 (IA-32 MCA), 0x01 (Intel 64 MCA) or "
				"0x02 (AMD64 MCA).",
				bank->status_data_format);
		}
	}

	*length -= total_size;
	*data += total_size;
}
示例#22
0
文件: srat.c 项目: ahs3/fwts-sbbr
static void srat_check_local_apic_sapic_affinity(
	fwts_framework *fw,
	ssize_t		*length,
	uint8_t		**data,
	bool		*passed)
{
	fwts_acpi_table_local_apic_sapic_affinity *affinity =
		(fwts_acpi_table_local_apic_sapic_affinity *)*data;

	if ((ssize_t)sizeof(fwts_acpi_table_local_apic_sapic_affinity) > *length) {
		fwts_failed(fw, LOG_LEVEL_MEDIUM,
			"SRATLocalApicSapicAffinityShort",
			"SRAT Local APIC/SPAIC Affinity structure too short, got "
			"%zu bytes, expecting %zu bytes",
			*length, sizeof(fwts_acpi_table_local_apic_sapic_affinity));
		*passed = false;
		goto done;
	}

	if (affinity->length != sizeof(fwts_acpi_table_local_apic_sapic_affinity)) {
		fwts_failed(fw, LOG_LEVEL_MEDIUM,
			"SRATLocalApicSapicAffinityLength",
			"SRAT Local APIC/SPAIC Affinity Length incorrect, got "
			"%" PRIu8 ", expecting %zu",
			affinity->length, sizeof(fwts_acpi_table_local_apic_sapic_affinity));
		*passed = false;
		goto done;
	}

	fwts_log_info_verbatum(fw, "SRAT Local APIC/SAPIC Affinity Structure:");
	fwts_log_info_verbatum(fw, "  Type:                     0x%2.2" PRIx8, affinity->type);
	fwts_log_info_verbatum(fw, "  Length:                   0x%2.2" PRIx8, affinity->length);
	fwts_log_info_verbatum(fw, "  Proximity Domain:   [7:0] 0x%2.2" PRIx8, affinity->proximity_domain_0);
	fwts_log_info_verbatum(fw, "  APIC ID:                  0x%2.2" PRIx8, affinity->apic_id);
	fwts_log_info_verbatum(fw, "  Flags:                    0x%8.8" PRIx32, affinity->flags);
	fwts_log_info_verbatum(fw, "  Local SAPIC EID:          0x%2.2" PRIx8, affinity->local_sapic_eid);
	fwts_log_info_verbatum(fw, "  Proximity Domain:  [8:15] 0x%2.2" PRIx8, affinity->proximity_domain_1);
	fwts_log_info_verbatum(fw, "  Proximity Domain: [16:23] 0x%2.2" PRIx8, affinity->proximity_domain_2);
	fwts_log_info_verbatum(fw, "  Proximity Domain: [23:31] 0x%2.2" PRIx8, affinity->proximity_domain_3);
	fwts_log_info_verbatum(fw, "  Clock Domain              0x%8.8" PRIx32, affinity->clock_domain);
	fwts_log_nl(fw);

	if (affinity->flags & ~0x1UL) {
		fwts_failed(fw, LOG_LEVEL_MEDIUM,
			"SRATLocalApicSapicAffinityFlags",
			"SRAT Local APIC/SPAIC Affinity Flags field reserved bits 1..31 should be zero, got "
			"0x%" PRIx32,
			affinity->flags);
		*passed = false;
	}

	/*
	 * Not clear of bits 0..7 of Proximity Domain are reserved or not
	 * so skip check for these
	 */

	/*
	 *  Clock domain probably needs deeper sanity checking, for now
	 *  skip this.
	 */
done:
	*length -= sizeof(fwts_acpi_table_local_apic_sapic_affinity);
	*data += sizeof(fwts_acpi_table_local_apic_sapic_affinity);
}
示例#23
0
文件: mchi.c 项目: ahs3/fwts-sbbr
/*
 *  MCHI Management Controller Host Interface Table
 *    http://www.dmtf.org/sites/default/files/standards/documents/DSP0256_1.0.0.pdf
 */
static int mchi_test1(fwts_framework *fw)
{
	bool passed = true;
	fwts_acpi_table_mchi *mchi = (fwts_acpi_table_mchi *)table->data;

	if (table->length < sizeof(fwts_acpi_table_mchi)) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"MCHITooShort",
			"MCHI table too short, expecting %zu bytes, "
			"instead got %zu bytes",
			sizeof(fwts_acpi_table_mchi), table->length);
		goto done;
	}

#if DUMP_MCHI_TABLE
	fwts_log_info_verbatum(fw, "MCHI Table:");
	fwts_log_info_verbatum(fw, "  Interface Type:           0x%2.2" PRIx8, mchi->interface_type);
	fwts_log_info_verbatum(fw, "  Protocol Identifier       0x%2.2" PRIx8, mchi->protocol_identifier);
	fwts_log_info_verbatum(fw, "  Protocol Data:            "
		"0x%2.2" PRIx8 " 0x%2.2" PRIx8 " 0x%2.2" PRIx8 " 0x%2.2" PRIx8,
			mchi->protocol_data[0], mchi->protocol_data[1],
			mchi->protocol_data[2], mchi->protocol_data[3]);
	fwts_log_info_verbatum(fw, "                            "
		"0x%2.2" PRIx8 " 0x%2.2" PRIx8 " 0x%2.2" PRIx8 " 0x%2.2" PRIx8,
			mchi->protocol_data[4], mchi->protocol_data[5],
			mchi->protocol_data[6], mchi->protocol_data[7]);
	fwts_log_info_verbatum(fw, "  Interrupt Type:           0x%2.2" PRIx8, mchi->interrupt_type);
	fwts_log_info_verbatum(fw, "  GPE:                      0x%2.2" PRIx8, mchi->gpe);
	fwts_log_info_verbatum(fw, "  PCI Device Flag:          0x%2.2" PRIx8, mchi->pci_device_flag);
	fwts_log_info_verbatum(fw, "  Global System Interrupt:  0x%8.8" PRIx32, mchi->global_system_interrupt);
	fwts_log_info_verbatum(fw, "  Base Address:");
	fwts_log_info_verbatum(fw, "    Address Space ID:       0x%2.2" PRIx8, mchi->base_address.address_space_id);
	fwts_log_info_verbatum(fw, "    Register Bit Width      0x%2.2" PRIx8, mchi->base_address.register_bit_width);
	fwts_log_info_verbatum(fw, "    Register Bit Offset     0x%2.2" PRIx8, mchi->base_address.register_bit_offset);
	fwts_log_info_verbatum(fw, "    Access Size             0x%2.2" PRIx8, mchi->base_address.access_width);
	fwts_log_info_verbatum(fw, "    Address                 0x%16.16" PRIx64, mchi->base_address.address);
	if ((mchi->pci_device_flag & 1) == 1) {
		fwts_log_info_verbatum(fw, "  PCI Segment Group:       0x%2.2" PRIx8, mchi->bytes[0]);
		fwts_log_info_verbatum(fw, "  PCI Bus Number:          0x%2.2" PRIx8, mchi->bytes[1]);
		fwts_log_info_verbatum(fw, "  PCI Device Number:       0x%2.2" PRIx8, mchi->bytes[2]);
		fwts_log_info_verbatum(fw, "  PCI Function Number:     0x%2.2" PRIx8, mchi->bytes[3]);
	} else {
		/* Zero -> UIDS */
		fwts_log_info_verbatum(fw, "  UID Bytes 1-4:            "
			"0x%2.2" PRIx8 " 0x%2.2" PRIx8 " 0x%2.2" PRIx8 " 0x%2.2" PRIx8,
			mchi->bytes[0], mchi->bytes[1], mchi->bytes[2], mchi->bytes[3]);
	}
	fwts_log_nl(fw);
#endif
	if ((mchi->interface_type < 2) ||
	    (mchi->interface_type > 8)) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"MCHIInvalidInterfaceType",
			"MCHI Interface Type is 0x%2.2" PRIx8 " which is reserved, "
			"allowed values are 0x02..0x08", mchi->interface_type);
	}
	if ((mchi->protocol_identifier > 2) &&
	    (mchi->protocol_identifier < 255)) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"MCHIInvalidProtocolIdentifier",
			"MCHI Protocol Identifier 0x%2.2" PRIx8 " which is reserved, "
			"allowed values are 0x00 (Unspecifier), 0x01 (MCTP), 0x02 (IPMI) or "
			"255 (OEM defined)", mchi->protocol_identifier);
	}
	if (mchi->interrupt_type & ~0x03) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"MCHIInterruptTypeReservedNonZero",
			"MCHI Interrupt Type 0x%2.2" PRIx8 " has some reserved "
			"bits [7:2] set, these should be all zero.",
			mchi->interrupt_type);
	}
	if (((mchi->interrupt_type & 0x01) == 0) &&
	    (mchi->gpe != 0)) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"MCHIGpeNonZero",
			"MCHI GPE is 0x%2.2" PRIx8 " and should be zero "
			"when bit 0 of the Interrupt Type field is 0 "
			"(SCI triggered through GPE non-supported)",
			mchi->gpe);
	}
	if (mchi->pci_device_flag & ~0x01) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"MCHIPciDeviceFlagReservedNonZero",
			"MCHI PCI Device Flag 0x%2.2" PRIx8 " has some reserved "
			"bits [7:1] set, these should be all zero.",
			mchi->pci_device_flag);
	}
	if (((mchi->interrupt_type & 0x02) == 0) &&
	    (mchi->global_system_interrupt != 0)) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"MCHIGsiNonZero",
			"MCHI Global System Interrupt is 0x%2.2" PRIx8 " and should be zero "
			"when bit 1 of the Interrupt Type field is 0",
			mchi->global_system_interrupt);
	}

	if ((mchi->base_address.address_space_id != 0x00) &&
	    (mchi->base_address.address_space_id != 0x01) &&
	    (mchi->base_address.address_space_id != 0x04)) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"MCHIAddrSpaceIdInvalid",
			"MCHI Address Space ID is 0x%2.2" PRIx8 " and should be "
			"0x00 (System Memory), 0x01 (System I/O) or 0x04 (SMBus)",
			mchi->base_address.address_space_id);
	}

	/* SMBus specific checks */
	if (mchi->base_address.address_space_id == 0x04) {
		if ((mchi->pci_device_flag & 0x01) == 1) {
			passed = false;
			fwts_failed(fw, LOG_LEVEL_HIGH,
				"MCHIPciDeviceFlagInvalid",
				"MCHI PCI Device Flag is 0x%2.2" PRIx8
				" and bit [0] should be 0 for a SMBus Address Space ID",
				mchi->pci_device_flag);
		}
		if (mchi->base_address.register_bit_width != 0) {
			passed = false;
			fwts_failed(fw, LOG_LEVEL_MEDIUM,
				"MCHISmbusRegBitWidthNonZero",
				"MCHI Base Address Register Bit Width is 0x%2.2" PRIx8
				" and should be zero for a SMBus Address Space ID",
				mchi->base_address.register_bit_width);
		}
		if (mchi->base_address.register_bit_offset != 0) {
			passed = false;
			fwts_failed(fw, LOG_LEVEL_MEDIUM,
				"MCHISmbusRegBitOffsetNonZero",
				"MCHI Base Address Register Bit Offset is 0x%2.2" PRIx8
				" and should be zero for a SMBus Address Space ID",
				mchi->base_address.register_bit_offset);
		}
		if (mchi->base_address.access_width != 1) {
			passed = false;
			fwts_failed(fw, LOG_LEVEL_MEDIUM,
				"MCHISmbusRegAddressSizeInvalid",
				"MCHI Base Address Register Address Size is 0x%2.2" PRIx8
				" and should be 1 (byte access) for a SMBus Address Space ID",
				mchi->base_address.access_width);
		}
		if (mchi->base_address.address & ~(0x7fULL)) {
			passed = false;
			fwts_failed(fw, LOG_LEVEL_MEDIUM,
				"MCHISmbusAddressInvalid",
				"MCHI Base Address is 0x%16.16" PRIx64
				" and should be 0x00..0x7f a SMBus Address Space ID",
				mchi->base_address.address);
		}
	}
	/* PCI Device field specific checks */
	if (mchi->pci_device_flag & 0x01) {
		if (mchi->bytes[2] & ~0x1f) {
			passed = false;
			fwts_failed(fw, LOG_LEVEL_MEDIUM,
				"MCHIPciDeviceNumberInvalid",
				"MCHI PCI Device Number is 0x%2.2" PRIx8
				" and reserved bits [7:5] should be zero",
				mchi->bytes[2]);
		}
		if (mchi->bytes[3] & ~0x47) {
			passed = false;
			fwts_failed(fw, LOG_LEVEL_MEDIUM,
				"MCHIPciFunctionNumberInvalid",
				"MCHI PCI Function Number is 0x%2.2" PRIx8
				" and reserved bits [7] and [5:3] should be zero",
				mchi->bytes[3]);
		}
	}

done:
	if (passed)
		fwts_passed(fw, "No issues found in MCHI table.");

	return FWTS_OK;
}