mirror of https://gitlab.com/qemu-project/qemu
100 lines
3.1 KiB
C
100 lines
3.1 KiB
C
/*
|
|
* 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);
|
|
}
|