[PATCH 1/2] acpi: nfit: add ACPI NFIT test
ivanhu
ivan.hu at canonical.com
Wed Aug 3 03:57:27 UTC 2016
On 2016年07月27日 18:48, Alex Hung wrote:
> Signed-off-by: Alex Hung <alex.hung at canonical.com>
> ---
> src/Makefile.am | 1 +
> src/acpi/nfit/nfit.c | 327 ++++++++++++++++++++++++++++++++++++++++++++
> src/lib/include/fwts_acpi.h | 110 +++++++++++++++
> 3 files changed, 438 insertions(+)
> create mode 100644 src/acpi/nfit/nfit.c
>
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 11c65b2..bc23e8d 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -73,6 +73,7 @@ fwts_SOURCES = main.c \
> acpi/msct/msct.c \
> acpi/msdm/msdm.c \
> acpi/method/method.c \
> + acpi/nfit/nfit.c \
> acpi/osilinux/osilinux.c \
> acpi/pcc/pcc.c \
> acpi/pcct/pcct.c \
> diff --git a/src/acpi/nfit/nfit.c b/src/acpi/nfit/nfit.c
> new file mode 100644
> index 0000000..3738a50
> --- /dev/null
> +++ b/src/acpi/nfit/nfit.c
> @@ -0,0 +1,327 @@
> +/*
> + * Copyright (C) 2016 Canonical
> + *
> + * Portions of this code original from the Linux-ready Firmware Developer Kit
minor: just wondering which part is from Linux-ready Firmware Developer Kit?
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> + *
> + */
> +#include "fwts.h"
> +
> +#if defined(FWTS_HAS_ACPI)
> +
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <inttypes.h>
> +#include <string.h>
> +#include <ctype.h>
> +
> +static fwts_acpi_table_info *table;
> +
> +static int nfit_init(fwts_framework *fw)
> +{
> + if (fwts_acpi_find_table(fw, "NFIT", 0, &table) != FWTS_OK) {
> + fwts_log_error(fw, "Cannot read ACPI tables.");
> + return FWTS_ERROR;
> + }
> + if (table == NULL || (table && table->length == 0)) {
> + fwts_log_error(fw, "ACPI NFIT table does not exist, skipping test");
> + return FWTS_SKIP;
> + }
> + return FWTS_OK;
> +}
> +
> +/*
> + * NFIT NVDIMM Firmware Interface Table
> + */
> +static int nfit_test1(fwts_framework *fw)
> +{
> + fwts_acpi_table_nfit *nfit = (fwts_acpi_table_nfit*) table->data;
> + fwts_acpi_table_nfit_struct_header *entry;
> + size_t offset;
> + bool passed = true;
> +
> + fwts_log_info_verbatim(fw, "NFIT NVDIMM Firmware Interface Table:");
> + fwts_log_info_verbatim(fw, " Reserved: 0x%8.8" PRIx32, nfit->reserved);
> + fwts_log_nl(fw);
> +
> + if (nfit->reserved != 0) {
> + passed = false;
> + fwts_failed(fw, LOG_LEVEL_LOW,
> + "NFITReservedNonZero",
> + "NFIT reserved field must be zero, got "
> + "0x%8.8" PRIx32 " instead", nfit->reserved);
> + }
> +
> + offset = sizeof(fwts_acpi_table_nfit);
> + entry = (fwts_acpi_table_nfit_struct_header *) (table->data + offset);
> +
> + while (offset < table->length) {
> + uint64_t reserved_passed = 0;
> +
> + fwts_log_info_verbatim(fw, " NFIT Subtable:");
> + fwts_log_info_verbatim(fw, " Type: 0x%4.4" PRIx16, entry->type);
> + fwts_log_info_verbatim(fw, " Length: 0x%4.4" PRIx16, entry->length);
> +
> + if (entry->type == FWTS_ACPI_NFIT_TYPE_SYSTEM_ADDRESS) {
> + fwts_acpi_table_nfit_system_memory *nfit_struct = (fwts_acpi_table_nfit_system_memory *) entry;
> + char guid_str[37];
> +
> + fwts_guid_buf_to_str(nfit_struct->range_guid, guid_str, sizeof(guid_str));
> +
> + fwts_log_info_verbatim(fw, " SPA Range Structure Index: 0x%4.4" PRIx16, nfit_struct->range_index);
> + fwts_log_info_verbatim(fw, " Flags: 0x%4.4" PRIx16, nfit_struct->flags);
> + fwts_log_info_verbatim(fw, " Reserved: 0x%8.8" PRIx32, nfit_struct->reserved);
> + fwts_log_info_verbatim(fw, " Proximity Domain: 0x%8.8" PRIx32, nfit_struct->proximity_domain);
> + fwts_log_info_verbatim(fw, " Address Range Type GUID: %s", guid_str);
> + fwts_log_info_verbatim(fw, " System Physical Address Range Base: 0x%16.16" PRIx64, nfit_struct->address);
> + fwts_log_info_verbatim(fw, " System Physical Address Range Length: 0x%16.16" PRIx64, nfit_struct->length);
> + fwts_log_info_verbatim(fw, " Address Range Memory Mapping Attribute: 0x%16.16" PRIx64, nfit_struct->memory_mapping);
> +
> + if (nfit_struct->range_index == 0) {
> + passed = false;
> + fwts_failed(fw, LOG_LEVEL_HIGH,
> + "NFITBadRangeIndexZero",
> + "NFIT SPA Range Structure Index must not be zero");
> + }
> +
> + if (nfit_struct->flags & ~0x03) {
> + passed = false;
> + fwts_failed(fw, LOG_LEVEL_HIGH,
> + "NFITBadFlags",
> + "NFIT Flags's Bits[15..2] must be zero, got "
> + "0x%8.8" PRIx32 " instead", nfit_struct->flags);
> + }
> +
> + if (nfit_struct->reserved != 0)
> + reserved_passed = nfit_struct->reserved;
> +
> + /* TODO check Proximity Domain with SRAT table */
> +
> + if (nfit_struct->memory_mapping & ~0x01F01F) {
> + passed = false;
> + fwts_failed(fw, LOG_LEVEL_HIGH,
> + "NFITBadMemoryMappingAttribute",
> + "NFIT Memory Mapping Attribute must meet UEFI Spec, got "
> + "0x%16.16" PRIx64 " instead", nfit_struct->memory_mapping);
> + }
> +
> + } else if (entry->type == FWTS_ACPI_NFIT_TYPE_MEMORY_MAP) {
> + fwts_acpi_table_nfit_memory_map *nfit_struct = (fwts_acpi_table_nfit_memory_map *) entry;
> +
> + fwts_log_info_verbatim(fw, " NFIT Device Handle: 0x%8.8" PRIx32, nfit_struct->device_handle);
> + fwts_log_info_verbatim(fw, " NVDIMM Physical ID: 0x%4.4" PRIx16, nfit_struct->physical_id);
> + fwts_log_info_verbatim(fw, " NVDIMM Region ID: 0x%4.4" PRIx16, nfit_struct->region_id);
> + fwts_log_info_verbatim(fw, " SPA Range Structure Index: 0x%4.4" PRIx16, nfit_struct->range_index);
> + fwts_log_info_verbatim(fw, " NVDIMM Control Region Structure Index: 0x%4.4" PRIx16, nfit_struct->region_index);
> + fwts_log_info_verbatim(fw, " NVDIMM Region Size: 0x%16.16" PRIx64, nfit_struct->region_size);
> + fwts_log_info_verbatim(fw, " Region Offset: 0x%16.16" PRIx64, nfit_struct->region_offset);
> + fwts_log_info_verbatim(fw, " NVDIMM Physical Address Region Base: 0x%16.16" PRIx64, nfit_struct->address);
> + fwts_log_info_verbatim(fw, " Interleave Structure Index: 0x%4.4" PRIx16, nfit_struct->interleave_index);
> + fwts_log_info_verbatim(fw, " Interleave Ways: 0x%4.4" PRIx16, nfit_struct->interleave_ways);
> + fwts_log_info_verbatim(fw, " NVDIMM State Flags: 0x%4.4" PRIx16, nfit_struct->flags);
> + fwts_log_info_verbatim(fw, " Reserved: 0x%4.4" PRIx16, nfit_struct->reserved);
> +
> + if (nfit_struct->flags & ~0x7F) {
> + passed = false;
> + fwts_failed(fw, LOG_LEVEL_HIGH,
> + "NFITBadFlags",
> + "NFIT Flags's Bits[15..7] must be zero, got "
> + "0x%8.8" PRIx32 " instead", nfit_struct->flags);
> + }
> +
> + if (nfit_struct->reserved != 0)
> + reserved_passed = nfit_struct->reserved;
> +
> + } else if (entry->type == FWTS_ACPI_NFIT_TYPE_INTERLEAVE) {
> + fwts_acpi_table_nfit_interleave *nfit_struct = (fwts_acpi_table_nfit_interleave *) entry;
> + uint32_t i;
> +
> + fwts_log_info_verbatim(fw, " Interleave Structure Index: 0x%4.4" PRIx16, nfit_struct->interleave_index);
> + fwts_log_info_verbatim(fw, " Reserved: 0x%4.4" PRIx16, nfit_struct->reserved);
> + fwts_log_info_verbatim(fw, " Number of Lines Described: 0x%8.8" PRIx32, nfit_struct->line_count);
> + fwts_log_info_verbatim(fw, " Line Size: 0x%8.8" PRIx32, nfit_struct->line_size);
> +
> + for (i = 0; i < nfit_struct->line_count; i++) {
> + fwts_log_info_verbatim(fw, " Line Offset: 0x%8.8" PRIx32, nfit_struct->line_offset[i]);
> +
> + if (nfit_struct->line_offset[i] % nfit_struct->line_size)
> + fwts_failed(fw, LOG_LEVEL_HIGH,
> + "NFITBadLineOffsetAlignment",
> + "NFIT Line Offset must be aligned nfit_struct->line_size, got "
> + "0x%8.8" PRIx32 " instead", nfit_struct->line_offset[i]);
> + }
> +
> + if (nfit_struct->reserved != 0)
> + reserved_passed = nfit_struct->reserved;
> +
> + if (nfit_struct->line_count == 0) {
> + passed = false;
> + fwts_failed(fw, LOG_LEVEL_HIGH,
> + "NFITBadLineCount",
> + "NFIT Number of Lines must not be zero");
> + }
> +
> + } else if (entry->type == FWTS_ACPI_NFIT_TYPE_SMBIOS) {
> + fwts_acpi_table_nfit_smbios *nfit_struct = (fwts_acpi_table_nfit_smbios *) entry;
> +
> + fwts_log_info_verbatim(fw, " Reserved: 0x%8.8" PRIx32, nfit_struct->reserved);
> +
> + } else if (entry->type == FWTS_ACPI_NFIT_TYPE_CONTROL_REGION) {
> + fwts_acpi_table_nfit_control_range *nfit_struct = (fwts_acpi_table_nfit_control_range *) entry;
> + uint64_t reserved1;
> +
> + reserved1 = (uint64_t) nfit_struct->reserved1[0] + ((uint64_t) nfit_struct->reserved1[1] << 8) +
> + ((uint64_t) nfit_struct->reserved1[2] << 16) + ((uint64_t) nfit_struct->reserved1[3] << 24) +
> + ((uint64_t) nfit_struct->reserved1[4] << 32) + ((uint64_t) nfit_struct->reserved1[5] << 40);
> +
> + if (reserved1 != 0)
> + reserved_passed = reserved1;
> +
> + fwts_log_info_verbatim(fw, " NVDIMM Control Region Structure Index: 0x%4.4" PRIx16, nfit_struct->region_index);
> + fwts_log_info_verbatim(fw, " Vendor ID: 0x%4.4" PRIx16, nfit_struct->vendor_id);
> + fwts_log_info_verbatim(fw, " Device ID: 0x%4.4" PRIx16, nfit_struct->device_id);
> + fwts_log_info_verbatim(fw, " Revision ID: 0x%4.4" PRIx16, nfit_struct->revision_id);
> + fwts_log_info_verbatim(fw, " Subsystem Vendor ID: 0x%4.4" PRIx16, nfit_struct->subsystem_vendor_id);
> + fwts_log_info_verbatim(fw, " Subsystem Device ID: 0x%4.4" PRIx16, nfit_struct->subsystem_device_id);
> + fwts_log_info_verbatim(fw, " Subsystem Revision ID: 0x%4.4" PRIx16, nfit_struct->subsystem_revision_id);
> + fwts_log_info_verbatim(fw, " Valid Fields: 0x%2.2" PRIx8, nfit_struct->valid_fields);
> + fwts_log_info_verbatim(fw, " Manufacturing Location: 0x%2.2" PRIx8, nfit_struct->manufacturing_location);
> + fwts_log_info_verbatim(fw, " Manufacturing Date: 0x%4.4" PRIx16, nfit_struct->manufacturing_date);
> + fwts_log_info_verbatim(fw, " Reserved: 0x%4.4" PRIx16, nfit_struct->reserved);
> + fwts_log_info_verbatim(fw, " Serial Number: 0x%8.8" PRIx32, nfit_struct->serial_number);
> + fwts_log_info_verbatim(fw, " Region Format Interface Code: 0x%4.4" PRIx16, nfit_struct->interface_code);
> + fwts_log_info_verbatim(fw, " Number of Block Control Windows: 0x%4.4" PRIx16, nfit_struct->windows_num);
> + fwts_log_info_verbatim(fw, " Size of Block Control Window: 0x%16.16" PRIx64, nfit_struct->window_size);
> + fwts_log_info_verbatim(fw, " Command Register Offset: 0x%16.16" PRIx64, nfit_struct->command_offset);
> + fwts_log_info_verbatim(fw, " Size of Command Register: 0x%16.16" PRIx64, nfit_struct->command_size);
> + fwts_log_info_verbatim(fw, " Status RegisterOffset: 0x%16.16" PRIx64, nfit_struct->status_offset);
> + fwts_log_info_verbatim(fw, " Size of Status Register: 0x%16.16" PRIx64, nfit_struct->status_size);
> + fwts_log_info_verbatim(fw, " NVDIMM Control Region Flag: 0x%4.4" PRIx16, nfit_struct->flags);
> + fwts_log_info_verbatim(fw, " Reserved: 0x%16.16" PRIx64, reserved1);
> +
> + if (nfit_struct->revision_id & 0xFF00) {
> + passed = false;
> + fwts_failed(fw, LOG_LEVEL_HIGH,
> + "NFITBadRevisionId",
> + "NFIT Revision ID's BYTE 1 must be zero, got "
> + "0x%4.4" PRIx16 " instead", nfit_struct->revision_id);
> + }
> +
> + if (nfit_struct->subsystem_revision_id & 0xFF00) {
> + passed = false;
> + fwts_failed(fw, LOG_LEVEL_HIGH,
> + "NFITBadRevisionId",
> + "NFIT Subsystem Revision ID's BYTE 1 must be zero, got "
> + "0x%4.4" PRIx16 " instead", nfit_struct->subsystem_revision_id);
> + }
> +
> + if (nfit_struct->reserved != 0)
> + reserved_passed = nfit_struct->reserved;
> +
> + if (nfit_struct->valid_fields & ~0x01) {
> + passed = false;
> + fwts_failed(fw, LOG_LEVEL_HIGH,
> + "NFITBadValidField",
> + "NFIT Valid Field's Bits[7..1] must be zero, got "
> + "0x%2.2" PRIx8 " instead", nfit_struct->valid_fields);
> + }
> +
> + if (nfit_struct->flags & ~0x01) {
> + passed = false;
> + fwts_failed(fw, LOG_LEVEL_HIGH,
> + "NFITBadFlags",
> + "NFIT Flags's Bits[15..1] must be zero, got "
> + "0x%4.4" PRIx16 " instead", nfit_struct->flags);
> + }
> +
> + } else if (entry->type == FWTS_ACPI_NFIT_TYPE_DATA_REGION) {
> + fwts_acpi_table_nfit_data_range *nfit_struct = (fwts_acpi_table_nfit_data_range *) entry;
> +
> + fwts_log_info_verbatim(fw, " NVDIMM Control Region Structure Index: 0x%4.4" PRIx16, nfit_struct->region_index);
> + fwts_log_info_verbatim(fw, " Number of Block Data Windows: 0x%4.4" PRIx16, nfit_struct->window_num);
> + fwts_log_info_verbatim(fw, " Block Data Window Start Offset: 0x%16.16" PRIx64, nfit_struct->window_offset);
> + fwts_log_info_verbatim(fw, " Size of Block Data Window: 0x%16.16" PRIx64, nfit_struct->window_size);
> + fwts_log_info_verbatim(fw, " NBlock Accessible Memory Capacity: 0x%16.16" PRIx64, nfit_struct->capacity);
> + fwts_log_info_verbatim(fw, " Beginning address of First Block: 0x%16.16" PRIx64, nfit_struct->start_address);
> +
> + if (nfit_struct->region_index == 0) {
> + passed = false;
> + fwts_failed(fw, LOG_LEVEL_HIGH,
> + "NFITBadRegionIndex",
> + "NFIT NVDIMM Control Region Structure Index must not be zero");
> + }
> +
> + } else if (entry->type == FWTS_ACPI_NFIT_TYPE_FLUSH_ADDRESS) {
> + fwts_acpi_table_nfit_flush_addr *nfit_struct = (fwts_acpi_table_nfit_flush_addr *) entry;
> + uint64_t reserved;
> + uint16_t i;
> +
> + reserved = (uint64_t) nfit_struct->reserved[0] + ((uint64_t) nfit_struct->reserved[1] << 8) +
> + ((uint64_t) nfit_struct->reserved[2] << 16) + ((uint64_t) nfit_struct->reserved[3] << 24) +
> + ((uint64_t) nfit_struct->reserved[4] << 32) + ((uint64_t) nfit_struct->reserved[5] << 40);
> +
> + fwts_log_info_verbatim(fw, " NFIT Device Handle: 0x%8.8" PRIx32, nfit_struct->device_handle);
> + fwts_log_info_verbatim(fw, " Number of Flush Hint Addresses: 0x%4.4" PRIx16, nfit_struct->hint_count);
> + fwts_log_info_verbatim(fw, " Reserved: 0x%16.16" PRIx64, reserved);
> + for (i = 0; i < nfit_struct->hint_count; i++)
> + fwts_log_info_verbatim(fw, " Flush Hint Address: 0x%16.16" PRIx64, nfit_struct->hint_address[i]);
> +
> + if (reserved != 0)
> + reserved_passed = reserved;
> +
> + } else {
> + passed = false;
> + fwts_failed(fw, LOG_LEVEL_HIGH,
> + "NFITBadSubType",
> + "NFIT Structure supports type 0..6, got "
> + "0x%4.4" PRIx16 " instead", entry->type);
> + }
> +
> + if (reserved_passed != 0) {
> + passed = false;
> + fwts_failed(fw, LOG_LEVEL_LOW,
> + "NFITReservedNonZero",
> + "NFIT reserved field must be zero, got "
> + "0x%16.16" PRIx64 " instead", reserved_passed);
> + }
> +
> + fwts_log_nl(fw);
> + offset += entry->length;
> + entry = (fwts_acpi_table_nfit_struct_header *) (table->data + offset);
> + }
> +
> +
> + if (passed)
> + fwts_passed(fw, "No issues found in NFIT table.");
> +
> + return FWTS_OK;
> +}
> +
> +static fwts_framework_minor_test nfit_tests[] = {
> + { nfit_test1, "NFIT NVDIMM Firmware Interface Table test." },
> + { NULL, NULL }
> +};
> +
> +static fwts_framework_ops nfit_ops = {
> + .description = "NFIT NVDIMM Firmware Interface Table test.",
> + .init = nfit_init,
> + .minor_tests = nfit_tests
> +};
> +
> +FWTS_REGISTER("nfit", &nfit_ops, FWTS_TEST_ANYTIME, FWTS_FLAG_BATCH | FWTS_FLAG_TEST_ACPI)
> +
> +#endif
> diff --git a/src/lib/include/fwts_acpi.h b/src/lib/include/fwts_acpi.h
> index b675f4f..fd5a6b0 100644
> --- a/src/lib/include/fwts_acpi.h
> +++ b/src/lib/include/fwts_acpi.h
> @@ -991,6 +991,116 @@ typedef struct {
> } __attribute__ ((packed)) fwts_acpi_table_rasf;
>
> /*
> + * ACPI NFIT (NVDIMM Firmware Interface), 5.2.25
> + */
> +typedef struct {
> + fwts_acpi_table_header header;
> + uint32_t reserved;
> +} __attribute__ ((packed)) fwts_acpi_table_nfit;
> +
> +typedef struct {
> + uint16_t type;
> + uint16_t length;
> +} __attribute__ ((packed)) fwts_acpi_table_nfit_struct_header;
> +
> +typedef enum {
> + FWTS_ACPI_NFIT_TYPE_SYSTEM_ADDRESS = 0,
> + FWTS_ACPI_NFIT_TYPE_MEMORY_MAP = 1,
> + FWTS_ACPI_NFIT_TYPE_INTERLEAVE = 2,
> + FWTS_ACPI_NFIT_TYPE_SMBIOS = 3,
> + FWTS_ACPI_NFIT_TYPE_CONTROL_REGION = 4,
> + FWTS_ACPI_NFIT_TYPE_DATA_REGION = 5,
> + FWTS_ACPI_NFIT_TYPE_FLUSH_ADDRESS = 6,
> + FWTS_ACPI_NFIT_TYPE_RESERVED = 7 /* >= 7 are reserved */
> +} fwts_acpi_nfit_type;
> +
> +typedef struct {
> + fwts_acpi_table_nfit_struct_header header;
> + uint16_t range_index;
> + uint16_t flags;
> + uint32_t reserved;
> + uint32_t proximity_domain;
> + uint8_t range_guid[16];
> + uint64_t address;
> + uint64_t length;
> + uint64_t memory_mapping;
> +} __attribute__ ((packed)) fwts_acpi_table_nfit_system_memory;
> +
> +typedef struct {
> + fwts_acpi_table_nfit_struct_header header;
> + uint32_t device_handle;
> + uint16_t physical_id;
> + uint16_t region_id;
> + uint16_t range_index;
> + uint16_t region_index;
> + uint64_t region_size;
> + uint64_t region_offset;
> + uint64_t address;
> + uint16_t interleave_index;
> + uint16_t interleave_ways;
> + uint16_t flags;
> + uint16_t reserved;
> +} __attribute__ ((packed)) fwts_acpi_table_nfit_memory_map;
> +
> +typedef struct {
> + fwts_acpi_table_nfit_struct_header header;
> + uint16_t interleave_index;
> + uint16_t reserved;
> + uint32_t line_count;
> + uint32_t line_size;
> + uint32_t line_offset[];
> +} __attribute__ ((packed)) fwts_acpi_table_nfit_interleave;
> +
> +typedef struct {
> + fwts_acpi_table_nfit_struct_header header;
> + uint32_t reserved;
> + uint8_t smbios[];
> +} __attribute__ ((packed)) fwts_acpi_table_nfit_smbios;
> +
> +typedef struct {
> + fwts_acpi_table_nfit_struct_header header;
> + uint16_t region_index;
> + uint16_t vendor_id;
> + uint16_t device_id;
> + uint16_t revision_id;
> + uint16_t subsystem_vendor_id;
> + uint16_t subsystem_device_id;
> + uint16_t subsystem_revision_id;
> + uint8_t valid_fields;
> + uint8_t manufacturing_location;
> + uint16_t manufacturing_date;
> + uint16_t reserved;
> + uint32_t serial_number;
> + uint16_t interface_code;
> + uint16_t windows_num;
> + uint64_t window_size;
> + uint64_t command_offset;
> + uint64_t command_size;
> + uint64_t status_offset;
> + uint64_t status_size;
> + uint16_t flags;
> + uint8_t reserved1[6];
> +} __attribute__ ((packed)) fwts_acpi_table_nfit_control_range;
> +
> +typedef struct {
> + fwts_acpi_table_nfit_struct_header header;
> + uint16_t region_index;
> + uint16_t window_num;
> + uint64_t window_offset;
> + uint64_t window_size;
> + uint64_t capacity;
> + uint64_t start_address;
> +} __attribute__ ((packed)) fwts_acpi_table_nfit_data_range;
> +
> +typedef struct {
> + fwts_acpi_table_nfit_struct_header header;
> + uint32_t device_handle;
> + uint16_t hint_count;
> + uint8_t reserved[6];
> + uint64_t hint_address[];
> +} __attribute__ ((packed)) fwts_acpi_table_nfit_flush_addr;
> +
> +/*
> * ACPI PCCT (Platform Communications Channel Table), 14.1
> */
> typedef struct {
>
More information about the fwts-devel
mailing list