|
@@ -0,0 +1,99 @@
|
|
|
+/*
|
|
|
+ * HMAT ACPI Implementation
|
|
|
+ *
|
|
|
+ * Copyright(C) 2019 Intel Corporation.
|
|
|
+ *
|
|
|
+ * Author:
|
|
|
+ * Liu jingqi <jingqi.liu@linux.intel.com>
|
|
|
+ * Tao Xu <tao3.xu@intel.com>
|
|
|
+ *
|
|
|
+ * HMAT is defined in ACPI 6.3: 5.2.27 Heterogeneous Memory Attribute Table
|
|
|
+ * (HMAT)
|
|
|
+ *
|
|
|
+ * This library is free software; you can redistribute it and/or
|
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
+ * License as published by the Free Software Foundation; either
|
|
|
+ * version 2 of the License, or (at your option) any later version.
|
|
|
+ *
|
|
|
+ * This library 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
|
|
|
+ * Lesser General Public License for more details.
|
|
|
+ *
|
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>
|
|
|
+ */
|
|
|
+
|
|
|
+#include "qemu/osdep.h"
|
|
|
+#include "sysemu/numa.h"
|
|
|
+#include "hw/acpi/hmat.h"
|
|
|
+
|
|
|
+/*
|
|
|
+ * ACPI 6.3:
|
|
|
+ * 5.2.27.3 Memory Proximity Domain Attributes Structure: Table 5-145
|
|
|
+ */
|
|
|
+static void build_hmat_mpda(GArray *table_data, uint16_t flags,
|
|
|
+ uint32_t initiator, uint32_t mem_node)
|
|
|
+{
|
|
|
+
|
|
|
+ /* Memory Proximity Domain Attributes Structure */
|
|
|
+ /* Type */
|
|
|
+ build_append_int_noprefix(table_data, 0, 2);
|
|
|
+ /* Reserved */
|
|
|
+ build_append_int_noprefix(table_data, 0, 2);
|
|
|
+ /* Length */
|
|
|
+ build_append_int_noprefix(table_data, 40, 4);
|
|
|
+ /* Flags */
|
|
|
+ build_append_int_noprefix(table_data, flags, 2);
|
|
|
+ /* Reserved */
|
|
|
+ build_append_int_noprefix(table_data, 0, 2);
|
|
|
+ /* Proximity Domain for the Attached Initiator */
|
|
|
+ build_append_int_noprefix(table_data, initiator, 4);
|
|
|
+ /* Proximity Domain for the Memory */
|
|
|
+ build_append_int_noprefix(table_data, mem_node, 4);
|
|
|
+ /* Reserved */
|
|
|
+ build_append_int_noprefix(table_data, 0, 4);
|
|
|
+ /*
|
|
|
+ * Reserved:
|
|
|
+ * Previously defined as the Start Address of the System Physical
|
|
|
+ * Address Range. Deprecated since ACPI Spec 6.3.
|
|
|
+ */
|
|
|
+ build_append_int_noprefix(table_data, 0, 8);
|
|
|
+ /*
|
|
|
+ * Reserved:
|
|
|
+ * Previously defined as the Range Length of the region in bytes.
|
|
|
+ * Deprecated since ACPI Spec 6.3.
|
|
|
+ */
|
|
|
+ build_append_int_noprefix(table_data, 0, 8);
|
|
|
+}
|
|
|
+
|
|
|
+/* Build HMAT sub table structures */
|
|
|
+static void hmat_build_table_structs(GArray *table_data, NumaState *numa_state)
|
|
|
+{
|
|
|
+ uint16_t flags;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 0; i < numa_state->num_nodes; i++) {
|
|
|
+ flags = 0;
|
|
|
+
|
|
|
+ if (numa_state->nodes[i].initiator < MAX_NODES) {
|
|
|
+ flags |= HMAT_PROXIMITY_INITIATOR_VALID;
|
|
|
+ }
|
|
|
+
|
|
|
+ build_hmat_mpda(table_data, flags, numa_state->nodes[i].initiator, i);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void build_hmat(GArray *table_data, BIOSLinker *linker, NumaState *numa_state)
|
|
|
+{
|
|
|
+ int hmat_start = table_data->len;
|
|
|
+
|
|
|
+ /* reserve space for HMAT header */
|
|
|
+ acpi_data_push(table_data, 40);
|
|
|
+
|
|
|
+ hmat_build_table_structs(table_data, numa_state);
|
|
|
+
|
|
|
+ build_header(linker, table_data,
|
|
|
+ (void *)(table_data->data + hmat_start),
|
|
|
+ "HMAT", table_data->len - hmat_start, 2, NULL, NULL);
|
|
|
+}
|