示例#1
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;
}
示例#2
0
文件: pcct.c 项目: ColinIanKing/fwts
static void memory_length(fwts_framework *fw, uint8_t type, uint64_t memory_range, uint64_t min_length, bool *passed)
{
	switch (type) {
	case 0 ... 2:
		fwts_log_info_verbatim(fw, "    Length:                      0x%16.16" PRIx64, memory_range);
		if (memory_range <= min_length) {
			*passed = false;
			fwts_failed(fw, LOG_LEVEL_HIGH,
				"PCCTBadSubtypeMemoryLength",
				"PCCT Subspace Type %" PRId8 " must have memory length > 0x%16.16" PRIx64
				", got 0x%16.16" PRIx64 " instead", type, min_length, memory_range);
		}
		break;
	case 3 ... 4:
		fwts_log_info_verbatim(fw, "    Length:                      0x%8.8" PRIx32, (uint32_t)memory_range);
		if (memory_range <= min_length) {
			*passed = false;
			fwts_failed(fw, LOG_LEVEL_HIGH,
				"PCCTBadSubtypeMemoryLength",
				"PCCT Subspace Type %" PRId8 " must have memory length > 0x%8.8" PRIx32
				", got 0x%8.8" PRIx32 " instead", type, (uint32_t)min_length, (uint32_t)memory_range);
		}
		break;
	}
}
示例#3
0
文件: asf.c 项目: 9elements/fwts
/*
 *  4.1.2.7 ASF_ADDR
 */
static void asf_check_addr(
	fwts_framework *fw,
	ssize_t record_length,
	ssize_t length,
	uint8_t *data,
	bool *passed,
	bool *abort)
{
	ssize_t total_length;
	fwts_acpi_table_asf_addr *addr = (fwts_acpi_table_asf_addr *)data;
#if ASF_DUMP
	uint8_t i;
#else
	(void)data;
#endif
	if (length < (ssize_t)sizeof(fwts_acpi_table_asf_addr)) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"ASF!AddrRecordTooShort",
			"ASF! ASF_ADDR Record too short, "
			"expecting %zu bytes, instead got %zu bytes",
			sizeof(fwts_acpi_table_asf_addr), length);
		*passed = false;
		*abort = true;
		return;
	}
#if ASF_DUMP
	fwts_log_info_verbatim(fw, "ASF! ASF_ADDR Record:");
	fwts_log_info_verbatim(fw, "  SEEPROM Address:          0x%2.2" PRIx8, addr->seeprom_addr);
	fwts_log_info_verbatim(fw, "  Number of Devices:        0x%2.2" PRIx8, addr->number_of_devices);
#endif
	total_length = sizeof(fwts_acpi_table_asf_addr) +
		(addr->number_of_devices * sizeof(fwts_acpi_table_asf_addr_element));
	if (total_length > record_length) {
		*passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"ASF!AddrArrayElementLengthInvalid",
			"ASF! ASF_ADDR Number of Devices makes the "
			"total ASF_ADDR record size to be %zu bytes, however the "
			"table is only %zu bytes long",
			total_length, record_length);
		*passed = false;
		*abort = true;
		return;
	}

#if ASF_DUMP
	data += sizeof(fwts_acpi_table_asf_addr);
	for (i = 0; i < addr->number_of_devices; i++) {
		fwts_acpi_table_asf_addr_element *element =
			(fwts_acpi_table_asf_addr_element *)data;
		fwts_log_info_verbatim(fw, "  Fixed SMBus Address       0x%2.2" PRIx8, element->fixed_smbus_addr);
		data += sizeof(fwts_acpi_table_asf_addr_element);
	}
#endif
	if (*passed)
		fwts_passed(fw, "No issues found in ASF! ASF_ADDR record.");
}
示例#4
0
/*
 *  Dump ACPI header in a form that matches IASL's header dump format
 */
static void acpidump_hdr(
	fwts_framework *fw,
	const fwts_acpi_table_header *hdr,
	const size_t length)
{
	if (length < sizeof(fwts_acpi_table_header))
		return;
	fwts_log_info_verbatim(fw, "[000h 0000   4]                    Signature : \"%4.4s\"",
		hdr->signature);
	fwts_log_info_verbatim(fw, "[004h 0004   4]                 Table Length : %8.8" PRIx32,
		hdr->length);
	fwts_log_info_verbatim(fw, "[008h 0008   1]                     Revision : %2.2" PRIx8,
		hdr->revision);
	fwts_log_info_verbatim(fw, "[009h 0009   1]                     Checksum : %2.2" PRIx8,
		hdr->checksum);
	fwts_log_info_verbatim(fw, "[00Ah 0010   6]                       Oem ID : \"%6.6s\"",
		hdr->oem_id);
	fwts_log_info_verbatim(fw, "[010h 0016   8]                 Oem Table ID : \"%8.8s\"",
		hdr->oem_tbl_id);
	fwts_log_info_verbatim(fw, "[018h 0024   4]                 Oem Revision : %8.8" PRIx32,
		hdr->oem_revision);
	fwts_log_info_verbatim(fw, "[01Ch 0028   4]              Asl Compiler ID : \"%4.4s\"",
		hdr->creator_id);
	fwts_log_info_verbatim(fw, "[020h 0032   4]        Asl Compiler Revision : %8.8" PRIx32,
		hdr->creator_revision);
}
示例#5
0
/*
 *  Alas, RSDP is a special case
 */
