On Fri, Mar 06, 2026 at 12:11:50PM +0000, Alireza Sanaee wrote: > Extend cxl_cfmws_find_device() with a parameter that filters on whether the > address lies in an interleaved range. For now all callers accept > interleave configurations so no functional changes. > > Reviewed-by: Li Zhijian <[email protected]> > Signed-off-by: Alireza Sanaee <[email protected]>
Reviewed-by: Gregory Price <[email protected]> Tested-by: Gregory Price <[email protected]> > --- > Thanks to Li for the tag. > > Change log: > v6->v7: No change! > hw/cxl/cxl-host.c | 33 ++++++++++++++++++++++++++------- > 1 file changed, 26 insertions(+), 7 deletions(-) > > diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c > index a94b893e99..2dc9f77007 100644 > --- a/hw/cxl/cxl-host.c > +++ b/hw/cxl/cxl-host.c > @@ -104,7 +104,7 @@ void cxl_fmws_link_targets(Error **errp) > } > > static bool cxl_hdm_find_target(uint32_t *cache_mem, hwaddr addr, > - uint8_t *target) > + uint8_t *target, bool *interleaved) > { > int hdm_inc = R_CXL_HDM_DECODER1_BASE_LO - R_CXL_HDM_DECODER0_BASE_LO; > unsigned int hdm_count; > @@ -138,6 +138,11 @@ static bool cxl_hdm_find_target(uint32_t *cache_mem, > hwaddr addr, > found = true; > ig_enc = FIELD_EX32(ctrl, CXL_HDM_DECODER0_CTRL, IG); > iw_enc = FIELD_EX32(ctrl, CXL_HDM_DECODER0_CTRL, IW); > + > + if (interleaved) { > + *interleaved = iw_enc != 0; > + } > + > target_idx = (addr / cxl_decode_ig(ig_enc)) % (1 << iw_enc); > > if (target_idx < 4) { > @@ -157,7 +162,8 @@ static bool cxl_hdm_find_target(uint32_t *cache_mem, > hwaddr addr, > return found; > } > > -static PCIDevice *cxl_cfmws_find_device(CXLFixedWindow *fw, hwaddr addr) > +static PCIDevice *cxl_cfmws_find_device(CXLFixedWindow *fw, hwaddr addr, > + bool allow_interleave) > { > CXLComponentState *hb_cstate, *usp_cstate; > PCIHostState *hb; > @@ -165,9 +171,13 @@ static PCIDevice *cxl_cfmws_find_device(CXLFixedWindow > *fw, hwaddr addr) > int rb_index; > uint32_t *cache_mem; > uint8_t target; > - bool target_found; > + bool target_found, interleaved; > PCIDevice *rp, *d; > > + if ((fw->num_targets > 1) && !allow_interleave) { > + return NULL; > + } > + > rb_index = (addr / cxl_decode_ig(fw->enc_int_gran)) % fw->num_targets; > hb = PCI_HOST_BRIDGE(fw->target_hbs[rb_index]->cxl_host_bridge); > if (!hb || !hb->bus || !pci_bus_is_cxl(hb->bus)) { > @@ -187,11 +197,16 @@ static PCIDevice *cxl_cfmws_find_device(CXLFixedWindow > *fw, hwaddr addr) > > cache_mem = hb_cstate->crb.cache_mem_registers; > > - target_found = cxl_hdm_find_target(cache_mem, addr, &target); > + target_found = cxl_hdm_find_target(cache_mem, addr, &target, > + &interleaved); > if (!target_found) { > return NULL; > } > > + if (interleaved && !allow_interleave) { > + return NULL; > + } > + > rp = pcie_find_port_by_pn(hb->bus, target); > if (!rp) { > return NULL; > @@ -223,11 +238,15 @@ static PCIDevice *cxl_cfmws_find_device(CXLFixedWindow > *fw, hwaddr addr) > > cache_mem = usp_cstate->crb.cache_mem_registers; > > - target_found = cxl_hdm_find_target(cache_mem, addr, &target); > + target_found = cxl_hdm_find_target(cache_mem, addr, &target, > &interleaved); > if (!target_found) { > return NULL; > } > > + if (interleaved && !allow_interleave) { > + return NULL; > + } > + > d = pcie_find_port_by_pn(&PCI_BRIDGE(d)->sec_bus, target); > if (!d) { > return NULL; > @@ -251,7 +270,7 @@ static MemTxResult cxl_read_cfmws(void *opaque, hwaddr > addr, uint64_t *data, > CXLFixedWindow *fw = opaque; > PCIDevice *d; > > - d = cxl_cfmws_find_device(fw, addr + fw->base); > + d = cxl_cfmws_find_device(fw, addr + fw->base, true); > if (d == NULL) { > *data = 0; > /* Reads to invalid address return poison */ > @@ -268,7 +287,7 @@ static MemTxResult cxl_write_cfmws(void *opaque, hwaddr > addr, > CXLFixedWindow *fw = opaque; > PCIDevice *d; > > - d = cxl_cfmws_find_device(fw, addr + fw->base); > + d = cxl_cfmws_find_device(fw, addr + fw->base, true); > if (d == NULL) { > /* Writes to invalid address are silent */ > return MEMTX_OK; > -- > 2.43.0 >
