@@ -22,56 +22,42 @@ static const guid_t acpi_cxl_qtg_id_guid =
2222 GUID_INIT (0xF365F9A6 , 0xA7DE , 0x4071 ,
2323 0xA6 , 0x6A , 0xB4 , 0x0C , 0x0B , 0x4F , 0x8E , 0x52 );
2424
25- /*
26- * Find a targets entry (n) in the host bridge interleave list.
27- * CXL Specification 3.0 Table 9-22
28- */
29- static int cxl_xor_calc_n (u64 hpa , struct cxl_cxims_data * cximsd , int iw ,
30- int ig )
31- {
32- int i = 0 , n = 0 ;
33- u8 eiw ;
34-
35- /* IW: 2,4,6,8,12,16 begin building 'n' using xormaps */
36- if (iw != 3 ) {
37- for (i = 0 ; i < cximsd -> nr_maps ; i ++ )
38- n |= (hweight64 (hpa & cximsd -> xormaps [i ]) & 1 ) << i ;
39- }
40- /* IW: 3,6,12 add a modulo calculation to 'n' */
41- if (!is_power_of_2 (iw )) {
42- if (ways_to_eiw (iw , & eiw ))
43- return -1 ;
44- hpa &= GENMASK_ULL (51 , eiw + ig );
45- n |= do_div (hpa , 3 ) << i ;
46- }
47- return n ;
48- }
4925
50- static struct cxl_dport * cxl_hb_xor (struct cxl_root_decoder * cxlrd , int pos )
26+ static u64 cxl_xor_hpa_to_spa (struct cxl_root_decoder * cxlrd , u64 hpa )
5127{
5228 struct cxl_cxims_data * cximsd = cxlrd -> platform_data ;
53- struct cxl_switch_decoder * cxlsd = & cxlrd -> cxlsd ;
54- struct cxl_decoder * cxld = & cxlsd -> cxld ;
55- int ig = cxld -> interleave_granularity ;
56- int iw = cxld -> interleave_ways ;
57- int n = 0 ;
58- u64 hpa ;
59-
60- if (dev_WARN_ONCE (& cxld -> dev ,
61- cxld -> interleave_ways != cxlsd -> nr_targets ,
62- "misconfigured root decoder\n" ))
63- return NULL ;
29+ int hbiw = cxlrd -> cxlsd .nr_targets ;
30+ u64 val ;
31+ int pos ;
6432
65- hpa = cxlrd -> res -> start + pos * ig ;
33+ /* No xormaps for host bridge interleave ways of 1 or 3 */
34+ if (hbiw == 1 || hbiw == 3 )
35+ return hpa ;
6636
67- /* Entry (n) is 0 for no interleave (iw == 1) */
68- if (iw != 1 )
69- n = cxl_xor_calc_n (hpa , cximsd , iw , ig );
37+ /*
38+ * For root decoders using xormaps (hbiw: 2,4,6,8,12,16) restore
39+ * the position bit to its value before the xormap was applied at
40+ * HPA->DPA translation.
41+ *
42+ * pos is the lowest set bit in an XORMAP
43+ * val is the XORALLBITS(HPA & XORMAP)
44+ *
45+ * XORALLBITS: The CXL spec (3.1 Table 9-22) defines XORALLBITS
46+ * as an operation that outputs a single bit by XORing all the
47+ * bits in the input (hpa & xormap). Implement XORALLBITS using
48+ * hweight64(). If the hamming weight is even the XOR of those
49+ * bits results in val==0, if odd the XOR result is val==1.
50+ */
7051
71- if (n < 0 )
72- return NULL ;
52+ for (int i = 0 ; i < cximsd -> nr_maps ; i ++ ) {
53+ if (!cximsd -> xormaps [i ])
54+ continue ;
55+ pos = __ffs (cximsd -> xormaps [i ]);
56+ val = (hweight64 (hpa & cximsd -> xormaps [i ]) & 1 );
57+ hpa = (hpa & ~(1ULL << pos )) | (val << pos );
58+ }
7359
74- return cxlrd -> cxlsd . target [ n ] ;
60+ return hpa ;
7561}
7662
7763struct cxl_cxims_context {
@@ -361,7 +347,6 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
361347 struct cxl_port * root_port = ctx -> root_port ;
362348 struct cxl_cxims_context cxims_ctx ;
363349 struct device * dev = ctx -> dev ;
364- cxl_calc_hb_fn cxl_calc_hb ;
365350 struct cxl_decoder * cxld ;
366351 unsigned int ways , i , ig ;
367352 int rc ;
@@ -389,13 +374,9 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
389374 if (rc )
390375 return rc ;
391376
392- if (cfmws -> interleave_arithmetic == ACPI_CEDT_CFMWS_ARITHMETIC_MODULO )
393- cxl_calc_hb = cxl_hb_modulo ;
394- else
395- cxl_calc_hb = cxl_hb_xor ;
396-
397377 struct cxl_root_decoder * cxlrd __free (put_cxlrd ) =
398- cxl_root_decoder_alloc (root_port , ways , cxl_calc_hb );
378+ cxl_root_decoder_alloc (root_port , ways );
379+
399380 if (IS_ERR (cxlrd ))
400381 return PTR_ERR (cxlrd );
401382
@@ -434,6 +415,9 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
434415
435416 cxlrd -> qos_class = cfmws -> qtg_id ;
436417
418+ if (cfmws -> interleave_arithmetic == ACPI_CEDT_CFMWS_ARITHMETIC_XOR )
419+ cxlrd -> hpa_to_spa = cxl_xor_hpa_to_spa ;
420+
437421 rc = cxl_decoder_add (cxld , target_map );
438422 if (rc )
439423 return rc ;
0 commit comments