static void acpidump_rsdp(
	fwts_framework *fw,
	const fwts_acpi_table_info *table)
{
	fwts_acpi_table_rsdp *rsdp = (fwts_acpi_table_rsdp *)table->data;

	if (table->length < sizeof(fwts_acpi_table_rsdp))
		return;

	fwts_log_info_verbatim(fw, "[000h 0000   8]                    Signature : \"%8.8s\"",
		rsdp->signature);
	fwts_log_info_verbatim(fw, "[008h 0008   1]                     Checksum : %1.1" PRIx8,
		rsdp->checksum);
	fwts_log_info_verbatim(fw, "[009h 0009   6]                       Oem ID : \"%6.6s\"",
		rsdp->oem_id);
	fwts_log_info_verbatim(fw, "[00fh 0015   1]                     Revision : %2.2" PRIx8,
		rsdp->revision);
	fwts_log_info_verbatim(fw, "[010h 0016   4]                 RSDT Address : %8.8" PRIx32,
		rsdp->rsdt_address);
	fwts_log_info_verbatim(fw, "[014h 0020   4]                 Table Length : %8.8" PRIx32,
		rsdp->length);
	fwts_log_info_verbatim(fw, "[018h 0024   8]                 XSDT Address : %16.16" PRIx64,
		rsdp->xsdt_address);
	fwts_log_info_verbatim(fw, "[020h 0032   1]            Extended Checksum : %2.2" PRIx8,
		rsdp->extended_checksum);
	fwts_log_info_verbatim(fw, "[021h 0033   3]                     Reserved : %2.2" PRIx8 " %2.2" PRIx8 " %2.2" PRIx8,
		rsdp->reserved[0], rsdp->reserved[1], rsdp->reserved[2]);
}
示例#6
0
文件: tpm2.c 项目: ColinIanKing/fwts
/*
 * 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;
}
示例#7
0
文件: asf.c 项目: 9elements/fwts
/*
 *  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.");
}
示例#8
0
文件: pcct.c 项目: ColinIanKing/fwts
static void hw_reduced_comm_test_type1(fwts_framework *fw, fwts_acpi_table_pcct_subspace_type_1 *entry, bool *passed)
{
	fwts_log_info_verbatim(fw, "    Platform Interrupt:          0x%8.8"   PRIx32, entry->platform_interrupt);
	fwts_log_info_verbatim(fw, "    Platform Interrupt Flags:    0x%2.2"   PRIx8, entry->platform_interrupt_flags);
	fwts_log_info_verbatim(fw, "    Reserved:                    0x%2.2"   PRIx8, entry->reserved);
	fwts_log_info_verbatim(fw, "    Base Address:                0x%16.16" PRIx64, entry->base_address);
	memory_length(fw, entry->header.type, entry->length, 8, passed);
	fwts_log_info_verbatim(fw, "    Doorbell Register:");
	gas_messages(fw, entry->header.type, &entry->doorbell_register, passed);
	fwts_log_info_verbatim(fw, "    Doorbell Preserve:           0x%16.16" PRIx64, entry->doorbell_preserve);
	fwts_log_info_verbatim(fw, "    Doorbell Write:              0x%16.16" PRIx64, entry->doorbell_write);
	fwts_log_info_verbatim(fw, "    Nominal Latency:             0x%8.8"   PRIx32, entry->nominal_latency);
	fwts_log_info_verbatim(fw, "    Max Periodic Access Rate:    0x%8.8"   PRIx32, entry->max_periodic_access_rate);
	fwts_log_info_verbatim(fw, "    Min Request Turnaround Time: 0x%8.8"   PRIx32, entry->min_request_turnaround_time);

	fwts_acpi_reserved_bits_check(fw, "PCCT", "Platform Interrupt Flags", entry->platform_interrupt_flags, sizeof(uint8_t), 2, 7, passed);
}
示例#9
0
文件: asf.c 项目: 9elements/fwts
/*
 *  4.1.2.6 ASF_RMCP
 */
