]> www.infradead.org Git - users/hch/misc.git/commitdiff
cxl: Define a SPA->CXL HPA root decoder callback for XOR Math
authorAlison Schofield <alison.schofield@intel.com>
Mon, 4 Aug 2025 08:00:10 +0000 (01:00 -0700)
committerDave Jiang <dave.jiang@intel.com>
Tue, 12 Aug 2025 23:02:00 +0000 (16:02 -0700)
When DPA->SPA translation was introduced, it included a helper that
applied the XOR maps to do the CXL HPA -> SPA translation for XOR
region interleaves. In preparation for adding SPA->DPA address
translation, introduce the reverse callback.

The root decoder callback is defined generically and not all usages
may be self inverting like this XOR function. Add another root decoder
callback that is the spa_to_hpa function.

Update the existing cxl_xor_hpa_to_spa() with a name that reflects
what it does without directionality: cxl_apply_xor_maps(), a generic
parameter: addr replaces hpa, and code comments stating that the
function supports the translation in either direction.

Signed-off-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Link: https://patch.msgid.link/79d9d72230c599cae94d7221781ead6392ae6d3f.1754290144.git.alison.schofield@intel.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
drivers/cxl/acpi.c
drivers/cxl/cxl.h

index b8d69460a36805e9cb3f66fb049e3db9c6fd0d69..f1625212b08ba3add6981d2b1d744a68d5f0693e 100644 (file)
@@ -20,7 +20,7 @@ static const guid_t acpi_cxl_qtg_id_guid =
        GUID_INIT(0xF365F9A6, 0xA7DE, 0x4071,
                  0xA6, 0x6A, 0xB4, 0x0C, 0x0B, 0x4F, 0x8E, 0x52);
 
-static u64 cxl_xor_hpa_to_spa(struct cxl_root_decoder *cxlrd, u64 hpa)
+static u64 cxl_apply_xor_maps(struct cxl_root_decoder *cxlrd, u64 addr)
 {
        struct cxl_cxims_data *cximsd = cxlrd->platform_data;
        int hbiw = cxlrd->cxlsd.nr_targets;
@@ -29,19 +29,23 @@ static u64 cxl_xor_hpa_to_spa(struct cxl_root_decoder *cxlrd, u64 hpa)
 
        /* No xormaps for host bridge interleave ways of 1 or 3 */
        if (hbiw == 1 || hbiw == 3)
-               return hpa;
+               return addr;
 
        /*
-        * For root decoders using xormaps (hbiw: 2,4,6,8,12,16) restore
-        * the position bit to its value before the xormap was applied at
-        * HPA->DPA translation.
+        * In regions using XOR interleave arithmetic the CXL HPA may not
+        * be the same as the SPA. This helper performs the SPA->CXL HPA
+        * or the CXL HPA->SPA translation. Since XOR is self-inverting,
+        * so is this function.
+        *
+        * For root decoders using xormaps (hbiw: 2,4,6,8,12,16) applying the
+        * xormaps will toggle a position bit.
         *
         * pos is the lowest set bit in an XORMAP
-        * val is the XORALLBITS(HPA & XORMAP)
+        * val is the XORALLBITS(addr & XORMAP)
         *
         * XORALLBITS: The CXL spec (3.1 Table 9-22) defines XORALLBITS
         * as an operation that outputs a single bit by XORing all the
-        * bits in the input (hpa & xormap). Implement XORALLBITS using
+        * bits in the input (addr & xormap). Implement XORALLBITS using
         * hweight64(). If the hamming weight is even the XOR of those
         * bits results in val==0, if odd the XOR result is val==1.
         */
@@ -50,11 +54,11 @@ static u64 cxl_xor_hpa_to_spa(struct cxl_root_decoder *cxlrd, u64 hpa)
                if (!cximsd->xormaps[i])
                        continue;
                pos = __ffs(cximsd->xormaps[i]);
-               val = (hweight64(hpa & cximsd->xormaps[i]) & 1);
-               hpa = (hpa & ~(1ULL << pos)) | (val << pos);
+               val = (hweight64(addr & cximsd->xormaps[i]) & 1);
+               addr = (addr & ~(1ULL << pos)) | (val << pos);
        }
 
-       return hpa;
+       return addr;
 }
 
 struct cxl_cxims_context {
@@ -476,7 +480,8 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
                if (!cxlrd->ops)
                        return -ENOMEM;
 
-               cxlrd->ops->hpa_to_spa = cxl_xor_hpa_to_spa;
+               cxlrd->ops->hpa_to_spa = cxl_apply_xor_maps;
+               cxlrd->ops->spa_to_hpa = cxl_apply_xor_maps;
        }
 
        rc = cxl_decoder_add(cxld, target_map);
index 4b247ab188833399a36aa9af7253529fd8d84528..4fe3df06f57a3cb24f216dbb9e7a79b738c35561 100644 (file)
@@ -422,9 +422,11 @@ struct cxl_root_decoder;
 /**
  * struct cxl_rd_ops - CXL root decoder callback operations
  * @hpa_to_spa: Convert host physical address to system physical address
+ * @spa_to_hpa: Convert system physical address to host physical address
  */
 struct cxl_rd_ops {
        u64 (*hpa_to_spa)(struct cxl_root_decoder *cxlrd, u64 hpa);
+       u64 (*spa_to_hpa)(struct cxl_root_decoder *cxlrd, u64 spa);
 };
 
 /**