new file mode 100644
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Generic Port device implementation
+ *
+ * Copyright (C) 2023 Intel Corporation
+ */
+#include "qemu/osdep.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "qom/object_interfaces.h"
+#include "hw/qdev-core.h"
+
+#define TYPE_GENERIC_PORT_DEVICE "genport"
+
+#define GENPORT_NUMA_NODE_PROP "node"
+#define GENPORT_DEV_PROP "genport"
+
+typedef struct GenericPortDevice {
+ /* private */
+ DeviceState parent_obj;
+
+ /* public */
+ uint32_t node;
+} GenericPortDevice;
+
+typedef struct GenericPortDeviceClass {
+ DeviceClass parent_class;
+} GenericPortDeviceClass;
+
+static Property genport_properties[] = {
+ DEFINE_PROP_UINT32(GENPORT_NUMA_NODE_PROP, GenericPortDevice, node, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+OBJECT_DEFINE_TYPE_WITH_INTERFACES(GenericPortDevice, genport_device,
+ GENERIC_PORT_DEVICE, DEVICE,
+ { TYPE_USER_CREATABLE },
+ { NULL })
+
+static void genport_device_init(Object *obj)
+{
+}
+
+static void genport_device_finalize(Object *obj)
+{
+}
+
+static void genport_device_realize(DeviceState *dev, Error **errp)
+{
+}
+
+static void genport_device_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ dc->realize = genport_device_realize;
+ dc->desc = "Generic Port";
+ device_class_set_props(dc, genport_properties);
+}
+
@@ -5,6 +5,7 @@ acpi_ss.add(files(
'bios-linker-loader.c',
'core.c',
'utils.c',
+ 'genport.c',
))
acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_true: files('cpu.c', 'cpu_hotplug.c'))
acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_false: files('acpi-cpu-hotplug-stub.c'))
@@ -1514,12 +1514,22 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
aml_append(dev, aml_name_decl("_UID", aml_int(bus_num)));
aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num)));
if (pci_bus_is_cxl(bus)) {
- CxlHBDev *hb_entry;
+ CxlHBDev *hb_entry, *match;
+ bool found = false;
struct Aml *pkg = aml_package(2);
- hb_entry = g_malloc0(sizeof(*hb_entry));
- hb_entry->uid = bus_num;
- QSLIST_INSERT_HEAD(&cxl_hb_list_head, hb_entry, entry);
+ QSLIST_FOREACH(match, &cxl_hb_list_head, entry)
+ {
+ if (match->uid == bus_num) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ hb_entry = g_malloc0(sizeof(*hb_entry));
+ hb_entry->uid = bus_num;
+ QSLIST_INSERT_HEAD(&cxl_hb_list_head, hb_entry, entry);
+ }
aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0016")));
aml_append(pkg, aml_eisaid("PNP0A08"));
@@ -1892,6 +1902,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
NULL);
AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = x86ms->oem_id,
.oem_table_id = x86ms->oem_table_id };
+ int pxm_domain;
acpi_table_begin(&table, table_data);
build_append_int_noprefix(table_data, 1, 4); /* Reserved */
@@ -1986,16 +1997,23 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
sgx_epc_build_srat(table_data);
+ /* FIXME: this is a hack, need a node property for genport */
+ pxm_domain = 6;
QSLIST_FOREACH(hb_entry, &cxl_hb_list_head, entry)
{
ACPIDeviceHandle handle = {
.hid = "ACPI0016",
- .uid = hb_entry->uid,
+ .reserved = { 0 },
};
+ char uid_str[5];
uint32_t flags = GEN_AFFINITY_ENABLED;
- build_srat_generic_port_affinity(table_data, 0, nb_numa_nodes,
- &handle, flags);
+ snprintf(uid_str, 4, "%u", hb_entry->uid);
+ memcpy(handle.uid, uid_str, 4);
+
+ build_srat_generic_port_affinity(table_data, 0, pxm_domain, &handle,
+ flags);
+ pxm_domain++;
}
/*
@@ -222,8 +222,8 @@ typedef enum {
typedef union ACPIDeviceHandle {
struct {
uint8_t hid[8];
- uint32_t uid;
- uint32_t reserved;
+ uint8_t uid[4];
+ uint8_t reserved[4];
};
uint64_t raw[2];
} ACPIDeviceHandle;
@@ -2523,6 +2523,31 @@ static void qemu_init_board(void)
}
}
+static int genport_realize_cb(Object *obj, void *opaque)
+{
+ DeviceState *dev = DEVICE(object_dynamic_cast(obj, TYPE_DEVICE));
+ ObjectClass *klass = object_get_class(obj);
+ ObjectClass *type_klass = object_class_by_name("genport");
+
+ if (!dev)
+ return 0;
+
+ if (dev->realized)
+ return 0;
+
+ if (klass != type_klass)
+ return 0;
+
+ qdev_realize(dev, NULL, &error_fatal);
+ return 0;
+}
+
+static void genports_realize(void)
+{
+ object_child_foreach_recursive(object_get_root(),
+ genport_realize_cb, NULL);
+}
+
static void qemu_create_cli_devices(void)
{
DeviceOption *opt;
@@ -2557,6 +2582,7 @@ static void qemu_create_cli_devices(void)
loc_pop(&opt->loc);
}
rom_reset_order_override();
+ genports_realize();
}
static void qemu_machine_creation_done(void)
Signed-off-by: Dave Jiang <dave.jiang@intel.com> --- hw/acpi/genport.c | 61 +++++++++++++++++++++++++++++++++++++++++++ hw/acpi/meson.build | 1 + hw/i386/acpi-build.c | 32 ++++++++++++++++++----- include/hw/acpi/aml-build.h | 4 +-- softmmu/vl.c | 26 ++++++++++++++++++ 5 files changed, 115 insertions(+), 9 deletions(-) create mode 100644 hw/acpi/genport.c