static void asf_check_rmcp(
	fwts_framework *fw,
	ssize_t length,
	uint8_t *data,
	bool *passed,
	bool *abort)
{
	fwts_acpi_table_asf_rmcp *rmcp = (fwts_acpi_table_asf_rmcp *)data;

	if (length < (ssize_t)sizeof(fwts_acpi_table_asf_rmcp)) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"ASF!RmcpRecordTooShort",
			"ASF! ASF_RMCP Record too short, "
			"expecting %zu bytes, instead got %zu bytes",
			sizeof(fwts_acpi_table_asf_rmcp), length);
		*passed = false;
		*abort = true;
		return;
	}
#if ASF_DUMP
	fwts_log_info_verbatim(fw, "ASF! ASF_RMCP Record:");
	fwts_log_info_verbatim(fw, "  Remote Control Cap.:      "
		"0x%2.2" PRIx8 " 0x%2.2" PRIx8 " 0x%2.2" PRIx8 " 0x%2.2" PRIx8 " "
		"0x%2.2" PRIx8 " 0x%2.2" PRIx8 " 0x%2.2" PRIx8,
		rmcp->remote_control_capabilities[0],
		rmcp->remote_control_capabilities[1],
		rmcp->remote_control_capabilities[2],
		rmcp->remote_control_capabilities[3],
		rmcp->remote_control_capabilities[4],
		rmcp->remote_control_capabilities[5],
		rmcp->remote_control_capabilities[6]);
	fwts_log_info_verbatim(fw, "  Boot Opt. Completion Code:0x%2.2" PRIx8, rmcp->completion_code);
	fwts_log_info_verbatim(fw, "  IANA Enterprise ID:       0x%8.8" PRIx32, rmcp->iana);
	fwts_log_info_verbatim(fw, "  Special Command:          0x%2.2" PRIx8, rmcp->special_command);
	fwts_log_info_verbatim(fw, "  Special Command Parameter:0x%4.4" PRIx16, rmcp->special_command_param);
	fwts_log_info_verbatim(fw, "  Boot Options:             0x%2.2" PRIx8 " 0x%2.2" PRIx8,
		rmcp->boot_options[0], rmcp->boot_options[1]);
	fwts_log_info_verbatim(fw, "  OEM Parameters:           0x%4.4" PRIx16, rmcp->oem_parameters);
#endif

	/* Specification, page 33-34 */
	if (rmcp->iana == 0x4542) {
		/* Values 0x00..0x05 and 0xc0..0xff are allowed */
		if ((rmcp->special_command > 0x05) &&
		    (rmcp->special_command < 0xc0)) {
			*passed = false;
			fwts_failed(fw, LOG_LEVEL_HIGH,
				"ASF!RmcpSpecialCommandInvalid",
				"ASF! ASF_RMCP Special Command is 0x%" PRIx8
				"and should be 0x00..0x05 or 0xc0..0xff",
				rmcp->special_command);
		}
	}
	if (*passed)
		fwts_passed(fw, "No issues found in ASF! ASF_RMCP record.");
}
示例#10
0
文件: aspt.c 项目: ColinIanKing/fwts
/*
 *  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 (!fwts_acpi_table_length_check(fw, "ASPT", table->length, sizeof(fwts_acpi_table_aspt))) {
		passed = false;
		goto done;
	}

	fwts_log_info_verbatim(fw, "ASPT Table:");
	fwts_log_info_verbatim(fw, "  SPTT Start Address: 0x%8.8" PRIx32,
		aspt->sptt_addr_start);
	fwts_log_info_verbatim(fw, "  SPTT End Address:   0x%8.8" PRIx32,
		aspt->sptt_addr_end);
	fwts_log_info_verbatim(fw, "  AMRT Start Address: 0x%8.8" PRIx32,
		aspt->amrt_addr_start);
	fwts_log_info_verbatim(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;
}
示例#11
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);
}
示例#12
0
文件: pcct.c 项目: ColinIanKing/fwts
static void gas_messages(fwts_framework *fw, uint8_t type, fwts_acpi_gas *gas, bool *passed)
{
	fwts_log_info_verbatim(fw, "      Address Space ID           0x%2.2"   PRIx8, gas->address_space_id);
	fwts_log_info_verbatim(fw, "      Register Bit Width         0x%2.2"   PRIx8, gas->register_bit_width);
	fwts_log_info_verbatim(fw, "      Register Bit Offset        0x%2.2"   PRIx8, gas->register_bit_offset);
	fwts_log_info_verbatim(fw, "      Access Size                0x%2.2"   PRIx8, gas->access_width);
	fwts_log_info_verbatim(fw, "      Address                    0x%16.16" PRIx64, gas->address);

	if ((gas->address_space_id != FWTS_GAS_ADDR_SPACE_ID_SYSTEM_IO) &&
	    (gas->address_space_id != FWTS_GAS_ADDR_SPACE_ID_SYSTEM_MEMORY) &&
			(gas->address_space_id != FWTS_GAS_ADDR_SPACE_ID_FFH)) {
		*passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"PCCTSubspaceInvalidAddrSpaceID",
			"PCCT Subspace Type %" PRId8 " has space ID = %" PRId8
			" which is not System I/O, Memory or FFH", type, gas->address_space_id);
	}
}
示例#13
0
文件: romdump.c 项目: 9elements/fwts
static void romdump_data(fwts_framework *fw, uint8_t *data,
	int offset, int length)
{
	char buffer[128];
	int i;

	for (i = 0; i < length; i += 16) {
		fwts_dump_raw_data(buffer, sizeof(buffer), data+i, offset+i, 16);
		fwts_log_info_verbatim(fw, "%s", buffer);
	}
}
示例#14
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;
}
示例#15
0
static bool machine_matches_reference_model(fwts_framework *fw,
	const char *compatible,
	int compat_len,
	const char *model)
{
	bool compatible_is_reference = false, model_is_reference = false;
	struct reference_platform *plat;
	int i;

	for (i = 0; i < (int)FWTS_ARRAY_LEN(openpower_reference_platforms);
			i++) {
		plat = &openpower_reference_platforms[i];
		if (dt_fdt_stringlist_contains_last(compatible,
				compat_len, plat->compatible)) {
			compatible_is_reference = true;
			break;
		}
	}

	/* Not a reference platform, nothing to check */
	if (!compatible_is_reference) {
		fwts_log_info(fw, "Informational: no reference model found,"
			" device tree \"compatible\" is \"%s\" and"
			" \"model\" is \"%s\"",
			compatible, model);
		return true;
	}

	/* Since we're on a reference platform, ensure that the model is also
	 * one of the reference model numbers */
	for (i = 0; i < plat->n_models; i++) {
		if (!strcmp(model, plat->models[i])) {
			model_is_reference = true;
			break;
		}
	}

	if (model_is_reference) {
		fwts_log_info_verbatim(fw,
			"Matched reference model, device tree "
			"\"compatible\" is \"%s\" and \"model\" is "
			"\"%s\"",
			plat->compatible, model);
	}

	return model_is_reference;
}
示例#16
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);
        }
}
示例#17
0
static int uefivarinfo_test1(fwts_framework *fw)
{
	uint64_t status;
	uint64_t remvarstoragesize;
	uint64_t maxvariablesize;
	uint64_t maxvarstoragesize;

	uint64_t usedvars;
	uint64_t usedvarssize;

	if (do_queryvariableinfo(&status, &maxvarstoragesize, &remvarstoragesize, &maxvariablesize) == FWTS_ERROR) {
		if (status == EFI_UNSUPPORTED) {
			fwts_skipped(fw,
				"QueryVariableInfo UEFI runtime interface not supported: cannot test.");
			fwts_advice(fw,
				"Firmware also needs to check if the revision "
				"of system table is correct or not. Linux "
				"kernel returns EFI_UNSUPPORTED as well, if "
				"the FirmwareRevision of system table is less "
				"than EFI_2_00_SYSTEM_TABLE_REVISION.");
			return FWTS_SKIP;
		} else {
			fwts_log_info(fw, "Failed to query variable info with UEFI runtime service.");
			fwts_uefi_print_status_info(fw, status);
			return FWTS_ERROR;
		}
	}

	fwts_log_info_verbatim(fw, "UEFI NVRAM storage:");
	fwts_log_info_verbatim(fw, "  Maximum storage:       %8" PRIu64 " bytes", maxvarstoragesize);
	fwts_log_info_verbatim(fw, "  Remaining storage:     %8" PRIu64 " bytes", remvarstoragesize);
	fwts_log_info_verbatim(fw, "  Maximum variable size: %8" PRIu64 " bytes", maxvariablesize);

	if (do_checkvariables(fw, &usedvars, &usedvarssize, maxvariablesize) == FWTS_OK) {
		fwts_log_info_verbatim(fw, "Currently used:");
		fwts_log_info_verbatim(fw, "  %" PRIu64 " variables, storage used: %" PRIu64 " bytes", usedvars, usedvarssize);
	}

	return FWTS_OK;
}
示例#18
0
文件: pcct.c 项目: ColinIanKing/fwts
static void generic_comm_test(fwts_framework *fw, fwts_acpi_table_pcct_subspace_type_0 *entry, bool *passed)
{
	fwts_acpi_gas *gas = &entry->doorbell_register;
	uint64_t reserved;

	reserved = (uint64_t) entry->reserved[0] + ((uint64_t) entry->reserved[1] << 8) +
		   ((uint64_t) entry->reserved[2] << 16) + ((uint64_t) entry->reserved[3] << 24) +
		   ((uint64_t) entry->reserved[4] << 32) + ((uint64_t) entry->reserved[5] << 40);

	fwts_log_info_verbatim(fw, "    Reserved:                    0x%16.16" PRIx64, reserved);
	fwts_log_info_verbatim(fw, "    Base Address:                0x%16.16" PRIx64, entry->base_address);
	memory_length(fw, entry->header.type, entry->length, 8, passed);
	fwts_log_info_verbatim(fw, "    Doorbell Register:");
	fwts_log_info_verbatim(fw, "      Address Space ID           0x%2.2"   PRIx8, gas->address_space_id);
	fwts_log_info_verbatim(fw, "      Register Bit Width         0x%2.2"   PRIx8, gas->register_bit_width);
	fwts_log_info_verbatim(fw, "      Register Bit Offset        0x%2.2"   PRIx8, gas->register_bit_offset);
	fwts_log_info_verbatim(fw, "      Access Size                0x%2.2"   PRIx8, gas->access_width);
	fwts_log_info_verbatim(fw, "      Address                    0x%16.16" PRIx64, gas->address);
	fwts_log_info_verbatim(fw, "    Doorbell Preserve:           0x%16.16" PRIx64, entry->doorbell_preserve);
	fwts_log_info_verbatim(fw, "    Doorbell Write:              0x%16.16" PRIx64, entry->doorbell_write);
	fwts_log_info_verbatim(fw, "    Nominal Latency:             0x%8.8"   PRIx32, entry->nominal_latency);
	fwts_log_info_verbatim(fw, "    Max Periodic Access Rate:    0x%8.8"   PRIx32, entry->max_periodic_access_rate);
	fwts_log_info_verbatim(fw, "    Min Request Turnaround Time: 0x%8.8"   PRIx32, entry->min_request_turnaround_time);

	if ((gas->address_space_id != FWTS_GAS_ADDR_SPACE_ID_SYSTEM_IO) &&
	    (gas->address_space_id != FWTS_GAS_ADDR_SPACE_ID_SYSTEM_MEMORY)) {
		*passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"PCCTSubspaceInvalidAddrSpaceID",
			"PCCT Subspace Type 0 has space ID = 0x%2.2" PRIx8
			" which is not System I/O or Memory",
			gas->address_space_id);
	}
}
示例#19
0
文件: spcr.c 项目: ColinIanKing/fwts
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;
}
示例#20
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;
}
示例#21
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);
	}
