@@ -22,57 +22,6 @@ 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- }
49-
50- static struct cxl_dport * cxl_hb_xor (struct cxl_root_decoder * cxlrd , int pos )
51- {
52- 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 ;
64-
65- hpa = cxlrd -> res -> start + pos * ig ;
66-
67- /* Entry (n) is 0 for no interleave (iw == 1) */
68- if (iw != 1 )
69- n = cxl_xor_calc_n (hpa , cximsd , iw , ig );
70-
71- if (n < 0 )
72- return NULL ;
73-
74- return cxlrd -> cxlsd .target [n ];
75- }
7625
7726static u64 cxl_xor_hpa_to_spa (struct cxl_root_decoder * cxlrd , u64 hpa )
7827{
@@ -398,7 +347,6 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
398347 struct cxl_port * root_port = ctx -> root_port ;
399348 struct cxl_cxims_context cxims_ctx ;
400349 struct device * dev = ctx -> dev ;
401- cxl_calc_hb_fn cxl_calc_hb ;
402350 struct cxl_decoder * cxld ;
403351 unsigned int ways , i , ig ;
404352 int rc ;
@@ -426,13 +374,9 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
426374 if (rc )
427375 return rc ;
428376
429- if (cfmws -> interleave_arithmetic == ACPI_CEDT_CFMWS_ARITHMETIC_MODULO )
430- cxl_calc_hb = cxl_hb_modulo ;
431- else
432- cxl_calc_hb = cxl_hb_xor ;
433-
434377 struct cxl_root_decoder * cxlrd __free (put_cxlrd ) =
435- cxl_root_decoder_alloc (root_port , ways , cxl_calc_hb );
378+ cxl_root_decoder_alloc (root_port , ways );
379+
436380 if (IS_ERR (cxlrd ))
437381 return PTR_ERR (cxlrd );
438382
@@ -522,6 +466,8 @@ struct cxl_chbs_context {
522466 unsigned long long uid ;
523467 resource_size_t base ;
524468 u32 cxl_version ;
469+ int nr_versions ;
470+ u32 saved_version ;
525471};
526472
527473static int cxl_get_chbs_iter (union acpi_subtable_headers * header , void * arg ,
@@ -530,22 +476,31 @@ static int cxl_get_chbs_iter(union acpi_subtable_headers *header, void *arg,
530476 struct cxl_chbs_context * ctx = arg ;
531477 struct acpi_cedt_chbs * chbs ;
532478
533- if (ctx -> base != CXL_RESOURCE_NONE )
534- return 0 ;
535-
536479 chbs = (struct acpi_cedt_chbs * ) header ;
537480
538- if (ctx -> uid != chbs -> uid )
481+ if (chbs -> cxl_version == ACPI_CEDT_CHBS_VERSION_CXL11 &&
482+ chbs -> length != CXL_RCRB_SIZE )
539483 return 0 ;
540484
541- ctx -> cxl_version = chbs -> cxl_version ;
542485 if (!chbs -> base )
543486 return 0 ;
544487
545- if (chbs -> cxl_version == ACPI_CEDT_CHBS_VERSION_CXL11 &&
546- chbs -> length != CXL_RCRB_SIZE )
488+ if (ctx -> saved_version != chbs -> cxl_version ) {
489+ /*
490+ * cxl_version cannot be overwritten before the next two
491+ * checks, then use saved_version
492+ */
493+ ctx -> saved_version = chbs -> cxl_version ;
494+ ctx -> nr_versions ++ ;
495+ }
496+
497+ if (ctx -> base != CXL_RESOURCE_NONE )
498+ return 0 ;
499+
500+ if (ctx -> uid != chbs -> uid )
547501 return 0 ;
548502
503+ ctx -> cxl_version = chbs -> cxl_version ;
549504 ctx -> base = chbs -> base ;
550505
551506 return 0 ;
@@ -569,10 +524,19 @@ static int cxl_get_chbs(struct device *dev, struct acpi_device *hb,
569524 .uid = uid ,
570525 .base = CXL_RESOURCE_NONE ,
571526 .cxl_version = UINT_MAX ,
527+ .saved_version = UINT_MAX ,
572528 };
573529
574530 acpi_table_parse_cedt (ACPI_CEDT_TYPE_CHBS , cxl_get_chbs_iter , ctx );
575531
532+ if (ctx -> nr_versions > 1 ) {
533+ /*
534+ * Disclaim eRCD support given some component register may
535+ * only be found via CHBCR
536+ */
537+ dev_info (dev , "Unsupported platform config, mixed Virtual Host and Restricted CXL Host hierarchy." );
538+ }
539+
576540 return 0 ;
577541}
578542
@@ -958,7 +922,8 @@ static void __exit cxl_acpi_exit(void)
958922 cxl_bus_drain ();
959923}
960924
961- module_init (cxl_acpi_init );
925+ /* load before dax_hmem sees 'Soft Reserved' CXL ranges */
926+ subsys_initcall (cxl_acpi_init );
962927
963928/*
964929 * Arrange for host-bridge ports to be active synchronous with
@@ -967,6 +932,7 @@ module_init(cxl_acpi_init);
967932MODULE_SOFTDEP ("pre: cxl_port" );
968933
969934module_exit (cxl_acpi_exit );
935+ MODULE_DESCRIPTION ("CXL ACPI: Platform Support" );
970936MODULE_LICENSE ("GPL v2" );
971937MODULE_IMPORT_NS (CXL );
972938MODULE_IMPORT_NS (ACPI );
0 commit comments