Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/i86pc/cpu/genuineintel/gintel_main.c
+++ new/usr/src/uts/i86pc/cpu/genuineintel/gintel_main.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 26 /*
27 27 * Intel model-specific support. Right now all this conists of is
28 28 * to modify the ereport subclass to produce different ereport classes
29 29 * so that we can have different diagnosis rules and corresponding faults.
30 30 */
31 31
32 32 #include <sys/types.h>
33 33 #include <sys/cmn_err.h>
34 34 #include <sys/modctl.h>
35 35 #include <sys/mca_x86.h>
36 36 #include <sys/cpu_module_ms_impl.h>
37 37 #include <sys/mc_intel.h>
38 38 #include <sys/pci_cfgspace.h>
39 39 #include <sys/fm/protocol.h>
40 40 #include <sys/fm/util.h>
41 41 #include <sys/fm/smb/fmsmb.h>
42 42
43 43 extern int x86gentopo_legacy;
44 44
45 45 int gintel_ms_support_disable = 0;
46 46 int gintel_error_action_return = 0;
47 47 int gintel_ms_unconstrained = 0;
48 48
49 49 int quickpath;
50 50 int max_bus_number = 0xff;
51 51
52 52 #define ERR_COUNTER_INDEX 2
53 53 #define MAX_CPU_NODES 2
54 54 #define N_MC_COR_ECC_CNT 6
55 55 uint32_t err_counter_array[MAX_CPU_NODES][ERR_COUNTER_INDEX][N_MC_COR_ECC_CNT];
56 56 uint8_t err_counter_index[MAX_CPU_NODES];
57 57
58 58 #define MAX_BUS_NUMBER max_bus_number
59 59 #define SOCKET_BUS(cpu) (MAX_BUS_NUMBER - (cpu))
60 60
61 61 #define MC_COR_ECC_CNT(chipid, reg) (*pci_getl_func)(SOCKET_BUS(chipid), \
62 62 NEHALEM_EP_MEMORY_CONTROLLER_DEV, NEHALEM_EP_MEMORY_CONTROLLER_FUNC, \
63 63 0x80 + (reg) * 4)
64 64
65 65 #define MSCOD_MEM_ECC_READ 0x1
66 66 #define MSCOD_MEM_ECC_SCRUB 0x2
67 67 #define MSCOD_MEM_WR_PARITY 0x4
68 68 #define MSCOD_MEM_REDUNDANT_MEM 0x8
69 69 #define MSCOD_MEM_SPARE_MEM 0x10
70 70 #define MSCOD_MEM_ILLEGAL_ADDR 0x20
71 71 #define MSCOD_MEM_BAD_ID 0x40
72 72 #define MSCOD_MEM_ADDR_PARITY 0x80
73 73 #define MSCOD_MEM_BYTE_PARITY 0x100
74 74
75 75 #define GINTEL_ERROR_MEM 0x1000
76 76 #define GINTEL_ERROR_QUICKPATH 0x2000
77 77 #define GINTEL_ERROR_UNKNOWN 0x4000
78 78
79 79 #define GINTEL_ERR_SPARE_MEM (GINTEL_ERROR_MEM | 1)
80 80 #define GINTEL_ERR_MEM_UE (GINTEL_ERROR_MEM | 2)
81 81 #define GINTEL_ERR_MEM_CE (GINTEL_ERROR_MEM | 3)
82 82 #define GINTEL_ERR_MEM_PARITY (GINTEL_ERROR_MEM | 4)
83 83 #define GINTEL_ERR_MEM_ADDR_PARITY (GINTEL_ERROR_MEM | 5)
84 84 #define GINTEL_ERR_MEM_REDUNDANT (GINTEL_ERROR_MEM | 6)
85 85 #define GINTEL_ERR_MEM_BAD_ADDR (GINTEL_ERROR_MEM | 7)
86 86 #define GINTEL_ERR_MEM_BAD_ID (GINTEL_ERROR_MEM | 8)
87 87 #define GINTEL_ERR_MEM_UNKNOWN (GINTEL_ERROR_MEM | 0xfff)
88 88
89 89 #define MSR_MC_MISC_MEM_CHANNEL_MASK 0x00000000000c0000ULL
90 90 #define MSR_MC_MISC_MEM_CHANNEL_SHIFT 18
91 91 #define MSR_MC_MISC_MEM_DIMM_MASK 0x0000000000030000ULL
92 92 #define MSR_MC_MISC_MEM_DIMM_SHIFT 16
93 93 #define MSR_MC_MISC_MEM_SYNDROME_MASK 0xffffffff00000000ULL
94 94 #define MSR_MC_MISC_MEM_SYNDROME_SHIFT 32
95 95
96 96 #define CPU_GENERATION_DONT_CARE 0
97 97 #define CPU_GENERATION_NEHALEM_EP 1
98 98
99 99 #define INTEL_CPU_6_ID 0x6
100 100 #define INTEL_NEHALEM_CPU_FAMILY_ID 0x6
101 101 #define INTEL_NEHALEM_CPU_MODEL_ID 0x1A
102 102
103 103 #define NEHALEM_EP_MEMORY_CONTROLLER_DEV 0x3
104 104 #define NEHALEM_EP_MEMORY_CONTROLLER_FUNC 0x2
105 105
106 106 /*ARGSUSED*/
107 107 int
108 108 gintel_init(cmi_hdl_t hdl, void **datap)
109 109 {
110 110 uint32_t nb_chipset;
111 111
112 112 if (gintel_ms_support_disable)
113 113 return (ENOTSUP);
114 114
115 115 if (!is_x86_feature(x86_featureset, X86FSET_MCA))
116 116 return (ENOTSUP);
117 117
118 118 nb_chipset = (*pci_getl_func)(0, 0, 0, 0x0);
119 119 switch (nb_chipset) {
120 120 case INTEL_NB_7300:
121 121 case INTEL_NB_5000P:
122 122 case INTEL_NB_5000X:
123 123 case INTEL_NB_5000V:
124 124 case INTEL_NB_5000Z:
125 125 case INTEL_NB_5400:
126 126 case INTEL_NB_5400A:
127 127 case INTEL_NB_5400B:
128 128 if (!gintel_ms_unconstrained)
129 129 gintel_error_action_return |= CMS_ERRSCOPE_POISONED;
130 130 break;
131 131 case INTEL_QP_IO:
132 132 case INTEL_QP_WP:
133 133 case INTEL_QP_36D:
134 134 case INTEL_QP_24D:
135 135 case INTEL_QP_U1:
136 136 case INTEL_QP_U2:
137 137 case INTEL_QP_U3:
138 138 case INTEL_QP_U4:
139 139 case INTEL_QP_JF:
140 140 case INTEL_QP_JF0:
141 141 case INTEL_QP_JF1:
142 142 case INTEL_QP_JF2:
143 143 case INTEL_QP_JF3:
144 144 case INTEL_QP_JF4:
145 145 case INTEL_QP_JF5:
146 146 case INTEL_QP_JF6:
147 147 case INTEL_QP_JF7:
148 148 case INTEL_QP_JF8:
149 149 case INTEL_QP_JF9:
150 150 case INTEL_QP_JFa:
151 151 case INTEL_QP_JFb:
152 152 case INTEL_QP_JFc:
153 153 case INTEL_QP_JFd:
154 154 case INTEL_QP_JFe:
155 155 case INTEL_QP_JFf:
156 156 quickpath = 1;
157 157 break;
158 158 default:
159 159 break;
160 160 }
161 161 return (0);
162 162 }
163 163
164 164 /*ARGSUSED*/
165 165 uint32_t
166 166 gintel_error_action(cmi_hdl_t hdl, int ismc, int bank,
167 167 uint64_t status, uint64_t addr, uint64_t misc, void *mslogout)
168 168 {
169 169 uint32_t rc;
170 170
171 171 if (ismc == 0 && bank == 0 &&
172 172 cmi_hdl_family(hdl) == INTEL_CPU_6_ID &&
173 173 cmi_hdl_model(hdl) < INTEL_NEHALEM_CPU_MODEL_ID &&
174 174 MCAX86_ERRCODE_ISBUS_INTERCONNECT(MCAX86_ERRCODE(status)) &&
175 175 MCAX86_MSERRCODE(status) == 0) {
176 176 rc = CMS_ERRSCOPE_CURCONTEXT_OK | CMS_ERRSCOPE_CLEARED_UC;
177 177 } else if ((status & MSR_MC_STATUS_PCC) == 0) {
178 178 rc = gintel_error_action_return;
179 179 } else {
180 180 rc = gintel_error_action_return & ~CMS_ERRSCOPE_POISONED;
181 181 }
182 182 return (rc);
183 183 }
184 184
185 185 /*ARGSUSED*/
186 186 cms_cookie_t
187 187 gintel_disp_match(cmi_hdl_t hdl, int ismc, int bank, uint64_t status,
188 188 uint64_t addr, uint64_t misc, void *mslogout)
189 189 {
190 190 cms_cookie_t rt = (cms_cookie_t)NULL;
191 191 uint16_t mcacode = MCAX86_ERRCODE(status);
192 192 uint16_t mscode = MCAX86_MSERRCODE(status);
193 193
194 194 if (MCAX86_ERRCODE_ISMEMORY_CONTROLLER(mcacode)) {
195 195 /*
196 196 * memory controller errors
197 197 */
198 198 if (mscode & MSCOD_MEM_SPARE_MEM) {
199 199 rt = (cms_cookie_t)GINTEL_ERR_SPARE_MEM;
200 200 } else if (mscode & (MSCOD_MEM_ECC_READ |
201 201 MSCOD_MEM_ECC_SCRUB)) {
202 202 if (status & MSR_MC_STATUS_UC)
203 203 rt = (cms_cookie_t)GINTEL_ERR_MEM_UE;
204 204 else
205 205 rt = (cms_cookie_t)GINTEL_ERR_MEM_CE;
206 206 } else if (mscode & (MSCOD_MEM_WR_PARITY |
207 207 MSCOD_MEM_BYTE_PARITY)) {
208 208 rt = (cms_cookie_t)GINTEL_ERR_MEM_PARITY;
209 209 } else if (mscode & MSCOD_MEM_ADDR_PARITY) {
210 210 rt = (cms_cookie_t)GINTEL_ERR_MEM_ADDR_PARITY;
211 211 } else if (mscode & MSCOD_MEM_REDUNDANT_MEM) {
212 212 rt = (cms_cookie_t)GINTEL_ERR_MEM_REDUNDANT;
213 213 } else if (mscode & MSCOD_MEM_ILLEGAL_ADDR) {
214 214 rt = (cms_cookie_t)GINTEL_ERR_MEM_BAD_ADDR;
215 215 } else if (mscode & MSCOD_MEM_BAD_ID) {
216 216 rt = (cms_cookie_t)GINTEL_ERR_MEM_BAD_ID;
217 217 } else {
218 218 rt = (cms_cookie_t)GINTEL_ERR_MEM_UNKNOWN;
219 219 }
220 220 } else if (quickpath &&
221 221 MCAX86_ERRCODE_ISBUS_INTERCONNECT(MCAX86_ERRCODE(status))) {
222 222 rt = (cms_cookie_t)GINTEL_ERROR_QUICKPATH;
223 223 } else if (ismc == 0 && bank == 0 &&
224 224 cmi_hdl_family(hdl) == INTEL_CPU_6_ID &&
225 225 cmi_hdl_model(hdl) < INTEL_NEHALEM_CPU_MODEL_ID &&
226 226 MCAX86_ERRCODE_ISBUS_INTERCONNECT(MCAX86_ERRCODE(status)) &&
227 227 MCAX86_MSERRCODE(status) == 0) {
228 228 rt = (cms_cookie_t)GINTEL_ERROR_UNKNOWN;
229 229 }
230 230 return (rt);
231 231 }
232 232
233 233 /*ARGSUSED*/
234 234 void
235 235 gintel_ereport_class(cmi_hdl_t hdl, cms_cookie_t mscookie,
236 236 const char **cpuclsp, const char **leafclsp)
237 237 {
238 238 *cpuclsp = FM_EREPORT_CPU_INTEL;
239 239 switch ((uintptr_t)mscookie) {
240 240 case GINTEL_ERROR_QUICKPATH:
241 241 *leafclsp = "quickpath.interconnect";
242 242 break;
243 243 case GINTEL_ERR_SPARE_MEM:
244 244 *leafclsp = "quickpath.mem_spare";
245 245 break;
246 246 case GINTEL_ERR_MEM_UE:
247 247 *leafclsp = "quickpath.mem_ue";
248 248 break;
249 249 case GINTEL_ERR_MEM_CE:
250 250 *leafclsp = "quickpath.mem_ce";
251 251 break;
252 252 case GINTEL_ERR_MEM_PARITY:
253 253 *leafclsp = "quickpath.mem_parity";
254 254 break;
255 255 case GINTEL_ERR_MEM_ADDR_PARITY:
256 256 *leafclsp = "quickpath.mem_addr_parity";
257 257 break;
258 258 case GINTEL_ERR_MEM_REDUNDANT:
259 259 *leafclsp = "quickpath.mem_redundant";
260 260 break;
261 261 case GINTEL_ERR_MEM_BAD_ADDR:
262 262 *leafclsp = "quickpath.mem_bad_addr";
263 263 break;
264 264 case GINTEL_ERR_MEM_BAD_ID:
265 265 *leafclsp = "quickpath.mem_bad_id";
266 266 break;
267 267 case GINTEL_ERR_MEM_UNKNOWN:
268 268 *leafclsp = "quickpath.mem_unknown";
269 269 break;
270 270 case GINTEL_ERROR_UNKNOWN:
271 271 *leafclsp = "unknown";
272 272 break;
273 273 }
274 274 }
275 275
276 276 static nvlist_t *
277 277 gintel_gentopo_ereport_detector(cmi_hdl_t hdl, cms_cookie_t mscookie,
278 278 nv_alloc_t *nva)
279 279 {
280 280 nvlist_t *nvl = (nvlist_t *)NULL;
281 281 nvlist_t *board_list = (nvlist_t *)NULL;
282 282
283 283 if (mscookie) {
284 284 board_list = cmi_hdl_smb_bboard(hdl);
285 285
286 286 if (board_list == NULL)
287 287 return (NULL);
288 288
289 289 if ((nvl = fm_nvlist_create(nva)) == NULL)
290 290 return (NULL);
291 291
292 292 if ((uintptr_t)mscookie & GINTEL_ERROR_QUICKPATH) {
293 293 fm_fmri_hc_create(nvl, FM_HC_SCHEME_VERSION,
294 294 NULL, NULL, board_list, 1,
295 295 "chip", cmi_hdl_smb_chipid(hdl));
296 296 } else {
297 297 fm_fmri_hc_create(nvl, FM_HC_SCHEME_VERSION,
298 298 NULL, NULL, board_list, 2,
299 299 "chip", cmi_hdl_smb_chipid(hdl),
300 300 "memory-controller", 0);
301 301 }
302 302 }
303 303 return (nvl);
304 304 }
305 305
306 306 /*ARGSUSED*/
307 307 nvlist_t *
308 308 gintel_ereport_detector(cmi_hdl_t hdl, int bankno, cms_cookie_t mscookie,
309 309 nv_alloc_t *nva)
310 310 {
311 311 nvlist_t *nvl = (nvlist_t *)NULL;
312 312
313 313 if (!x86gentopo_legacy) {
314 314 nvl = gintel_gentopo_ereport_detector(hdl, mscookie, nva);
315 315 return (nvl);
316 316 }
317 317
318 318 if (mscookie) {
319 319 if ((nvl = fm_nvlist_create(nva)) == NULL)
320 320 return (NULL);
321 321 if (((uintptr_t)mscookie & GINTEL_ERROR_QUICKPATH) ||
322 322 ((uintptr_t)mscookie & GINTEL_ERROR_UNKNOWN)) {
323 323 fm_fmri_hc_set(nvl, FM_HC_SCHEME_VERSION, NULL, NULL, 2,
324 324 "motherboard", 0,
325 325 "chip", cmi_hdl_chipid(hdl));
326 326 } else {
327 327 fm_fmri_hc_set(nvl, FM_HC_SCHEME_VERSION, NULL, NULL, 3,
328 328 "motherboard", 0,
329 329 "chip", cmi_hdl_chipid(hdl),
330 330 "memory-controller", 0);
331 331 }
332 332 }
333 333 return (nvl);
334 334 }
335 335
336 336 static nvlist_t *
337 337 gintel_gentopo_ereport_create_resource_elem(cmi_hdl_t hdl, nv_alloc_t *nva,
338 338 mc_unum_t *unump)
339 339 {
340 340 nvlist_t *nvl, *snvl;
341 341 nvlist_t *board_list = NULL;
342 342
343 343 board_list = cmi_hdl_smb_bboard(hdl);
344 344 if (board_list == NULL) {
345 345 return (NULL);
346 346 }
347 347
348 348 if ((nvl = fm_nvlist_create(nva)) == NULL) /* freed by caller */
349 349 return (NULL);
350 350
351 351 if ((snvl = fm_nvlist_create(nva)) == NULL) {
352 352 fm_nvlist_destroy(nvl, nva ? FM_NVA_RETAIN : FM_NVA_FREE);
353 353 return (NULL);
354 354 }
355 355
356 356 (void) nvlist_add_uint64(snvl, FM_FMRI_HC_SPECIFIC_OFFSET,
357 357 unump->unum_offset);
358 358
359 359 if (unump->unum_chan == -1) {
360 360 fm_fmri_hc_create(nvl, FM_HC_SCHEME_VERSION, NULL, snvl,
361 361 board_list, 2,
362 362 "chip", cmi_hdl_smb_chipid(hdl),
363 363 "memory-controller", unump->unum_mc);
364 364 } else if (unump->unum_cs == -1) {
365 365 fm_fmri_hc_create(nvl, FM_HC_SCHEME_VERSION, NULL, snvl,
366 366 board_list, 3,
367 367 "chip", cmi_hdl_smb_chipid(hdl),
368 368 "memory-controller", unump->unum_mc,
369 369 "dram-channel", unump->unum_chan);
370 370 } else if (unump->unum_rank == -1) {
371 371 fm_fmri_hc_create(nvl, FM_HC_SCHEME_VERSION, NULL, snvl,
372 372 board_list, 4,
373 373 "chip", cmi_hdl_smb_chipid(hdl),
374 374 "memory-controller", unump->unum_mc,
375 375 "dram-channel", unump->unum_chan,
376 376 "dimm", unump->unum_cs);
377 377 } else {
378 378 fm_fmri_hc_create(nvl, FM_HC_SCHEME_VERSION, NULL, snvl,
379 379 board_list, 5,
380 380 "chip", cmi_hdl_smb_chipid(hdl),
381 381 "memory-controller", unump->unum_mc,
382 382 "dram-channel", unump->unum_chan,
383 383 "dimm", unump->unum_cs,
384 384 "rank", unump->unum_rank);
385 385 }
386 386
387 387 fm_nvlist_destroy(snvl, nva ? FM_NVA_RETAIN : FM_NVA_FREE);
388 388
389 389 return (nvl);
390 390 }
391 391
392 392 static nvlist_t *
393 393 gintel_ereport_create_resource_elem(nv_alloc_t *nva, mc_unum_t *unump)
394 394 {
395 395 nvlist_t *nvl, *snvl;
396 396
397 397 if ((nvl = fm_nvlist_create(nva)) == NULL) /* freed by caller */
398 398 return (NULL);
399 399
400 400 if ((snvl = fm_nvlist_create(nva)) == NULL) {
401 401 fm_nvlist_destroy(nvl, nva ? FM_NVA_RETAIN : FM_NVA_FREE);
402 402 return (NULL);
403 403 }
404 404
405 405 (void) nvlist_add_uint64(snvl, FM_FMRI_HC_SPECIFIC_OFFSET,
406 406 unump->unum_offset);
407 407
408 408 if (unump->unum_chan == -1) {
409 409 fm_fmri_hc_set(nvl, FM_HC_SCHEME_VERSION, NULL, snvl, 3,
410 410 "motherboard", unump->unum_board,
411 411 "chip", unump->unum_chip,
412 412 "memory-controller", unump->unum_mc);
413 413 } else if (unump->unum_cs == -1) {
414 414 fm_fmri_hc_set(nvl, FM_HC_SCHEME_VERSION, NULL, snvl, 4,
415 415 "motherboard", unump->unum_board,
416 416 "chip", unump->unum_chip,
417 417 "memory-controller", unump->unum_mc,
418 418 "dram-channel", unump->unum_chan);
419 419 } else if (unump->unum_rank == -1) {
420 420 fm_fmri_hc_set(nvl, FM_HC_SCHEME_VERSION, NULL, snvl, 5,
421 421 "motherboard", unump->unum_board,
422 422 "chip", unump->unum_chip,
423 423 "memory-controller", unump->unum_mc,
424 424 "dram-channel", unump->unum_chan,
425 425 "dimm", unump->unum_cs);
426 426 } else {
427 427 fm_fmri_hc_set(nvl, FM_HC_SCHEME_VERSION, NULL, snvl, 6,
428 428 "motherboard", unump->unum_board,
429 429 "chip", unump->unum_chip,
430 430 "memory-controller", unump->unum_mc,
431 431 "dram-channel", unump->unum_chan,
432 432 "dimm", unump->unum_cs,
433 433 "rank", unump->unum_rank);
434 434 }
435 435
436 436 fm_nvlist_destroy(snvl, nva ? FM_NVA_RETAIN : FM_NVA_FREE);
437 437
438 438 return (nvl);
439 439 }
440 440
441 441 static void
442 442 nehalem_ep_ereport_add_memory_error_counter(uint_t chipid,
443 443 uint32_t *this_err_counter_array)
444 444 {
445 445 int index;
446 446
447 447 for (index = 0; index < N_MC_COR_ECC_CNT; index ++)
448 448 this_err_counter_array[index] = MC_COR_ECC_CNT(chipid, index);
449 449 }
450 450
451 451 static int
452 452 gintel_cpu_generation(cmi_hdl_t hdl)
453 453 {
454 454 int cpu_generation = CPU_GENERATION_DONT_CARE;
455 455
456 456 if ((cmi_hdl_family(hdl) == INTEL_NEHALEM_CPU_FAMILY_ID) &&
457 457 (cmi_hdl_model(hdl) == INTEL_NEHALEM_CPU_MODEL_ID))
458 458 cpu_generation = CPU_GENERATION_NEHALEM_EP;
459 459
460 460 return (cpu_generation);
461 461 }
462 462
463 463 /*ARGSUSED*/
464 464 void
465 465 gintel_ereport_add_logout(cmi_hdl_t hdl, nvlist_t *ereport,
466 466 nv_alloc_t *nva, int banknum, uint64_t status, uint64_t addr,
467 467 uint64_t misc, void *mslogout, cms_cookie_t mscookie)
468 468 {
469 469 mc_unum_t unum;
470 470 nvlist_t *resource;
471 471 uint32_t synd = 0;
472 472 int chan = MCAX86_ERRCODE_CCCC(status);
473 473 uint8_t last_index, this_index;
474 474 int chipid;
475 475
476 476 if (chan == 0xf)
477 477 chan = -1;
478 478
479 479 if ((uintptr_t)mscookie & GINTEL_ERROR_MEM) {
480 480 unum.unum_board = 0;
481 481 unum.unum_chip = cmi_hdl_chipid(hdl);
482 482 unum.unum_mc = 0;
483 483 unum.unum_chan = chan;
484 484 unum.unum_cs = -1;
485 485 unum.unum_rank = -1;
486 486 unum.unum_offset = -1ULL;
487 487 if (status & MSR_MC_STATUS_MISCV) {
488 488 unum.unum_chan =
489 489 (misc & MSR_MC_MISC_MEM_CHANNEL_MASK) >>
490 490 MSR_MC_MISC_MEM_CHANNEL_SHIFT;
491 491 unum.unum_cs =
492 492 (misc & MSR_MC_MISC_MEM_DIMM_MASK) >>
493 493 MSR_MC_MISC_MEM_DIMM_SHIFT;
494 494 synd = (misc & MSR_MC_MISC_MEM_SYNDROME_MASK) >>
495 495 MSR_MC_MISC_MEM_SYNDROME_SHIFT;
496 496 fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ECC_SYND,
497 497 DATA_TYPE_UINT32, synd, 0);
498 498 }
499 499 if (status & MSR_MC_STATUS_ADDRV) {
500 500 fm_payload_set(ereport, FM_FMRI_MEM_PHYSADDR,
501 501 DATA_TYPE_UINT64, addr, NULL);
502 502 (void) cmi_mc_patounum(addr, 0, 0, synd, 0, &unum);
503 503 if (unum.unum_offset != -1ULL &&
504 504 (unum.unum_offset & OFFSET_ROW_BANK_COL) != 0) {
505 505 fm_payload_set(ereport,
506 506 FM_EREPORT_PAYLOAD_NAME_BANK,
507 507 DATA_TYPE_INT32,
508 508 TCODE_OFFSET_BANK(unum.unum_offset), NULL);
509 509 fm_payload_set(ereport,
510 510 FM_EREPORT_PAYLOAD_NAME_CAS,
511 511 DATA_TYPE_INT32,
512 512 TCODE_OFFSET_CAS(unum.unum_offset), NULL);
513 513 fm_payload_set(ereport,
514 514 FM_EREPORT_PAYLOAD_NAME_RAS,
515 515 DATA_TYPE_INT32,
516 516 TCODE_OFFSET_RAS(unum.unum_offset), NULL);
517 517 }
518 518 }
519 519
520 520 if (!x86gentopo_legacy) {
521 521 resource = gintel_gentopo_ereport_create_resource_elem(
522 522 hdl, nva, &unum);
523 523 } else {
524 524 resource = gintel_ereport_create_resource_elem(nva,
525 525 &unum);
526 526 }
527 527
528 528 fm_payload_set(ereport, FM_EREPORT_PAYLOAD_NAME_RESOURCE,
529 529 DATA_TYPE_NVLIST_ARRAY, 1, &resource, NULL);
530 530 fm_nvlist_destroy(resource, nva ? FM_NVA_RETAIN:FM_NVA_FREE);
531 531
532 532 if (gintel_cpu_generation(hdl) == CPU_GENERATION_NEHALEM_EP) {
533 533
534 534 chipid = unum.unum_chip;
535 535 if (chipid < MAX_CPU_NODES) {
536 536 last_index = err_counter_index[chipid];
537 537 this_index =
538 538 (last_index + 1) % ERR_COUNTER_INDEX;
539 539 err_counter_index[chipid] = this_index;
540 540 nehalem_ep_ereport_add_memory_error_counter(
541 541 chipid,
542 542 err_counter_array[chipid][this_index]);
543 543 fm_payload_set(ereport,
544 544 FM_EREPORT_PAYLOAD_MEM_ECC_COUNTER_THIS,
545 545 DATA_TYPE_UINT32_ARRAY, N_MC_COR_ECC_CNT,
546 546 err_counter_array[chipid][this_index],
547 547 NULL);
548 548 fm_payload_set(ereport,
549 549 FM_EREPORT_PAYLOAD_MEM_ECC_COUNTER_LAST,
550 550 DATA_TYPE_UINT32_ARRAY, N_MC_COR_ECC_CNT,
551 551 err_counter_array[chipid][last_index],
552 552 NULL);
553 553 }
554 554 }
555 555 }
556 556 }
557 557
558 558 boolean_t
559 559 gintel_bankctl_skipinit(cmi_hdl_t hdl, int banknum)
560 560 {
561 561 /*
562 562 * On Intel family 6 before QuickPath we must not enable machine check
563 563 * from bank 0 detectors. bank 0 is reserved for the platform
564 564 */
565 565
566 566 if (banknum == 0 &&
567 567 cmi_hdl_family(hdl) == INTEL_NEHALEM_CPU_FAMILY_ID &&
568 568 cmi_hdl_model(hdl) < INTEL_NEHALEM_CPU_MODEL_ID)
569 569 return (1);
570 570 else
571 571 return (0);
572 572 }
573 573
574 574 cms_api_ver_t _cms_api_version = CMS_API_VERSION_2;
575 575
576 576 const cms_ops_t _cms_ops = {
577 577 gintel_init, /* cms_init */
578 578 NULL, /* cms_post_startup */
579 579 NULL, /* cms_post_mpstartup */
580 580 NULL, /* cms_logout_size */
581 581 NULL, /* cms_mcgctl_val */
582 582 gintel_bankctl_skipinit, /* cms_bankctl_skipinit */
583 583 NULL, /* cms_bankctl_val */
584 584 NULL, /* cms_bankstatus_skipinit */
585 585 NULL, /* cms_bankstatus_val */
586 586 NULL, /* cms_mca_init */
587 587 NULL, /* cms_poll_ownermask */
588 588 NULL, /* cms_bank_logout */
589 589 gintel_error_action, /* cms_error_action */
590 590 gintel_disp_match, /* cms_disp_match */
591 591 gintel_ereport_class, /* cms_ereport_class */
592 592 gintel_ereport_detector, /* cms_ereport_detector */
593 593 NULL, /* cms_ereport_includestack */
594 594 gintel_ereport_add_logout, /* cms_ereport_add_logout */
595 595 NULL, /* cms_msrinject */
↓ open down ↓ |
595 lines elided |
↑ open up ↑ |
596 596 NULL, /* cms_fini */
597 597 };
598 598
599 599 static struct modlcpu modlcpu = {
600 600 &mod_cpuops,
601 601 "Generic Intel model-specific MCA"
602 602 };
603 603
604 604 static struct modlinkage modlinkage = {
605 605 MODREV_1,
606 - (void *)&modlcpu,
607 - NULL
606 + { (void *)&modlcpu, NULL }
608 607 };
609 608
610 609 int
611 610 _init(void)
612 611 {
613 612 return (mod_install(&modlinkage));
614 613 }
615 614
616 615 int
617 616 _info(struct modinfo *modinfop)
618 617 {
619 618 return (mod_info(&modlinkage, modinfop));
620 619 }
621 620
622 621 int
623 622 _fini(void)
624 623 {
625 624 return (mod_remove(&modlinkage));
626 625 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX