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 2023 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_base = { 111 .udb_base = 0, 112 .udb_valid = B_TRUE 113 }, 114 .ucs_base_mask = 0x7ffffffff, 115 .ucs_nbanks = 0x4, 116 .ucs_ncol = 0xa, 117 .ucs_nrow_lo = 0x12, 118 .ucs_nbank_groups = 0x2, 119 .ucs_row_hi_bit = 0x18, 120 .ucs_row_low_bit = 0x11, 121 .ucs_bank_bits = { 0xf, 0x10, 0xd, 122 0xe }, 123 .ucs_col_bits = { 0x3, 0x4, 0x5, 0x6, 124 0x7, 0x8, 0x9, 0xa, 0xb, 0xc } 125 }, { 126 .ucs_base = { 127 .udb_base = 0x800000000, 128 .udb_valid = B_TRUE 129 }, 130 .ucs_base_mask = 0x7ffffffff, 131 .ucs_nbanks = 0x4, 132 .ucs_ncol = 0xa, 133 .ucs_nrow_lo = 0x12, 134 .ucs_nbank_groups = 0x2, 135 .ucs_row_hi_bit = 0x18, 136 .ucs_row_low_bit = 0x11, 137 .ucs_bank_bits = { 0xf, 0x10, 0xd, 138 0xe }, 139 .ucs_col_bits = { 0x3, 0x4, 0x5, 0x6, 140 0x7, 0x8, 0x9, 0xa, 0xb, 0xc } 141 } } 142 }, { 143 .ud_flags = UMC_DIMM_F_VALID, 144 .ud_width = UMC_DIMM_W_X4, 145 .ud_kind = UMC_DIMM_K_RDIMM, 146 .ud_dimmno = 1, 147 .ud_cs = { { 148 .ucs_base = { 149 .udb_base = 0x1000000000, 150 .udb_valid = B_TRUE 151 }, 152 .ucs_base_mask = 0x7ffffffff, 153 .ucs_nbanks = 0x4, 154 .ucs_ncol = 0xa, 155 .ucs_nrow_lo = 0x12, 156 .ucs_nbank_groups = 0x2, 157 .ucs_row_hi_bit = 0x18, 158 .ucs_row_low_bit = 0x11, 159 .ucs_bank_bits = { 0xf, 0x10, 0xd, 160 0xe }, 161 .ucs_col_bits = { 0x3, 0x4, 0x5, 0x6, 162 0x7, 0x8, 0x9, 0xa, 0xb, 0xc } 163 }, { 164 .ucs_base = { 165 .udb_base = 0x1800000000, 166 .udb_valid = B_TRUE 167 }, 168 .ucs_base_mask = 0x7ffffffff, 169 .ucs_nbanks = 0x4, 170 .ucs_ncol = 0xa, 171 .ucs_nrow_lo = 0x12, 172 .ucs_nbank_groups = 0x2, 173 .ucs_row_hi_bit = 0x18, 174 .ucs_row_low_bit = 0x11, 175 .ucs_bank_bits = { 0xf, 0x10, 0xd, 176 0xe }, 177 .ucs_col_bits = { 0x3, 0x4, 0x5, 0x6, 178 0x7, 0x8, 0x9, 0xa, 0xb, 0xc } 179 } } 180 } } 181 }, { 182 .chan_flags = UMC_CHAN_F_ECC_EN, 183 .chan_fabid = 1, 184 .chan_instid = 1, 185 .chan_logid = 1, 186 .chan_nrules = 1, 187 .chan_type = UMC_DIMM_T_DDR4, 188 .chan_rules = { { 189 .ddr_flags = DF_DRAM_F_VALID, 190 .ddr_base = 0x1c70000000, 191 .ddr_limit = 0x2470000000, 192 .ddr_dest_fabid = 0, 193 .ddr_sock_ileave_bits = 0, 194 .ddr_die_ileave_bits = 0, 195 .ddr_addr_start = 8, 196 .ddr_chan_ileave = DF_CHAN_ILEAVE_2CH 197 } }, 198 .chan_dimms = { { 199 .ud_flags = UMC_DIMM_F_VALID, 200 .ud_width = UMC_DIMM_W_X8, 201 .ud_kind = UMC_DIMM_K_RDIMM, 202 .ud_dimmno = 0, 203 .ud_cs = { { 204 .ucs_base = { 205 .udb_base = 0, 206 .udb_valid = B_TRUE 207 }, 208 .ucs_base_mask = 0x3fffdffff, 209 .ucs_nbanks = 0x4, 210 .ucs_ncol = 0xa, 211 .ucs_nrow_lo = 0x10, 212 .ucs_nbank_groups = 0x2, 213 .ucs_row_hi_bit = 0x18, 214 .ucs_row_low_bit = 0x11, 215 .ucs_bank_bits = { 0xf, 0x10, 0xd, 216 0xe }, 217 .ucs_col_bits = { 0x3, 0x4, 0x5, 0x6, 218 0x7, 0x8, 0x9, 0xa, 0xb, 0xc } 219 } } 220 }, { 221 .ud_flags = UMC_DIMM_F_VALID, 222 .ud_width = UMC_DIMM_W_X8, 223 .ud_kind = UMC_DIMM_K_RDIMM, 224 .ud_dimmno = 0, 225 .ud_cs = { { 226 .ucs_base = { 227 .udb_base = 0x20000, 228 .udb_valid = B_TRUE 229 }, 230 .ucs_base_mask = 0x3fffdffff, 231 .ucs_nbanks = 0x4, 232 .ucs_ncol = 0xa, 233 .ucs_nrow_lo = 0x10, 234 .ucs_nbank_groups = 0x2, 235 .ucs_row_hi_bit = 0x18, 236 .ucs_row_low_bit = 0x11, 237 .ucs_bank_bits = { 0xf, 0x10, 0xd, 238 0xe }, 239 .ucs_col_bits = { 0x3, 0x4, 0x5, 0x6, 240 0x7, 0x8, 0x9, 0xa, 0xb, 0xc } 241 } } 242 } }, 243 } } 244 } } 245 }; 246 247 const umc_decode_test_t zen_umc_test_multi[] = { { 248 .udt_desc = "Multi-rule (0)", 249 .udt_umc = &zen_umc_multi, 250 .udt_pa = 0x12345603, 251 .udt_pass = B_TRUE, 252 .udt_norm_addr = 0x12345603, 253 .udt_sock = 0, 254 .udt_die = 0, 255 .udt_comp = 0, 256 .udt_dimm_no = 0, 257 .udt_dimm_col = 0x2c0, 258 .udt_dimm_row = 0x91a, 259 .udt_dimm_bank = 2, 260 .udt_dimm_bank_group = 0, 261 .udt_dimm_subchan = UINT8_MAX, 262 .udt_dimm_rm = 0, 263 .udt_dimm_cs = 0 264 265 }, { 266 .udt_desc = "Multi-rule (1)", 267 .udt_umc = &zen_umc_multi, 268 .udt_pa = 0x12345703, 269 .udt_pass = B_TRUE, 270 .udt_norm_addr = 0x12345703, 271 .udt_sock = 0, 272 .udt_die = 0, 273 .udt_comp = 0, 274 .udt_dimm_no = 0, 275 .udt_dimm_col = 0x2e0, 276 .udt_dimm_row = 0x91a, 277 .udt_dimm_bank = 2, 278 .udt_dimm_bank_group = 0, 279 .udt_dimm_subchan = UINT8_MAX, 280 .udt_dimm_rm = 0, 281 .udt_dimm_cs = 0 282 283 }, { 284 .udt_desc = "Multi-rule (2)", 285 .udt_umc = &zen_umc_multi, 286 .udt_pa = 0x1ba9876543, 287 .udt_pass = B_TRUE, 288 .udt_norm_addr = 0x1b39876543, 289 .udt_sock = 0, 290 .udt_die = 0, 291 .udt_comp = 0, 292 .udt_dimm_no = 1, 293 .udt_dimm_col = 0xa8, 294 .udt_dimm_row = 0x19cc3, 295 .udt_dimm_bank = 3, 296 .udt_dimm_bank_group = 2, 297 .udt_dimm_subchan = UINT8_MAX, 298 .udt_dimm_rm = 0, 299 .udt_dimm_cs = 1 300 301 }, { 302 .udt_desc = "Multi-rule (3)", 303 .udt_umc = &zen_umc_multi, 304 .udt_pa = 0x1ba9876643, 305 .udt_pass = B_TRUE, 306 .udt_norm_addr = 0x1b39876643, 307 .udt_sock = 0, 308 .udt_die = 0, 309 .udt_comp = 0, 310 .udt_dimm_no = 1, 311 .udt_dimm_col = 0xc8, 312 .udt_dimm_row = 0x19cc3, 313 .udt_dimm_bank = 3, 314 .udt_dimm_bank_group = 2, 315 .udt_dimm_subchan = UINT8_MAX, 316 .udt_dimm_rm = 0, 317 .udt_dimm_cs = 1 318 }, 319 /* 320 * All of the accesses below should now hit our second rule. When normalizing we 321 * subtract the base and add the channel offset. So that is why the normalized 322 * address will look totally different depending on which DIMM we go to. 323 */ 324 { 325 .udt_desc = "Multi-rule (4)", 326 .udt_umc = &zen_umc_multi, 327 .udt_pa = 0x1c70000000, 328 .udt_pass = B_TRUE, 329 .udt_norm_addr = 0x1c00000000, 330 .udt_sock = 0, 331 .udt_die = 0, 332 .udt_comp = 0, 333 .udt_dimm_no = 1, 334 .udt_dimm_col = 0, 335 .udt_dimm_row = 0x20000, 336 .udt_dimm_bank = 0, 337 .udt_dimm_bank_group = 0, 338 .udt_dimm_subchan = UINT8_MAX, 339 .udt_dimm_rm = 0, 340 .udt_dimm_cs = 1 341 }, { 342 .udt_desc = "Multi-rule (5)", 343 .udt_umc = &zen_umc_multi, 344 .udt_pa = 0x1c70000100, 345 .udt_pass = B_TRUE, 346 .udt_norm_addr = 0x0, 347 .udt_sock = 0, 348 .udt_die = 0, 349 .udt_comp = 1, 350 .udt_dimm_no = 0, 351 .udt_dimm_col = 0, 352 .udt_dimm_row = 0, 353 .udt_dimm_bank = 0, 354 .udt_dimm_bank_group = 0, 355 .udt_dimm_subchan = UINT8_MAX, 356 .udt_dimm_rm = 0, 357 .udt_dimm_cs = 0 358 }, { 359 .udt_desc = "Multi-rule (6)", 360 .udt_umc = &zen_umc_multi, 361 .udt_pa = 0x23456789ab, 362 .udt_pass = B_TRUE, 363 .udt_norm_addr = 0x36ab3c4ab, 364 .udt_sock = 0, 365 .udt_die = 0, 366 .udt_comp = 1, 367 .udt_dimm_no = 1, 368 .udt_dimm_col = 0x95, 369 .udt_dimm_row = 0xb559, 370 .udt_dimm_bank = 2, 371 .udt_dimm_bank_group = 3, 372 .udt_dimm_subchan = UINT8_MAX, 373 .udt_dimm_rm = 0, 374 .udt_dimm_cs = 0 375 }, { 376 .udt_desc = "Multi-rule (7)", 377 .udt_umc = &zen_umc_multi, 378 .udt_pa = 0x2345678aab, 379 .udt_pass = B_TRUE, 380 .udt_norm_addr = 0x1f6ab3c5ab, 381 .udt_sock = 0, 382 .udt_die = 0, 383 .udt_comp = 0, 384 .udt_dimm_no = 1, 385 .udt_dimm_col = 0xb5, 386 .udt_dimm_row = 0x3b559, 387 .udt_dimm_bank = 2, 388 .udt_dimm_bank_group = 3, 389 .udt_dimm_subchan = UINT8_MAX, 390 .udt_dimm_rm = 0, 391 .udt_dimm_cs = 1 392 }, { 393 .udt_desc = NULL 394 } }; 395