xref: /illumos-gate/usr/src/test/os-tests/tests/zen_umc/zen_umc_test_multi.c (revision 94f64ebe984dee2f328427bf26cd88f3c6470308)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2025 Oxide Computer Company
14  */
15 
16 /*
17  * Here we construct a more realistic DF situation where we have multiple rules.
18  * In particular, we use a DFv3 style configuration with a single die and
19  * socket. To make sense of the channel offset logic, we construct a system with
20  * two channels, one with 64 GiB and one one 8 GiB DIMMs. We basically
21  * interleave with the 16 GiB channel over the last 16 GiB of the 128 GiB
22  * channel. This requires us to therefore use the channel offset for the first
23  * channel to get it in a reasonable spot for the second rule. This also allows
24  * us to test what happens with multiple rules and ensure that we select the
25  * right one and when two rules map to one channel.
26  *
27  * Here, the hole is sized to 1.75 GiB. This is based on a system we saw that
28  * was set up this way.
29  */
30 
31 #include "zen_umc_test.h"
32 
33 static const zen_umc_t zen_umc_multi = {
34 	.umc_tom = 0x90000000,
35 	.umc_tom2 = 0x2470000000,
36 	.umc_df_rev = DF_REV_3,
37 	.umc_decomp = {
38 		.dfd_sock_mask = 0x01,
39 		.dfd_die_mask = 0x00,
40 		.dfd_node_mask = 0x20,
41 		.dfd_comp_mask = 0x1f,
42 		.dfd_sock_shift = 0,
43 		.dfd_die_shift = 0,
44 		.dfd_node_shift = 5,
45 		.dfd_comp_shift = 0
46 	},
47 	.umc_ndfs = 1,
48 	.umc_dfs = { {
49 		.zud_flags = ZEN_UMC_DF_F_HOLE_VALID,
50 		.zud_dfno = 0,
51 		.zud_dram_nrules = 2,
52 		.zud_nchan = 4,
53 		.zud_cs_nremap = 0,
54 		.zud_hole_base = 0x90000000,
55 		.zud_rules = { {
56 			.ddr_flags = DF_DRAM_F_VALID | DF_DRAM_F_HOLE,
57 			.ddr_base = 0,
58 			.ddr_limit = 0x1c70000000,
59 			.ddr_dest_fabid = 0,
60 			.ddr_sock_ileave_bits = 0,
61 			.ddr_die_ileave_bits = 0,
62 			.ddr_addr_start = 8,
63 			.ddr_chan_ileave = DF_CHAN_ILEAVE_1CH
64 		}, {
65 			.ddr_flags = DF_DRAM_F_VALID,
66 			.ddr_base = 0x1c70000000,
67 			.ddr_limit = 0x2470000000,
68 			.ddr_dest_fabid = 0,
69 			.ddr_sock_ileave_bits = 0,
70 			.ddr_die_ileave_bits = 0,
71 			.ddr_addr_start = 8,
72 			.ddr_chan_ileave = DF_CHAN_ILEAVE_2CH
73 		} },
74 		.zud_chan = { {
75 			.chan_flags = UMC_CHAN_F_ECC_EN,
76 			.chan_fabid = 0,
77 			.chan_instid = 0,
78 			.chan_logid = 0,
79 			.chan_nrules = 2,
80 			.chan_type = UMC_DIMM_T_DDR4,
81 			.chan_rules = { {
82 				.ddr_flags = DF_DRAM_F_VALID | DF_DRAM_F_HOLE,
83 				.ddr_base = 0,
84 				.ddr_limit = 0x1c70000000,
85 				.ddr_dest_fabid = 0,
86 				.ddr_sock_ileave_bits = 0,
87 				.ddr_die_ileave_bits = 0,
88 				.ddr_addr_start = 8,
89 				.ddr_chan_ileave = DF_CHAN_ILEAVE_1CH
90 			}, {
91 				.ddr_flags = DF_DRAM_F_VALID,
92 				.ddr_base = 0x1c70000000,
93 				.ddr_limit = 0x2470000000,
94 				.ddr_dest_fabid = 0,
95 				.ddr_sock_ileave_bits = 0,
96 				.ddr_die_ileave_bits = 0,
97 				.ddr_addr_start = 8,
98 				.ddr_chan_ileave = DF_CHAN_ILEAVE_2CH
99 			} },
100 			.chan_offsets = { {
101 				.cho_valid = B_TRUE,
102 				.cho_offset = 0x1c00000000,
103 			} },
104 			.chan_dimms = { {
105 				.ud_flags = UMC_DIMM_F_VALID,
106 				.ud_width = UMC_DIMM_W_X4,
107 				.ud_kind = UMC_DIMM_K_RDIMM,
108 				.ud_dimmno = 0,
109 				.ud_cs = { {
110 					.ucs_flags = UMC_CS_F_DECODE_EN,
111 					.ucs_base = {
112 						.udb_base = 0,
113 						.udb_valid = B_TRUE
114 					},
115 					.ucs_base_mask = 0x7ffffffff,
116 					.ucs_nbanks = 0x4,
117 					.ucs_ncol = 0xa,
118 					.ucs_nrow_lo = 0x12,
119 					.ucs_nbank_groups = 0x2,
120 					.ucs_row_hi_bit = 0x18,
121 					.ucs_row_low_bit = 0x11,
122 					.ucs_bank_bits = { 0xf, 0x10, 0xd,
123 					    0xe },
124 					.ucs_col_bits = { 0x3, 0x4, 0x5, 0x6,
125 					    0x7, 0x8, 0x9, 0xa, 0xb, 0xc }
126 				}, {
127 					.ucs_flags = UMC_CS_F_DECODE_EN,
128 					.ucs_base = {
129 						.udb_base = 0x800000000,
130 						.udb_valid = B_TRUE
131 					},
132 					.ucs_base_mask = 0x7ffffffff,
133 					.ucs_nbanks = 0x4,
134 					.ucs_ncol = 0xa,
135 					.ucs_nrow_lo = 0x12,
136 					.ucs_nbank_groups = 0x2,
137 					.ucs_row_hi_bit = 0x18,
138 					.ucs_row_low_bit = 0x11,
139 					.ucs_bank_bits = { 0xf, 0x10, 0xd,
140 					    0xe },
141 					.ucs_col_bits = { 0x3, 0x4, 0x5, 0x6,
142 					    0x7, 0x8, 0x9, 0xa, 0xb, 0xc }
143 				} }
144 			}, {
145 				.ud_flags = UMC_DIMM_F_VALID,
146 				.ud_width = UMC_DIMM_W_X4,
147 				.ud_kind = UMC_DIMM_K_RDIMM,
148 				.ud_dimmno = 1,
149 				.ud_cs = { {
150 					.ucs_flags = UMC_CS_F_DECODE_EN,
151 					.ucs_base = {
152 						.udb_base = 0x1000000000,
153 						.udb_valid = B_TRUE
154 					},
155 					.ucs_base_mask = 0x7ffffffff,
156 					.ucs_nbanks = 0x4,
157 					.ucs_ncol = 0xa,
158 					.ucs_nrow_lo = 0x12,
159 					.ucs_nbank_groups = 0x2,
160 					.ucs_row_hi_bit = 0x18,
161 					.ucs_row_low_bit = 0x11,
162 					.ucs_bank_bits = { 0xf, 0x10, 0xd,
163 					    0xe },
164 					.ucs_col_bits = { 0x3, 0x4, 0x5, 0x6,
165 					    0x7, 0x8, 0x9, 0xa, 0xb, 0xc }
166 				}, {
167 					.ucs_flags = UMC_CS_F_DECODE_EN,
168 					.ucs_base = {
169 						.udb_base = 0x1800000000,
170 						.udb_valid = B_TRUE
171 					},
172 					.ucs_base_mask = 0x7ffffffff,
173 					.ucs_nbanks = 0x4,
174 					.ucs_ncol = 0xa,
175 					.ucs_nrow_lo = 0x12,
176 					.ucs_nbank_groups = 0x2,
177 					.ucs_row_hi_bit = 0x18,
178 					.ucs_row_low_bit = 0x11,
179 					.ucs_bank_bits = { 0xf, 0x10, 0xd,
180 					    0xe },
181 					.ucs_col_bits = { 0x3, 0x4, 0x5, 0x6,
182 					    0x7, 0x8, 0x9, 0xa, 0xb, 0xc }
183 				} }
184 			} }
185 		}, {
186 			.chan_flags = UMC_CHAN_F_ECC_EN,
187 			.chan_fabid = 1,
188 			.chan_instid = 1,
189 			.chan_logid = 1,
190 			.chan_nrules = 1,
191 			.chan_type = UMC_DIMM_T_DDR4,
192 			.chan_rules = { {
193 				.ddr_flags = DF_DRAM_F_VALID,
194 				.ddr_base = 0x1c70000000,
195 				.ddr_limit = 0x2470000000,
196 				.ddr_dest_fabid = 0,
197 				.ddr_sock_ileave_bits = 0,
198 				.ddr_die_ileave_bits = 0,
199 				.ddr_addr_start = 8,
200 				.ddr_chan_ileave = DF_CHAN_ILEAVE_2CH
201 			} },
202 			.chan_dimms = { {
203 				.ud_flags = UMC_DIMM_F_VALID,
204 				.ud_width = UMC_DIMM_W_X8,
205 				.ud_kind = UMC_DIMM_K_RDIMM,
206 				.ud_dimmno = 0,
207 				.ud_cs = { {
208 					.ucs_flags = UMC_CS_F_DECODE_EN,
209 					.ucs_base = {
210 						.udb_base = 0,
211 						.udb_valid = B_TRUE
212 					},
213 					.ucs_base_mask = 0x3fffdffff,
214 					.ucs_nbanks = 0x4,
215 					.ucs_ncol = 0xa,
216 					.ucs_nrow_lo = 0x10,
217 					.ucs_nbank_groups = 0x2,
218 					.ucs_row_hi_bit = 0x18,
219 					.ucs_row_low_bit = 0x11,
220 					.ucs_bank_bits = { 0xf, 0x10, 0xd,
221 					    0xe },
222 					.ucs_col_bits = { 0x3, 0x4, 0x5, 0x6,
223 					    0x7, 0x8, 0x9, 0xa, 0xb, 0xc }
224 				} }
225 			}, {
226 				.ud_flags = UMC_DIMM_F_VALID,
227 				.ud_width = UMC_DIMM_W_X8,
228 				.ud_kind = UMC_DIMM_K_RDIMM,
229 				.ud_dimmno = 0,
230 				.ud_cs = { {
231 					.ucs_flags = UMC_CS_F_DECODE_EN,
232 					.ucs_base = {
233 						.udb_base = 0x20000,
234 						.udb_valid = B_TRUE
235 					},
236 					.ucs_base_mask = 0x3fffdffff,
237 					.ucs_nbanks = 0x4,
238 					.ucs_ncol = 0xa,
239 					.ucs_nrow_lo = 0x10,
240 					.ucs_nbank_groups = 0x2,
241 					.ucs_row_hi_bit = 0x18,
242 					.ucs_row_low_bit = 0x11,
243 					.ucs_bank_bits = { 0xf, 0x10, 0xd,
244 					    0xe },
245 					.ucs_col_bits = { 0x3, 0x4, 0x5, 0x6,
246 					    0x7, 0x8, 0x9, 0xa, 0xb, 0xc }
247 				} }
248 			} },
249 		}  }
250 	} }
251 };
252 
253 const umc_decode_test_t zen_umc_test_multi[] = { {
254 	.udt_desc = "Multi-rule (0)",
255 	.udt_umc = &zen_umc_multi,
256 	.udt_pa = 0x12345603,
257 	.udt_pass = B_TRUE,
258 	.udt_norm_addr = 0x12345603,
259 	.udt_sock = 0,
260 	.udt_die = 0,
261 	.udt_comp = 0,
262 	.udt_dimm_no = 0,
263 	.udt_dimm_col = 0x2c0,
264 	.udt_dimm_row = 0x91a,
265 	.udt_dimm_bank = 2,
266 	.udt_dimm_bank_group = 0,
267 	.udt_dimm_subchan = UINT8_MAX,
268 	.udt_dimm_rm = 0,
269 	.udt_dimm_cs = 0
270 
271 }, {
272 	.udt_desc = "Multi-rule (1)",
273 	.udt_umc = &zen_umc_multi,
274 	.udt_pa = 0x12345703,
275 	.udt_pass = B_TRUE,
276 	.udt_norm_addr = 0x12345703,
277 	.udt_sock = 0,
278 	.udt_die = 0,
279 	.udt_comp = 0,
280 	.udt_dimm_no = 0,
281 	.udt_dimm_col = 0x2e0,
282 	.udt_dimm_row = 0x91a,
283 	.udt_dimm_bank = 2,
284 	.udt_dimm_bank_group = 0,
285 	.udt_dimm_subchan = UINT8_MAX,
286 	.udt_dimm_rm = 0,
287 	.udt_dimm_cs = 0
288 
289 }, {
290 	.udt_desc = "Multi-rule (2)",
291 	.udt_umc = &zen_umc_multi,
292 	.udt_pa = 0x1ba9876543,
293 	.udt_pass = B_TRUE,
294 	.udt_norm_addr = 0x1b39876543,
295 	.udt_sock = 0,
296 	.udt_die = 0,
297 	.udt_comp = 0,
298 	.udt_dimm_no = 1,
299 	.udt_dimm_col = 0xa8,
300 	.udt_dimm_row = 0x19cc3,
301 	.udt_dimm_bank = 3,
302 	.udt_dimm_bank_group = 2,
303 	.udt_dimm_subchan = UINT8_MAX,
304 	.udt_dimm_rm = 0,
305 	.udt_dimm_cs = 1
306 
307 }, {
308 	.udt_desc = "Multi-rule (3)",
309 	.udt_umc = &zen_umc_multi,
310 	.udt_pa = 0x1ba9876643,
311 	.udt_pass = B_TRUE,
312 	.udt_norm_addr = 0x1b39876643,
313 	.udt_sock = 0,
314 	.udt_die = 0,
315 	.udt_comp = 0,
316 	.udt_dimm_no = 1,
317 	.udt_dimm_col = 0xc8,
318 	.udt_dimm_row = 0x19cc3,
319 	.udt_dimm_bank = 3,
320 	.udt_dimm_bank_group = 2,
321 	.udt_dimm_subchan = UINT8_MAX,
322 	.udt_dimm_rm = 0,
323 	.udt_dimm_cs = 1
324 },
325 /*
326  * All of the accesses below should now hit our second rule. When normalizing we
327  * subtract the base and add the channel offset. So that is why the normalized
328  * address will look totally different depending on which DIMM we go to.
329  */
330 {
331 	.udt_desc = "Multi-rule (4)",
332 	.udt_umc = &zen_umc_multi,
333 	.udt_pa = 0x1c70000000,
334 	.udt_pass = B_TRUE,
335 	.udt_norm_addr = 0x1c00000000,
336 	.udt_sock = 0,
337 	.udt_die = 0,
338 	.udt_comp = 0,
339 	.udt_dimm_no = 1,
340 	.udt_dimm_col = 0,
341 	.udt_dimm_row = 0x20000,
342 	.udt_dimm_bank = 0,
343 	.udt_dimm_bank_group = 0,
344 	.udt_dimm_subchan = UINT8_MAX,
345 	.udt_dimm_rm = 0,
346 	.udt_dimm_cs = 1
347 }, {
348 	.udt_desc = "Multi-rule (5)",
349 	.udt_umc = &zen_umc_multi,
350 	.udt_pa = 0x1c70000100,
351 	.udt_pass = B_TRUE,
352 	.udt_norm_addr = 0x0,
353 	.udt_sock = 0,
354 	.udt_die = 0,
355 	.udt_comp = 1,
356 	.udt_dimm_no = 0,
357 	.udt_dimm_col = 0,
358 	.udt_dimm_row = 0,
359 	.udt_dimm_bank = 0,
360 	.udt_dimm_bank_group = 0,
361 	.udt_dimm_subchan = UINT8_MAX,
362 	.udt_dimm_rm = 0,
363 	.udt_dimm_cs = 0
364 }, {
365 	.udt_desc = "Multi-rule (6)",
366 	.udt_umc = &zen_umc_multi,
367 	.udt_pa = 0x23456789ab,
368 	.udt_pass = B_TRUE,
369 	.udt_norm_addr = 0x36ab3c4ab,
370 	.udt_sock = 0,
371 	.udt_die = 0,
372 	.udt_comp = 1,
373 	.udt_dimm_no = 1,
374 	.udt_dimm_col = 0x95,
375 	.udt_dimm_row = 0xb559,
376 	.udt_dimm_bank = 2,
377 	.udt_dimm_bank_group = 3,
378 	.udt_dimm_subchan = UINT8_MAX,
379 	.udt_dimm_rm = 0,
380 	.udt_dimm_cs = 0
381 }, {
382 	.udt_desc = "Multi-rule (7)",
383 	.udt_umc = &zen_umc_multi,
384 	.udt_pa = 0x2345678aab,
385 	.udt_pass = B_TRUE,
386 	.udt_norm_addr = 0x1f6ab3c5ab,
387 	.udt_sock = 0,
388 	.udt_die = 0,
389 	.udt_comp = 0,
390 	.udt_dimm_no = 1,
391 	.udt_dimm_col = 0xb5,
392 	.udt_dimm_row = 0x3b559,
393 	.udt_dimm_bank = 2,
394 	.udt_dimm_bank_group = 3,
395 	.udt_dimm_subchan = UINT8_MAX,
396 	.udt_dimm_rm = 0,
397 	.udt_dimm_cs = 1
398 }, {
399 	.udt_desc = NULL
400 } };
401