cxl: Define a SPA->CXL HPA root decoder callback for XOR Math

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>
This commit is contained in:
Alison Schofield
2025-08-04 01:00:10 -07:00
committed by Dave Jiang
parent 524b2b76f3
commit b83ee9614a
2 changed files with 18 additions and 11 deletions

View 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);

View 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);
};
/**