示例#22
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;
}
示例#23
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;
}
示例#24
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;
}
示例#25
0
文件: asf.c 项目: 9elements/fwts
/*
 *  4.1.2.4 ASF_RCTL
 */
static void asf_check_rctl(
	fwts_framework *fw,
	ssize_t record_length,
	ssize_t length,
	uint8_t *data,
	bool *passed,
	bool *abort)
{
	fwts_acpi_table_asf_rctl *rctl = (fwts_acpi_table_asf_rctl *)data;
	uint8_t i;
	ssize_t total_length;

	if (length < (ssize_t)sizeof(fwts_acpi_table_asf_rctl)) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"ASF!RctlRecordTooShort",
			"ASF! ASF_RCTL Record too short, "
			"expecting %zu bytes, instead got %zu bytes",
			sizeof(fwts_acpi_table_asf_rctl), length);
		*passed = false;
		*abort = true;
		return;
	}
#if ASF_DUMP
	fwts_log_info_verbatim(fw, "ASF! ASF_RCTL Record:");
	fwts_log_info_verbatim(fw, "  Number of Controls:       0x%2.2" PRIx8, rctl->number_of_controls);
	fwts_log_info_verbatim(fw, "  Array Element Length:     0x%2.2" PRIx8, rctl->array_element_length);
	fwts_log_info_verbatim(fw, "  Reserved:                 0x%4.4" PRIx16, rctl->array_element_length);
