E820, SRAT and HDM decoder programming in this series all need per‑device host physical address (HPA) information for CXL Type 3 memory. Today, CXLType3Dev does not expose this in a convenient way.
This patch adds minimal state to CXLHost and CXLType3Dev, plus a helper to walk from a Type 3 device back to its host, so that each CXL Type 3 device can be assigned a stable HPA offset within the CFMW window and an index that later code can rely on when building firmware tables and regions. Co-developed-by: Li Zhijian <[email protected]> Signed-off-by: Yukiya Takaki <[email protected]> --- hw/mem/cxl_type3.c | 37 +++++++++++++++++++++++++++++++++++++ include/hw/cxl/cxl.h | 2 ++ include/hw/cxl/cxl_device.h | 2 ++ 3 files changed, 41 insertions(+) diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c index b65ddd264d..d08a4255c9 100644 --- a/hw/mem/cxl_type3.c +++ b/hw/mem/cxl_type3.c @@ -732,9 +732,39 @@ static void cxl_destroy_dc_regions(CXLType3Dev *ct3d) } } + +static CXLHost *ct3d_to_cxl_pxb(DeviceState *dev) +{ + BusState *bus = dev->parent_bus; + + DeviceState *cxl_rp_dev = NULL; + if (bus && bus->parent) { + cxl_rp_dev = bus->parent; + } + assert(cxl_rp_dev); + + DeviceState *cxl_host_dev = NULL; + if (cxl_rp_dev) { + BusState *rp_bus = cxl_rp_dev->parent_bus; + if (rp_bus && rp_bus->parent) { + cxl_host_dev = rp_bus->parent; + } + } + assert(cxl_host_dev); + + if (cxl_host_dev && + object_dynamic_cast(OBJECT(cxl_host_dev), TYPE_PXB_CXL_HOST)) { + CXLHost *host = PXB_CXL_HOST(cxl_host_dev); + return host; + } + + return NULL; +} + static bool cxl_setup_memory(CXLType3Dev *ct3d, Error **errp) { DeviceState *ds = DEVICE(ct3d); + CXLHost *host = ct3d_to_cxl_pxb(ds); if (!ct3d->hostmem && !ct3d->hostvmem && !ct3d->hostpmem && !ct3d->dc.num_regions) { @@ -816,6 +846,13 @@ static bool cxl_setup_memory(CXLType3Dev *ct3d, Error **errp) g_free(p_name); } + if (ct3d->program_hdm_decoder) { + ct3d->hpa_offset = host->unused_hpa_offset; + ct3d->idx = host->unused_dev_num; + host->unused_hpa_offset += ct3d->cxl_dstate.static_mem_size; + host->unused_dev_num++; + } + ct3d->dc.total_capacity = 0; if (ct3d->dc.num_regions > 0) { MemoryRegion *dc_mr; diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h index 7cf3dc622c..b8b3071f81 100644 --- a/include/hw/cxl/cxl.h +++ b/include/hw/cxl/cxl.h @@ -67,6 +67,8 @@ struct CXLHost { CXLComponentState cxl_cstate; bool passthrough; + hwaddr unused_hpa_offset; + int unused_dev_num; }; #define TYPE_PXB_CXL_HOST "pxb-cxl-host" diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h index a2c830d181..c3a729f8c5 100644 --- a/include/hw/cxl/cxl_device.h +++ b/include/hw/cxl/cxl_device.h @@ -778,6 +778,8 @@ struct CXLType3Dev { bool hdmdb; bool program_hdm_decoder; + hwaddr hpa_offset; + int idx; struct dynamic_capacity { HostMemoryBackend *host_dc; -- 2.52.0
