aboutsummaryrefslogtreecommitdiff
path: root/hw/acpi/aml-build.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/acpi/aml-build.c')
-rw-r--r--hw/acpi/aml-build.c108
1 files changed, 101 insertions, 7 deletions
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 6d4517c..f8f93a9 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -24,7 +24,7 @@
#include "hw/acpi/aml-build.h"
#include "qemu/bswap.h"
#include "qemu/bitops.h"
-#include "sysemu/numa.h"
+#include "system/numa.h"
#include "hw/boards.h"
#include "hw/acpi/tpm.h"
#include "hw/pci/pci_host.h"
@@ -534,8 +534,7 @@ void aml_append(Aml *parent_ctx, Aml *child)
case AML_NO_OPCODE:
break;
default:
- assert(0);
- break;
+ g_assert_not_reached();
}
build_append_array(parent_ctx->buf, buf);
build_free_array(buf);
@@ -1939,6 +1938,89 @@ void build_srat_memory(GArray *table_data, uint64_t base,
}
/*
+ * ACPI Spec Revision 6.3
+ * Table 5-80 Device Handle - PCI
+ */
+static void build_append_srat_pci_device_handle(GArray *table_data,
+ uint16_t segment,
+ uint8_t bus, uint8_t devfn)
+{
+ /* PCI segment number */
+ build_append_int_noprefix(table_data, segment, 2);
+ /* PCI Bus Device Function */
+ build_append_int_noprefix(table_data, bus, 1);
+ build_append_int_noprefix(table_data, devfn, 1);
+ /* Reserved */
+ build_append_int_noprefix(table_data, 0, 12);
+}
+
+static void build_append_srat_acpi_device_handle(GArray *table_data,
+ const char *hid,
+ uint32_t uid)
+{
+ assert(strlen(hid) == 8);
+ /* Device Handle - ACPI */
+ for (int i = 0; i < 8; i++) {
+ build_append_int_noprefix(table_data, hid[i], 1);
+ }
+ build_append_int_noprefix(table_data, uid, 4);
+ build_append_int_noprefix(table_data, 0, 4);
+}
+
+/*
+ * ACPI spec, Revision 6.3
+ * 5.2.16.6 Generic Initiator Affinity Structure
+ * With PCI Device Handle.
+ */
+void build_srat_pci_generic_initiator(GArray *table_data, uint32_t node,
+ uint16_t segment, uint8_t bus,
+ uint8_t devfn)
+{
+ /* Type */
+ build_append_int_noprefix(table_data, 5, 1);
+ /* Length */
+ build_append_int_noprefix(table_data, 32, 1);
+ /* Reserved */
+ build_append_int_noprefix(table_data, 0, 1);
+ /* Device Handle Type: PCI */
+ build_append_int_noprefix(table_data, 1, 1);
+ /* Proximity Domain */
+ build_append_int_noprefix(table_data, node, 4);
+ /* Device Handle */
+ build_append_srat_pci_device_handle(table_data, segment, bus, devfn);
+ /* Flags - GI Enabled */
+ build_append_int_noprefix(table_data, 1, 4);
+ /* Reserved */
+ build_append_int_noprefix(table_data, 0, 4);
+}
+
+/*
+ * ACPI spec, Revision 6.5
+ * 5.2.16.7 Generic Port Affinity Structure
+ * With ACPI Device Handle.
+ */
+void build_srat_acpi_generic_port(GArray *table_data, uint32_t node,
+ const char *hid, uint32_t uid)
+{
+ /* Type */
+ build_append_int_noprefix(table_data, 6, 1);
+ /* Length */
+ build_append_int_noprefix(table_data, 32, 1);
+ /* Reserved */
+ build_append_int_noprefix(table_data, 0, 1);
+ /* Device Handle Type: ACPI */
+ build_append_int_noprefix(table_data, 0, 1);
+ /* Proximity Domain */
+ build_append_int_noprefix(table_data, node, 4);
+ /* Device Handle */
+ build_append_srat_acpi_device_handle(table_data, hid, uid);
+ /* Flags - GP Enabled */
+ build_append_int_noprefix(table_data, 1, 4);
+ /* Reserved */
+ build_append_int_noprefix(table_data, 0, 4);
+}
+
+/*
* ACPI spec 5.2.17 System Locality Distance Information Table
* (Revision 2.0 or later)
*/
@@ -1996,7 +2078,7 @@ static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags,
void build_spcr(GArray *table_data, BIOSLinker *linker,
const AcpiSpcrData *f, const uint8_t rev,
- const char *oem_id, const char *oem_table_id)
+ const char *oem_id, const char *oem_table_id, const char *name)
{
AcpiTable table = { .sig = "SPCR", .rev = rev, .oem_id = oem_id,
.oem_table_id = oem_table_id };
@@ -2042,9 +2124,21 @@ void build_spcr(GArray *table_data, BIOSLinker *linker,
build_append_int_noprefix(table_data, f->pci_flags, 4);
/* PCI Segment */
build_append_int_noprefix(table_data, f->pci_segment, 1);
- /* Reserved */
- build_append_int_noprefix(table_data, 0, 4);
-
+ if (rev < 4) {
+ /* Reserved */
+ build_append_int_noprefix(table_data, 0, 4);
+ } else {
+ /* UartClkFreq */
+ build_append_int_noprefix(table_data, f->uart_clk_freq, 4);
+ /* PreciseBaudrate */
+ build_append_int_noprefix(table_data, f->precise_baudrate, 4);
+ /* NameSpaceStringLength */
+ build_append_int_noprefix(table_data, f->namespace_string_length, 2);
+ /* NameSpaceStringOffset */
+ build_append_int_noprefix(table_data, f->namespace_string_offset, 2);
+ /* NamespaceString[] */
+ g_array_append_vals(table_data, name, f->namespace_string_length);
+ }
acpi_table_end(linker, &table);
}
/*