@@ -703,6 +703,142 @@ static int mock_decoder_reset(struct cxl_decoder *cxld)
703703 return 0 ;
704704}
705705
706+ static void default_mock_decoder (struct cxl_decoder * cxld )
707+ {
708+ cxld -> hpa_range = (struct range ){
709+ .start = 0 ,
710+ .end = -1 ,
711+ };
712+
713+ cxld -> interleave_ways = 1 ;
714+ cxld -> interleave_granularity = 256 ;
715+ cxld -> target_type = CXL_DECODER_EXPANDER ;
716+ cxld -> commit = mock_decoder_commit ;
717+ cxld -> reset = mock_decoder_reset ;
718+ }
719+
720+ static int first_decoder (struct device * dev , void * data )
721+ {
722+ struct cxl_decoder * cxld ;
723+
724+ if (!is_switch_decoder (dev ))
725+ return 0 ;
726+ cxld = to_cxl_decoder (dev );
727+ if (cxld -> id == 0 )
728+ return 1 ;
729+ return 0 ;
730+ }
731+
732+ static void mock_init_hdm_decoder (struct cxl_decoder * cxld )
733+ {
734+ struct acpi_cedt_cfmws * window = mock_cfmws [0 ];
735+ struct platform_device * pdev = NULL ;
736+ struct cxl_endpoint_decoder * cxled ;
737+ struct cxl_switch_decoder * cxlsd ;
738+ struct cxl_port * port , * iter ;
739+ const int size = SZ_512M ;
740+ struct cxl_memdev * cxlmd ;
741+ struct cxl_dport * dport ;
742+ struct device * dev ;
743+ bool hb0 = false;
744+ u64 base ;
745+ int i ;
746+
747+ if (is_endpoint_decoder (& cxld -> dev )) {
748+ cxled = to_cxl_endpoint_decoder (& cxld -> dev );
749+ cxlmd = cxled_to_memdev (cxled );
750+ WARN_ON (!dev_is_platform (cxlmd -> dev .parent ));
751+ pdev = to_platform_device (cxlmd -> dev .parent );
752+
753+ /* check is endpoint is attach to host-bridge0 */
754+ port = cxled_to_port (cxled );
755+ do {
756+ if (port -> uport == & cxl_host_bridge [0 ]-> dev ) {
757+ hb0 = true;
758+ break ;
759+ }
760+ if (is_cxl_port (port -> dev .parent ))
761+ port = to_cxl_port (port -> dev .parent );
762+ else
763+ port = NULL ;
764+ } while (port );
765+ port = cxled_to_port (cxled );
766+ }
767+
768+ /*
769+ * The first decoder on the first 2 devices on the first switch
770+ * attached to host-bridge0 mock a fake / static RAM region. All
771+ * other decoders are default disabled. Given the round robin
772+ * assignment those devices are named cxl_mem.0, and cxl_mem.4.
773+ *
774+ * See 'cxl list -BMPu -m cxl_mem.0,cxl_mem.4'
775+ */
776+ if (!hb0 || pdev -> id % 4 || pdev -> id > 4 || cxld -> id > 0 ) {
777+ default_mock_decoder (cxld );
778+ return ;
779+ }
780+
781+ base = window -> base_hpa ;
782+ cxld -> hpa_range = (struct range ) {
783+ .start = base ,
784+ .end = base + size - 1 ,
785+ };
786+
787+ cxld -> interleave_ways = 2 ;
788+ eig_to_granularity (window -> granularity , & cxld -> interleave_granularity );
789+ cxld -> target_type = CXL_DECODER_EXPANDER ;
790+ cxld -> flags = CXL_DECODER_F_ENABLE ;
791+ cxled -> state = CXL_DECODER_STATE_AUTO ;
792+ port -> commit_end = cxld -> id ;
793+ devm_cxl_dpa_reserve (cxled , 0 , size / cxld -> interleave_ways , 0 );
794+ cxld -> commit = mock_decoder_commit ;
795+ cxld -> reset = mock_decoder_reset ;
796+
797+ /*
798+ * Now that endpoint decoder is set up, walk up the hierarchy
799+ * and setup the switch and root port decoders targeting @cxlmd.
800+ */
801+ iter = port ;
802+ for (i = 0 ; i < 2 ; i ++ ) {
803+ dport = iter -> parent_dport ;
804+ iter = dport -> port ;
805+ dev = device_find_child (& iter -> dev , NULL , first_decoder );
806+ /*
807+ * Ancestor ports are guaranteed to be enumerated before
808+ * @port, and all ports have at least one decoder.
809+ */
810+ if (WARN_ON (!dev ))
811+ continue ;
812+ cxlsd = to_cxl_switch_decoder (dev );
813+ if (i == 0 ) {
814+ /* put cxl_mem.4 second in the decode order */
815+ if (pdev -> id == 4 )
816+ cxlsd -> target [1 ] = dport ;
817+ else
818+ cxlsd -> target [0 ] = dport ;
819+ } else
820+ cxlsd -> target [0 ] = dport ;
821+ cxld = & cxlsd -> cxld ;
822+ cxld -> target_type = CXL_DECODER_EXPANDER ;
823+ cxld -> flags = CXL_DECODER_F_ENABLE ;
824+ iter -> commit_end = 0 ;
825+ /*
826+ * Switch targets 2 endpoints, while host bridge targets
827+ * one root port
828+ */
829+ if (i == 0 )
830+ cxld -> interleave_ways = 2 ;
831+ else
832+ cxld -> interleave_ways = 1 ;
833+ cxld -> interleave_granularity = 256 ;
834+ cxld -> hpa_range = (struct range ) {
835+ .start = base ,
836+ .end = base + size - 1 ,
837+ };
838+ put_device (dev );
839+ }
840+ }
841+
706842static int mock_cxl_enumerate_decoders (struct cxl_hdm * cxlhdm )
707843{
708844 struct cxl_port * port = cxlhdm -> port ;
@@ -748,16 +884,7 @@ static int mock_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm)
748884 cxld = & cxled -> cxld ;
749885 }
750886
751- cxld -> hpa_range = (struct range ) {
752- .start = 0 ,
753- .end = -1 ,
754- };
755-
756- cxld -> interleave_ways = min_not_zero (target_count , 1 );
757- cxld -> interleave_granularity = SZ_4K ;
758- cxld -> target_type = CXL_DECODER_EXPANDER ;
759- cxld -> commit = mock_decoder_commit ;
760- cxld -> reset = mock_decoder_reset ;
887+ mock_init_hdm_decoder (cxld );
761888
762889 if (target_count ) {
763890 rc = device_for_each_child (port -> uport , & ctx ,
0 commit comments