#endif
	if (rctl->array_element_length != sizeof(fwts_acpi_table_asf_rctl_element)) {
		*passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"ASF!RctlArrayElementLengthInvalid",
			"ASF! ASF_RCTL Array Element Length is 0x%" PRIx8
			" and must be instead 0x%" PRIx8,
			rctl->array_element_length,
			(uint8_t)sizeof(fwts_acpi_table_asf_rctl_element));
	}

	total_length = sizeof(fwts_acpi_table_asf_rctl) +
		(rctl->number_of_controls * sizeof(fwts_acpi_table_asf_rctl_element));
	if (total_length > record_length) {
		*passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"ASF!RctlArrayElementLengthInvalid",
			"ASF! ASF_RCTL Array Element Length makes the "
			"total ASF_RCTL record size to be %zu bytes, however the "
			"table is only %zu bytes long",
			total_length, record_length);
		*passed = false;
		*abort = true;
		return;
	}

	data += sizeof(fwts_acpi_table_asf_rctl);
	for (i = 0; i < rctl->number_of_controls; i++) {
		fwts_acpi_table_asf_rctl_element *element =
			(fwts_acpi_table_asf_rctl_element *)data;
#if ASF_DUMP
		fwts_log_info_verbatim(fw, "ASF! ASF_RCTL Element %" PRIu8 ":", i);
		fwts_log_info_verbatim(fw, "  Control Function:         0x%2.2" PRIx8, element->control_function);
		fwts_log_info_verbatim(fw, "  Control Device Address:   0x%2.2" PRIx8, element->control_device_addr);
		fwts_log_info_verbatim(fw, "  Control Command:          0x%2.2" PRIx8, element->control_command);
		fwts_log_info_verbatim(fw, "  Control Value:            0x%2.2" PRIx8, element->control_value);
#endif

		if (element->control_function > 0x03) {
			*passed = false;
			fwts_failed(fw, LOG_LEVEL_HIGH,
				"ASF!RctlCtrlFuncInvalid",
				"ASF! ASF_RCTL Control Function is 0x%" PRIx8
				" and must be in the range 0x00..0x03",
				element->control_function);
		}
		data += sizeof(fwts_acpi_table_asf_rctl_element);
	}
	if (*passed)
		fwts_passed(fw, "No issues found in ASF! ASF_RCTL record.");
}
示例#26
0
文件: asf.c 项目: 9elements/fwts
/*
 *  4.1.2.2 ASF_ALRT
 */
static void asf_check_alrt(
	fwts_framework *fw,
	ssize_t record_length,
	ssize_t length,
	uint8_t *data,
	bool *passed,
	bool *abort)
{
	fwts_acpi_table_asf_alrt *alrt = (fwts_acpi_table_asf_alrt *)data;
	uint8_t i;
	ssize_t total_length;

	if (length < (ssize_t)sizeof(fwts_acpi_table_asf_alrt)) {
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"ASF!AlrtRecordTooShort",
			"ASF! ASF_ALRT Record too short, "
			"expecting %zu bytes, instead got %zu bytes",
			sizeof(fwts_acpi_table_asf_alrt), length);
		*passed = false;
		*abort = true;
		return;
	}

#if ASF_DUMP
	fwts_log_info_verbatim(fw, "ASF! ASF_ALRT Record:");
	fwts_log_info_verbatim(fw, "  Assertion Event Mask:     0x%2.2" PRIx8, alrt->assertion_mask);
	fwts_log_info_verbatim(fw, "  De-Assertion Event Mask:  0x%2.2" PRIx8, alrt->deassertion_mask);
	fwts_log_info_verbatim(fw, "  Number of Alerts:         0x%2.2" PRIx8, alrt->number_of_alerts);
	fwts_log_info_verbatim(fw, "  Array Element Length:     0x%2.2" PRIx8, alrt->array_length);
