xref: /linux/tools/testing/cxl/test/cxl.c (revision 769f0b350c81ab147fff37b92637e12190f1be29)
1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright(c) 2021 Intel Corporation. All rights reserved.
3 
4 #include <linux/platform_device.h>
5 #include <linux/memory_hotplug.h>
6 #include <linux/genalloc.h>
7 #include <linux/module.h>
8 #include <linux/mutex.h>
9 #include <linux/acpi.h>
10 #include <linux/pci.h>
11 #include <linux/mm.h>
12 #include <cxlmem.h>
13 
14 #include "../watermark.h"
15 #include "mock.h"
16 
17 static int interleave_arithmetic;
18 static bool extended_linear_cache;
19 static bool fail_autoassemble;
20 
21 #define FAKE_QTG_ID	42
22 
23 #define NR_CXL_HOST_BRIDGES 2
24 #define NR_CXL_SINGLE_HOST 1
25 #define NR_CXL_RCH 1
26 #define NR_CXL_ROOT_PORTS 2
27 #define NR_CXL_SWITCH_PORTS 2
28 #define NR_CXL_PORT_DECODERS 8
29 #define NR_BRIDGES (NR_CXL_HOST_BRIDGES + NR_CXL_SINGLE_HOST + NR_CXL_RCH)
30 
31 #define MOCK_AUTO_REGION_SIZE_DEFAULT SZ_512M
32 static int mock_auto_region_size = MOCK_AUTO_REGION_SIZE_DEFAULT;
33 
34 static struct platform_device *cxl_acpi;
35 static struct platform_device *cxl_host_bridge[NR_CXL_HOST_BRIDGES];
36 #define NR_MULTI_ROOT (NR_CXL_HOST_BRIDGES * NR_CXL_ROOT_PORTS)
37 static struct platform_device *cxl_root_port[NR_MULTI_ROOT];
38 static struct platform_device *cxl_switch_uport[NR_MULTI_ROOT];
39 #define NR_MEM_MULTI \
40 	(NR_CXL_HOST_BRIDGES * NR_CXL_ROOT_PORTS * NR_CXL_SWITCH_PORTS)
41 static struct platform_device *cxl_switch_dport[NR_MEM_MULTI];
42 
43 static struct platform_device *cxl_hb_single[NR_CXL_SINGLE_HOST];
44 static struct platform_device *cxl_root_single[NR_CXL_SINGLE_HOST];
45 static struct platform_device *cxl_swu_single[NR_CXL_SINGLE_HOST];
46 #define NR_MEM_SINGLE (NR_CXL_SINGLE_HOST * NR_CXL_SWITCH_PORTS)
47 static struct platform_device *cxl_swd_single[NR_MEM_SINGLE];
48 
49 struct platform_device *cxl_mem[NR_MEM_MULTI];
50 struct platform_device *cxl_mem_single[NR_MEM_SINGLE];
51 
52 static struct platform_device *cxl_rch[NR_CXL_RCH];
53 static struct platform_device *cxl_rcd[NR_CXL_RCH];
54 
55 /*
56  * Decoder registry
57  *
58  * Record decoder programming so that the topology can be reconstructed
59  * after cxl_acpi unbind/bind. This allows a user-created region config
60  * to be replayed as if firmware had provided the region at enumeration
61  * time.
62  *
63  * Entries are keyed by a stable port identity (port->uport_dev) combined
64  * with the decoder id. Decoder state is saved at initialization and
65  * updated on commit and reset.
66  *
67  * On re-enumeration mock_init_hdm_decoder() consults this registry to
68  * restore enabled decoders. Disabled decoders are reinitialized to a
69  * clean default state rather than replaying stale programming.
70  */
71 static DEFINE_XARRAY(decoder_registry);
72 
73 /*
74  * When set, decoder reset will not update the registry. This allows
75  * region destroy operations to reset live decoders without erasing
76  * the saved programming needed for replay after re-enumeration.
77  */
78 static bool decoder_reset_preserve_registry;
79 
80 static inline bool is_multi_bridge(struct device *dev)
81 {
82 	int i;
83 
84 	for (i = 0; i < ARRAY_SIZE(cxl_host_bridge); i++)
85 		if (&cxl_host_bridge[i]->dev == dev)
86 			return true;
87 	return false;
88 }
89 
90 static inline bool is_single_bridge(struct device *dev)
91 {
92 	int i;
93 
94 	for (i = 0; i < ARRAY_SIZE(cxl_hb_single); i++)
95 		if (&cxl_hb_single[i]->dev == dev)
96 			return true;
97 	return false;
98 }
99 
100 static struct acpi_device acpi0017_mock;
101 static struct acpi_device host_bridge[NR_BRIDGES] = {
102 	[0] = {
103 		.handle = &host_bridge[0],
104 		.pnp.unique_id = "0",
105 	},
106 	[1] = {
107 		.handle = &host_bridge[1],
108 		.pnp.unique_id = "1",
109 	},
110 	[2] = {
111 		.handle = &host_bridge[2],
112 		.pnp.unique_id = "2",
113 	},
114 	[3] = {
115 		.handle = &host_bridge[3],
116 		.pnp.unique_id = "3",
117 	},
118 };
119 
120 static bool is_mock_dev(struct device *dev)
121 {
122 	int i;
123 
124 	for (i = 0; i < ARRAY_SIZE(cxl_mem); i++)
125 		if (dev == &cxl_mem[i]->dev)
126 			return true;
127 	for (i = 0; i < ARRAY_SIZE(cxl_mem_single); i++)
128 		if (dev == &cxl_mem_single[i]->dev)
129 			return true;
130 	for (i = 0; i < ARRAY_SIZE(cxl_rcd); i++)
131 		if (dev == &cxl_rcd[i]->dev)
132 			return true;
133 	if (dev == &cxl_acpi->dev)
134 		return true;
135 	return false;
136 }
137 
138 static bool is_mock_adev(struct acpi_device *adev)
139 {
140 	int i;
141 
142 	if (adev == &acpi0017_mock)
143 		return true;
144 
145 	for (i = 0; i < ARRAY_SIZE(host_bridge); i++)
146 		if (adev == &host_bridge[i])
147 			return true;
148 
149 	return false;
150 }
151 
152 static struct {
153 	struct acpi_table_cedt cedt;
154 	struct acpi_cedt_chbs chbs[NR_BRIDGES];
155 	struct {
156 		struct acpi_cedt_cfmws cfmws;
157 		u32 target[1];
158 	} cfmws0;
159 	struct {
160 		struct acpi_cedt_cfmws cfmws;
161 		u32 target[2];
162 	} cfmws1;
163 	struct {
164 		struct acpi_cedt_cfmws cfmws;
165 		u32 target[1];
166 	} cfmws2;
167 	struct {
168 		struct acpi_cedt_cfmws cfmws;
169 		u32 target[2];
170 	} cfmws3;
171 	struct {
172 		struct acpi_cedt_cfmws cfmws;
173 		u32 target[1];
174 	} cfmws4;
175 	struct {
176 		struct acpi_cedt_cfmws cfmws;
177 		u32 target[1];
178 	} cfmws5;
179 	struct {
180 		struct acpi_cedt_cfmws cfmws;
181 		u32 target[1];
182 	} cfmws6;
183 	struct {
184 		struct acpi_cedt_cfmws cfmws;
185 		u32 target[2];
186 	} cfmws7;
187 	struct {
188 		struct acpi_cedt_cfmws cfmws;
189 		u32 target[3];
190 	} cfmws8;
191 	struct {
192 		struct acpi_cedt_cxims cxims;
193 		u64 xormap_list[2];
194 	} cxims0;
195 } __packed mock_cedt = {
196 	.cedt = {
197 		.header = {
198 			.signature = "CEDT",
199 			.length = sizeof(mock_cedt),
200 			.revision = 1,
201 		},
202 	},
203 	.chbs[0] = {
204 		.header = {
205 			.type = ACPI_CEDT_TYPE_CHBS,
206 			.length = sizeof(mock_cedt.chbs[0]),
207 		},
208 		.uid = 0,
209 		.cxl_version = ACPI_CEDT_CHBS_VERSION_CXL20,
210 	},
211 	.chbs[1] = {
212 		.header = {
213 			.type = ACPI_CEDT_TYPE_CHBS,
214 			.length = sizeof(mock_cedt.chbs[0]),
215 		},
216 		.uid = 1,
217 		.cxl_version = ACPI_CEDT_CHBS_VERSION_CXL20,
218 	},
219 	.chbs[2] = {
220 		.header = {
221 			.type = ACPI_CEDT_TYPE_CHBS,
222 			.length = sizeof(mock_cedt.chbs[0]),
223 		},
224 		.uid = 2,
225 		.cxl_version = ACPI_CEDT_CHBS_VERSION_CXL20,
226 	},
227 	.chbs[3] = {
228 		.header = {
229 			.type = ACPI_CEDT_TYPE_CHBS,
230 			.length = sizeof(mock_cedt.chbs[0]),
231 		},
232 		.uid = 3,
233 		.cxl_version = ACPI_CEDT_CHBS_VERSION_CXL11,
234 	},
235 	.cfmws0 = {
236 		.cfmws = {
237 			.header = {
238 				.type = ACPI_CEDT_TYPE_CFMWS,
239 				.length = sizeof(mock_cedt.cfmws0),
240 			},
241 			.interleave_ways = 0,
242 			.granularity = 4,
243 			.restrictions = ACPI_CEDT_CFMWS_RESTRICT_HOSTONLYMEM |
244 					ACPI_CEDT_CFMWS_RESTRICT_VOLATILE,
245 			.qtg_id = FAKE_QTG_ID,
246 			.window_size = SZ_256M * 4UL,
247 		},
248 		.target = { 0 },
249 	},
250 	.cfmws1 = {
251 		.cfmws = {
252 			.header = {
253 				.type = ACPI_CEDT_TYPE_CFMWS,
254 				.length = sizeof(mock_cedt.cfmws1),
255 			},
256 			.interleave_ways = 1,
257 			.granularity = 4,
258 			.restrictions = ACPI_CEDT_CFMWS_RESTRICT_HOSTONLYMEM |
259 					ACPI_CEDT_CFMWS_RESTRICT_VOLATILE,
260 			.qtg_id = FAKE_QTG_ID,
261 			.window_size = SZ_256M * 8UL,
262 		},
263 		.target = { 0, 1, },
264 	},
265 	.cfmws2 = {
266 		.cfmws = {
267 			.header = {
268 				.type = ACPI_CEDT_TYPE_CFMWS,
269 				.length = sizeof(mock_cedt.cfmws2),
270 			},
271 			.interleave_ways = 0,
272 			.granularity = 4,
273 			.restrictions = ACPI_CEDT_CFMWS_RESTRICT_HOSTONLYMEM |
274 					ACPI_CEDT_CFMWS_RESTRICT_PMEM,
275 			.qtg_id = FAKE_QTG_ID,
276 			.window_size = SZ_256M * 4UL,
277 		},
278 		.target = { 0 },
279 	},
280 	.cfmws3 = {
281 		.cfmws = {
282 			.header = {
283 				.type = ACPI_CEDT_TYPE_CFMWS,
284 				.length = sizeof(mock_cedt.cfmws3),
285 			},
286 			.interleave_ways = 1,
287 			.granularity = 4,
288 			.restrictions = ACPI_CEDT_CFMWS_RESTRICT_HOSTONLYMEM |
289 					ACPI_CEDT_CFMWS_RESTRICT_PMEM,
290 			.qtg_id = FAKE_QTG_ID,
291 			.window_size = SZ_256M * 8UL,
292 		},
293 		.target = { 0, 1, },
294 	},
295 	.cfmws4 = {
296 		.cfmws = {
297 			.header = {
298 				.type = ACPI_CEDT_TYPE_CFMWS,
299 				.length = sizeof(mock_cedt.cfmws4),
300 			},
301 			.interleave_ways = 0,
302 			.granularity = 4,
303 			.restrictions = ACPI_CEDT_CFMWS_RESTRICT_HOSTONLYMEM |
304 					ACPI_CEDT_CFMWS_RESTRICT_PMEM,
305 			.qtg_id = FAKE_QTG_ID,
306 			.window_size = SZ_256M * 4UL,
307 		},
308 		.target = { 2 },
309 	},
310 	.cfmws5 = {
311 		.cfmws = {
312 			.header = {
313 				.type = ACPI_CEDT_TYPE_CFMWS,
314 				.length = sizeof(mock_cedt.cfmws5),
315 			},
316 			.interleave_ways = 0,
317 			.granularity = 4,
318 			.restrictions = ACPI_CEDT_CFMWS_RESTRICT_HOSTONLYMEM |
319 					ACPI_CEDT_CFMWS_RESTRICT_VOLATILE,
320 			.qtg_id = FAKE_QTG_ID,
321 			.window_size = SZ_256M > PMD_SIZE ? SZ_256M : PMD_SIZE,
322 		},
323 		.target = { 3 },
324 	},
325 	/* .cfmws6,7,8 use ACPI_CEDT_CFMWS_ARITHMETIC_XOR */
326 	.cfmws6 = {
327 		.cfmws = {
328 			.header = {
329 				.type = ACPI_CEDT_TYPE_CFMWS,
330 				.length = sizeof(mock_cedt.cfmws6),
331 			},
332 			.interleave_arithmetic = ACPI_CEDT_CFMWS_ARITHMETIC_XOR,
333 			.interleave_ways = 0,
334 			.granularity = 4,
335 			.restrictions = ACPI_CEDT_CFMWS_RESTRICT_HOSTONLYMEM |
336 					ACPI_CEDT_CFMWS_RESTRICT_PMEM,
337 			.qtg_id = FAKE_QTG_ID,
338 			.window_size = SZ_256M * 8UL,
339 		},
340 		.target = { 0, },
341 	},
342 	.cfmws7 = {
343 		.cfmws = {
344 			.header = {
345 				.type = ACPI_CEDT_TYPE_CFMWS,
346 				.length = sizeof(mock_cedt.cfmws7),
347 			},
348 			.interleave_arithmetic = ACPI_CEDT_CFMWS_ARITHMETIC_XOR,
349 			.interleave_ways = 1,
350 			.granularity = 0,
351 			.restrictions = ACPI_CEDT_CFMWS_RESTRICT_HOSTONLYMEM |
352 					ACPI_CEDT_CFMWS_RESTRICT_PMEM,
353 			.qtg_id = FAKE_QTG_ID,
354 			.window_size = SZ_256M * 8UL,
355 		},
356 		.target = { 0, 1, },
357 	},
358 	.cfmws8 = {
359 		.cfmws = {
360 			.header = {
361 				.type = ACPI_CEDT_TYPE_CFMWS,
362 				.length = sizeof(mock_cedt.cfmws8),
363 			},
364 			.interleave_arithmetic = ACPI_CEDT_CFMWS_ARITHMETIC_XOR,
365 			.interleave_ways = 8,
366 			.granularity = 1,
367 			.restrictions = ACPI_CEDT_CFMWS_RESTRICT_HOSTONLYMEM |
368 					ACPI_CEDT_CFMWS_RESTRICT_PMEM,
369 			.qtg_id = FAKE_QTG_ID,
370 			.window_size = SZ_512M * 6UL,
371 		},
372 		.target = { 0, 1, 2, },
373 	},
374 	.cxims0 = {
375 		.cxims = {
376 			.header = {
377 				.type = ACPI_CEDT_TYPE_CXIMS,
378 				.length = sizeof(mock_cedt.cxims0),
379 			},
380 			.hbig = 0,
381 			.nr_xormaps = 2,
382 		},
383 		.xormap_list = { 0x404100, 0x808200, },
384 	},
385 };
386 
387 struct acpi_cedt_cfmws *mock_cfmws[] = {
388 	[0] = &mock_cedt.cfmws0.cfmws,
389 	[1] = &mock_cedt.cfmws1.cfmws,
390 	[2] = &mock_cedt.cfmws2.cfmws,
391 	[3] = &mock_cedt.cfmws3.cfmws,
392 	[4] = &mock_cedt.cfmws4.cfmws,
393 	[5] = &mock_cedt.cfmws5.cfmws,
394 	/* Modulo Math above, XOR Math below */
395 	[6] = &mock_cedt.cfmws6.cfmws,
396 	[7] = &mock_cedt.cfmws7.cfmws,
397 	[8] = &mock_cedt.cfmws8.cfmws,
398 };
399 
400 static int cfmws_start;
401 static int cfmws_end;
402 #define CFMWS_MOD_ARRAY_START 0
403 #define CFMWS_MOD_ARRAY_END   5
404 #define CFMWS_XOR_ARRAY_START 6
405 #define CFMWS_XOR_ARRAY_END   8
406 
407 struct acpi_cedt_cxims *mock_cxims[1] = {
408 	[0] = &mock_cedt.cxims0.cxims,
409 };
410 
411 struct cxl_mock_res {
412 	struct list_head list;
413 	struct range range;
414 };
415 
416 static LIST_HEAD(mock_res);
417 static DEFINE_MUTEX(mock_res_lock);
418 static struct gen_pool *cxl_mock_pool;
419 
420 static void depopulate_all_mock_resources(void)
421 {
422 	struct cxl_mock_res *res, *_res;
423 
424 	mutex_lock(&mock_res_lock);
425 	list_for_each_entry_safe(res, _res, &mock_res, list) {
426 		gen_pool_free(cxl_mock_pool, res->range.start,
427 			      range_len(&res->range));
428 		list_del(&res->list);
429 		kfree(res);
430 	}
431 	mutex_unlock(&mock_res_lock);
432 }
433 
434 static struct cxl_mock_res *alloc_mock_res(resource_size_t size, int align)
435 {
436 	struct genpool_data_align data = {
437 		.align = align,
438 	};
439 	unsigned long phys;
440 
441 	struct cxl_mock_res *res __free(kfree) = kzalloc(sizeof(*res),
442 							 GFP_KERNEL);
443 	if (!res)
444 		return NULL;
445 
446 	INIT_LIST_HEAD(&res->list);
447 	phys = gen_pool_alloc_algo(cxl_mock_pool, size,
448 				   gen_pool_first_fit_align, &data);
449 	if (!phys)
450 		return NULL;
451 
452 	res->range = (struct range) {
453 		.start = phys,
454 		.end = phys + size - 1,
455 	};
456 	mutex_lock(&mock_res_lock);
457 	list_add(&res->list, &mock_res);
458 	mutex_unlock(&mock_res_lock);
459 
460 	return no_free_ptr(res);
461 }
462 
463 /* Only update CFMWS0 as this is used by the auto region. */
464 static void cfmws_elc_update(struct acpi_cedt_cfmws *window, int index)
465 {
466 	if (!extended_linear_cache)
467 		return;
468 
469 	if (index != 0)
470 		return;
471 
472 	/*
473 	 * The window size should be 2x of the CXL region size where half is
474 	 * DRAM and half is CXL
475 	 */
476 	window->window_size = mock_auto_region_size * 2;
477 }
478 
479 static int populate_cedt(void)
480 {
481 	struct cxl_mock_res *res;
482 	int i;
483 
484 	for (i = 0; i < ARRAY_SIZE(mock_cedt.chbs); i++) {
485 		struct acpi_cedt_chbs *chbs = &mock_cedt.chbs[i];
486 		resource_size_t size;
487 
488 		if (chbs->cxl_version == ACPI_CEDT_CHBS_VERSION_CXL20)
489 			size = ACPI_CEDT_CHBS_LENGTH_CXL20;
490 		else
491 			size = ACPI_CEDT_CHBS_LENGTH_CXL11;
492 
493 		res = alloc_mock_res(size, size);
494 		if (!res)
495 			return -ENOMEM;
496 		chbs->base = res->range.start;
497 		chbs->length = size;
498 	}
499 
500 	for (i = cfmws_start; i <= cfmws_end; i++) {
501 		struct acpi_cedt_cfmws *window = mock_cfmws[i];
502 		int align = SZ_256M;
503 
504 		cfmws_elc_update(window, i);
505 		if (window->restrictions & ACPI_CEDT_CFMWS_RESTRICT_VOLATILE)
506 			align = max_t(int, SZ_256M, PMD_SIZE);
507 		res = alloc_mock_res(window->window_size, align);
508 		if (!res)
509 			return -ENOMEM;
510 		window->base_hpa = res->range.start;
511 	}
512 
513 	return 0;
514 }
515 
516 static bool is_mock_port(struct device *dev);
517 
518 /*
519  * WARNING, this hack assumes the format of 'struct cxl_cfmws_context'
520  * and 'struct cxl_chbs_context' share the property that the first
521  * struct member is a cxl_test device being probed by the cxl_acpi
522  * driver.
523  */
524 struct cxl_cedt_context {
525 	struct device *dev;
526 };
527 
528 static int mock_acpi_table_parse_cedt(enum acpi_cedt_type id,
529 				      acpi_tbl_entry_handler_arg handler_arg,
530 				      void *arg)
531 {
532 	struct cxl_cedt_context *ctx = arg;
533 	struct device *dev = ctx->dev;
534 	union acpi_subtable_headers *h;
535 	unsigned long end;
536 	int i;
537 
538 	if (!is_mock_port(dev) && !is_mock_dev(dev))
539 		return acpi_table_parse_cedt(id, handler_arg, arg);
540 
541 	if (id == ACPI_CEDT_TYPE_CHBS)
542 		for (i = 0; i < ARRAY_SIZE(mock_cedt.chbs); i++) {
543 			h = (union acpi_subtable_headers *)&mock_cedt.chbs[i];
544 			end = (unsigned long)&mock_cedt.chbs[i + 1];
545 			handler_arg(h, arg, end);
546 		}
547 
548 	if (id == ACPI_CEDT_TYPE_CFMWS)
549 		for (i = cfmws_start; i <= cfmws_end; i++) {
550 			h = (union acpi_subtable_headers *) mock_cfmws[i];
551 			end = (unsigned long) h + mock_cfmws[i]->header.length;
552 			handler_arg(h, arg, end);
553 		}
554 
555 	if (id == ACPI_CEDT_TYPE_CXIMS)
556 		for (i = 0; i < ARRAY_SIZE(mock_cxims); i++) {
557 			h = (union acpi_subtable_headers *)mock_cxims[i];
558 			end = (unsigned long)h + mock_cxims[i]->header.length;
559 			handler_arg(h, arg, end);
560 		}
561 
562 	return 0;
563 }
564 
565 static bool is_mock_bridge(struct device *dev)
566 {
567 	int i;
568 
569 	for (i = 0; i < ARRAY_SIZE(cxl_host_bridge); i++)
570 		if (dev == &cxl_host_bridge[i]->dev)
571 			return true;
572 	for (i = 0; i < ARRAY_SIZE(cxl_hb_single); i++)
573 		if (dev == &cxl_hb_single[i]->dev)
574 			return true;
575 	for (i = 0; i < ARRAY_SIZE(cxl_rch); i++)
576 		if (dev == &cxl_rch[i]->dev)
577 			return true;
578 
579 	return false;
580 }
581 
582 static bool is_mock_port(struct device *dev)
583 {
584 	int i;
585 
586 	if (is_mock_bridge(dev))
587 		return true;
588 
589 	for (i = 0; i < ARRAY_SIZE(cxl_root_port); i++)
590 		if (dev == &cxl_root_port[i]->dev)
591 			return true;
592 
593 	for (i = 0; i < ARRAY_SIZE(cxl_switch_uport); i++)
594 		if (dev == &cxl_switch_uport[i]->dev)
595 			return true;
596 
597 	for (i = 0; i < ARRAY_SIZE(cxl_switch_dport); i++)
598 		if (dev == &cxl_switch_dport[i]->dev)
599 			return true;
600 
601 	for (i = 0; i < ARRAY_SIZE(cxl_root_single); i++)
602 		if (dev == &cxl_root_single[i]->dev)
603 			return true;
604 
605 	for (i = 0; i < ARRAY_SIZE(cxl_swu_single); i++)
606 		if (dev == &cxl_swu_single[i]->dev)
607 			return true;
608 
609 	for (i = 0; i < ARRAY_SIZE(cxl_swd_single); i++)
610 		if (dev == &cxl_swd_single[i]->dev)
611 			return true;
612 
613 	if (is_cxl_memdev(dev))
614 		return is_mock_dev(dev->parent);
615 
616 	return false;
617 }
618 
619 static int host_bridge_index(struct acpi_device *adev)
620 {
621 	return adev - host_bridge;
622 }
623 
624 static struct acpi_device *find_host_bridge(acpi_handle handle)
625 {
626 	int i;
627 
628 	for (i = 0; i < ARRAY_SIZE(host_bridge); i++)
629 		if (handle == host_bridge[i].handle)
630 			return &host_bridge[i];
631 	return NULL;
632 }
633 
634 static acpi_status
635 mock_acpi_evaluate_integer(acpi_handle handle, acpi_string pathname,
636 			   struct acpi_object_list *arguments,
637 			   unsigned long long *data)
638 {
639 	struct acpi_device *adev = find_host_bridge(handle);
640 
641 	if (!adev || strcmp(pathname, METHOD_NAME__UID) != 0)
642 		return acpi_evaluate_integer(handle, pathname, arguments, data);
643 
644 	*data = host_bridge_index(adev);
645 	return AE_OK;
646 }
647 
648 static int
649 mock_hmat_get_extended_linear_cache_size(struct resource *backing_res,
650 					 int nid, resource_size_t *cache_size)
651 {
652 	struct acpi_cedt_cfmws *window = mock_cfmws[0];
653 	struct resource cfmws0_res =
654 		DEFINE_RES_MEM(window->base_hpa, window->window_size);
655 
656 	if (!extended_linear_cache ||
657 	    !resource_contains(&cfmws0_res, backing_res)) {
658 		return hmat_get_extended_linear_cache_size(backing_res,
659 							   nid, cache_size);
660 	}
661 
662 	*cache_size = mock_auto_region_size;
663 
664 	return 0;
665 }
666 
667 static struct pci_bus mock_pci_bus[NR_BRIDGES];
668 static struct acpi_pci_root mock_pci_root[ARRAY_SIZE(mock_pci_bus)] = {
669 	[0] = {
670 		.bus = &mock_pci_bus[0],
671 	},
672 	[1] = {
673 		.bus = &mock_pci_bus[1],
674 	},
675 	[2] = {
676 		.bus = &mock_pci_bus[2],
677 	},
678 	[3] = {
679 		.bus = &mock_pci_bus[3],
680 	},
681 
682 };
683 
684 static bool is_mock_bus(struct pci_bus *bus)
685 {
686 	int i;
687 
688 	for (i = 0; i < ARRAY_SIZE(mock_pci_bus); i++)
689 		if (bus == &mock_pci_bus[i])
690 			return true;
691 	return false;
692 }
693 
694 static struct acpi_pci_root *mock_acpi_pci_find_root(acpi_handle handle)
695 {
696 	struct acpi_device *adev = find_host_bridge(handle);
697 
698 	if (!adev)
699 		return acpi_pci_find_root(handle);
700 	return &mock_pci_root[host_bridge_index(adev)];
701 }
702 
703 static struct cxl_hdm *mock_cxl_setup_hdm(struct cxl_port *port,
704 					  struct cxl_endpoint_dvsec_info *info)
705 {
706 	struct cxl_hdm *cxlhdm = devm_kzalloc(&port->dev, sizeof(*cxlhdm), GFP_KERNEL);
707 	struct device *dev = &port->dev;
708 
709 	if (!cxlhdm)
710 		return ERR_PTR(-ENOMEM);
711 
712 	cxlhdm->port = port;
713 	cxlhdm->interleave_mask = ~0U;
714 	cxlhdm->iw_cap_mask = ~0UL;
715 	dev_set_drvdata(dev, cxlhdm);
716 	return cxlhdm;
717 }
718 
719 struct target_map_ctx {
720 	u32 *target_map;
721 	int index;
722 	int target_count;
723 };
724 
725 static int map_targets(struct device *dev, void *data)
726 {
727 	struct platform_device *pdev = to_platform_device(dev);
728 	struct target_map_ctx *ctx = data;
729 
730 	ctx->target_map[ctx->index++] = pdev->id;
731 
732 	if (ctx->index > ctx->target_count) {
733 		dev_WARN_ONCE(dev, 1, "too many targets found?\n");
734 		return -ENXIO;
735 	}
736 
737 	return 0;
738 }
739 
740 /*
741  * Build a stable registry key from the decoder's upstream port identity
742  * and decoder id.
743  *
744  * Decoder objects and cxl_port objects are reallocated on each enumeration,
745  * so their addresses cannot be used directly as replay keys. However,
746  * port->uport_dev is stable for a given topology across cxl_acpi unbind/bind
747  * in cxl_test, so use that as the port identity and pack the local decoder
748  * id into the low bits.
749  *
750  * The key is formed as:
751  *     ((unsigned long)port->uport_dev << 4) | cxld->id
752  *
753  * The low bits hold the decoder id (which must fit in 4 bits) while
754  * the remaining bits identify the upstream port. This key is only used
755  * within cxl_test to locate saved decoder state during replay.
756  */
757 static unsigned long cxld_registry_index(struct cxl_decoder *cxld)
758 {
759 	struct cxl_port *port = to_cxl_port(cxld->dev.parent);
760 
761 	dev_WARN_ONCE(&port->dev, cxld->id >= 16,
762 		      "decoder id:%d out of range\n", cxld->id);
763 	return (((unsigned long)port->uport_dev) << 4) | cxld->id;
764 }
765 
766 struct cxl_test_decoder {
767 	union {
768 		struct cxl_switch_decoder cxlsd;
769 		struct cxl_endpoint_decoder cxled;
770 	};
771 	struct range dpa_range;
772 };
773 
774 static struct cxl_test_decoder *cxld_registry_find(struct cxl_decoder *cxld)
775 {
776 	return xa_load(&decoder_registry, cxld_registry_index(cxld));
777 }
778 
779 #define dbg_cxld(port, msg, cxld)                                                       \
780 	do {                                                                            \
781 		struct cxl_decoder *___d = (cxld);                                      \
782 		dev_dbg((port)->uport_dev,                                              \
783 			"decoder%d: %s range: %#llx-%#llx iw: %d ig: %d flags: %#lx\n", \
784 			___d->id, msg, ___d->hpa_range.start,                           \
785 			___d->hpa_range.end + 1, ___d->interleave_ways,                 \
786 			___d->interleave_granularity, ___d->flags);                     \
787 	} while (0)
788 
789 static int mock_decoder_commit(struct cxl_decoder *cxld);
790 static void mock_decoder_reset(struct cxl_decoder *cxld);
791 static void init_disabled_mock_decoder(struct cxl_decoder *cxld);
792 
793 static void cxld_copy(struct cxl_decoder *a, struct cxl_decoder *b)
794 {
795 	a->id = b->id;
796 	a->hpa_range = b->hpa_range;
797 	a->interleave_ways = b->interleave_ways;
798 	a->interleave_granularity = b->interleave_granularity;
799 	a->target_type = b->target_type;
800 	a->flags = b->flags;
801 	a->commit = mock_decoder_commit;
802 	a->reset = mock_decoder_reset;
803 }
804 
805 /*
806  * Restore decoder programming saved in the registry.
807  *
808  * Only decoders that were saved enabled are restored. Disabled decoders
809  * are left in their default inactive state so that stale programming is
810  * not resurrected after topology replay.
811  *
812  * For endpoint decoders this also restores the DPA reservation needed
813  * to reconstruct committed mappings.
814  */
815 static int cxld_registry_restore(struct cxl_decoder *cxld,
816 				 struct cxl_test_decoder *td)
817 {
818 	struct cxl_port *port = to_cxl_port(cxld->dev.parent);
819 	int rc;
820 
821 	if (is_switch_decoder(&cxld->dev)) {
822 		struct cxl_switch_decoder *cxlsd =
823 			to_cxl_switch_decoder(&cxld->dev);
824 
825 		if (!(td->cxlsd.cxld.flags & CXL_DECODER_F_ENABLE))
826 			return 0;
827 
828 		dbg_cxld(port, "restore", &td->cxlsd.cxld);
829 		cxld_copy(cxld, &td->cxlsd.cxld);
830 		WARN_ON(cxlsd->nr_targets != td->cxlsd.nr_targets);
831 
832 		/* Restore saved target intent; live dport binding happens later */
833 		for (int i = 0; i < cxlsd->nr_targets; i++) {
834 			cxlsd->target[i] = NULL;
835 			cxld->target_map[i] = td->cxlsd.cxld.target_map[i];
836 		}
837 
838 		port->commit_end = cxld->id;
839 
840 	} else {
841 		struct cxl_endpoint_decoder *cxled =
842 			to_cxl_endpoint_decoder(&cxld->dev);
843 
844 		if (!(td->cxled.cxld.flags & CXL_DECODER_F_ENABLE))
845 			return 0;
846 
847 		dbg_cxld(port, "restore", &td->cxled.cxld);
848 		cxld_copy(cxld, &td->cxled.cxld);
849 		cxled->state = td->cxled.state;
850 		cxled->skip = td->cxled.skip;
851 		if (range_len(&td->dpa_range)) {
852 			rc = devm_cxl_dpa_reserve(cxled, td->dpa_range.start,
853 						  range_len(&td->dpa_range),
854 						  td->cxled.skip);
855 			if (rc) {
856 				init_disabled_mock_decoder(cxld);
857 				return rc;
858 			}
859 		}
860 		port->commit_end = cxld->id;
861 	}
862 
863 	return 0;
864 }
865 
866 static void __cxld_registry_save(struct cxl_test_decoder *td,
867 				 struct cxl_decoder *cxld)
868 {
869 	if (is_switch_decoder(&cxld->dev)) {
870 		struct cxl_switch_decoder *cxlsd =
871 			to_cxl_switch_decoder(&cxld->dev);
872 
873 		cxld_copy(&td->cxlsd.cxld, cxld);
874 		td->cxlsd.nr_targets = cxlsd->nr_targets;
875 
876 		/* Save target port_id as a stable identify for the dport */
877 		for (int i = 0; i < cxlsd->nr_targets; i++) {
878 			struct cxl_dport *dport;
879 
880 			if (!cxlsd->target[i])
881 				continue;
882 
883 			dport = cxlsd->target[i];
884 			td->cxlsd.cxld.target_map[i] = dport->port_id;
885 		}
886 	} else {
887 		struct cxl_endpoint_decoder *cxled =
888 			to_cxl_endpoint_decoder(&cxld->dev);
889 
890 		cxld_copy(&td->cxled.cxld, cxld);
891 		td->cxled.state = cxled->state;
892 		td->cxled.skip = cxled->skip;
893 
894 		if (!(cxld->flags & CXL_DECODER_F_ENABLE)) {
895 			td->dpa_range.start = 0;
896 			td->dpa_range.end = -1;
897 		} else if (cxled->dpa_res) {
898 			td->dpa_range.start = cxled->dpa_res->start;
899 			td->dpa_range.end = cxled->dpa_res->end;
900 		} else {
901 			td->dpa_range.start = 0;
902 			td->dpa_range.end = -1;
903 		}
904 	}
905 }
906 
907 static void cxld_registry_save(struct cxl_test_decoder *td,
908 			       struct cxl_decoder *cxld)
909 {
910 	struct cxl_port *port = to_cxl_port(cxld->dev.parent);
911 
912 	dbg_cxld(port, "save", cxld);
913 	__cxld_registry_save(td, cxld);
914 }
915 
916 static void cxld_registry_update(struct cxl_decoder *cxld)
917 {
918 	struct cxl_test_decoder *td = cxld_registry_find(cxld);
919 	struct cxl_port *port = to_cxl_port(cxld->dev.parent);
920 
921 	if (WARN_ON_ONCE(!td))
922 		return;
923 
924 	dbg_cxld(port, "update", cxld);
925 	__cxld_registry_save(td, cxld);
926 }
927 
928 static int mock_decoder_commit(struct cxl_decoder *cxld)
929 {
930 	struct cxl_port *port = to_cxl_port(cxld->dev.parent);
931 	int id = cxld->id;
932 
933 	if (cxld->flags & CXL_DECODER_F_ENABLE)
934 		return 0;
935 
936 	dev_dbg(&port->dev, "%s commit\n", dev_name(&cxld->dev));
937 	if (cxl_num_decoders_committed(port) != id) {
938 		dev_dbg(&port->dev,
939 			"%s: out of order commit, expected decoder%d.%d\n",
940 			dev_name(&cxld->dev), port->id,
941 			cxl_num_decoders_committed(port));
942 		return -EBUSY;
943 	}
944 
945 	port->commit_end++;
946 	cxld->flags |= CXL_DECODER_F_ENABLE;
947 	if (is_endpoint_decoder(&cxld->dev)) {
948 		struct cxl_endpoint_decoder *cxled =
949 			to_cxl_endpoint_decoder(&cxld->dev);
950 
951 		cxled->state = CXL_DECODER_STATE_AUTO;
952 	}
953 	cxld_registry_update(cxld);
954 
955 	return 0;
956 }
957 
958 static void mock_decoder_reset(struct cxl_decoder *cxld)
959 {
960 	struct cxl_port *port = to_cxl_port(cxld->dev.parent);
961 	int id = cxld->id;
962 
963 	if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)
964 		return;
965 
966 	dev_dbg(&port->dev, "%s reset\n", dev_name(&cxld->dev));
967 	if (port->commit_end == id)
968 		cxl_port_commit_reap(cxld);
969 	else
970 		dev_dbg(&port->dev,
971 			"%s: out of order reset, expected decoder%d.%d\n",
972 			dev_name(&cxld->dev), port->id, port->commit_end);
973 	cxld->flags &= ~CXL_DECODER_F_ENABLE;
974 
975 	if (is_endpoint_decoder(&cxld->dev)) {
976 		struct cxl_endpoint_decoder *cxled =
977 			to_cxl_endpoint_decoder(&cxld->dev);
978 
979 		cxled->state = CXL_DECODER_STATE_MANUAL;
980 		cxled->skip = 0;
981 	}
982 	if (decoder_reset_preserve_registry)
983 		dev_dbg(port->uport_dev, "decoder%d: skip registry update\n",
984 			cxld->id);
985 	else
986 		cxld_registry_update(cxld);
987 }
988 
989 static struct cxl_test_decoder *cxld_registry_new(struct cxl_decoder *cxld)
990 {
991 	struct cxl_test_decoder *td __free(kfree) =
992 		kzalloc(sizeof(*td), GFP_KERNEL);
993 	unsigned long key = cxld_registry_index(cxld);
994 
995 	if (!td)
996 		return NULL;
997 
998 	if (xa_insert(&decoder_registry, key, td, GFP_KERNEL)) {
999 		WARN_ON(1);
1000 		return NULL;
1001 	}
1002 
1003 	cxld_registry_save(td, cxld);
1004 	return no_free_ptr(td);
1005 }
1006 
1007 static void init_disabled_mock_decoder(struct cxl_decoder *cxld)
1008 {
1009 	cxld->hpa_range.start = 0;
1010 	cxld->hpa_range.end = -1;
1011 	cxld->interleave_ways = 1;
1012 	cxld->interleave_granularity = 0;
1013 	cxld->target_type = CXL_DECODER_HOSTONLYMEM;
1014 	cxld->flags = 0;
1015 	cxld->commit = mock_decoder_commit;
1016 	cxld->reset = mock_decoder_reset;
1017 
1018 	if (is_switch_decoder(&cxld->dev)) {
1019 		struct cxl_switch_decoder *cxlsd =
1020 			to_cxl_switch_decoder(&cxld->dev);
1021 
1022 		for (int i = 0; i < cxlsd->nr_targets; i++) {
1023 			cxlsd->target[i] = NULL;
1024 			cxld->target_map[i] = 0;
1025 		}
1026 	} else {
1027 		struct cxl_endpoint_decoder *cxled =
1028 			to_cxl_endpoint_decoder(&cxld->dev);
1029 
1030 		cxled->state = CXL_DECODER_STATE_MANUAL;
1031 		cxled->skip = 0;
1032 	}
1033 }
1034 
1035 static void default_mock_decoder(struct cxl_decoder *cxld)
1036 {
1037 	cxld->hpa_range = (struct range){
1038 		.start = 0,
1039 		.end = -1,
1040 	};
1041 
1042 	cxld->interleave_ways = 1;
1043 	cxld->interleave_granularity = 256;
1044 	cxld->target_type = CXL_DECODER_HOSTONLYMEM;
1045 	cxld->commit = mock_decoder_commit;
1046 	cxld->reset = mock_decoder_reset;
1047 
1048 	WARN_ON_ONCE(!cxld_registry_new(cxld));
1049 }
1050 
1051 static int first_decoder(struct device *dev, const void *data)
1052 {
1053 	struct cxl_decoder *cxld;
1054 
1055 	if (!is_switch_decoder(dev))
1056 		return 0;
1057 	cxld = to_cxl_decoder(dev);
1058 	if (cxld->id == 0)
1059 		return 1;
1060 	return 0;
1061 }
1062 
1063 /*
1064  * Initialize a decoder during HDM enumeration.
1065  *
1066  * If a saved registry entry exists:
1067  *   - enabled decoders are restored from the saved programming
1068  *   - disabled decoders are initialized in a clean disabled state
1069  *
1070  * If no registry entry exists the decoder follows the normal mock
1071  * initialization path, including the special auto-region setup for
1072  * the first endpoints under host-bridge0.
1073  *
1074  * Returns true if decoder state was restored from the registry. In
1075  * that case the saved decode configuration (including target mapping)
1076  * has already been applied and the map_targets() is skipped.
1077  */
1078 static bool mock_init_hdm_decoder(struct cxl_decoder *cxld)
1079 {
1080 	struct acpi_cedt_cfmws *window = mock_cfmws[0];
1081 	struct platform_device *pdev = NULL;
1082 	struct cxl_endpoint_decoder *cxled;
1083 	struct cxl_switch_decoder *cxlsd;
1084 	struct cxl_port *port, *iter;
1085 	struct cxl_test_decoder *td;
1086 	struct cxl_memdev *cxlmd;
1087 	struct cxl_dport *dport;
1088 	struct device *dev;
1089 	bool hb0 = false;
1090 	u64 base;
1091 	int i;
1092 
1093 	if (is_endpoint_decoder(&cxld->dev)) {
1094 		cxled = to_cxl_endpoint_decoder(&cxld->dev);
1095 		cxlmd = cxled_to_memdev(cxled);
1096 		WARN_ON(!dev_is_platform(cxlmd->dev.parent));
1097 		pdev = to_platform_device(cxlmd->dev.parent);
1098 
1099 		/* check is endpoint is attach to host-bridge0 */
1100 		port = cxled_to_port(cxled);
1101 		do {
1102 			if (port->uport_dev == &cxl_host_bridge[0]->dev) {
1103 				hb0 = true;
1104 				break;
1105 			}
1106 			if (is_cxl_port(port->dev.parent))
1107 				port = to_cxl_port(port->dev.parent);
1108 			else
1109 				port = NULL;
1110 		} while (port);
1111 		port = cxled_to_port(cxled);
1112 	} else {
1113 		port = to_cxl_port(cxld->dev.parent);
1114 	}
1115 
1116 	td = cxld_registry_find(cxld);
1117 	if (td) {
1118 		bool enabled;
1119 
1120 		if (is_switch_decoder(&cxld->dev))
1121 			enabled = td->cxlsd.cxld.flags & CXL_DECODER_F_ENABLE;
1122 		else
1123 			enabled = td->cxled.cxld.flags & CXL_DECODER_F_ENABLE;
1124 
1125 		if (enabled)
1126 			return !cxld_registry_restore(cxld, td);
1127 
1128 		init_disabled_mock_decoder(cxld);
1129 		return false;
1130 	}
1131 
1132 	/*
1133 	 * The first decoder on the first 2 devices on the first switch
1134 	 * attached to host-bridge0 mock a fake / static RAM region. All
1135 	 * other decoders are default disabled. Given the round robin
1136 	 * assignment those devices are named cxl_mem.0, and cxl_mem.4.
1137 	 *
1138 	 * See 'cxl list -BMPu -m cxl_mem.0,cxl_mem.4'
1139 	 */
1140 	if (!is_endpoint_decoder(&cxld->dev) || !hb0 || pdev->id % 4 ||
1141 	    pdev->id > 4 || cxld->id > 0) {
1142 		default_mock_decoder(cxld);
1143 		return false;
1144 	}
1145 
1146 	/* Simulate missing cxl_mem.4 configuration */
1147 	if (hb0 && pdev->id == 4 && cxld->id == 0 && fail_autoassemble) {
1148 		default_mock_decoder(cxld);
1149 		return false;
1150 	}
1151 
1152 	base = window->base_hpa;
1153 	if (extended_linear_cache)
1154 		base += mock_auto_region_size;
1155 	cxld->hpa_range = (struct range) {
1156 		.start = base,
1157 		.end = base + mock_auto_region_size - 1,
1158 	};
1159 
1160 	cxld->interleave_ways = 2;
1161 	eig_to_granularity(window->granularity, &cxld->interleave_granularity);
1162 	cxld->target_type = CXL_DECODER_HOSTONLYMEM;
1163 	cxld->flags = CXL_DECODER_F_ENABLE;
1164 	cxled->state = CXL_DECODER_STATE_AUTO;
1165 	port->commit_end = cxld->id;
1166 	devm_cxl_dpa_reserve(cxled, 0,
1167 			     mock_auto_region_size / cxld->interleave_ways, 0);
1168 	cxld->commit = mock_decoder_commit;
1169 	cxld->reset = mock_decoder_reset;
1170 
1171 	WARN_ON_ONCE(!cxld_registry_new(cxld));
1172 	/*
1173 	 * Now that endpoint decoder is set up, walk up the hierarchy
1174 	 * and setup the switch and root port decoders targeting @cxlmd.
1175 	 */
1176 	iter = port;
1177 	for (i = 0; i < 2; i++) {
1178 		dport = iter->parent_dport;
1179 		iter = dport->port;
1180 		dev = device_find_child(&iter->dev, NULL, first_decoder);
1181 		/*
1182 		 * Ancestor ports are guaranteed to be enumerated before
1183 		 * @port, and all ports have at least one decoder.
1184 		 */
1185 		if (WARN_ON(!dev))
1186 			continue;
1187 
1188 		cxlsd = to_cxl_switch_decoder(dev);
1189 		if (i == 0) {
1190 			/* put cxl_mem.4 second in the decode order */
1191 			if (pdev->id == 4)
1192 				cxlsd->cxld.target_map[1] = dport->port_id;
1193 			else
1194 				cxlsd->cxld.target_map[0] = dport->port_id;
1195 		} else {
1196 			cxlsd->cxld.target_map[0] = dport->port_id;
1197 		}
1198 		cxld = &cxlsd->cxld;
1199 		cxld->target_type = CXL_DECODER_HOSTONLYMEM;
1200 		cxld->flags = CXL_DECODER_F_ENABLE;
1201 		iter->commit_end = 0;
1202 		/*
1203 		 * Switch targets 2 endpoints, while host bridge targets
1204 		 * one root port
1205 		 */
1206 		if (i == 0)
1207 			cxld->interleave_ways = 2;
1208 		else
1209 			cxld->interleave_ways = 1;
1210 		cxld->interleave_granularity = 4096;
1211 		cxld->hpa_range = (struct range) {
1212 			.start = base,
1213 			.end = base + mock_auto_region_size - 1,
1214 		};
1215 		cxld->commit = mock_decoder_commit;
1216 		cxld->reset = mock_decoder_reset;
1217 
1218 		/*
1219 		 * Only target_map[] is programmed above, mimicking
1220 		 * firmware. On real hardware target[] is populated as
1221 		 * dports enumerate, via update_decoder_targets(). The
1222 		 * mock's dports are already bound by now, so fire that
1223 		 * resolution explicitly here rather than stamping
1224 		 * target[] directly.
1225 		 */
1226 		cxl_port_update_decoder_targets(iter, dport);
1227 
1228 		cxld_registry_update(cxld);
1229 		put_device(dev);
1230 	}
1231 
1232 	return false;
1233 }
1234 
1235 static int mock_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,
1236 				       struct cxl_endpoint_dvsec_info *info)
1237 {
1238 	struct cxl_port *port = cxlhdm->port;
1239 	struct cxl_port *parent_port = to_cxl_port(port->dev.parent);
1240 	int target_count, i;
1241 	bool restored;
1242 
1243 	if (is_cxl_endpoint(port))
1244 		target_count = 0;
1245 	else if (is_cxl_root(parent_port))
1246 		target_count = NR_CXL_ROOT_PORTS;
1247 	else
1248 		target_count = NR_CXL_SWITCH_PORTS;
1249 
1250 	for (i = 0; i < NR_CXL_PORT_DECODERS; i++) {
1251 		struct target_map_ctx ctx = {
1252 			.target_count = target_count,
1253 		};
1254 		struct cxl_decoder *cxld;
1255 		int rc;
1256 
1257 		if (target_count) {
1258 			struct cxl_switch_decoder *cxlsd;
1259 
1260 			cxlsd = cxl_switch_decoder_alloc(port, target_count);
1261 			if (IS_ERR(cxlsd)) {
1262 				dev_warn(&port->dev,
1263 					 "Failed to allocate the decoder\n");
1264 				return PTR_ERR(cxlsd);
1265 			}
1266 			cxld = &cxlsd->cxld;
1267 		} else {
1268 			struct cxl_endpoint_decoder *cxled;
1269 
1270 			cxled = cxl_endpoint_decoder_alloc(port);
1271 
1272 			if (IS_ERR(cxled)) {
1273 				dev_warn(&port->dev,
1274 					 "Failed to allocate the decoder\n");
1275 				return PTR_ERR(cxled);
1276 			}
1277 			cxld = &cxled->cxld;
1278 		}
1279 
1280 		ctx.target_map = cxld->target_map;
1281 		restored = mock_init_hdm_decoder(cxld);
1282 		if (target_count && !restored) {
1283 			rc = device_for_each_child(port->uport_dev, &ctx,
1284 						   map_targets);
1285 			if (rc) {
1286 				put_device(&cxld->dev);
1287 				return rc;
1288 			}
1289 		}
1290 
1291 		rc = cxl_decoder_add_locked(cxld);
1292 		if (rc) {
1293 			put_device(&cxld->dev);
1294 			dev_err(&port->dev, "Failed to add decoder\n");
1295 			return rc;
1296 		}
1297 
1298 		rc = cxl_decoder_autoremove(&port->dev, cxld);
1299 		if (rc)
1300 			return rc;
1301 		dev_dbg(&cxld->dev, "Added to port %s\n", dev_name(&port->dev));
1302 	}
1303 
1304 	return 0;
1305 }
1306 
1307 static int __mock_cxl_decoders_setup(struct cxl_port *port)
1308 {
1309 	struct cxl_hdm *cxlhdm;
1310 
1311 	cxlhdm = mock_cxl_setup_hdm(port, NULL);
1312 	if (IS_ERR(cxlhdm)) {
1313 		if (PTR_ERR(cxlhdm) != -ENODEV)
1314 			dev_err(&port->dev, "Failed to map HDM decoder capability\n");
1315 		return PTR_ERR(cxlhdm);
1316 	}
1317 
1318 	return mock_cxl_enumerate_decoders(cxlhdm, NULL);
1319 }
1320 
1321 static int mock_cxl_switch_port_decoders_setup(struct cxl_port *port)
1322 {
1323 	if (is_cxl_root(port) || is_cxl_endpoint(port))
1324 		return -EOPNOTSUPP;
1325 
1326 	return __mock_cxl_decoders_setup(port);
1327 }
1328 
1329 static int mock_cxl_endpoint_decoders_setup(struct cxl_port *port)
1330 {
1331 	if (!is_cxl_endpoint(port))
1332 		return -EOPNOTSUPP;
1333 
1334 	return __mock_cxl_decoders_setup(port);
1335 }
1336 
1337 static int get_port_array(struct cxl_port *port,
1338 			  struct platform_device ***port_array,
1339 			  int *port_array_size)
1340 {
1341 	struct platform_device **array;
1342 	int array_size;
1343 
1344 	if (port->depth == 1) {
1345 		if (is_multi_bridge(port->uport_dev)) {
1346 			array_size = ARRAY_SIZE(cxl_root_port);
1347 			array = cxl_root_port;
1348 		} else if (is_single_bridge(port->uport_dev)) {
1349 			array_size = ARRAY_SIZE(cxl_root_single);
1350 			array = cxl_root_single;
1351 		} else {
1352 			dev_dbg(&port->dev, "%s: unknown bridge type\n",
1353 				dev_name(port->uport_dev));
1354 			return -ENXIO;
1355 		}
1356 	} else if (port->depth == 2) {
1357 		struct cxl_port *parent = to_cxl_port(port->dev.parent);
1358 
1359 		if (is_multi_bridge(parent->uport_dev)) {
1360 			array_size = ARRAY_SIZE(cxl_switch_dport);
1361 			array = cxl_switch_dport;
1362 		} else if (is_single_bridge(parent->uport_dev)) {
1363 			array_size = ARRAY_SIZE(cxl_swd_single);
1364 			array = cxl_swd_single;
1365 		} else {
1366 			dev_dbg(&port->dev, "%s: unknown bridge type\n",
1367 				dev_name(port->uport_dev));
1368 			return -ENXIO;
1369 		}
1370 	} else {
1371 		dev_WARN_ONCE(&port->dev, 1, "unexpected depth %d\n",
1372 			      port->depth);
1373 		return -ENXIO;
1374 	}
1375 
1376 	*port_array = array;
1377 	*port_array_size = array_size;
1378 
1379 	return 0;
1380 }
1381 
1382 static struct cxl_dport *mock_cxl_add_dport_by_dev(struct cxl_port *port,
1383 						   struct device *dport_dev)
1384 {
1385 	struct platform_device **array;
1386 	int rc, i, array_size;
1387 
1388 	rc = get_port_array(port, &array, &array_size);
1389 	if (rc)
1390 		return ERR_PTR(rc);
1391 
1392 	for (i = 0; i < array_size; i++) {
1393 		struct platform_device *pdev = array[i];
1394 
1395 		if (pdev->dev.parent != port->uport_dev) {
1396 			dev_dbg(&port->dev, "%s: mismatch parent %s\n",
1397 				dev_name(port->uport_dev),
1398 				dev_name(pdev->dev.parent));
1399 			continue;
1400 		}
1401 
1402 		if (&pdev->dev != dport_dev)
1403 			continue;
1404 
1405 		return devm_cxl_add_dport(port, &pdev->dev, pdev->id,
1406 					  CXL_RESOURCE_NONE);
1407 	}
1408 
1409 	return ERR_PTR(-ENODEV);
1410 }
1411 
1412 /*
1413  * Faking the cxl_dpa_perf for the memdev when appropriate.
1414  */
1415 static void dpa_perf_setup(struct cxl_port *endpoint, struct range *range,
1416 			   struct cxl_dpa_perf *dpa_perf)
1417 {
1418 	dpa_perf->qos_class = FAKE_QTG_ID;
1419 	dpa_perf->dpa_range = *range;
1420 	for (int i = 0; i < ACCESS_COORDINATE_MAX; i++) {
1421 		dpa_perf->coord[i].read_latency = 500;
1422 		dpa_perf->coord[i].write_latency = 500;
1423 		dpa_perf->coord[i].read_bandwidth = 1000;
1424 		dpa_perf->coord[i].write_bandwidth = 1000;
1425 	}
1426 }
1427 
1428 static void mock_cxl_endpoint_parse_cdat(struct cxl_port *port)
1429 {
1430 	struct cxl_root *cxl_root __free(put_cxl_root) =
1431 		find_cxl_root(port);
1432 	struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport_dev);
1433 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
1434 	struct access_coordinate ep_c[ACCESS_COORDINATE_MAX];
1435 
1436 	if (!cxl_root)
1437 		return;
1438 
1439 	for (int i = 0; i < cxlds->nr_partitions; i++) {
1440 		struct resource *res = &cxlds->part[i].res;
1441 		struct cxl_dpa_perf *perf = &cxlds->part[i].perf;
1442 		struct range range = {
1443 			.start = res->start,
1444 			.end = res->end,
1445 		};
1446 
1447 		dpa_perf_setup(port, &range, perf);
1448 	}
1449 
1450 	cxl_memdev_update_perf(cxlmd);
1451 
1452 	/*
1453 	 * This function is here to only test the topology iterator. It serves
1454 	 * no other purpose.
1455 	 */
1456 	cxl_endpoint_get_perf_coordinates(port, ep_c);
1457 }
1458 
1459 /*
1460  * Simulate that the first half of mock CXL Window 0 is "Soft Reserve" capacity
1461  */
1462 static int mock_walk_hmem_resources(struct device *host, walk_hmem_fn fn)
1463 {
1464 	struct acpi_cedt_cfmws *cfmws = mock_cfmws[0];
1465 	struct resource window =
1466 		DEFINE_RES_MEM(cfmws->base_hpa, cfmws->window_size / 2);
1467 
1468 	dev_dbg(host, "walk cxl_test resource: %pr\n", &window);
1469 	return fn(host, 0, &window);
1470 }
1471 
1472 /*
1473  * This should only be called by the dax_hmem case, treat mismatches (negative
1474  * result) as "fallback to base region_intersects()". Simulate that the first
1475  * half of mock CXL Window 0 is IORES_DESC_CXL capacity.
1476  */
1477 static int mock_region_intersects(resource_size_t start, size_t size,
1478 				  unsigned long flags, unsigned long desc)
1479 {
1480 	struct resource res = DEFINE_RES_MEM(start, size);
1481 	struct acpi_cedt_cfmws *cfmws = mock_cfmws[0];
1482 	struct resource window =
1483 		DEFINE_RES_MEM(cfmws->base_hpa, cfmws->window_size / 2);
1484 
1485 	if (resource_overlaps(&res, &window))
1486 		return REGION_INTERSECTS;
1487 	pr_debug("warning: no cxl_test CXL intersection for %pr\n", &res);
1488 	return -1;
1489 }
1490 
1491 
1492 static int
1493 mock_region_intersects_soft_reserve(resource_size_t start, size_t size)
1494 {
1495 	struct resource res = DEFINE_RES_MEM(start, size);
1496 	struct acpi_cedt_cfmws *cfmws = mock_cfmws[0];
1497 	struct resource window =
1498 		DEFINE_RES_MEM(cfmws->base_hpa, cfmws->window_size / 2);
1499 
1500 	if (resource_overlaps(&res, &window))
1501 		return REGION_INTERSECTS;
1502 	pr_debug("warning: no cxl_test soft reserve intersection for %pr\n", &res);
1503 	return -1;
1504 }
1505 
1506 static struct cxl_mock_ops cxl_mock_ops = {
1507 	.is_mock_adev = is_mock_adev,
1508 	.is_mock_bridge = is_mock_bridge,
1509 	.is_mock_bus = is_mock_bus,
1510 	.is_mock_port = is_mock_port,
1511 	.is_mock_dev = is_mock_dev,
1512 	.acpi_table_parse_cedt = mock_acpi_table_parse_cedt,
1513 	.acpi_evaluate_integer = mock_acpi_evaluate_integer,
1514 	.acpi_pci_find_root = mock_acpi_pci_find_root,
1515 	.devm_cxl_switch_port_decoders_setup = mock_cxl_switch_port_decoders_setup,
1516 	.devm_cxl_endpoint_decoders_setup = mock_cxl_endpoint_decoders_setup,
1517 	.cxl_endpoint_parse_cdat = mock_cxl_endpoint_parse_cdat,
1518 	.devm_cxl_add_dport_by_dev = mock_cxl_add_dport_by_dev,
1519 	.hmat_get_extended_linear_cache_size =
1520 		mock_hmat_get_extended_linear_cache_size,
1521 	.walk_hmem_resources = mock_walk_hmem_resources,
1522 	.region_intersects = mock_region_intersects,
1523 	.region_intersects_soft_reserve = mock_region_intersects_soft_reserve,
1524 	.list = LIST_HEAD_INIT(cxl_mock_ops.list),
1525 };
1526 
1527 static void mock_companion(struct acpi_device *adev, struct device *dev)
1528 {
1529 	device_initialize(&adev->dev);
1530 	fwnode_init(&adev->fwnode, NULL);
1531 	dev->fwnode = &adev->fwnode;
1532 	adev->fwnode.dev = dev;
1533 }
1534 
1535 #ifndef SZ_64G
1536 #define SZ_64G (SZ_32G * 2)
1537 #endif
1538 
1539 static int cxl_mock_platform_device_add(struct platform_device *pdev,
1540 					struct platform_device **ppdev)
1541 {
1542 	int rc;
1543 
1544 	if (ppdev)
1545 		*ppdev = pdev;
1546 	rc = platform_device_add(pdev);
1547 	if (rc) {
1548 		platform_device_put(pdev);
1549 		if (ppdev)
1550 			*ppdev = NULL;
1551 	}
1552 
1553 	return rc;
1554 }
1555 
1556 static __init int cxl_rch_topo_init(void)
1557 {
1558 	int rc, i;
1559 
1560 	for (i = 0; i < ARRAY_SIZE(cxl_rch); i++) {
1561 		int idx = NR_CXL_HOST_BRIDGES + NR_CXL_SINGLE_HOST + i;
1562 		struct acpi_device *adev = &host_bridge[idx];
1563 		struct platform_device *pdev;
1564 
1565 		pdev = platform_device_alloc("cxl_host_bridge", idx);
1566 		if (!pdev)
1567 			goto err_bridge;
1568 
1569 		mock_companion(adev, &pdev->dev);
1570 		rc = cxl_mock_platform_device_add(pdev, &cxl_rch[i]);
1571 		if (rc)
1572 			goto err_bridge;
1573 
1574 		mock_pci_bus[idx].bridge = &pdev->dev;
1575 		rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
1576 				       "firmware_node");
1577 		if (rc)
1578 			goto err_bridge;
1579 	}
1580 
1581 	return 0;
1582 
1583 err_bridge:
1584 	for (i = ARRAY_SIZE(cxl_rch) - 1; i >= 0; i--) {
1585 		struct platform_device *pdev = cxl_rch[i];
1586 
1587 		if (!pdev)
1588 			continue;
1589 		sysfs_remove_link(&pdev->dev.kobj, "firmware_node");
1590 		platform_device_unregister(cxl_rch[i]);
1591 	}
1592 
1593 	return rc;
1594 }
1595 
1596 static void cxl_rch_topo_exit(void)
1597 {
1598 	int i;
1599 
1600 	for (i = ARRAY_SIZE(cxl_rch) - 1; i >= 0; i--) {
1601 		struct platform_device *pdev = cxl_rch[i];
1602 
1603 		if (!pdev)
1604 			continue;
1605 		sysfs_remove_link(&pdev->dev.kobj, "firmware_node");
1606 		platform_device_unregister(cxl_rch[i]);
1607 	}
1608 }
1609 
1610 static __init int cxl_single_topo_init(void)
1611 {
1612 	int i, rc;
1613 
1614 	for (i = 0; i < ARRAY_SIZE(cxl_hb_single); i++) {
1615 		struct acpi_device *adev =
1616 			&host_bridge[NR_CXL_HOST_BRIDGES + i];
1617 		struct platform_device *pdev;
1618 
1619 		pdev = platform_device_alloc("cxl_host_bridge",
1620 					     NR_CXL_HOST_BRIDGES + i);
1621 		if (!pdev)
1622 			goto err_bridge;
1623 
1624 		mock_companion(adev, &pdev->dev);
1625 		rc = cxl_mock_platform_device_add(pdev, &cxl_hb_single[i]);
1626 		if (rc)
1627 			goto err_bridge;
1628 
1629 		mock_pci_bus[i + NR_CXL_HOST_BRIDGES].bridge = &pdev->dev;
1630 		rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
1631 				       "physical_node");
1632 		if (rc)
1633 			goto err_bridge;
1634 	}
1635 
1636 	for (i = 0; i < ARRAY_SIZE(cxl_root_single); i++) {
1637 		struct platform_device *bridge =
1638 			cxl_hb_single[i % ARRAY_SIZE(cxl_hb_single)];
1639 		struct platform_device *pdev;
1640 
1641 		pdev = platform_device_alloc("cxl_root_port",
1642 					     NR_MULTI_ROOT + i);
1643 		if (!pdev)
1644 			goto err_port;
1645 		pdev->dev.parent = &bridge->dev;
1646 
1647 		rc = cxl_mock_platform_device_add(pdev, &cxl_root_single[i]);
1648 		if (rc)
1649 			goto err_port;
1650 	}
1651 
1652 	for (i = 0; i < ARRAY_SIZE(cxl_swu_single); i++) {
1653 		struct platform_device *root_port = cxl_root_single[i];
1654 		struct platform_device *pdev;
1655 
1656 		pdev = platform_device_alloc("cxl_switch_uport",
1657 					     NR_MULTI_ROOT + i);
1658 		if (!pdev)
1659 			goto err_uport;
1660 		pdev->dev.parent = &root_port->dev;
1661 
1662 		rc = cxl_mock_platform_device_add(pdev, &cxl_swu_single[i]);
1663 		if (rc)
1664 			goto err_uport;
1665 	}
1666 
1667 	for (i = 0; i < ARRAY_SIZE(cxl_swd_single); i++) {
1668 		struct platform_device *uport =
1669 			cxl_swu_single[i % ARRAY_SIZE(cxl_swu_single)];
1670 		struct platform_device *pdev;
1671 
1672 		pdev = platform_device_alloc("cxl_switch_dport",
1673 					     i + NR_MEM_MULTI);
1674 		if (!pdev)
1675 			goto err_dport;
1676 		pdev->dev.parent = &uport->dev;
1677 
1678 		rc = cxl_mock_platform_device_add(pdev, &cxl_swd_single[i]);
1679 		if (rc)
1680 			goto err_dport;
1681 	}
1682 
1683 	return 0;
1684 
1685 err_dport:
1686 	for (i = ARRAY_SIZE(cxl_swd_single) - 1; i >= 0; i--)
1687 		platform_device_unregister(cxl_swd_single[i]);
1688 err_uport:
1689 	for (i = ARRAY_SIZE(cxl_swu_single) - 1; i >= 0; i--)
1690 		platform_device_unregister(cxl_swu_single[i]);
1691 err_port:
1692 	for (i = ARRAY_SIZE(cxl_root_single) - 1; i >= 0; i--)
1693 		platform_device_unregister(cxl_root_single[i]);
1694 err_bridge:
1695 	for (i = ARRAY_SIZE(cxl_hb_single) - 1; i >= 0; i--) {
1696 		struct platform_device *pdev = cxl_hb_single[i];
1697 
1698 		if (!pdev)
1699 			continue;
1700 		sysfs_remove_link(&pdev->dev.kobj, "physical_node");
1701 		platform_device_unregister(cxl_hb_single[i]);
1702 	}
1703 
1704 	return rc;
1705 }
1706 
1707 static void cxl_single_topo_exit(void)
1708 {
1709 	int i;
1710 
1711 	for (i = ARRAY_SIZE(cxl_swd_single) - 1; i >= 0; i--)
1712 		platform_device_unregister(cxl_swd_single[i]);
1713 	for (i = ARRAY_SIZE(cxl_swu_single) - 1; i >= 0; i--)
1714 		platform_device_unregister(cxl_swu_single[i]);
1715 	for (i = ARRAY_SIZE(cxl_root_single) - 1; i >= 0; i--)
1716 		platform_device_unregister(cxl_root_single[i]);
1717 	for (i = ARRAY_SIZE(cxl_hb_single) - 1; i >= 0; i--) {
1718 		struct platform_device *pdev = cxl_hb_single[i];
1719 
1720 		if (!pdev)
1721 			continue;
1722 		sysfs_remove_link(&pdev->dev.kobj, "physical_node");
1723 		platform_device_unregister(cxl_hb_single[i]);
1724 	}
1725 }
1726 
1727 static void cxl_mem_exit(void)
1728 {
1729 	int i;
1730 
1731 	for (i = ARRAY_SIZE(cxl_rcd) - 1; i >= 0; i--)
1732 		platform_device_unregister(cxl_rcd[i]);
1733 	for (i = ARRAY_SIZE(cxl_mem_single) - 1; i >= 0; i--)
1734 		platform_device_unregister(cxl_mem_single[i]);
1735 	for (i = ARRAY_SIZE(cxl_mem) - 1; i >= 0; i--)
1736 		platform_device_unregister(cxl_mem[i]);
1737 }
1738 
1739 static int cxl_mem_init(void)
1740 {
1741 	int i, rc;
1742 
1743 	for (i = 0; i < ARRAY_SIZE(cxl_mem); i++) {
1744 		struct platform_device *dport = cxl_switch_dport[i];
1745 		struct platform_device *pdev;
1746 
1747 		pdev = platform_device_alloc("cxl_mem", i);
1748 		if (!pdev)
1749 			goto err_mem;
1750 		pdev->dev.parent = &dport->dev;
1751 		set_dev_node(&pdev->dev, i % 2);
1752 
1753 		rc = cxl_mock_platform_device_add(pdev, &cxl_mem[i]);
1754 		if (rc)
1755 			goto err_mem;
1756 	}
1757 
1758 	for (i = 0; i < ARRAY_SIZE(cxl_mem_single); i++) {
1759 		struct platform_device *dport = cxl_swd_single[i];
1760 		struct platform_device *pdev;
1761 
1762 		pdev = platform_device_alloc("cxl_mem", NR_MEM_MULTI + i);
1763 		if (!pdev)
1764 			goto err_single;
1765 		pdev->dev.parent = &dport->dev;
1766 		set_dev_node(&pdev->dev, i % 2);
1767 
1768 		rc = cxl_mock_platform_device_add(pdev, &cxl_mem_single[i]);
1769 		if (rc)
1770 			goto err_single;
1771 	}
1772 
1773 	for (i = 0; i < ARRAY_SIZE(cxl_rcd); i++) {
1774 		int idx = NR_MEM_MULTI + NR_MEM_SINGLE + i;
1775 		struct platform_device *rch = cxl_rch[i];
1776 		struct platform_device *pdev;
1777 
1778 		pdev = platform_device_alloc("cxl_rcd", idx);
1779 		if (!pdev)
1780 			goto err_rcd;
1781 		pdev->dev.parent = &rch->dev;
1782 		set_dev_node(&pdev->dev, i % 2);
1783 
1784 		rc = cxl_mock_platform_device_add(pdev, &cxl_rcd[i]);
1785 		if (rc)
1786 			goto err_rcd;
1787 	}
1788 
1789 	return 0;
1790 
1791 err_rcd:
1792 	for (i = ARRAY_SIZE(cxl_rcd) - 1; i >= 0; i--)
1793 		platform_device_unregister(cxl_rcd[i]);
1794 err_single:
1795 	for (i = ARRAY_SIZE(cxl_mem_single) - 1; i >= 0; i--)
1796 		platform_device_unregister(cxl_mem_single[i]);
1797 err_mem:
1798 	for (i = ARRAY_SIZE(cxl_mem) - 1; i >= 0; i--)
1799 		platform_device_unregister(cxl_mem[i]);
1800 	return rc;
1801 }
1802 
1803 static ssize_t
1804 decoder_reset_preserve_registry_show(struct device *dev,
1805 				     struct device_attribute *attr, char *buf)
1806 {
1807 	return sysfs_emit(buf, "%d\n", decoder_reset_preserve_registry);
1808 }
1809 
1810 static ssize_t
1811 decoder_reset_preserve_registry_store(struct device *dev,
1812 				      struct device_attribute *attr,
1813 				      const char *buf, size_t count)
1814 {
1815 	int rc;
1816 
1817 	rc = kstrtobool(buf, &decoder_reset_preserve_registry);
1818 	if (rc)
1819 		return rc;
1820 	return count;
1821 }
1822 
1823 static DEVICE_ATTR_RW(decoder_reset_preserve_registry);
1824 
1825 static struct attribute *cxl_acpi_attrs[] = {
1826 	&dev_attr_decoder_reset_preserve_registry.attr, NULL
1827 };
1828 ATTRIBUTE_GROUPS(cxl_acpi);
1829 
1830 static __init int cxl_test_init(void)
1831 {
1832 	int rc, i;
1833 	struct range mappable;
1834 
1835 	if (!IS_ALIGNED(mock_auto_region_size, PMD_SIZE)) {
1836 		pr_err_once("mock_auto_region_size %d must be PMD-aligned\n",
1837 			    mock_auto_region_size);
1838 		return -EINVAL;
1839 	}
1840 
1841 	cxl_acpi_test();
1842 	cxl_core_test();
1843 	cxl_mem_test();
1844 	cxl_pmem_test();
1845 	cxl_port_test();
1846 
1847 	register_cxl_mock_ops(&cxl_mock_ops);
1848 
1849 	cxl_mock_pool = gen_pool_create(ilog2(SZ_2M), NUMA_NO_NODE);
1850 	if (!cxl_mock_pool) {
1851 		rc = -ENOMEM;
1852 		goto err_gen_pool_create;
1853 	}
1854 	mappable = mhp_get_pluggable_range(true);
1855 
1856 	rc = gen_pool_add(cxl_mock_pool,
1857 			  min(iomem_resource.end + 1 - SZ_64G,
1858 			      mappable.end + 1 - SZ_64G),
1859 			  SZ_64G, NUMA_NO_NODE);
1860 	if (rc)
1861 		goto err_gen_pool_add;
1862 
1863 	if (interleave_arithmetic == 1) {
1864 		cfmws_start = CFMWS_XOR_ARRAY_START;
1865 		cfmws_end = CFMWS_XOR_ARRAY_END;
1866 	} else {
1867 		cfmws_start = CFMWS_MOD_ARRAY_START;
1868 		cfmws_end = CFMWS_MOD_ARRAY_END;
1869 	}
1870 
1871 	rc = populate_cedt();
1872 	if (rc)
1873 		goto err_populate;
1874 
1875 	for (i = 0; i < ARRAY_SIZE(cxl_host_bridge); i++) {
1876 		struct acpi_device *adev = &host_bridge[i];
1877 		struct platform_device *pdev;
1878 
1879 		pdev = platform_device_alloc("cxl_host_bridge", i);
1880 		if (!pdev)
1881 			goto err_bridge;
1882 
1883 		mock_companion(adev, &pdev->dev);
1884 		rc = cxl_mock_platform_device_add(pdev, &cxl_host_bridge[i]);
1885 		if (rc)
1886 			goto err_bridge;
1887 
1888 		mock_pci_bus[i].bridge = &pdev->dev;
1889 		rc = sysfs_create_link(&pdev->dev.kobj, &pdev->dev.kobj,
1890 				       "physical_node");
1891 		if (rc)
1892 			goto err_bridge;
1893 	}
1894 
1895 	for (i = 0; i < ARRAY_SIZE(cxl_root_port); i++) {
1896 		struct platform_device *bridge =
1897 			cxl_host_bridge[i % ARRAY_SIZE(cxl_host_bridge)];
1898 		struct platform_device *pdev;
1899 
1900 		pdev = platform_device_alloc("cxl_root_port", i);
1901 		if (!pdev)
1902 			goto err_port;
1903 		pdev->dev.parent = &bridge->dev;
1904 
1905 		rc = cxl_mock_platform_device_add(pdev, &cxl_root_port[i]);
1906 		if (rc)
1907 			goto err_port;
1908 	}
1909 
1910 	BUILD_BUG_ON(ARRAY_SIZE(cxl_switch_uport) != ARRAY_SIZE(cxl_root_port));
1911 	for (i = 0; i < ARRAY_SIZE(cxl_switch_uport); i++) {
1912 		struct platform_device *root_port = cxl_root_port[i];
1913 		struct platform_device *pdev;
1914 
1915 		pdev = platform_device_alloc("cxl_switch_uport", i);
1916 		if (!pdev)
1917 			goto err_uport;
1918 		pdev->dev.parent = &root_port->dev;
1919 
1920 		rc = cxl_mock_platform_device_add(pdev, &cxl_switch_uport[i]);
1921 		if (rc)
1922 			goto err_uport;
1923 	}
1924 
1925 	for (i = 0; i < ARRAY_SIZE(cxl_switch_dport); i++) {
1926 		struct platform_device *uport =
1927 			cxl_switch_uport[i % ARRAY_SIZE(cxl_switch_uport)];
1928 		struct platform_device *pdev;
1929 
1930 		pdev = platform_device_alloc("cxl_switch_dport", i);
1931 		if (!pdev)
1932 			goto err_dport;
1933 		pdev->dev.parent = &uport->dev;
1934 
1935 		rc = cxl_mock_platform_device_add(pdev, &cxl_switch_dport[i]);
1936 		if (rc)
1937 			goto err_dport;
1938 	}
1939 
1940 	rc = cxl_single_topo_init();
1941 	if (rc)
1942 		goto err_dport;
1943 
1944 	rc = cxl_rch_topo_init();
1945 	if (rc)
1946 		goto err_single;
1947 
1948 	cxl_acpi = platform_device_alloc("cxl_acpi", 0);
1949 	if (!cxl_acpi)
1950 		goto err_rch;
1951 
1952 	mock_companion(&acpi0017_mock, &cxl_acpi->dev);
1953 	acpi0017_mock.dev.bus = &platform_bus_type;
1954 	cxl_acpi->dev.groups = cxl_acpi_groups;
1955 
1956 	rc = cxl_mock_platform_device_add(cxl_acpi, NULL);
1957 	if (rc)
1958 		goto err_rch;
1959 
1960 	rc = cxl_mem_init();
1961 	if (rc)
1962 		goto err_root;
1963 
1964 	rc = hmem_test_init();
1965 	if (rc)
1966 		goto err_mem;
1967 
1968 	return 0;
1969 
1970 err_mem:
1971 	cxl_mem_exit();
1972 err_root:
1973 	platform_device_unregister(cxl_acpi);
1974 err_rch:
1975 	cxl_rch_topo_exit();
1976 err_single:
1977 	cxl_single_topo_exit();
1978 err_dport:
1979 	for (i = ARRAY_SIZE(cxl_switch_dport) - 1; i >= 0; i--)
1980 		platform_device_unregister(cxl_switch_dport[i]);
1981 err_uport:
1982 	for (i = ARRAY_SIZE(cxl_switch_uport) - 1; i >= 0; i--)
1983 		platform_device_unregister(cxl_switch_uport[i]);
1984 err_port:
1985 	for (i = ARRAY_SIZE(cxl_root_port) - 1; i >= 0; i--)
1986 		platform_device_unregister(cxl_root_port[i]);
1987 err_bridge:
1988 	for (i = ARRAY_SIZE(cxl_host_bridge) - 1; i >= 0; i--) {
1989 		struct platform_device *pdev = cxl_host_bridge[i];
1990 
1991 		if (!pdev)
1992 			continue;
1993 		sysfs_remove_link(&pdev->dev.kobj, "physical_node");
1994 		platform_device_unregister(cxl_host_bridge[i]);
1995 	}
1996 err_populate:
1997 	depopulate_all_mock_resources();
1998 err_gen_pool_add:
1999 	gen_pool_destroy(cxl_mock_pool);
2000 err_gen_pool_create:
2001 	unregister_cxl_mock_ops(&cxl_mock_ops);
2002 	return rc;
2003 }
2004 
2005 static void free_decoder_registry(void)
2006 {
2007 	unsigned long index;
2008 	void *entry;
2009 
2010 	xa_for_each(&decoder_registry, index, entry) {
2011 		xa_erase(&decoder_registry, index);
2012 		kfree(entry);
2013 	}
2014 }
2015 
2016 static __exit void cxl_test_exit(void)
2017 {
2018 	int i;
2019 
2020 	hmem_test_exit();
2021 	cxl_mem_exit();
2022 	platform_device_unregister(cxl_acpi);
2023 	cxl_rch_topo_exit();
2024 	cxl_single_topo_exit();
2025 	for (i = ARRAY_SIZE(cxl_switch_dport) - 1; i >= 0; i--)
2026 		platform_device_unregister(cxl_switch_dport[i]);
2027 	for (i = ARRAY_SIZE(cxl_switch_uport) - 1; i >= 0; i--)
2028 		platform_device_unregister(cxl_switch_uport[i]);
2029 	for (i = ARRAY_SIZE(cxl_root_port) - 1; i >= 0; i--)
2030 		platform_device_unregister(cxl_root_port[i]);
2031 	for (i = ARRAY_SIZE(cxl_host_bridge) - 1; i >= 0; i--) {
2032 		struct platform_device *pdev = cxl_host_bridge[i];
2033 
2034 		if (!pdev)
2035 			continue;
2036 		sysfs_remove_link(&pdev->dev.kobj, "physical_node");
2037 		platform_device_unregister(cxl_host_bridge[i]);
2038 	}
2039 	depopulate_all_mock_resources();
2040 	gen_pool_destroy(cxl_mock_pool);
2041 	unregister_cxl_mock_ops(&cxl_mock_ops);
2042 	free_decoder_registry();
2043 	xa_destroy(&decoder_registry);
2044 }
2045 
2046 module_param(interleave_arithmetic, int, 0444);
2047 MODULE_PARM_DESC(interleave_arithmetic, "Modulo:0, XOR:1");
2048 module_param(extended_linear_cache, bool, 0444);
2049 MODULE_PARM_DESC(extended_linear_cache, "Enable extended linear cache support");
2050 module_param(fail_autoassemble, bool, 0444);
2051 MODULE_PARM_DESC(fail_autoassemble, "Simulate missing member of an auto-region");
2052 module_init(cxl_test_init);
2053 module_exit(cxl_test_exit);
2054 MODULE_LICENSE("GPL v2");
2055 MODULE_DESCRIPTION("cxl_test: setup module");
2056 MODULE_IMPORT_NS("ACPI");
2057 MODULE_IMPORT_NS("CXL");
2058