[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v5 18/43] hw/cxl/component: Implement host bridge MMIO (8.2.5, ta
From: |
Jonathan Cameron |
Subject: |
[PATCH v5 18/43] hw/cxl/component: Implement host bridge MMIO (8.2.5, table 142) |
Date: |
Wed, 2 Feb 2022 14:10:12 +0000 |
From: Ben Widawsky <ben.widawsky@intel.com>
CXL host bridges themselves may have MMIO. Since host bridges don't have
a BAR they are treated as special for MMIO. This patch includes
i386/pc support.
Signed-off-by: Ben Widawsky <ben.widawsky@intel.com>
Co-developed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
hw/i386/acpi-build.c | 26 +++++++++++---
hw/i386/pc.c | 27 ++++++++++++++-
hw/pci-bridge/pci_expander_bridge.c | 53 ++++++++++++++++++++++++++++-
include/hw/cxl/cxl.h | 4 +++
4 files changed, 104 insertions(+), 6 deletions(-)
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 09940f6e84..1e1e9b9d38 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -28,6 +28,7 @@
#include "qemu/bitmap.h"
#include "qemu/error-report.h"
#include "hw/pci/pci.h"
+#include "hw/cxl/cxl.h"
#include "hw/core/cpu.h"
#include "target/i386/cpu.h"
#include "hw/misc/pvpanic.h"
@@ -1398,7 +1399,7 @@ static void build_smb0(Aml *table, I2CBus *smbus, int
devnr, int func)
aml_append(table, scope);
}
-typedef enum { PCI, PCIE } PCIBusType;
+typedef enum { PCI, PCIE, CXL } PCIBusType;
static void init_pci_acpi(Aml *dev, int uid, PCIBusType type,
bool native_pcie_hp)
{
@@ -1562,22 +1563,30 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
QLIST_FOREACH(bus, &bus->child, sibling) {
uint8_t bus_num = pci_bus_num(bus);
uint8_t numa_node = pci_bus_numa_node(bus);
+ int32_t uid = bus_num; /* TODO: Explicit uid */
+ int type;
/* look only for expander root buses */
if (!pci_bus_is_root(bus)) {
continue;
}
+ type = pci_bus_is_cxl(bus) ? CXL :
+ pci_bus_is_express(bus) ? PCIE : PCI;
+
if (bus_num < root_bus_limit) {
root_bus_limit = bus_num - 1;
}
scope = aml_scope("\\_SB");
- dev = aml_device("PC%.02X", bus_num);
+ if (type == CXL) {
+ dev = aml_device("CL%.02X", uid);
+ } else {
+ dev = aml_device("PC%.02X", bus_num);
+ }
aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num)));
- init_pci_acpi(dev, bus_num,
- pci_bus_is_express(bus) ? PCIE : PCI, true);
+ init_pci_acpi(dev, uid, type, true);
if (numa_node != NUMA_NODE_UNASSIGNED) {
aml_append(dev, aml_name_decl("_PXM", aml_int(numa_node)));
@@ -1589,6 +1598,15 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
aml_append(dev, aml_name_decl("_CRS", crs));
aml_append(scope, dev);
aml_append(dsdt, scope);
+
+ /* Handle the ranges for the PXB expanders */
+ if (type == CXL) {
+ MemoryRegion *mr = &machine->cxl_devices_state->host_mr;
+ uint64_t base = mr->addr;
+
+ crs_range_insert(crs_range_set.mem_ranges, base,
+ base + memory_region_size(mr) - 1);
+ }
}
}
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index b6800a511a..7a18dce529 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -75,6 +75,7 @@
#include "acpi-build.h"
#include "hw/mem/pc-dimm.h"
#include "hw/mem/nvdimm.h"
+#include "hw/cxl/cxl.h"
#include "qapi/error.h"
#include "qapi/qapi-visit-common.h"
#include "qapi/qapi-visit-machine.h"
@@ -815,6 +816,7 @@ void pc_memory_init(PCMachineState *pcms,
MachineClass *mc = MACHINE_GET_CLASS(machine);
PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
X86MachineState *x86ms = X86_MACHINE(pcms);
+ hwaddr cxl_base;
assert(machine->ram_size == x86ms->below_4g_mem_size +
x86ms->above_4g_mem_size);
@@ -904,6 +906,26 @@ void pc_memory_init(PCMachineState *pcms,
&machine->device_memory->mr);
}
+ if (machine->cxl_devices_state->is_enabled) {
+ MemoryRegion *mr = &machine->cxl_devices_state->host_mr;
+ hwaddr cxl_size = MiB;
+
+ if (pcmc->has_reserved_memory && machine->device_memory->base) {
+ cxl_base = machine->device_memory->base;
+ if (!pcmc->broken_reserved_end) {
+ cxl_base += memory_region_size(&machine->device_memory->mr);
+ }
+ } else if (pcms->sgx_epc.size != 0) {
+ cxl_base = sgx_epc_above_4g_end(&pcms->sgx_epc);
+ } else {
+ cxl_base = 0x100000000ULL + x86ms->above_4g_mem_size;
+ }
+
+ e820_add_entry(cxl_base, cxl_size, E820_RESERVED);
+ memory_region_init(mr, OBJECT(machine), "cxl_host_reg", cxl_size);
+ memory_region_add_subregion(system_memory, cxl_base, mr);
+ }
+
/* Initialize PC system firmware */
pc_system_firmware_init(pcms, rom_memory);
@@ -964,7 +986,10 @@ uint64_t pc_pci_hole64_start(void)
X86MachineState *x86ms = X86_MACHINE(pcms);
uint64_t hole64_start = 0;
- if (pcmc->has_reserved_memory && ms->device_memory->base) {
+ if (ms->cxl_devices_state->host_mr.addr) {
+ hole64_start = ms->cxl_devices_state->host_mr.addr +
+ memory_region_size(&ms->cxl_devices_state->host_mr);
+ } else if (pcmc->has_reserved_memory && ms->device_memory->base) {
hole64_start = ms->device_memory->base;
if (!pcmc->broken_reserved_end) {
hole64_start += memory_region_size(&ms->device_memory->mr);
diff --git a/hw/pci-bridge/pci_expander_bridge.c
b/hw/pci-bridge/pci_expander_bridge.c
index c7a28c7b2e..164bdeff9f 100644
--- a/hw/pci-bridge/pci_expander_bridge.c
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -204,6 +204,56 @@ static const TypeInfo pxb_host_info = {
.class_init = pxb_host_class_init,
};
+static void pxb_cxl_realize(DeviceState *dev, Error **errp)
+{
+ MachineState *ms = MACHINE(qdev_get_machine());
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+ CXLHost *cxl = PXB_CXL_HOST(dev);
+ CXLComponentState *cxl_cstate = &cxl->cxl_cstate;
+ struct MemoryRegion *mr = &cxl_cstate->crb.component_registers;
+ hwaddr offset;
+
+ if (!ms->cxl_devices_state->is_enabled) {
+ error_setg(errp, "Machine does not have cxl=on");
+ return;
+ }
+ cxl_component_register_block_init(OBJECT(dev), cxl_cstate,
+ TYPE_PXB_CXL_HOST);
+ sysbus_init_mmio(sbd, mr);
+
+ offset = memory_region_size(mr) * ms->cxl_devices_state->next_mr_idx;
+ if (offset > memory_region_size(&ms->cxl_devices_state->host_mr)) {
+ error_setg(errp, "Insufficient space for pxb cxl host register space");
+ return;
+ }
+
+ memory_region_add_subregion(&ms->cxl_devices_state->host_mr, offset, mr);
+ ms->cxl_devices_state->next_mr_idx++;
+}
+
+static void pxb_cxl_host_class_init(ObjectClass *class, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(class);
+ PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(class);
+
+ hc->root_bus_path = pxb_host_root_bus_path;
+ dc->fw_name = "cxl";
+ dc->realize = pxb_cxl_realize;
+ /* Reason: Internal part of the pxb/pxb-pcie device, not usable by itself
*/
+ dc->user_creatable = false;
+}
+
+/*
+ * This is a device to handle the MMIO for a CXL host bridge. It does nothing
+ * else.
+ */
+static const TypeInfo cxl_host_info = {
+ .name = TYPE_PXB_CXL_HOST,
+ .parent = TYPE_PCI_HOST_BRIDGE,
+ .instance_size = sizeof(CXLHost),
+ .class_init = pxb_cxl_host_class_init,
+};
+
/*
* Registers the PXB bus as a child of pci host root bus.
*/
@@ -294,7 +344,7 @@ static void pxb_dev_realize_common(PCIDevice *dev, enum
BusType type,
dev_name = dev->qdev.id;
}
- ds = qdev_new(TYPE_PXB_HOST);
+ ds = qdev_new(type == CXL ? TYPE_PXB_CXL_HOST : TYPE_PXB_HOST);
if (type == PCIE) {
bus = pci_root_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_PCIE_BUS);
} else if (type == CXL) {
@@ -484,6 +534,7 @@ static void pxb_register_types(void)
type_register_static(&pxb_pcie_bus_info);
type_register_static(&pxb_cxl_bus_info);
type_register_static(&pxb_host_info);
+ type_register_static(&cxl_host_info);
type_register_static(&pxb_dev_info);
type_register_static(&pxb_pcie_dev_info);
type_register_static(&pxb_cxl_dev_info);
diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h
index 31af92fd5e..75e5bf71e1 100644
--- a/include/hw/cxl/cxl.h
+++ b/include/hw/cxl/cxl.h
@@ -17,8 +17,12 @@
#define CXL_COMPONENT_REG_BAR_IDX 0
#define CXL_DEVICE_REG_BAR_IDX 2
+#define CXL_WINDOW_MAX 10
+
typedef struct CXLState {
bool is_enabled;
+ MemoryRegion host_mr;
+ unsigned int next_mr_idx;
} CXLState;
#endif
--
2.32.0
- [PATCH v5 11/43] hw/pxb: Use a type for realizing expanders, (continued)
- [PATCH v5 11/43] hw/pxb: Use a type for realizing expanders, Jonathan Cameron, 2022/02/02
- [PATCH v5 12/43] hw/pci/cxl: Create a CXL bus type, Jonathan Cameron, 2022/02/02
- [PATCH v5 13/43] hw/pxb: Allow creation of a CXL PXB (host bridge), Jonathan Cameron, 2022/02/02
- [PATCH v5 14/43] tests/acpi: allow DSDT.viot table changes., Jonathan Cameron, 2022/02/02
- [PATCH v5 15/43] acpi/pci: Consolidate host bridge setup, Jonathan Cameron, 2022/02/02
- [PATCH v5 16/43] tests/acpi: Add update DSDT.viot, Jonathan Cameron, 2022/02/02
- [PATCH v5 17/43] cxl: Machine level control on whether CXL support is enabled, Jonathan Cameron, 2022/02/02
- [PATCH v5 18/43] hw/cxl/component: Implement host bridge MMIO (8.2.5, table 142),
Jonathan Cameron <=
- [PATCH v5 19/43] hw/cxl/rp: Add a root port, Jonathan Cameron, 2022/02/02
- [PATCH v5 20/43] hw/cxl/device: Add a memory device (8.2.8.5), Jonathan Cameron, 2022/02/02
[PATCH v5 21/43] hw/cxl/device: Implement MMIO HDM decoding (8.2.5.12), Jonathan Cameron, 2022/02/02
[PATCH v5 22/43] acpi/cxl: Add _OSC implementation (9.14.2), Jonathan Cameron, 2022/02/02
[PATCH v5 23/43] tests/acpi: allow CEDT table addition, Jonathan Cameron, 2022/02/02
[PATCH v5 24/43] acpi/cxl: Create the CEDT (9.14.1), Jonathan Cameron, 2022/02/02
[PATCH v5 25/43] hw/cxl/device: Add some trivial commands, Jonathan Cameron, 2022/02/02