#endif

	if ((alrt->number_of_alerts < 1) ||
	    (alrt->number_of_alerts > 8)) {
		*passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"ASF!AlrtNumOfAlertsInvalid",
			"ASF! ASF_ALRT Number of Alerts field is 0x%" PRIx8
			" and must be in the range 0x01..0x08",
			alrt->number_of_alerts);
		/* Don't trust the ALRT data, so abort */
		return;
	}
	if (alrt->array_length != sizeof(fwts_acpi_table_asf_alrt_element)) {
		*passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"ASF!AlrtArrayElementLengthInvalid",
			"ASF! ASF_ALRT Array Element Length is 0x%" PRIx8
			" and must be instead 0x%" PRIx8,
			alrt->array_length,
			(uint8_t)sizeof(fwts_acpi_table_asf_alrt_element));
	}

	total_length = sizeof(fwts_acpi_table_asf_alrt) +
		(alrt->number_of_alerts * sizeof(fwts_acpi_table_asf_alrt_element));
	if (total_length > record_length) {
		*passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"ASF!AlrtArrayElementLengthInvalid",
			"ASF! ASF_ALRT Array Element Length makes the "
			"total ASF_ALRT record size to be %zu bytes, however the "
			"table is only %zu bytes long",
			total_length, record_length);
		*passed = false;
		*abort = true;
		return;
	}

	data += sizeof(fwts_acpi_table_asf_alrt);
	for (i = 0; i < alrt->number_of_alerts; i++) {
		fwts_acpi_table_asf_alrt_element *element =
			(fwts_acpi_table_asf_alrt_element *)data;

#if ASF_DUMP
		fwts_log_info_verbatim(fw, "ASF! ASF_ALRT Element %" PRIu8 ":", i);
		fwts_log_info_verbatim(fw, "  Device Address:           0x%2.2" PRIx8, element->device_addr);
		fwts_log_info_verbatim(fw, "  Alert Command:            0x%2.2" PRIx8, element->command);
		fwts_log_info_verbatim(fw, "  Alert Data Mask:          0x%2.2" PRIx8, element->data_mask);
		fwts_log_info_verbatim(fw, "  Alert Compare Value:      0x%2.2" PRIx8, element->compare_value);
		fwts_log_info_verbatim(fw, "  Alert Event Sensor Type:  0x%2.2" PRIx8, element->sensor_type);
		fwts_log_info_verbatim(fw, "  Alert Event Type:         0x%2.2" PRIx8, element->event_type);
		fwts_log_info_verbatim(fw, "  Alert Event Offset:       0x%2.2" PRIx8, element->event_offset);
		fwts_log_info_verbatim(fw, "  Alert Source Type:        0x%2.2" PRIx8, element->event_source_type);
		fwts_log_info_verbatim(fw, "  Alert Event Severity:     0x%2.2" PRIx8, element->event_severity);
		fwts_log_info_verbatim(fw, "  Alert Sensor Number:      0x%2.2" PRIx8, element->sensor_number);
		fwts_log_info_verbatim(fw, "  Alert Entity:             0x%2.2" PRIx8, element->entity);
		fwts_log_info_verbatim(fw, "  Alert Entity Instance:    0x%2.2" PRIx8, element->entity_instance);
#endif

		if (element->event_offset & 0x80) {
			*passed = false;
			fwts_failed(fw, LOG_LEVEL_HIGH,
				"ASF!AlrtEventOffsetBit7Set",
				"ASF! ASF_ALRT Array Element %" PRIu8 " Event Offset Bit 7 is 1, "
				" and should be 0", i);
		}
		data += sizeof(fwts_acpi_table_asf_alrt_element);
	}
	if (*passed)
		fwts_passed(fw, "No issues found in ASF! ASF_ALRT record.");
}
示例#27
0
文件: pcct.c 项目: ColinIanKing/fwts
static void extended_pcc_test(fwts_framework *fw, fwts_acpi_table_pcct_subspace_type_3_4 *entry, bool *passed)
{
	fwts_log_info_verbatim(fw, "    Platform Interrupt:          0x%8.8"   PRIx32, entry->platform_interrupt);
	fwts_log_info_verbatim(fw, "    Platform Interrupt Flags:    0x%2.2"   PRIx8, entry->platform_interrupt_flags);
	fwts_log_info_verbatim(fw, "    Reserved:                    0x%2.2"   PRIx8, entry->reserved1);
	fwts_log_info_verbatim(fw, "    Base Address:                0x%16.16" PRIx64, entry->base_address);
	memory_length(fw, entry->header.type, entry->length, 16, passed);
	fwts_log_info_verbatim(fw, "    Doorbell Register:");
	gas_messages(fw, entry->header.type, &entry->doorbell_register, passed);
	fwts_log_info_verbatim(fw, "    Doorbell Preserve:           0x%16.16" PRIx64, entry->doorbell_preserve);
	fwts_log_info_verbatim(fw, "    Doorbell Write:              0x%16.16" PRIx64, entry->doorbell_write);
	fwts_log_info_verbatim(fw, "    Nominal Latency:             0x%8.8"   PRIx32, entry->nominal_latency);
	fwts_log_info_verbatim(fw, "    Max Periodic Access Rate:    0x%8.8"   PRIx32, entry->max_periodic_access_rate);
	fwts_log_info_verbatim(fw, "    Min Request Turnaround Time: 0x%8.8"   PRIx32, entry->min_request_turnaround_time);
	fwts_log_info_verbatim(fw, "    Command Complete Check Register:");
	gas_messages(fw, entry->header.type, &entry->platform_ack_register, passed);
	fwts_log_info_verbatim(fw, "    Doorbell Ack Preserve:       0x%16.16" PRIx64, entry->platform_ack_preserve);
	fwts_log_info_verbatim(fw, "    Doorbell Ack Write:          0x%16.16" PRIx64, entry->platform_ack_write);
	fwts_log_info_verbatim(fw, "    Reserved:                    0x%16.16" PRIx64, entry->reserved2);
	fwts_log_info_verbatim(fw, "    Cmd Complete Check Register:");
	gas_messages(fw, entry->header.type, &entry->cmd_complete_register, passed);
	fwts_log_info_verbatim(fw, "    Cmd Complete Check Mask:     0x%16.16" PRIx64, entry->cmd_complete_mask);
	fwts_log_info_verbatim(fw, "    Cmd Complete Update Register:");
	gas_messages(fw, entry->header.type, &entry->cmd_update_register, passed);
	fwts_log_info_verbatim(fw, "    Cmd Complete Update Mask:    0x%16.16" PRIx64, entry->cmd_update_preserve_mask);
	fwts_log_info_verbatim(fw, "    Cmd Complete Set Mask:       0x%16.16" PRIx64, entry->cmd_update_preserve_mask);
	fwts_log_info_verbatim(fw, "    Error Status Register:");
	gas_messages(fw, entry->header.type, &entry->error_status_register, passed);
	fwts_log_info_verbatim(fw, "    Error Status Mask:           0x%16.16" PRIx64, entry->error_status_mask);

	fwts_acpi_reserved_bits_check(fw, "PCCT", "Platform Interrupt Flags", entry->platform_interrupt_flags, sizeof(uint8_t), 2, 7, passed);
}
示例#28
0
文件: uefi.c 项目: ColinIanKing/fwts
/*
 *  UEFI ACPI DATA Table
 *  See UEFI specification Appendix O.
 */
