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
> 

Reply via email to