[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v5 06/10] ACPI ERST: build the ACPI ERST table
From: |
Eric DeVolder |
Subject: |
[PATCH v5 06/10] ACPI ERST: build the ACPI ERST table |
Date: |
Wed, 30 Jun 2021 15:07:17 -0400 |
This code is called from the machine code (if ACPI supported)
to generate the ACPI ERST table.
Signed-off-by: Eric DeVolder <eric.devolder@oracle.com>
---
hw/acpi/erst.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 214 insertions(+)
diff --git a/hw/acpi/erst.c b/hw/acpi/erst.c
index 6e9bd2e..1f1dbbc 100644
--- a/hw/acpi/erst.c
+++ b/hw/acpi/erst.c
@@ -555,6 +555,220 @@ static const MemoryRegionOps erst_mem_ops = {
/*******************************************************************/
/*******************************************************************/
+/* ACPI 4.0: 17.4.1.2 Serialization Instruction Entries */
+static void build_serialization_instruction_entry(GArray *table_data,
+ uint8_t serialization_action,
+ uint8_t instruction,
+ uint8_t flags,
+ uint8_t register_bit_width,
+ uint64_t register_address,
+ uint64_t value,
+ uint64_t mask)
+{
+ /* ACPI 4.0: Table 17-18 Serialization Instruction Entry */
+ struct AcpiGenericAddress gas;
+
+ /* Serialization Action */
+ build_append_int_noprefix(table_data, serialization_action, 1);
+ /* Instruction */
+ build_append_int_noprefix(table_data, instruction , 1);
+ /* Flags */
+ build_append_int_noprefix(table_data, flags , 1);
+ /* Reserved */
+ build_append_int_noprefix(table_data, 0 , 1);
+ /* Register Region */
+ gas.space_id = AML_SYSTEM_MEMORY;
+ gas.bit_width = register_bit_width;
+ gas.bit_offset = 0;
+ switch (register_bit_width) {
+ case 8:
+ gas.access_width = 1;
+ break;
+ case 16:
+ gas.access_width = 2;
+ break;
+ case 32:
+ gas.access_width = 3;
+ break;
+ case 64:
+ gas.access_width = 4;
+ break;
+ default:
+ gas.access_width = 0;
+ break;
+ }
+ gas.address = register_address;
+ build_append_gas_from_struct(table_data, &gas);
+ /* Value */
+ build_append_int_noprefix(table_data, value , 8);
+ /* Mask */
+ build_append_int_noprefix(table_data, mask , 8);
+}
+
+/* ACPI 4.0: 17.4.1 Serialization Action Table */
+void build_erst(GArray *table_data, BIOSLinker *linker, Object *erst_dev,
+ const char *oem_id, const char *oem_table_id)
+{
+ ERSTDeviceState *s = ACPIERST(erst_dev);
+ unsigned action;
+ unsigned erst_start = table_data->len;
+
+ s->bar0 = (hwaddr)pci_get_bar_addr(PCI_DEVICE(erst_dev), 0);
+ trace_acpi_erst_pci_bar_0(s->bar0);
+ s->bar1 = (hwaddr)pci_get_bar_addr(PCI_DEVICE(erst_dev), 1);
+ trace_acpi_erst_pci_bar_1(s->bar1);
+
+ acpi_data_push(table_data, sizeof(AcpiTableHeader));
+ /* serialization_header_length */
+ build_append_int_noprefix(table_data, 48, 4);
+ /* reserved */
+ build_append_int_noprefix(table_data, 0, 4);
+ /*
+ * instruction_entry_count - changes to the number of serialization
+ * instructions in the ACTIONs below must be reflected in this
+ * pre-computed value.
+ */
+ build_append_int_noprefix(table_data, 29, 4);
+
+#define MASK8 0x00000000000000FFUL
+#define MASK16 0x000000000000FFFFUL
+#define MASK32 0x00000000FFFFFFFFUL
+#define MASK64 0xFFFFFFFFFFFFFFFFUL
+
+ for (action = 0; action < ACPI_ERST_MAX_ACTIONS; ++action) {
+ switch (action) {
+ case ACPI_ERST_ACTION_BEGIN_WRITE_OPERATION:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ break;
+ case ACPI_ERST_ACTION_BEGIN_READ_OPERATION:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ break;
+ case ACPI_ERST_ACTION_BEGIN_CLEAR_OPERATION:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ break;
+ case ACPI_ERST_ACTION_END_OPERATION:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ break;
+ case ACPI_ERST_ACTION_SET_RECORD_OFFSET:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER , 0, 32,
+ s->bar0 + ERST_CSR_VALUE , 0, MASK32);
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ break;
+ case ACPI_ERST_ACTION_EXECUTE_OPERATION:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_VALUE , ERST_EXECUTE_OPERATION_MAGIC,
MASK8);
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ break;
+ case ACPI_ERST_ACTION_CHECK_BUSY_STATUS:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_READ_REGISTER_VALUE , 0, 32,
+ s->bar0 + ERST_CSR_VALUE, 0x01, MASK8);
+ break;
+ case ACPI_ERST_ACTION_GET_COMMAND_STATUS:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_READ_REGISTER , 0, 32,
+ s->bar0 + ERST_CSR_VALUE, 0, MASK8);
+ break;
+ case ACPI_ERST_ACTION_GET_RECORD_IDENTIFIER:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_READ_REGISTER , 0, 64,
+ s->bar0 + ERST_CSR_VALUE, 0, MASK64);
+ break;
+ case ACPI_ERST_ACTION_SET_RECORD_IDENTIFIER:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER , 0, 64,
+ s->bar0 + ERST_CSR_VALUE , 0, MASK64);
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ break;
+ case ACPI_ERST_ACTION_GET_RECORD_COUNT:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_READ_REGISTER , 0, 32,
+ s->bar0 + ERST_CSR_VALUE, 0, MASK32);
+ break;
+ case ACPI_ERST_ACTION_BEGIN_DUMMY_WRITE_OPERATION:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ break;
+ case ACPI_ERST_ACTION_RESERVED:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ break;
+ case ACPI_ERST_ACTION_GET_ERROR_LOG_ADDRESS_RANGE:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_READ_REGISTER , 0, 64,
+ s->bar0 + ERST_CSR_VALUE, 0, MASK64);
+ break;
+ case ACPI_ERST_ACTION_GET_ERROR_LOG_ADDRESS_LENGTH:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_READ_REGISTER , 0, 64,
+ s->bar0 + ERST_CSR_VALUE, 0, MASK32);
+ break;
+ case ACPI_ERST_ACTION_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_READ_REGISTER , 0, 32,
+ s->bar0 + ERST_CSR_VALUE, 0, MASK32);
+ break;
+ case ACPI_ERST_ACTION_GET_EXECUTE_OPERATION_TIMINGS:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_WRITE_REGISTER_VALUE, 0, 32,
+ s->bar0 + ERST_CSR_ACTION, action, MASK8);
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_READ_REGISTER , 0, 64,
+ s->bar0 + ERST_CSR_VALUE, 0, MASK64);
+ default:
+ build_serialization_instruction_entry(table_data, action,
+ ACPI_ERST_INST_NOOP, 0, 0, 0, action, 0);
+ break;
+ }
+ }
+ build_header(linker, table_data,
+ (void *)(table_data->data + erst_start),
+ "ERST", table_data->len - erst_start,
+ 1, oem_id, oem_table_id);
+}
+
+/*******************************************************************/
+/*******************************************************************/
+
static const VMStateDescription erst_vmstate = {
.name = "acpi-erst",
.version_id = 1,
--
1.8.3.1
- [PATCH v5 00/10] acpi: Error Record Serialization Table, ERST, support for QEMU, Eric DeVolder, 2021/06/30
- [PATCH v5 01/10] ACPI ERST: bios-tables-test.c steps 1 and 2, Eric DeVolder, 2021/06/30
- [PATCH v5 04/10] ACPI ERST: header file for ERST, Eric DeVolder, 2021/06/30
- [PATCH v5 02/10] ACPI ERST: specification for ERST support, Eric DeVolder, 2021/06/30
- [PATCH v5 03/10] ACPI ERST: PCI device_id for ERST, Eric DeVolder, 2021/06/30
- [PATCH v5 07/10] ACPI ERST: trace support, Eric DeVolder, 2021/06/30
- [PATCH v5 08/10] ACPI ERST: create ACPI ERST table for pc/x86 machines., Eric DeVolder, 2021/06/30
- [PATCH v5 05/10] ACPI ERST: support for ACPI ERST feature, Eric DeVolder, 2021/06/30
- [PATCH v5 06/10] ACPI ERST: build the ACPI ERST table,
Eric DeVolder <=
- [PATCH v5 09/10] ACPI ERST: qtest for ERST, Eric DeVolder, 2021/06/30
- [PATCH v5 10/10] ACPI ERST: step 6 of bios-tables-test.c, Eric DeVolder, 2021/06/30