static int uefi_test1(fwts_framework *fw)
{
	fwts_acpi_table_uefi *uefi = (fwts_acpi_table_uefi *)table->data;
	bool passed = true;
	uint32_t i;
	char guid[37];

	/*
	 * GUID for SMM Communication ACPI Table
	 * {0xc68ed8e2, 0x9dc6, 0x4cbd, 0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32}
	 */
	static const uint8_t guid_smm[16] = { 0xe2, 0xd8, 0x8e, 0xc6, 0xc6, 0x9d, 0xbd, 0x4c,
						0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32 };

	/* Enough length for the uefi table? */
	if (!fwts_acpi_table_length_check(fw, "UEFI", table->length, sizeof(fwts_acpi_table_uefi))) {
		passed = false;
		goto done;
	}

	fwts_guid_buf_to_str(uefi->uuid, guid, sizeof(guid));

	fwts_log_info_verbatim(fw, "UEFI ACPI Data Table:");
	fwts_log_info_verbatim(fw, "  Identifier: %s", guid);
	fwts_log_info_verbatim(fw, "  DataOffset: 0x%4.4" PRIx16, uefi->dataoffset);

	/* Sanity check the dataoffset */
	if (uefi->dataoffset > table->length) {
		passed = false;
		fwts_failed(fw, LOG_LEVEL_HIGH,
			"UEFIDataOffset",
			"Invalid UEFI DataOffset, exceed the whole table length "
			"%zu bytes, instead got %" PRIu16 " offset bytes"
			, table->length, uefi->dataoffset);
	}

	/* check the GUID for SMM Communication ACPI table */
	if (memcmp(uefi->uuid, guid_smm, 16) == 0) {
		fwts_acpi_table_uefi_smmcomm *uefi_smmcomm = (fwts_acpi_table_uefi_smmcomm *)table->data;

		/* chekc the dataoffset for SMM Comm table */
		if (uefi_smmcomm->boot.dataoffset != 54) {
			passed = false;
			fwts_failed(fw, LOG_LEVEL_HIGH,
				"UEFIDataOffset",
				"Invalid UEFI DataOffset for SMM Communication table, "
				"DataOffset should be 54, instead got %" PRIu16 " offset bytes"
				, uefi_smmcomm->boot.dataoffset);
		}

		fwts_log_info_verbatim(fw, "  SW SMI Number: 0x%8.8" PRIx32, uefi_smmcomm->sw_smi_number);
		fwts_log_info_verbatim(fw, "  Buffer Ptr Address: 0x%16.16" PRIx64, uefi_smmcomm->buf_ptr_addr);
	} else {
		/* dump the remaining data */
		fwts_log_info_verbatim(fw, "  Data:");
		for (i = 0; i < (table->length - uefi->dataoffset) ; i += 16) {
			int left = table->length - uefi->dataoffset -i;
			char buffer[128];
			fwts_dump_raw_data(buffer,sizeof(buffer), uefi->data + i, i, left > 16 ? 16 : left);
			fwts_log_info_verbatim(fw, "%s", buffer);
		}
	}

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

	return FWTS_OK;
}
示例#29
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;
}
示例#30
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;
}