On real systems, CXL Type 3 memory is exposed to the OS via the E820 table as E820_SOFT_RESERVED, so the kernel can treat it as a dedicated reserved range rather than normal RAM.
This patch adds a small helper and a recursive walker so that, on x86, the HPA ranges assigned to CXL Type 3 devices are added to the E820 table as E820_SOFT_RESERVED when `program_hdm_decoder` is enabled. An ARM stub is also added as a placeholder for future support. Signed-off-by: Yukiya Takaki <[email protected]> --- hw/arm/cxl.c | 10 ++++++++++ hw/arm/meson.build | 2 ++ hw/cxl/cxl-host.c | 25 +++++++++++++++++++++++++ hw/i386/cxl.c | 11 +++++++++++ hw/i386/meson.build | 1 + hw/i386/pc.c | 1 + include/hw/cxl/cxl_host.h | 2 ++ 7 files changed, 52 insertions(+) create mode 100644 hw/arm/cxl.c create mode 100644 hw/i386/cxl.c diff --git a/hw/arm/cxl.c b/hw/arm/cxl.c new file mode 100644 index 0000000000..1cbcf2d8e5 --- /dev/null +++ b/hw/arm/cxl.c @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "qemu/osdep.h" +#include "exec/hwaddr.h" +#include "hw/cxl/cxl_host.h" + +void cxl_c3_add_memory_map(hwaddr base, hwaddr size) +{ + /* TODO: Implement memory map addition for CXL Type 3 on ARM */ +} diff --git a/hw/arm/meson.build b/hw/arm/meson.build index bcc068de04..2a4f09fbef 100644 --- a/hw/arm/meson.build +++ b/hw/arm/meson.build @@ -116,6 +116,8 @@ arm_common_ss.add(when: ['CONFIG_AXIADO_EVK', 'TARGET_AARCH64'], if_true: files( 'ax3000-boards.c', 'ax3000-evk.c')) +arm_common_ss.add(when: 'CONFIG_CXL', if_true: files('cxl.c')) + arm_common_ss.add(files('boot.c')) hw_common_arch += {'arm': arm_common_ss} diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c index e279ce5fe3..1967c9a9c3 100644 --- a/hw/cxl/cxl-host.c +++ b/hw/cxl/cxl-host.c @@ -689,12 +689,37 @@ static int cxl_fmws_mmio_map(Object *obj, void *opaque) return 0; } +static int cxl_c3_mmio_map(Object *obj, void *opaque) +{ + uint64_t base, size; + CXLType3Dev *c3d; + + if (!object_dynamic_cast(obj, TYPE_CXL_TYPE3)) { + return 0; + } + c3d = CXL_TYPE3(obj); + + if (!c3d->program_hdm_decoder) { + return 0; + } + + ct3_type3_get_hpm_range(c3d, &base, &size); + cxl_c3_add_memory_map(base, size); + + return 0; +} + void cxl_fmws_update_mmio(void) { /* Ordering is not required for this */ object_child_foreach_recursive(object_get_root(), cxl_fmws_mmio_map, NULL); } +void cxl_c3_update_mmio(void) +{ + object_child_foreach_recursive(object_get_root(), cxl_c3_mmio_map, NULL); +} + hwaddr cxl_fmws_set_memmap(hwaddr base, hwaddr max_addr) { GSList *cfmws_list, *iter; diff --git a/hw/i386/cxl.c b/hw/i386/cxl.c new file mode 100644 index 0000000000..02dbe4d3f0 --- /dev/null +++ b/hw/i386/cxl.c @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "qemu/osdep.h" +#include "exec/hwaddr.h" +#include "hw/cxl/cxl_host.h" +#include "hw/i386/e820_memory_layout.h" + +void cxl_c3_add_memory_map(hwaddr base, hwaddr size) +{ + e820_add_entry(base, size, E820_SOFT_RESERVED); +} diff --git a/hw/i386/meson.build b/hw/i386/meson.build index e16930c431..b212b3f6fa 100644 --- a/hw/i386/meson.build +++ b/hw/i386/meson.build @@ -24,6 +24,7 @@ i386_ss.add(when: 'CONFIG_VTD', if_true: files('intel_iommu.c')) i386_ss.add(when: 'CONFIG_VTD_ACCEL', if_true: files('intel_iommu_accel.c')) i386_ss.add(when: 'CONFIG_SGX', if_true: files('sgx-epc.c','sgx.c'), if_false: files('sgx-stub.c')) +i386_ss.add(when: 'CONFIG_CXL', if_true: files('cxl.c')) if have_hmp stub_ss.add(files('sgx-hmp-stub.c')) endif diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 2d8c87b0e3..f843629543 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -534,6 +534,7 @@ void pc_machine_done(Notifier *notifier, void *data) if (pcms->cxl_devices_state.is_enabled) { cxl_fmws_link_targets(&error_fatal); + cxl_c3_update_mmio(); } /* set the number of CPUs */ diff --git a/include/hw/cxl/cxl_host.h b/include/hw/cxl/cxl_host.h index 21619bb748..6c142a5b89 100644 --- a/include/hw/cxl/cxl_host.h +++ b/include/hw/cxl/cxl_host.h @@ -18,6 +18,8 @@ void cxl_fmws_link_targets(Error **errp); void cxl_hook_up_pxb_registers(PCIBus *bus, CXLState *state, Error **errp); hwaddr cxl_fmws_set_memmap(hwaddr base, hwaddr max_addr); void cxl_fmws_update_mmio(void); +void cxl_c3_update_mmio(void); +void cxl_c3_add_memory_map(hwaddr base, hwaddr size); GSList *cxl_fmws_get_all_sorted(void); extern const MemoryRegionOps cfmws_ops; -- 2.52.0
