1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* 26 * All Rights Reserved, Copyright (c) FUJITSU LIMITED 2006 27 */ 28 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 #include <sys/types.h> 32 #include <sys/sysmacros.h> 33 #include <sys/conf.h> 34 #include <sys/modctl.h> 35 #include <sys/stat.h> 36 #include <sys/async.h> 37 #include <sys/machcpuvar.h> 38 #include <sys/machsystm.h> 39 #include <sys/promif.h> 40 #include <sys/ksynch.h> 41 #include <sys/ddi.h> 42 #include <sys/sunddi.h> 43 #include <sys/sunndi.h> 44 #include <sys/ddifm.h> 45 #include <sys/fm/protocol.h> 46 #include <sys/fm/util.h> 47 #include <sys/kmem.h> 48 #include <sys/fm/io/opl_mc_fm.h> 49 #include <sys/memlist.h> 50 #include <sys/param.h> 51 #include <sys/disp.h> 52 #include <vm/page.h> 53 #include <sys/mc-opl.h> 54 #include <sys/opl.h> 55 #include <sys/opl_dimm.h> 56 #include <sys/scfd/scfostoescf.h> 57 #include <sys/cpu_module.h> 58 #include <vm/seg_kmem.h> 59 #include <sys/vmem.h> 60 #include <vm/hat_sfmmu.h> 61 #include <sys/vmsystm.h> 62 #include <sys/membar.h> 63 64 /* 65 * Function prototypes 66 */ 67 static int mc_open(dev_t *, int, int, cred_t *); 68 static int mc_close(dev_t, int, int, cred_t *); 69 static int mc_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 70 static int mc_attach(dev_info_t *, ddi_attach_cmd_t); 71 static int mc_detach(dev_info_t *, ddi_detach_cmd_t); 72 73 static int mc_poll_init(void); 74 static void mc_poll_fini(void); 75 static int mc_board_add(mc_opl_t *mcp); 76 static int mc_board_del(mc_opl_t *mcp); 77 static int mc_suspend(mc_opl_t *mcp, uint32_t flag); 78 static int mc_resume(mc_opl_t *mcp, uint32_t flag); 79 int opl_mc_suspend(void); 80 int opl_mc_resume(void); 81 82 static void insert_mcp(mc_opl_t *mcp); 83 static void delete_mcp(mc_opl_t *mcp); 84 85 static int pa_to_maddr(mc_opl_t *mcp, uint64_t pa, mc_addr_t *maddr); 86 87 static int mc_rangecheck_pa(mc_opl_t *mcp, uint64_t pa); 88 89 int mc_get_mem_unum(int, uint64_t, char *, int, int *); 90 int mc_get_mem_addr(char *unum, char *sid, uint64_t offset, uint64_t *paddr); 91 int mc_get_mem_offset(uint64_t paddr, uint64_t *offp); 92 int mc_get_mem_sid(char *unum, char *buf, int buflen, int *lenp); 93 int mc_get_mem_sid_dimm(mc_opl_t *mcp, char *dname, char *buf, 94 int buflen, int *lenp); 95 mc_dimm_info_t *mc_get_dimm_list(mc_opl_t *mcp); 96 mc_dimm_info_t *mc_prepare_dimmlist(board_dimm_info_t *bd_dimmp); 97 int mc_set_mem_sid(mc_opl_t *mcp, char *buf, int buflen, int lsb, int bank, 98 uint32_t mf_type, uint32_t d_slot); 99 static void mc_free_dimm_list(mc_dimm_info_t *d); 100 static void mc_get_mlist(mc_opl_t *); 101 static void mc_polling(void); 102 static int mc_opl_get_physical_board(int); 103 104 #ifdef DEBUG 105 static int mc_ioctl_debug(dev_t, int, intptr_t, int, cred_t *, int *); 106 void mc_dump_dimm(char *buf, int dnamesz, int serialsz, int partnumsz); 107 void mc_dump_dimm_info(board_dimm_info_t *bd_dimmp); 108 #endif 109 110 #pragma weak opl_get_physical_board 111 extern int opl_get_physical_board(int); 112 extern int plat_max_boards(void); 113 114 /* 115 * Configuration data structures 116 */ 117 static struct cb_ops mc_cb_ops = { 118 mc_open, /* open */ 119 mc_close, /* close */ 120 nulldev, /* strategy */ 121 nulldev, /* print */ 122 nodev, /* dump */ 123 nulldev, /* read */ 124 nulldev, /* write */ 125 mc_ioctl, /* ioctl */ 126 nodev, /* devmap */ 127 nodev, /* mmap */ 128 nodev, /* segmap */ 129 nochpoll, /* poll */ 130 ddi_prop_op, /* cb_prop_op */ 131 0, /* streamtab */ 132 D_MP | D_NEW | D_HOTPLUG, /* Driver compatibility flag */ 133 CB_REV, /* rev */ 134 nodev, /* cb_aread */ 135 nodev /* cb_awrite */ 136 }; 137 138 static struct dev_ops mc_ops = { 139 DEVO_REV, /* rev */ 140 0, /* refcnt */ 141 ddi_getinfo_1to1, /* getinfo */ 142 nulldev, /* identify */ 143 nulldev, /* probe */ 144 mc_attach, /* attach */ 145 mc_detach, /* detach */ 146 nulldev, /* reset */ 147 &mc_cb_ops, /* cb_ops */ 148 (struct bus_ops *)0, /* bus_ops */ 149 nulldev /* power */ 150 }; 151 152 /* 153 * Driver globals 154 */ 155 156 static enum { 157 MODEL_FF1 = 0, 158 MODEL_FF2 = 1, 159 MODEL_DC = 2 160 } plat_model = MODEL_DC; /* The default behaviour is DC */ 161 162 static struct plat_model_names { 163 const char *unit_name; 164 const char *mem_name; 165 } model_names[] = { 166 { "MBU_A", "MEMB" }, 167 { "MBU_B", "MEMB" }, 168 { "CMU", "" } 169 }; 170 171 /* 172 * The DIMM Names for DC platform. 173 * The index into this table is made up of (bank, dslot), 174 * Where dslot occupies bits 0-1 and bank occupies 2-4. 175 */ 176 static char *mc_dc_dimm_unum_table[OPL_MAX_DIMMS] = { 177 /* --------CMUnn----------- */ 178 /* --CS0-----|--CS1------ */ 179 /* -H-|--L-- | -H- | -L-- */ 180 "03A", "02A", "03B", "02B", /* Bank 0 (MAC 0 bank 0) */ 181 "13A", "12A", "13B", "12B", /* Bank 1 (MAC 0 bank 1) */ 182 "23A", "22A", "23B", "22B", /* Bank 2 (MAC 1 bank 0) */ 183 "33A", "32A", "33B", "32B", /* Bank 3 (MAC 1 bank 1) */ 184 "01A", "00A", "01B", "00B", /* Bank 4 (MAC 2 bank 0) */ 185 "11A", "10A", "11B", "10B", /* Bank 5 (MAC 2 bank 1) */ 186 "21A", "20A", "21B", "20B", /* Bank 6 (MAC 3 bank 0) */ 187 "31A", "30A", "31B", "30B" /* Bank 7 (MAC 3 bank 1) */ 188 }; 189 190 /* 191 * The DIMM Names for FF1/FF2 platforms. 192 * The index into this table is made up of (board, bank, dslot), 193 * Where dslot occupies bits 0-1, bank occupies 2-4 and 194 * board occupies the bit 5. 195 */ 196 static char *mc_ff_dimm_unum_table[2 * OPL_MAX_DIMMS] = { 197 /* --------CMU0---------- */ 198 /* --CS0-----|--CS1------ */ 199 /* -H-|--L-- | -H- | -L-- */ 200 "03A", "02A", "03B", "02B", /* Bank 0 (MAC 0 bank 0) */ 201 "01A", "00A", "01B", "00B", /* Bank 1 (MAC 0 bank 1) */ 202 "13A", "12A", "13B", "12B", /* Bank 2 (MAC 1 bank 0) */ 203 "11A", "10A", "11B", "10B", /* Bank 3 (MAC 1 bank 1) */ 204 "23A", "22A", "23B", "22B", /* Bank 4 (MAC 2 bank 0) */ 205 "21A", "20A", "21B", "20B", /* Bank 5 (MAC 2 bank 1) */ 206 "33A", "32A", "33B", "32B", /* Bank 6 (MAC 3 bank 0) */ 207 "31A", "30A", "31B", "30B", /* Bank 7 (MAC 3 bank 1) */ 208 /* --------CMU1---------- */ 209 /* --CS0-----|--CS1------ */ 210 /* -H-|--L-- | -H- | -L-- */ 211 "43A", "42A", "43B", "42B", /* Bank 0 (MAC 0 bank 0) */ 212 "41A", "40A", "41B", "40B", /* Bank 1 (MAC 0 bank 1) */ 213 "53A", "52A", "53B", "52B", /* Bank 2 (MAC 1 bank 0) */ 214 "51A", "50A", "51B", "50B", /* Bank 3 (MAC 1 bank 1) */ 215 "63A", "62A", "63B", "62B", /* Bank 4 (MAC 2 bank 0) */ 216 "61A", "60A", "61B", "60B", /* Bank 5 (MAC 2 bank 1) */ 217 "73A", "72A", "73B", "72B", /* Bank 6 (MAC 3 bank 0) */ 218 "71A", "70A", "71B", "70B" /* Bank 7 (MAC 3 bank 1) */ 219 }; 220 221 #define BD_BK_SLOT_TO_INDEX(bd, bk, s) \ 222 (((bd & 0x01) << 5) | ((bk & 0x07) << 2) | (s & 0x03)) 223 224 #define INDEX_TO_BANK(i) (((i) & 0x1C) >> 2) 225 #define INDEX_TO_SLOT(i) ((i) & 0x03) 226 227 #define SLOT_TO_CS(slot) ((slot & 0x3) >> 1) 228 229 /* Isolation unit size is 64 MB */ 230 #define MC_ISOLATION_BSIZE (64 * 1024 * 1024) 231 232 #define MC_MAX_SPEEDS 7 233 234 typedef struct { 235 uint32_t mc_speeds; 236 uint32_t mc_period; 237 } mc_scan_speed_t; 238 239 #define MC_CNTL_SPEED_SHIFT 26 240 241 /* 242 * In mirror mode, we normalized the bank idx to "even" since 243 * the HW treats them as one unit w.r.t programming. 244 * This bank index will be the "effective" bank index. 245 * All mirrored bank state info on mc_period, mc_speedup_period 246 * will be stored in the even bank structure to avoid code duplication. 247 */ 248 #define MIRROR_IDX(bankidx) (bankidx & ~1) 249 250 static mc_scan_speed_t mc_scan_speeds[MC_MAX_SPEEDS] = { 251 {0x6 << MC_CNTL_SPEED_SHIFT, 0}, 252 {0x5 << MC_CNTL_SPEED_SHIFT, 32}, 253 {0x4 << MC_CNTL_SPEED_SHIFT, 64}, 254 {0x3 << MC_CNTL_SPEED_SHIFT, 128}, 255 {0x2 << MC_CNTL_SPEED_SHIFT, 256}, 256 {0x1 << MC_CNTL_SPEED_SHIFT, 512}, 257 {0x0 << MC_CNTL_SPEED_SHIFT, 1024} 258 }; 259 260 static uint32_t mc_max_speed = (0x6 << 26); 261 262 int mc_isolation_bsize = MC_ISOLATION_BSIZE; 263 int mc_patrol_interval_sec = MC_PATROL_INTERVAL_SEC; 264 int mc_max_scf_retry = 16; 265 int mc_max_scf_logs = 64; 266 int mc_max_errlog_processed = BANKNUM_PER_SB*2; 267 int mc_scan_period = 12 * 60 * 60; /* 12 hours period */ 268 int mc_max_rewrite_loop = 100; 269 int mc_rewrite_delay = 10; 270 /* 271 * it takes SCF about 300 m.s. to process a requst. We can bail out 272 * if it is busy. It does not pay to wait for it too long. 273 */ 274 int mc_max_scf_loop = 2; 275 int mc_scf_delay = 100; 276 int mc_pce_dropped = 0; 277 int mc_poll_priority = MINCLSYSPRI; 278 279 280 /* 281 * Mutex hierarchy in mc-opl 282 * If both mcmutex and mc_lock must be held, 283 * mcmutex must be acquired first, and then mc_lock. 284 */ 285 286 static kmutex_t mcmutex; 287 mc_opl_t *mc_instances[OPL_MAX_BOARDS]; 288 289 static kmutex_t mc_polling_lock; 290 static kcondvar_t mc_polling_cv; 291 static kcondvar_t mc_poll_exit_cv; 292 static int mc_poll_cmd = 0; 293 static int mc_pollthr_running = 0; 294 int mc_timeout_period = 0; /* this is in m.s. */ 295 void *mc_statep; 296 297 #ifdef DEBUG 298 int oplmc_debug = 0; 299 #endif 300 301 static int mc_debug_show_all = 0; 302 303 extern struct mod_ops mod_driverops; 304 305 static struct modldrv modldrv = { 306 &mod_driverops, /* module type, this one is a driver */ 307 "OPL Memory-controller %I%", /* module name */ 308 &mc_ops, /* driver ops */ 309 }; 310 311 static struct modlinkage modlinkage = { 312 MODREV_1, /* rev */ 313 (void *)&modldrv, 314 NULL 315 }; 316 317 #pragma weak opl_get_mem_unum 318 #pragma weak opl_get_mem_sid 319 #pragma weak opl_get_mem_offset 320 #pragma weak opl_get_mem_addr 321 322 extern int (*opl_get_mem_unum)(int, uint64_t, char *, int, int *); 323 extern int (*opl_get_mem_sid)(char *unum, char *buf, int buflen, int *lenp); 324 extern int (*opl_get_mem_offset)(uint64_t paddr, uint64_t *offp); 325 extern int (*opl_get_mem_addr)(char *unum, char *sid, uint64_t offset, 326 uint64_t *paddr); 327 328 329 /* 330 * pseudo-mc node portid format 331 * 332 * [10] = 0 333 * [9] = 1 334 * [8] = LSB_ID[4] = 0 335 * [7:4] = LSB_ID[3:0] 336 * [3:0] = 0 337 * 338 */ 339 340 /* 341 * These are the module initialization routines. 342 */ 343 int 344 _init(void) 345 { 346 int error; 347 int plen; 348 char model[20]; 349 pnode_t node; 350 351 352 if ((error = ddi_soft_state_init(&mc_statep, 353 sizeof (mc_opl_t), 1)) != 0) 354 return (error); 355 356 if ((error = mc_poll_init()) != 0) { 357 ddi_soft_state_fini(&mc_statep); 358 return (error); 359 } 360 361 mutex_init(&mcmutex, NULL, MUTEX_DRIVER, NULL); 362 if (&opl_get_mem_unum) 363 opl_get_mem_unum = mc_get_mem_unum; 364 if (&opl_get_mem_sid) 365 opl_get_mem_sid = mc_get_mem_sid; 366 if (&opl_get_mem_offset) 367 opl_get_mem_offset = mc_get_mem_offset; 368 if (&opl_get_mem_addr) 369 opl_get_mem_addr = mc_get_mem_addr; 370 371 node = prom_rootnode(); 372 plen = prom_getproplen(node, "model"); 373 374 if (plen > 0 && plen < sizeof (model)) { 375 (void) prom_getprop(node, "model", model); 376 model[plen] = '\0'; 377 if (strcmp(model, "FF1") == 0) 378 plat_model = MODEL_FF1; 379 else if (strcmp(model, "FF2") == 0) 380 plat_model = MODEL_FF2; 381 else if (strncmp(model, "DC", 2) == 0) 382 plat_model = MODEL_DC; 383 } 384 385 error = mod_install(&modlinkage); 386 if (error != 0) { 387 if (&opl_get_mem_unum) 388 opl_get_mem_unum = NULL; 389 if (&opl_get_mem_sid) 390 opl_get_mem_sid = NULL; 391 if (&opl_get_mem_offset) 392 opl_get_mem_offset = NULL; 393 if (&opl_get_mem_addr) 394 opl_get_mem_addr = NULL; 395 mutex_destroy(&mcmutex); 396 mc_poll_fini(); 397 ddi_soft_state_fini(&mc_statep); 398 } 399 return (error); 400 } 401 402 int 403 _fini(void) 404 { 405 int error; 406 407 if ((error = mod_remove(&modlinkage)) != 0) 408 return (error); 409 410 if (&opl_get_mem_unum) 411 opl_get_mem_unum = NULL; 412 if (&opl_get_mem_sid) 413 opl_get_mem_sid = NULL; 414 if (&opl_get_mem_offset) 415 opl_get_mem_offset = NULL; 416 if (&opl_get_mem_addr) 417 opl_get_mem_addr = NULL; 418 419 mutex_destroy(&mcmutex); 420 mc_poll_fini(); 421 ddi_soft_state_fini(&mc_statep); 422 423 return (0); 424 } 425 426 int 427 _info(struct modinfo *modinfop) 428 { 429 return (mod_info(&modlinkage, modinfop)); 430 } 431 432 static void 433 mc_polling_thread() 434 { 435 mutex_enter(&mc_polling_lock); 436 mc_pollthr_running = 1; 437 while (!(mc_poll_cmd & MC_POLL_EXIT)) { 438 mc_polling(); 439 cv_timedwait(&mc_polling_cv, &mc_polling_lock, 440 ddi_get_lbolt() + mc_timeout_period); 441 } 442 mc_pollthr_running = 0; 443 444 /* 445 * signal if any one is waiting for this thread to exit. 446 */ 447 cv_signal(&mc_poll_exit_cv); 448 mutex_exit(&mc_polling_lock); 449 thread_exit(); 450 /* NOTREACHED */ 451 } 452 453 static int 454 mc_poll_init() 455 { 456 mutex_init(&mc_polling_lock, NULL, MUTEX_DRIVER, NULL); 457 cv_init(&mc_polling_cv, NULL, CV_DRIVER, NULL); 458 cv_init(&mc_poll_exit_cv, NULL, CV_DRIVER, NULL); 459 return (0); 460 } 461 462 static void 463 mc_poll_fini() 464 { 465 mutex_enter(&mc_polling_lock); 466 if (mc_pollthr_running) { 467 mc_poll_cmd = MC_POLL_EXIT; 468 cv_signal(&mc_polling_cv); 469 while (mc_pollthr_running) { 470 cv_wait(&mc_poll_exit_cv, &mc_polling_lock); 471 } 472 } 473 mutex_exit(&mc_polling_lock); 474 mutex_destroy(&mc_polling_lock); 475 cv_destroy(&mc_polling_cv); 476 cv_destroy(&mc_poll_exit_cv); 477 } 478 479 static int 480 mc_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 481 { 482 mc_opl_t *mcp; 483 int instance; 484 int rv; 485 486 /* get the instance of this devi */ 487 instance = ddi_get_instance(devi); 488 489 switch (cmd) { 490 case DDI_ATTACH: 491 break; 492 case DDI_RESUME: 493 mcp = ddi_get_soft_state(mc_statep, instance); 494 rv = mc_resume(mcp, MC_DRIVER_SUSPENDED); 495 return (rv); 496 default: 497 return (DDI_FAILURE); 498 } 499 500 if (ddi_soft_state_zalloc(mc_statep, instance) != DDI_SUCCESS) 501 return (DDI_FAILURE); 502 503 if ((mcp = ddi_get_soft_state(mc_statep, instance)) == NULL) { 504 goto bad; 505 } 506 507 if (mc_timeout_period == 0) { 508 mc_patrol_interval_sec = (int)ddi_getprop(DDI_DEV_T_ANY, devi, 509 DDI_PROP_DONTPASS, "mc-timeout-interval-sec", 510 mc_patrol_interval_sec); 511 mc_timeout_period = drv_usectohz(1000000 * 512 mc_patrol_interval_sec / OPL_MAX_BOARDS); 513 } 514 515 /* set informations in mc state */ 516 mcp->mc_dip = devi; 517 518 if (mc_board_add(mcp)) 519 goto bad; 520 521 insert_mcp(mcp); 522 523 /* 524 * Start the polling thread if it is not running already. 525 */ 526 mutex_enter(&mc_polling_lock); 527 if (!mc_pollthr_running) { 528 (void) thread_create(NULL, 0, (void (*)())mc_polling_thread, 529 NULL, 0, &p0, TS_RUN, mc_poll_priority); 530 } 531 mutex_exit(&mc_polling_lock); 532 ddi_report_dev(devi); 533 534 return (DDI_SUCCESS); 535 536 bad: 537 ddi_soft_state_free(mc_statep, instance); 538 return (DDI_FAILURE); 539 } 540 541 /* ARGSUSED */ 542 static int 543 mc_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 544 { 545 int rv; 546 int instance; 547 mc_opl_t *mcp; 548 549 /* get the instance of this devi */ 550 instance = ddi_get_instance(devi); 551 if ((mcp = ddi_get_soft_state(mc_statep, instance)) == NULL) { 552 return (DDI_FAILURE); 553 } 554 555 switch (cmd) { 556 case DDI_SUSPEND: 557 rv = mc_suspend(mcp, MC_DRIVER_SUSPENDED); 558 return (rv); 559 case DDI_DETACH: 560 break; 561 default: 562 return (DDI_FAILURE); 563 } 564 565 delete_mcp(mcp); 566 if (mc_board_del(mcp) != DDI_SUCCESS) { 567 return (DDI_FAILURE); 568 } 569 570 /* free up the soft state */ 571 ddi_soft_state_free(mc_statep, instance); 572 573 return (DDI_SUCCESS); 574 } 575 576 /* ARGSUSED */ 577 static int 578 mc_open(dev_t *devp, int flag, int otyp, cred_t *credp) 579 { 580 return (0); 581 } 582 583 /* ARGSUSED */ 584 static int 585 mc_close(dev_t devp, int flag, int otyp, cred_t *credp) 586 { 587 return (0); 588 } 589 590 /* ARGSUSED */ 591 static int 592 mc_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, 593 int *rvalp) 594 { 595 #ifdef DEBUG 596 return (mc_ioctl_debug(dev, cmd, arg, mode, credp, rvalp)); 597 #else 598 return (ENXIO); 599 #endif 600 } 601 602 /* 603 * PA validity check: 604 * This function return 1 if the PA is a valid PA 605 * in the running Solaris instance i.e. in physinstall 606 * Otherwise, return 0. 607 */ 608 609 /* ARGSUSED */ 610 static int 611 pa_is_valid(mc_opl_t *mcp, uint64_t addr) 612 { 613 if (mcp->mlist == NULL) 614 mc_get_mlist(mcp); 615 616 if (mcp->mlist && address_in_memlist(mcp->mlist, addr, 0)) { 617 return (1); 618 } 619 return (0); 620 } 621 622 /* 623 * mac-pa translation routines. 624 * 625 * Input: mc driver state, (LSB#, Bank#, DIMM address) 626 * Output: physical address 627 * 628 * Valid - return value: 0 629 * Invalid - return value: -1 630 */ 631 static int 632 mcaddr_to_pa(mc_opl_t *mcp, mc_addr_t *maddr, uint64_t *pa) 633 { 634 int i; 635 uint64_t pa_offset = 0; 636 int cs = (maddr->ma_dimm_addr >> CS_SHIFT) & 1; 637 int bank = maddr->ma_bank; 638 mc_addr_t maddr1; 639 int bank0, bank1; 640 641 MC_LOG("mcaddr /LSB%d/B%d/%x\n", maddr->ma_bd, bank, 642 maddr->ma_dimm_addr); 643 644 /* loc validity check */ 645 ASSERT(maddr->ma_bd >= 0 && OPL_BOARD_MAX > maddr->ma_bd); 646 ASSERT(bank >= 0 && OPL_BANK_MAX > bank); 647 648 /* Do translation */ 649 for (i = 0; i < PA_BITS_FOR_MAC; i++) { 650 int pa_bit = 0; 651 int mc_bit = mcp->mc_trans_table[cs][i]; 652 if (mc_bit < MC_ADDRESS_BITS) { 653 pa_bit = (maddr->ma_dimm_addr >> mc_bit) & 1; 654 } else if (mc_bit == MP_NONE) { 655 pa_bit = 0; 656 } else if (mc_bit == MP_BANK_0) { 657 pa_bit = bank & 1; 658 } else if (mc_bit == MP_BANK_1) { 659 pa_bit = (bank >> 1) & 1; 660 } else if (mc_bit == MP_BANK_2) { 661 pa_bit = (bank >> 2) & 1; 662 } 663 pa_offset |= ((uint64_t)pa_bit) << i; 664 } 665 *pa = mcp->mc_start_address + pa_offset; 666 MC_LOG("pa = %lx\n", *pa); 667 668 if (pa_to_maddr(mcp, *pa, &maddr1) == -1) { 669 cmn_err(CE_WARN, "mcaddr_to_pa: /LSB%d/B%d/%x failed to " 670 "convert PA %lx\n", maddr->ma_bd, bank, 671 maddr->ma_dimm_addr, *pa); 672 return (-1); 673 } 674 675 /* 676 * In mirror mode, PA is always translated to the even bank. 677 */ 678 if (IS_MIRROR(mcp, maddr->ma_bank)) { 679 bank0 = maddr->ma_bank & ~(1); 680 bank1 = maddr1.ma_bank & ~(1); 681 } else { 682 bank0 = maddr->ma_bank; 683 bank1 = maddr1.ma_bank; 684 } 685 /* 686 * there is no need to check ma_bd because it is generated from 687 * mcp. They are the same. 688 */ 689 if ((bank0 == bank1) && (maddr->ma_dimm_addr == 690 maddr1.ma_dimm_addr)) { 691 return (0); 692 } else { 693 cmn_err(CE_WARN, "Translation error source /LSB%d/B%d/%x, " 694 "PA %lx, target /LSB%d/B%d/%x\n", maddr->ma_bd, bank, 695 maddr->ma_dimm_addr, *pa, maddr1.ma_bd, maddr1.ma_bank, 696 maddr1.ma_dimm_addr); 697 return (-1); 698 } 699 } 700 701 /* 702 * PA to CS (used by pa_to_maddr). 703 */ 704 static int 705 pa_to_cs(mc_opl_t *mcp, uint64_t pa_offset) 706 { 707 int i; 708 int cs = 1; 709 710 for (i = 0; i < PA_BITS_FOR_MAC; i++) { 711 /* MAC address bit<29> is arranged on the same PA bit */ 712 /* on both table. So we may use any table. */ 713 if (mcp->mc_trans_table[0][i] == CS_SHIFT) { 714 cs = (pa_offset >> i) & 1; 715 break; 716 } 717 } 718 return (cs); 719 } 720 721 /* 722 * PA to DIMM (used by pa_to_maddr). 723 */ 724 /* ARGSUSED */ 725 static uint32_t 726 pa_to_dimm(mc_opl_t *mcp, uint64_t pa_offset) 727 { 728 int i; 729 int cs = pa_to_cs(mcp, pa_offset); 730 uint32_t dimm_addr = 0; 731 732 for (i = 0; i < PA_BITS_FOR_MAC; i++) { 733 int pa_bit_value = (pa_offset >> i) & 1; 734 int mc_bit = mcp->mc_trans_table[cs][i]; 735 if (mc_bit < MC_ADDRESS_BITS) { 736 dimm_addr |= pa_bit_value << mc_bit; 737 } 738 } 739 dimm_addr |= cs << CS_SHIFT; 740 return (dimm_addr); 741 } 742 743 /* 744 * PA to Bank (used by pa_to_maddr). 745 */ 746 static int 747 pa_to_bank(mc_opl_t *mcp, uint64_t pa_offset) 748 { 749 int i; 750 int cs = pa_to_cs(mcp, pa_offset); 751 int bankno = mcp->mc_trans_table[cs][INDEX_OF_BANK_SUPPLEMENT_BIT]; 752 753 754 for (i = 0; i < PA_BITS_FOR_MAC; i++) { 755 int pa_bit_value = (pa_offset >> i) & 1; 756 int mc_bit = mcp->mc_trans_table[cs][i]; 757 switch (mc_bit) { 758 case MP_BANK_0: 759 bankno |= pa_bit_value; 760 break; 761 case MP_BANK_1: 762 bankno |= pa_bit_value << 1; 763 break; 764 case MP_BANK_2: 765 bankno |= pa_bit_value << 2; 766 break; 767 } 768 } 769 770 return (bankno); 771 } 772 773 /* 774 * PA to MAC address translation 775 * 776 * Input: MAC driver state, physicall adress 777 * Output: LSB#, Bank id, mac address 778 * 779 * Valid - return value: 0 780 * Invalid - return value: -1 781 */ 782 783 int 784 pa_to_maddr(mc_opl_t *mcp, uint64_t pa, mc_addr_t *maddr) 785 { 786 uint64_t pa_offset; 787 788 if (!mc_rangecheck_pa(mcp, pa)) 789 return (-1); 790 791 /* Do translation */ 792 pa_offset = pa - mcp->mc_start_address; 793 794 maddr->ma_bd = mcp->mc_board_num; 795 maddr->ma_phys_bd = mcp->mc_phys_board_num; 796 maddr->ma_bank = pa_to_bank(mcp, pa_offset); 797 maddr->ma_dimm_addr = pa_to_dimm(mcp, pa_offset); 798 MC_LOG("pa %lx -> mcaddr /LSB%d/B%d/%x\n", pa_offset, maddr->ma_bd, 799 maddr->ma_bank, maddr->ma_dimm_addr); 800 return (0); 801 } 802 803 /* 804 * UNUM format for DC is "/CMUnn/MEMxyZ", where 805 * nn = 00..03 for DC1 and 00..07 for DC2 and 00..15 for DC3. 806 * x = MAC 0..3 807 * y = 0..3 (slot info). 808 * Z = 'A' or 'B' 809 * 810 * UNUM format for FF1 is "/MBU_A/MEMBx/MEMyZ", where 811 * x = 0..3 (MEMB number) 812 * y = 0..3 (slot info). 813 * Z = 'A' or 'B' 814 * 815 * UNUM format for FF2 is "/MBU_B/MEMBx/MEMyZ" 816 * x = 0..7 (MEMB number) 817 * y = 0..3 (slot info). 818 * Z = 'A' or 'B' 819 */ 820 int 821 mc_set_mem_unum(char *buf, int buflen, int sb, int bank, 822 uint32_t mf_type, uint32_t d_slot) 823 { 824 char *dimmnm; 825 char memb_num; 826 int cs; 827 int i; 828 int j; 829 830 cs = SLOT_TO_CS(d_slot); 831 832 if (plat_model == MODEL_DC) { 833 if (mf_type == FLT_TYPE_PERMANENT_CE) { 834 i = BD_BK_SLOT_TO_INDEX(0, bank, d_slot); 835 dimmnm = mc_dc_dimm_unum_table[i]; 836 snprintf(buf, buflen, "/%s%02d/MEM%s", 837 model_names[plat_model].unit_name, sb, dimmnm); 838 } else { 839 i = BD_BK_SLOT_TO_INDEX(0, bank, 0); 840 j = (cs == 0) ? i : i + 2; 841 snprintf(buf, buflen, "/%s%02d/MEM%s MEM%s", 842 model_names[plat_model].unit_name, sb, 843 mc_dc_dimm_unum_table[j], 844 mc_dc_dimm_unum_table[j + 1]); 845 } 846 } else { 847 if (mf_type == FLT_TYPE_PERMANENT_CE) { 848 i = BD_BK_SLOT_TO_INDEX(sb, bank, d_slot); 849 dimmnm = mc_ff_dimm_unum_table[i]; 850 memb_num = dimmnm[0]; 851 snprintf(buf, buflen, "/%s/%s%c/MEM%s", 852 model_names[plat_model].unit_name, 853 model_names[plat_model].mem_name, 854 memb_num, &dimmnm[1]); 855 } else { 856 i = BD_BK_SLOT_TO_INDEX(sb, bank, 0); 857 j = (cs == 0) ? i : i + 2; 858 memb_num = mc_ff_dimm_unum_table[i][0], 859 snprintf(buf, buflen, "/%s/%s%c/MEM%s MEM%s", 860 model_names[plat_model].unit_name, 861 model_names[plat_model].mem_name, memb_num, 862 &mc_ff_dimm_unum_table[j][1], 863 &mc_ff_dimm_unum_table[j + 1][1]); 864 } 865 } 866 return (0); 867 } 868 869 static void 870 mc_ereport_post(mc_aflt_t *mc_aflt) 871 { 872 char buf[FM_MAX_CLASS]; 873 char device_path[MAXPATHLEN]; 874 char sid[MAXPATHLEN]; 875 nv_alloc_t *nva = NULL; 876 nvlist_t *ereport, *detector, *resource; 877 errorq_elem_t *eqep; 878 int nflts; 879 mc_flt_stat_t *flt_stat; 880 int i, n; 881 int blen = MAXPATHLEN; 882 char *p, *s = NULL; 883 uint32_t values[2], synd[2], dslot[2]; 884 uint64_t offset = (uint64_t)-1; 885 int ret = -1; 886 887 if (panicstr) { 888 eqep = errorq_reserve(ereport_errorq); 889 if (eqep == NULL) 890 return; 891 ereport = errorq_elem_nvl(ereport_errorq, eqep); 892 nva = errorq_elem_nva(ereport_errorq, eqep); 893 } else { 894 ereport = fm_nvlist_create(nva); 895 } 896 897 /* 898 * Create the scheme "dev" FMRI. 899 */ 900 detector = fm_nvlist_create(nva); 901 resource = fm_nvlist_create(nva); 902 903 nflts = mc_aflt->mflt_nflts; 904 905 ASSERT(nflts >= 1 && nflts <= 2); 906 907 flt_stat = mc_aflt->mflt_stat[0]; 908 (void) ddi_pathname(mc_aflt->mflt_mcp->mc_dip, device_path); 909 (void) fm_fmri_dev_set(detector, FM_DEV_SCHEME_VERSION, NULL, 910 device_path, NULL); 911 912 /* 913 * Encode all the common data into the ereport. 914 */ 915 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s-%s", MC_OPL_ERROR_CLASS, 916 mc_aflt->mflt_is_ptrl ? MC_OPL_PTRL_SUBCLASS : MC_OPL_MI_SUBCLASS, 917 mc_aflt->mflt_erpt_class); 918 919 MC_LOG("mc_ereport_post: ereport %s\n", buf); 920 921 922 fm_ereport_set(ereport, FM_EREPORT_VERSION, buf, 923 fm_ena_generate(mc_aflt->mflt_id, FM_ENA_FMT1), detector, NULL); 924 925 /* 926 * Set payload. 927 */ 928 fm_payload_set(ereport, MC_OPL_BOARD, DATA_TYPE_UINT32, 929 flt_stat->mf_flt_maddr.ma_bd, NULL); 930 931 fm_payload_set(ereport, MC_OPL_PA, DATA_TYPE_UINT64, 932 flt_stat->mf_flt_paddr, NULL); 933 934 if (flt_stat->mf_type == FLT_TYPE_PERMANENT_CE) { 935 fm_payload_set(ereport, MC_OPL_FLT_TYPE, DATA_TYPE_UINT8, 936 ECC_STICKY, NULL); 937 } 938 939 for (i = 0; i < nflts; i++) 940 values[i] = mc_aflt->mflt_stat[i]->mf_flt_maddr.ma_bank; 941 942 fm_payload_set(ereport, MC_OPL_BANK, DATA_TYPE_UINT32_ARRAY, nflts, 943 values, NULL); 944 945 for (i = 0; i < nflts; i++) 946 values[i] = mc_aflt->mflt_stat[i]->mf_cntl; 947 948 fm_payload_set(ereport, MC_OPL_STATUS, DATA_TYPE_UINT32_ARRAY, nflts, 949 values, NULL); 950 951 for (i = 0; i < nflts; i++) 952 values[i] = mc_aflt->mflt_stat[i]->mf_err_add; 953 954 /* offset is set only for PCE */ 955 if (mc_aflt->mflt_stat[0]->mf_type == FLT_TYPE_PERMANENT_CE) { 956 offset = values[0]; 957 958 } 959 fm_payload_set(ereport, MC_OPL_ERR_ADD, DATA_TYPE_UINT32_ARRAY, nflts, 960 values, NULL); 961 962 for (i = 0; i < nflts; i++) 963 values[i] = mc_aflt->mflt_stat[i]->mf_err_log; 964 965 fm_payload_set(ereport, MC_OPL_ERR_LOG, DATA_TYPE_UINT32_ARRAY, nflts, 966 values, NULL); 967 968 for (i = 0; i < nflts; i++) { 969 flt_stat = mc_aflt->mflt_stat[i]; 970 if (flt_stat->mf_errlog_valid) { 971 synd[i] = flt_stat->mf_synd; 972 dslot[i] = flt_stat->mf_dimm_slot; 973 values[i] = flt_stat->mf_dram_place; 974 } else { 975 synd[i] = 0; 976 dslot[i] = 0; 977 values[i] = 0; 978 } 979 } 980 981 fm_payload_set(ereport, MC_OPL_ERR_SYND, DATA_TYPE_UINT32_ARRAY, nflts, 982 synd, NULL); 983 984 fm_payload_set(ereport, MC_OPL_ERR_DIMMSLOT, DATA_TYPE_UINT32_ARRAY, 985 nflts, dslot, NULL); 986 987 fm_payload_set(ereport, MC_OPL_ERR_DRAM, DATA_TYPE_UINT32_ARRAY, nflts, 988 values, NULL); 989 990 device_path[0] = 0; 991 p = &device_path[0]; 992 sid[0] = 0; 993 s = &sid[0]; 994 ret = 0; 995 996 for (i = 0; i < nflts; i++) { 997 int bank; 998 999 flt_stat = mc_aflt->mflt_stat[i]; 1000 bank = flt_stat->mf_flt_maddr.ma_bank; 1001 ret = mc_set_mem_unum(p + strlen(p), blen, 1002 flt_stat->mf_flt_maddr.ma_phys_bd, bank, flt_stat->mf_type, 1003 flt_stat->mf_dimm_slot); 1004 1005 if (ret != 0) { 1006 cmn_err(CE_WARN, 1007 "mc_ereport_post: Failed to determine the unum " 1008 "for board=%d bank=%d type=0x%x slot=0x%x", 1009 flt_stat->mf_flt_maddr.ma_bd, bank, 1010 flt_stat->mf_type, flt_stat->mf_dimm_slot); 1011 continue; 1012 } 1013 n = strlen(device_path); 1014 blen = MAXPATHLEN - n; 1015 p = &device_path[n]; 1016 if (i < (nflts - 1)) { 1017 snprintf(p, blen, " "); 1018 blen--; 1019 p++; 1020 } 1021 1022 if (ret == 0) { 1023 ret = mc_set_mem_sid(mc_aflt->mflt_mcp, s + strlen(s), 1024 blen, flt_stat->mf_flt_maddr.ma_phys_bd, bank, 1025 flt_stat->mf_type, flt_stat->mf_dimm_slot); 1026 1027 } 1028 } 1029 1030 (void) fm_fmri_mem_set(resource, FM_MEM_SCHEME_VERSION, NULL, 1031 device_path, (ret == 0) ? sid : NULL, (ret == 0) ? offset : 1032 (uint64_t)-1); 1033 1034 fm_payload_set(ereport, MC_OPL_RESOURCE, DATA_TYPE_NVLIST, resource, 1035 NULL); 1036 1037 if (panicstr) { 1038 errorq_commit(ereport_errorq, eqep, ERRORQ_SYNC); 1039 } else { 1040 (void) fm_ereport_post(ereport, EVCH_TRYHARD); 1041 fm_nvlist_destroy(ereport, FM_NVA_FREE); 1042 fm_nvlist_destroy(detector, FM_NVA_FREE); 1043 fm_nvlist_destroy(resource, FM_NVA_FREE); 1044 } 1045 } 1046 1047 1048 static void 1049 mc_err_drain(mc_aflt_t *mc_aflt) 1050 { 1051 int rv; 1052 uint64_t pa = (uint64_t)(-1); 1053 int i; 1054 1055 MC_LOG("mc_err_drain: %s\n", mc_aflt->mflt_erpt_class); 1056 /* 1057 * we come here only when we have: 1058 * In mirror mode: MUE, SUE 1059 * In normal mode: UE, Permanent CE 1060 */ 1061 for (i = 0; i < mc_aflt->mflt_nflts; i++) { 1062 rv = mcaddr_to_pa(mc_aflt->mflt_mcp, 1063 &(mc_aflt->mflt_stat[i]->mf_flt_maddr), &pa); 1064 1065 /* Ensure the pa is valid (not in isolated memory block) */ 1066 if (rv == 0 && pa_is_valid(mc_aflt->mflt_mcp, pa)) 1067 mc_aflt->mflt_stat[i]->mf_flt_paddr = pa; 1068 else 1069 mc_aflt->mflt_stat[i]->mf_flt_paddr = (uint64_t)-1; 1070 } 1071 1072 MC_LOG("mc_err_drain:pa = %lx\n", pa); 1073 1074 switch (page_retire_check(pa, NULL)) { 1075 case 0: 1076 case EAGAIN: 1077 MC_LOG("Page retired or pending\n"); 1078 return; 1079 case EIO: 1080 /* 1081 * Do page retirement except for the PCE case. 1082 * This is taken care by the OPL DE 1083 */ 1084 if (mc_aflt->mflt_stat[0]->mf_type != FLT_TYPE_PERMANENT_CE) { 1085 MC_LOG("offline page at pa %lx error %x\n", pa, 1086 mc_aflt->mflt_pr); 1087 (void) page_retire(pa, mc_aflt->mflt_pr); 1088 } 1089 break; 1090 case EINVAL: 1091 default: 1092 /* 1093 * Some memory do not have page structure so 1094 * we keep going in case of EINVAL. 1095 */ 1096 break; 1097 } 1098 1099 for (i = 0; i < mc_aflt->mflt_nflts; i++) { 1100 mc_aflt_t mc_aflt0; 1101 if (mc_aflt->mflt_stat[i]->mf_flt_paddr != (uint64_t)-1) { 1102 mc_aflt0 = *mc_aflt; 1103 mc_aflt0.mflt_nflts = 1; 1104 mc_aflt0.mflt_stat[0] = mc_aflt->mflt_stat[i]; 1105 mc_ereport_post(&mc_aflt0); 1106 } 1107 } 1108 } 1109 1110 /* 1111 * The restart address is actually defined in unit of PA[37:6] 1112 * the mac patrol will convert that to dimm offset. If the 1113 * address is not in the bank, it will continue to search for 1114 * the next PA that is within the bank. 1115 * 1116 * Also the mac patrol scans the dimms based on PA, not 1117 * dimm offset. 1118 */ 1119 static int 1120 restart_patrol(mc_opl_t *mcp, int bank, mc_rsaddr_info_t *rsaddr_info) 1121 { 1122 uint64_t pa; 1123 int rv; 1124 1125 if (rsaddr_info == NULL || (rsaddr_info->mi_valid == 0)) { 1126 MAC_PTRL_START(mcp, bank); 1127 return (0); 1128 } 1129 1130 rv = mcaddr_to_pa(mcp, &rsaddr_info->mi_restartaddr, &pa); 1131 if (rv != 0) { 1132 MC_LOG("cannot convert mcaddr to pa. use auto restart\n"); 1133 MAC_PTRL_START(mcp, bank); 1134 return (0); 1135 } 1136 1137 if (!mc_rangecheck_pa(mcp, pa)) { 1138 /* pa is not on this board, just retry */ 1139 cmn_err(CE_WARN, "restart_patrol: invalid address %lx " 1140 "on board %d\n", pa, mcp->mc_board_num); 1141 MAC_PTRL_START(mcp, bank); 1142 return (0); 1143 } 1144 1145 MC_LOG("restart_patrol: pa = %lx\n", pa); 1146 1147 if (!rsaddr_info->mi_injectrestart) { 1148 /* 1149 * For non-error injection restart we need to 1150 * determine if the current restart pa/page is 1151 * a "good" page. A "good" page is a page that 1152 * has not been page retired. If the current 1153 * page that contains the pa is "good", we will 1154 * do a HW auto restart and let HW patrol continue 1155 * where it last stopped. Most desired scenario. 1156 * 1157 * If the current page is not "good", we will advance 1158 * to the next page to find the next "good" page and 1159 * restart the patrol from there. 1160 */ 1161 int wrapcount = 0; 1162 uint64_t origpa = pa; 1163 while (wrapcount < 2) { 1164 if (!pa_is_valid(mcp, pa)) { 1165 /* 1166 * Not in physinstall - advance to the 1167 * next memory isolation blocksize 1168 */ 1169 MC_LOG("Invalid PA\n"); 1170 pa = roundup(pa + 1, mc_isolation_bsize); 1171 } else { 1172 int rv; 1173 if ((rv = page_retire_check(pa, NULL)) != 0 && 1174 rv != EAGAIN) { 1175 /* 1176 * The page is "good" (not retired), 1177 * we will use automatic HW restart 1178 * algorithm if this is the original 1179 * current starting page. 1180 */ 1181 if (pa == origpa) { 1182 MC_LOG("Page has no error. " 1183 "Auto restart\n"); 1184 MAC_PTRL_START(mcp, bank); 1185 return (0); 1186 } else { 1187 /* 1188 * found a subsequent good page 1189 */ 1190 break; 1191 } 1192 } 1193 1194 /* 1195 * Skip to the next page 1196 */ 1197 pa = roundup(pa + 1, PAGESIZE); 1198 MC_LOG("Skipping bad page to %lx\n", pa); 1199 } 1200 1201 /* Check to see if we hit the end of the memory range */ 1202 if (pa >= (mcp->mc_start_address + mcp->mc_size)) { 1203 MC_LOG("Wrap around\n"); 1204 pa = mcp->mc_start_address; 1205 wrapcount++; 1206 } 1207 } 1208 1209 if (wrapcount > 1) { 1210 MC_LOG("Failed to find a good page. Just restart\n"); 1211 MAC_PTRL_START(mcp, bank); 1212 return (0); 1213 } 1214 } 1215 1216 /* 1217 * We reached here either: 1218 * 1. We are doing an error injection restart that specify 1219 * the exact pa/page to restart. OR 1220 * 2. We found a subsequent good page different from the 1221 * original restart pa/page. 1222 * Restart MAC patrol: PA[37:6] 1223 */ 1224 MC_LOG("restart at pa = %lx\n", pa); 1225 ST_MAC_REG(MAC_RESTART_ADD(mcp, bank), MAC_RESTART_PA(pa)); 1226 MAC_PTRL_START_ADD(mcp, bank); 1227 1228 return (0); 1229 } 1230 1231 /* 1232 * Rewriting is used for two purposes. 1233 * - to correct the error in memory. 1234 * - to determine whether the error is permanent or intermittent. 1235 * It's done by writing the address in MAC_BANKm_REWRITE_ADD 1236 * and issuing REW_REQ command in MAC_BANKm_PTRL_CNRL. After that, 1237 * REW_END (and REW_CE/REW_UE if some error detected) is set when 1238 * rewrite operation is done. See 4.7.3 and 4.7.11 in Columbus2 PRM. 1239 * 1240 * Note that rewrite operation doesn't change RAW_UE to Marked UE. 1241 * Therefore, we use it only CE case. 1242 */ 1243 static uint32_t 1244 do_rewrite(mc_opl_t *mcp, int bank, uint32_t dimm_addr) 1245 { 1246 uint32_t cntl; 1247 int count = 0; 1248 1249 /* first wait to make sure PTRL_STATUS is 0 */ 1250 while (count++ < mc_max_rewrite_loop) { 1251 cntl = LD_MAC_REG(MAC_PTRL_CNTL(mcp, bank)); 1252 if (!(cntl & MAC_CNTL_PTRL_STATUS)) 1253 break; 1254 drv_usecwait(mc_rewrite_delay); 1255 } 1256 if (count >= mc_max_rewrite_loop) 1257 goto bad; 1258 1259 count = 0; 1260 1261 ST_MAC_REG(MAC_REWRITE_ADD(mcp, bank), dimm_addr); 1262 MAC_REW_REQ(mcp, bank); 1263 1264 do { 1265 cntl = LD_MAC_REG(MAC_PTRL_CNTL(mcp, bank)); 1266 if (count++ >= mc_max_rewrite_loop) { 1267 goto bad; 1268 } else { 1269 drv_usecwait(mc_rewrite_delay); 1270 } 1271 /* 1272 * If there are other MEMORY or PCI activities, this 1273 * will be BUSY, else it should be set immediately 1274 */ 1275 } while (!(cntl & MAC_CNTL_REW_END)); 1276 1277 MAC_CLEAR_ERRS(mcp, bank, MAC_CNTL_REW_ERRS); 1278 return (cntl); 1279 bad: 1280 /* This is bad. Just reset the circuit */ 1281 cmn_err(CE_WARN, "mc-opl rewrite timeout on /LSB%d/B%d\n", 1282 mcp->mc_board_num, bank); 1283 cntl = MAC_CNTL_REW_END; 1284 MAC_CMD(mcp, bank, MAC_CNTL_PTRL_RESET); 1285 MAC_CLEAR_ERRS(mcp, bank, MAC_CNTL_REW_ERRS); 1286 return (cntl); 1287 } 1288 void 1289 mc_process_scf_log(mc_opl_t *mcp) 1290 { 1291 int count; 1292 int n = 0; 1293 scf_log_t *p; 1294 int bank; 1295 1296 for (bank = 0; bank < BANKNUM_PER_SB; bank++) { 1297 while ((p = mcp->mc_scf_log[bank]) != NULL && 1298 (n < mc_max_errlog_processed)) { 1299 ASSERT(bank == p->sl_bank); 1300 count = 0; 1301 while ((LD_MAC_REG(MAC_STATIC_ERR_ADD(mcp, p->sl_bank)) 1302 & MAC_STATIC_ERR_VLD)) { 1303 if (count++ >= (mc_max_scf_loop)) { 1304 break; 1305 } 1306 drv_usecwait(mc_scf_delay); 1307 } 1308 1309 if (count < mc_max_scf_loop) { 1310 ST_MAC_REG(MAC_STATIC_ERR_LOG(mcp, p->sl_bank), 1311 p->sl_err_log); 1312 1313 ST_MAC_REG(MAC_STATIC_ERR_ADD(mcp, p->sl_bank), 1314 p->sl_err_add|MAC_STATIC_ERR_VLD); 1315 mcp->mc_scf_retry[bank] = 0; 1316 } else { 1317 /* 1318 * if we try too many times, just drop the req 1319 */ 1320 if (mcp->mc_scf_retry[bank]++ <= 1321 mc_max_scf_retry) { 1322 return; 1323 } else { 1324 if ((++mc_pce_dropped & 0xff) == 0) { 1325 cmn_err(CE_WARN, "Cannot " 1326 "report Permanent CE to " 1327 "SCF\n"); 1328 } 1329 } 1330 } 1331 n++; 1332 mcp->mc_scf_log[bank] = p->sl_next; 1333 mcp->mc_scf_total[bank]--; 1334 ASSERT(mcp->mc_scf_total[bank] >= 0); 1335 kmem_free(p, sizeof (scf_log_t)); 1336 } 1337 } 1338 } 1339 void 1340 mc_queue_scf_log(mc_opl_t *mcp, mc_flt_stat_t *flt_stat, int bank) 1341 { 1342 scf_log_t *p; 1343 1344 if (mcp->mc_scf_total[bank] >= mc_max_scf_logs) { 1345 if ((++mc_pce_dropped & 0xff) == 0) { 1346 cmn_err(CE_WARN, "Too many Permanent CE requests.\n"); 1347 } 1348 return; 1349 } 1350 p = kmem_zalloc(sizeof (scf_log_t), KM_SLEEP); 1351 p->sl_next = 0; 1352 p->sl_err_add = flt_stat->mf_err_add; 1353 p->sl_err_log = flt_stat->mf_err_log; 1354 p->sl_bank = bank; 1355 1356 if (mcp->mc_scf_log[bank] == NULL) { 1357 /* 1358 * we rely on mc_scf_log to detect NULL queue. 1359 * mc_scf_log_tail is irrelevant is such case. 1360 */ 1361 mcp->mc_scf_log_tail[bank] = mcp->mc_scf_log[bank] = p; 1362 } else { 1363 mcp->mc_scf_log_tail[bank]->sl_next = p; 1364 mcp->mc_scf_log_tail[bank] = p; 1365 } 1366 mcp->mc_scf_total[bank]++; 1367 } 1368 /* 1369 * This routine determines what kind of CE happens, intermittent 1370 * or permanent as follows. (See 4.7.3 in Columbus2 PRM.) 1371 * - Do rewrite by issuing REW_REQ command to MAC_PTRL_CNTL register. 1372 * - If CE is still detected on the same address even after doing 1373 * rewrite operation twice, it is determined as permanent error. 1374 * - If error is not detected anymore, it is determined as intermittent 1375 * error. 1376 * - If UE is detected due to rewrite operation, it should be treated 1377 * as UE. 1378 */ 1379 1380 /* ARGSUSED */ 1381 static void 1382 mc_scrub_ce(mc_opl_t *mcp, int bank, mc_flt_stat_t *flt_stat, int ptrl_error) 1383 { 1384 uint32_t cntl; 1385 int i; 1386 1387 flt_stat->mf_type = FLT_TYPE_PERMANENT_CE; 1388 /* 1389 * rewrite request 1st time reads and correct error data 1390 * and write to DIMM. 2nd rewrite request must be issued 1391 * after REW_CE/UE/END is 0. When the 2nd request is completed, 1392 * if REW_CE = 1, then it is permanent CE. 1393 */ 1394 for (i = 0; i < 2; i++) { 1395 cntl = do_rewrite(mcp, bank, flt_stat->mf_err_add); 1396 /* 1397 * If the error becomes UE or CMPE 1398 * we return to the caller immediately. 1399 */ 1400 if (cntl & MAC_CNTL_REW_UE) { 1401 if (ptrl_error) 1402 flt_stat->mf_cntl |= MAC_CNTL_PTRL_UE; 1403 else 1404 flt_stat->mf_cntl |= MAC_CNTL_MI_UE; 1405 flt_stat->mf_type = FLT_TYPE_UE; 1406 return; 1407 } 1408 if (cntl & MAC_CNTL_REW_CMPE) { 1409 if (ptrl_error) 1410 flt_stat->mf_cntl |= MAC_CNTL_PTRL_CMPE; 1411 else 1412 flt_stat->mf_cntl |= MAC_CNTL_MI_CMPE; 1413 flt_stat->mf_type = FLT_TYPE_CMPE; 1414 return; 1415 } 1416 } 1417 if (!(cntl & MAC_CNTL_REW_CE)) { 1418 flt_stat->mf_type = FLT_TYPE_INTERMITTENT_CE; 1419 } 1420 1421 if (flt_stat->mf_type == FLT_TYPE_PERMANENT_CE) { 1422 /* report PERMANENT_CE to SP via SCF */ 1423 if (!(flt_stat->mf_err_log & MAC_ERR_LOG_INVALID)) { 1424 mc_queue_scf_log(mcp, flt_stat, bank); 1425 } 1426 } 1427 } 1428 1429 #define IS_CMPE(cntl, f) ((cntl) & ((f) ? MAC_CNTL_PTRL_CMPE :\ 1430 MAC_CNTL_MI_CMPE)) 1431 #define IS_UE(cntl, f) ((cntl) & ((f) ? MAC_CNTL_PTRL_UE : MAC_CNTL_MI_UE)) 1432 #define IS_CE(cntl, f) ((cntl) & ((f) ? MAC_CNTL_PTRL_CE : MAC_CNTL_MI_CE)) 1433 #define IS_OK(cntl, f) (!((cntl) & ((f) ? MAC_CNTL_PTRL_ERRS : \ 1434 MAC_CNTL_MI_ERRS))) 1435 1436 1437 static int 1438 IS_CE_ONLY(uint32_t cntl, int ptrl_error) 1439 { 1440 if (ptrl_error) { 1441 return ((cntl & MAC_CNTL_PTRL_ERRS) == MAC_CNTL_PTRL_CE); 1442 } else { 1443 return ((cntl & MAC_CNTL_MI_ERRS) == MAC_CNTL_MI_CE); 1444 } 1445 } 1446 1447 void 1448 mc_write_cntl(mc_opl_t *mcp, int bank, uint32_t value) 1449 { 1450 int ebank = (IS_MIRROR(mcp, bank)) ? MIRROR_IDX(bank) : bank; 1451 1452 if (mcp->mc_speedup_period[ebank] > 0) 1453 value |= mc_max_speed; 1454 else 1455 value |= mcp->mc_speed; 1456 ST_MAC_REG(MAC_PTRL_CNTL(mcp, bank), value); 1457 } 1458 1459 static void 1460 mc_read_ptrl_reg(mc_opl_t *mcp, int bank, mc_flt_stat_t *flt_stat) 1461 { 1462 flt_stat->mf_cntl = LD_MAC_REG(MAC_PTRL_CNTL(mcp, bank)) & 1463 MAC_CNTL_PTRL_ERRS; 1464 flt_stat->mf_err_add = LD_MAC_REG(MAC_PTRL_ERR_ADD(mcp, bank)); 1465 flt_stat->mf_err_log = LD_MAC_REG(MAC_PTRL_ERR_LOG(mcp, bank)); 1466 flt_stat->mf_flt_maddr.ma_bd = mcp->mc_board_num; 1467 flt_stat->mf_flt_maddr.ma_phys_bd = mcp->mc_phys_board_num; 1468 flt_stat->mf_flt_maddr.ma_bank = bank; 1469 flt_stat->mf_flt_maddr.ma_dimm_addr = flt_stat->mf_err_add; 1470 } 1471 1472 static void 1473 mc_read_mi_reg(mc_opl_t *mcp, int bank, mc_flt_stat_t *flt_stat) 1474 { 1475 uint32_t status, old_status; 1476 1477 status = LD_MAC_REG(MAC_PTRL_CNTL(mcp, bank)) & MAC_CNTL_MI_ERRS; 1478 old_status = 0; 1479 1480 /* we keep reading until the status is stable */ 1481 while (old_status != status) { 1482 old_status = status; 1483 flt_stat->mf_err_add = LD_MAC_REG(MAC_MI_ERR_ADD(mcp, bank)); 1484 flt_stat->mf_err_log = LD_MAC_REG(MAC_MI_ERR_LOG(mcp, bank)); 1485 status = LD_MAC_REG(MAC_PTRL_CNTL(mcp, bank)) & 1486 MAC_CNTL_MI_ERRS; 1487 if (status == old_status) { 1488 break; 1489 } 1490 } 1491 1492 flt_stat->mf_cntl = status; 1493 flt_stat->mf_flt_maddr.ma_bd = mcp->mc_board_num; 1494 flt_stat->mf_flt_maddr.ma_phys_bd = mcp->mc_phys_board_num; 1495 flt_stat->mf_flt_maddr.ma_bank = bank; 1496 flt_stat->mf_flt_maddr.ma_dimm_addr = flt_stat->mf_err_add; 1497 } 1498 1499 1500 /* 1501 * Error philosophy for mirror mode: 1502 * 1503 * PTRL (The error address for both banks are same, since ptrl stops if it 1504 * detects error.) 1505 * - Compare error log CMPE. 1506 * 1507 * - UE-UE Report MUE. No rewrite. 1508 * 1509 * - UE-* UE-(CE/OK). Rewrite to scrub UE. Report SUE. 1510 * 1511 * - CE-* CE-(CE/OK). Scrub to determine if CE is permanent. 1512 * If CE is permanent, inform SCF. Once for each 1513 * Dimm. If CE becomes UE or CMPE, go back to above. 1514 * 1515 * 1516 * MI (The error addresses for each bank are the same or different.) 1517 * - Compare error If addresses are the same. Just CMPE, so log CMPE. 1518 * If addresses are different (this could happen 1519 * as a result of scrubbing. Report each separately. 1520 * Only report error info on each side. 1521 * 1522 * - UE-UE Addresses are the same. Report MUE. 1523 * Addresses are different. Report SUE on each bank. 1524 * Rewrite to clear UE. 1525 * 1526 * - UE-* UE-(CE/OK) 1527 * Rewrite to clear UE. Report SUE for the bank. 1528 * 1529 * - CE-* CE-(CE/OK). Scrub to determine if CE is permanent. 1530 * If CE becomes UE or CMPE, go back to above. 1531 * 1532 */ 1533 1534 static int 1535 mc_process_error_mir(mc_opl_t *mcp, mc_aflt_t *mc_aflt, mc_flt_stat_t *flt_stat) 1536 { 1537 int ptrl_error = mc_aflt->mflt_is_ptrl; 1538 int i; 1539 int rv = 0; 1540 1541 MC_LOG("process mirror errors cntl[0] = %x, cntl[1] = %x\n", 1542 flt_stat[0].mf_cntl, flt_stat[1].mf_cntl); 1543 1544 if (ptrl_error) { 1545 if (((flt_stat[0].mf_cntl | flt_stat[1].mf_cntl) & 1546 MAC_CNTL_PTRL_ERRS) == 0) 1547 return (0); 1548 } else { 1549 if (((flt_stat[0].mf_cntl | flt_stat[1].mf_cntl) & 1550 MAC_CNTL_MI_ERRS) == 0) 1551 return (0); 1552 } 1553 1554 /* 1555 * First we take care of the case of CE 1556 * because they can become UE or CMPE 1557 */ 1558 for (i = 0; i < 2; i++) { 1559 if (IS_CE_ONLY(flt_stat[i].mf_cntl, ptrl_error)) { 1560 MC_LOG("CE detected on bank %d\n", 1561 flt_stat[i].mf_flt_maddr.ma_bank); 1562 mc_scrub_ce(mcp, flt_stat[i].mf_flt_maddr.ma_bank, 1563 &flt_stat[i], ptrl_error); 1564 rv = 1; 1565 } 1566 } 1567 1568 /* The above scrubbing can turn CE into UE or CMPE */ 1569 1570 /* 1571 * Now we distinguish two cases: same address or not 1572 * the same address. It might seem more intuitive to 1573 * distinguish PTRL v.s. MI error but it is more 1574 * complicated that way. 1575 */ 1576 1577 if (flt_stat[0].mf_err_add == flt_stat[1].mf_err_add) { 1578 1579 if (IS_CMPE(flt_stat[0].mf_cntl, ptrl_error) || 1580 IS_CMPE(flt_stat[1].mf_cntl, ptrl_error)) { 1581 flt_stat[0].mf_type = FLT_TYPE_CMPE; 1582 flt_stat[1].mf_type = FLT_TYPE_CMPE; 1583 mc_aflt->mflt_erpt_class = MC_OPL_CMPE; 1584 mc_aflt->mflt_nflts = 2; 1585 mc_aflt->mflt_stat[0] = &flt_stat[0]; 1586 mc_aflt->mflt_stat[1] = &flt_stat[1]; 1587 mc_aflt->mflt_pr = PR_UE; 1588 /* 1589 * Compare error is result of MAC internal error, so 1590 * simply log it instead of publishing an ereport. SCF 1591 * diagnoses all the MAC internal and its i/f error. 1592 * mc_err_drain(mc_aflt); 1593 */ 1594 MC_LOG("cmpe error detected\n"); 1595 return (1); 1596 } 1597 1598 if (IS_UE(flt_stat[0].mf_cntl, ptrl_error) && 1599 IS_UE(flt_stat[1].mf_cntl, ptrl_error)) { 1600 /* Both side are UE's */ 1601 1602 MAC_SET_ERRLOG_INFO(&flt_stat[0]); 1603 MAC_SET_ERRLOG_INFO(&flt_stat[1]); 1604 MC_LOG("MUE detected\n"); 1605 flt_stat[0].mf_type = FLT_TYPE_MUE; 1606 flt_stat[1].mf_type = FLT_TYPE_MUE; 1607 mc_aflt->mflt_erpt_class = MC_OPL_MUE; 1608 mc_aflt->mflt_nflts = 2; 1609 mc_aflt->mflt_stat[0] = &flt_stat[0]; 1610 mc_aflt->mflt_stat[1] = &flt_stat[1]; 1611 mc_aflt->mflt_pr = PR_UE; 1612 mc_err_drain(mc_aflt); 1613 return (1); 1614 } 1615 1616 /* Now the only case is UE/CE, UE/OK, or don't care */ 1617 for (i = 0; i < 2; i++) { 1618 if (!IS_UE(flt_stat[i].mf_cntl, ptrl_error)) { 1619 continue; 1620 } 1621 1622 /* rewrite can clear the one side UE error */ 1623 1624 if (IS_OK(flt_stat[i^1].mf_cntl, ptrl_error)) { 1625 (void) do_rewrite(mcp, 1626 flt_stat[i].mf_flt_maddr.ma_bank, 1627 flt_stat[i].mf_flt_maddr.ma_dimm_addr); 1628 } 1629 flt_stat[i].mf_type = FLT_TYPE_UE; 1630 MAC_SET_ERRLOG_INFO(&flt_stat[i]); 1631 mc_aflt->mflt_erpt_class = MC_OPL_SUE; 1632 mc_aflt->mflt_stat[0] = &flt_stat[i]; 1633 mc_aflt->mflt_nflts = 1; 1634 mc_aflt->mflt_pr = PR_MCE; 1635 mc_err_drain(mc_aflt); 1636 /* Once we hit a UE/CE or UE/OK case, done */ 1637 return (1); 1638 } 1639 1640 } else { 1641 /* 1642 * addresses are different. That means errors 1643 * on the 2 banks are not related at all. 1644 */ 1645 for (i = 0; i < 2; i++) { 1646 if (IS_CMPE(flt_stat[i].mf_cntl, ptrl_error)) { 1647 flt_stat[i].mf_type = FLT_TYPE_CMPE; 1648 mc_aflt->mflt_erpt_class = MC_OPL_CMPE; 1649 mc_aflt->mflt_nflts = 1; 1650 mc_aflt->mflt_stat[0] = &flt_stat[i]; 1651 mc_aflt->mflt_pr = PR_UE; 1652 /* 1653 * Compare error is result of MAC internal 1654 * error, so simply log it instead of 1655 * publishing an ereport. SCF diagnoses all 1656 * the MAC internal and its interface error. 1657 * mc_err_drain(mc_aflt); 1658 */ 1659 MC_LOG("cmpe error detected\n"); 1660 /* no more report on this bank */ 1661 flt_stat[i].mf_cntl = 0; 1662 rv = 1; 1663 } 1664 } 1665 1666 /* rewrite can clear the one side UE error */ 1667 1668 for (i = 0; i < 2; i++) { 1669 if (IS_UE(flt_stat[i].mf_cntl, ptrl_error)) { 1670 (void) do_rewrite(mcp, 1671 flt_stat[i].mf_flt_maddr.ma_bank, 1672 flt_stat[i].mf_flt_maddr.ma_dimm_addr); 1673 flt_stat[i].mf_type = FLT_TYPE_UE; 1674 MAC_SET_ERRLOG_INFO(&flt_stat[i]); 1675 mc_aflt->mflt_erpt_class = MC_OPL_SUE; 1676 mc_aflt->mflt_stat[0] = &flt_stat[i]; 1677 mc_aflt->mflt_nflts = 1; 1678 mc_aflt->mflt_pr = PR_MCE; 1679 mc_err_drain(mc_aflt); 1680 rv = 1; 1681 } 1682 } 1683 } 1684 return (rv); 1685 } 1686 static void 1687 mc_error_handler_mir(mc_opl_t *mcp, int bank, mc_rsaddr_info_t *rsaddr) 1688 { 1689 mc_aflt_t mc_aflt; 1690 mc_flt_stat_t flt_stat[2], mi_flt_stat[2]; 1691 int i; 1692 int mi_valid; 1693 1694 ASSERT(rsaddr); 1695 1696 bzero(&mc_aflt, sizeof (mc_aflt_t)); 1697 bzero(&flt_stat, 2 * sizeof (mc_flt_stat_t)); 1698 bzero(&mi_flt_stat, 2 * sizeof (mc_flt_stat_t)); 1699 1700 1701 mc_aflt.mflt_mcp = mcp; 1702 mc_aflt.mflt_id = gethrtime(); 1703 1704 /* Now read all the registers into flt_stat */ 1705 1706 for (i = 0; i < 2; i++) { 1707 MC_LOG("Reading registers of bank %d\n", bank); 1708 /* patrol registers */ 1709 mc_read_ptrl_reg(mcp, bank, &flt_stat[i]); 1710 1711 /* 1712 * In mirror mode, it is possible that only one bank 1713 * may report the error. We need to check for it to 1714 * ensure we pick the right addr value for patrol restart. 1715 * Note that if both banks reported errors, we pick the 1716 * 2nd one. Both banks should reported the same error address. 1717 */ 1718 if (flt_stat[i].mf_cntl & MAC_CNTL_PTRL_ERRS) 1719 rsaddr->mi_restartaddr = flt_stat[i].mf_flt_maddr; 1720 1721 MC_LOG("ptrl registers cntl %x add %x log %x\n", 1722 flt_stat[i].mf_cntl, flt_stat[i].mf_err_add, 1723 flt_stat[i].mf_err_log); 1724 1725 /* MI registers */ 1726 mc_read_mi_reg(mcp, bank, &mi_flt_stat[i]); 1727 1728 MC_LOG("MI registers cntl %x add %x log %x\n", 1729 mi_flt_stat[i].mf_cntl, mi_flt_stat[i].mf_err_add, 1730 mi_flt_stat[i].mf_err_log); 1731 1732 bank = bank^1; 1733 } 1734 1735 /* clear errors once we read all the registers */ 1736 MAC_CLEAR_ERRS(mcp, bank, (MAC_CNTL_PTRL_ERRS|MAC_CNTL_MI_ERRS)); 1737 1738 MAC_CLEAR_ERRS(mcp, bank ^ 1, (MAC_CNTL_PTRL_ERRS|MAC_CNTL_MI_ERRS)); 1739 1740 /* Process MI errors first */ 1741 1742 /* if not error mode, cntl1 is 0 */ 1743 if ((mi_flt_stat[0].mf_err_add & MAC_ERR_ADD_INVALID) || 1744 (mi_flt_stat[0].mf_err_log & MAC_ERR_LOG_INVALID)) 1745 mi_flt_stat[0].mf_cntl = 0; 1746 1747 if ((mi_flt_stat[1].mf_err_add & MAC_ERR_ADD_INVALID) || 1748 (mi_flt_stat[1].mf_err_log & MAC_ERR_LOG_INVALID)) 1749 mi_flt_stat[1].mf_cntl = 0; 1750 1751 mc_aflt.mflt_is_ptrl = 0; 1752 mi_valid = mc_process_error_mir(mcp, &mc_aflt, &mi_flt_stat[0]); 1753 1754 if ((((flt_stat[0].mf_cntl & MAC_CNTL_PTRL_ERRS) >> 1755 MAC_CNTL_PTRL_ERR_SHIFT) == ((mi_flt_stat[0].mf_cntl & 1756 MAC_CNTL_MI_ERRS) >> MAC_CNTL_MI_ERR_SHIFT)) && 1757 (flt_stat[0].mf_err_add == mi_flt_stat[0].mf_err_add) && 1758 (((flt_stat[1].mf_cntl & MAC_CNTL_PTRL_ERRS) >> 1759 MAC_CNTL_PTRL_ERR_SHIFT) == ((mi_flt_stat[1].mf_cntl & 1760 MAC_CNTL_MI_ERRS) >> MAC_CNTL_MI_ERR_SHIFT)) && 1761 (flt_stat[1].mf_err_add == mi_flt_stat[1].mf_err_add)) { 1762 #ifdef DEBUG 1763 MC_LOG("discarding PTRL error because " 1764 "it is the same as MI\n"); 1765 #endif 1766 rsaddr->mi_valid = mi_valid; 1767 return; 1768 } 1769 /* if not error mode, cntl1 is 0 */ 1770 if ((flt_stat[0].mf_err_add & MAC_ERR_ADD_INVALID) || 1771 (flt_stat[0].mf_err_log & MAC_ERR_LOG_INVALID)) 1772 flt_stat[0].mf_cntl = 0; 1773 1774 if ((flt_stat[1].mf_err_add & MAC_ERR_ADD_INVALID) || 1775 (flt_stat[1].mf_err_log & MAC_ERR_LOG_INVALID)) 1776 flt_stat[1].mf_cntl = 0; 1777 1778 mc_aflt.mflt_is_ptrl = 1; 1779 rsaddr->mi_valid = mc_process_error_mir(mcp, &mc_aflt, &flt_stat[0]); 1780 } 1781 static int 1782 mc_process_error(mc_opl_t *mcp, int bank, mc_aflt_t *mc_aflt, 1783 mc_flt_stat_t *flt_stat) 1784 { 1785 int ptrl_error = mc_aflt->mflt_is_ptrl; 1786 int rv = 0; 1787 1788 mc_aflt->mflt_erpt_class = NULL; 1789 if (IS_UE(flt_stat->mf_cntl, ptrl_error)) { 1790 MC_LOG("UE detected\n"); 1791 flt_stat->mf_type = FLT_TYPE_UE; 1792 mc_aflt->mflt_erpt_class = MC_OPL_UE; 1793 mc_aflt->mflt_pr = PR_UE; 1794 MAC_SET_ERRLOG_INFO(flt_stat); 1795 rv = 1; 1796 } else if (IS_CE(flt_stat->mf_cntl, ptrl_error)) { 1797 MC_LOG("CE detected\n"); 1798 MAC_SET_ERRLOG_INFO(flt_stat); 1799 1800 /* Error type can change after scrubbing */ 1801 mc_scrub_ce(mcp, bank, flt_stat, ptrl_error); 1802 1803 if (flt_stat->mf_type == FLT_TYPE_PERMANENT_CE) { 1804 mc_aflt->mflt_erpt_class = MC_OPL_CE; 1805 mc_aflt->mflt_pr = PR_MCE; 1806 } else if (flt_stat->mf_type == FLT_TYPE_UE) { 1807 mc_aflt->mflt_erpt_class = MC_OPL_UE; 1808 mc_aflt->mflt_pr = PR_UE; 1809 } 1810 rv = 1; 1811 } 1812 MC_LOG("mc_process_error: fault type %x erpt %s\n", flt_stat->mf_type, 1813 mc_aflt->mflt_erpt_class); 1814 if (mc_aflt->mflt_erpt_class) { 1815 mc_aflt->mflt_stat[0] = flt_stat; 1816 mc_aflt->mflt_nflts = 1; 1817 mc_err_drain(mc_aflt); 1818 } 1819 return (rv); 1820 } 1821 1822 static void 1823 mc_error_handler(mc_opl_t *mcp, int bank, mc_rsaddr_info_t *rsaddr) 1824 { 1825 mc_aflt_t mc_aflt; 1826 mc_flt_stat_t flt_stat, mi_flt_stat; 1827 int mi_valid; 1828 1829 bzero(&mc_aflt, sizeof (mc_aflt_t)); 1830 bzero(&flt_stat, sizeof (mc_flt_stat_t)); 1831 bzero(&mi_flt_stat, sizeof (mc_flt_stat_t)); 1832 1833 mc_aflt.mflt_mcp = mcp; 1834 mc_aflt.mflt_id = gethrtime(); 1835 1836 /* patrol registers */ 1837 mc_read_ptrl_reg(mcp, bank, &flt_stat); 1838 1839 ASSERT(rsaddr); 1840 rsaddr->mi_restartaddr = flt_stat.mf_flt_maddr; 1841 1842 MC_LOG("ptrl registers cntl %x add %x log %x\n", flt_stat.mf_cntl, 1843 flt_stat.mf_err_add, flt_stat.mf_err_log); 1844 1845 /* MI registers */ 1846 mc_read_mi_reg(mcp, bank, &mi_flt_stat); 1847 1848 1849 MC_LOG("MI registers cntl %x add %x log %x\n", mi_flt_stat.mf_cntl, 1850 mi_flt_stat.mf_err_add, mi_flt_stat.mf_err_log); 1851 1852 /* clear errors once we read all the registers */ 1853 MAC_CLEAR_ERRS(mcp, bank, (MAC_CNTL_PTRL_ERRS|MAC_CNTL_MI_ERRS)); 1854 1855 mc_aflt.mflt_is_ptrl = 0; 1856 if ((mi_flt_stat.mf_cntl & MAC_CNTL_MI_ERRS) && 1857 ((mi_flt_stat.mf_err_add & MAC_ERR_ADD_INVALID) == 0) && 1858 ((mi_flt_stat.mf_err_log & MAC_ERR_LOG_INVALID) == 0)) { 1859 mi_valid = mc_process_error(mcp, bank, &mc_aflt, &mi_flt_stat); 1860 } 1861 1862 if ((((flt_stat.mf_cntl & MAC_CNTL_PTRL_ERRS) >> 1863 MAC_CNTL_PTRL_ERR_SHIFT) == ((mi_flt_stat.mf_cntl & 1864 MAC_CNTL_MI_ERRS) >> MAC_CNTL_MI_ERR_SHIFT)) && 1865 (flt_stat.mf_err_add == mi_flt_stat.mf_err_add)) { 1866 #ifdef DEBUG 1867 MC_LOG("discarding PTRL error because " 1868 "it is the same as MI\n"); 1869 #endif 1870 rsaddr->mi_valid = mi_valid; 1871 return; 1872 } 1873 1874 mc_aflt.mflt_is_ptrl = 1; 1875 if ((flt_stat.mf_cntl & MAC_CNTL_PTRL_ERRS) && 1876 ((flt_stat.mf_err_add & MAC_ERR_ADD_INVALID) == 0) && 1877 ((flt_stat.mf_err_log & MAC_ERR_LOG_INVALID) == 0)) { 1878 rsaddr->mi_valid = mc_process_error(mcp, bank, &mc_aflt, 1879 &flt_stat); 1880 } 1881 } 1882 /* 1883 * memory patrol error handling algorithm: 1884 * timeout() is used to do periodic polling 1885 * This is the flow chart. 1886 * timeout -> 1887 * mc_check_errors() 1888 * if memory bank is installed, read the status register 1889 * if any error bit is set, 1890 * -> mc_error_handler() 1891 * -> read all error registers 1892 * -> mc_process_error() 1893 * determine error type 1894 * rewrite to clear error or scrub to determine CE type 1895 * inform SCF on permanent CE 1896 * -> mc_err_drain 1897 * page offline processing 1898 * -> mc_ereport_post() 1899 */ 1900 1901 static void 1902 mc_check_errors_func(mc_opl_t *mcp) 1903 { 1904 mc_rsaddr_info_t rsaddr_info; 1905 int i, error_count = 0; 1906 uint32_t stat, cntl; 1907 int running; 1908 int wrapped; 1909 int ebk; 1910 1911 /* 1912 * scan errors. 1913 */ 1914 if (mcp->mc_status & MC_MEMORYLESS) 1915 return; 1916 1917 for (i = 0; i < BANKNUM_PER_SB; i++) { 1918 if (mcp->mc_bank[i].mcb_status & BANK_INSTALLED) { 1919 stat = ldphysio(MAC_PTRL_STAT(mcp, i)); 1920 cntl = ldphysio(MAC_PTRL_CNTL(mcp, i)); 1921 running = cntl & MAC_CNTL_PTRL_START; 1922 wrapped = cntl & MAC_CNTL_PTRL_ADD_MAX; 1923 1924 /* Compute the effective bank idx */ 1925 ebk = (IS_MIRROR(mcp, i)) ? MIRROR_IDX(i) : i; 1926 1927 if (mc_debug_show_all || stat) { 1928 MC_LOG("/LSB%d/B%d stat %x cntl %x\n", 1929 mcp->mc_board_num, i, stat, cntl); 1930 } 1931 1932 /* 1933 * Update stats and reset flag if the HW patrol 1934 * wrapped around in its scan. 1935 */ 1936 if (wrapped) { 1937 MAC_CLEAR_MAX(mcp, i); 1938 mcp->mc_period[ebk]++; 1939 if (IS_MIRROR(mcp, i)) 1940 MC_LOG("mirror mc period %ld on " 1941 "/LSB%d/B%d\n", mcp->mc_period[ebk], 1942 mcp->mc_board_num, i); 1943 else { 1944 MC_LOG("mc period %ld on " 1945 "/LSB%d/B%d\n", mcp->mc_period[ebk], 1946 mcp->mc_board_num, i); 1947 } 1948 } 1949 1950 if (running) { 1951 /* 1952 * Mac patrol HW is still running. 1953 * Normally when an error is detected, 1954 * the HW patrol will stop so that we 1955 * can collect error data for reporting. 1956 * Certain errors (MI errors) detected may not 1957 * cause the HW patrol to stop which is a 1958 * problem since we cannot read error data while 1959 * the HW patrol is running. SW is not allowed 1960 * to stop the HW patrol while it is running 1961 * as it may cause HW inconsistency. This is 1962 * described in a HW errata. 1963 * In situations where we detected errors 1964 * that may not cause the HW patrol to stop. 1965 * We speed up the HW patrol scanning in 1966 * the hope that it will find the 'real' PTRL 1967 * errors associated with the previous errors 1968 * causing the HW to finally stop so that we 1969 * can do the reporting. 1970 */ 1971 /* 1972 * Check to see if we did speed up 1973 * the HW patrol due to previous errors 1974 * detected that did not cause the patrol 1975 * to stop. We only do it if HW patrol scan 1976 * wrapped (counted as completing a 'period'). 1977 */ 1978 if (mcp->mc_speedup_period[ebk] > 0) { 1979 if (wrapped && 1980 (--mcp->mc_speedup_period[ebk] == 1981 0)) { 1982 /* 1983 * We did try to speed up. 1984 * The speed up period has 1985 * expired and the HW patrol 1986 * is still running. The 1987 * errors must be intermittent. 1988 * We have no choice but to 1989 * ignore them, reset the scan 1990 * speed to normal and clear 1991 * the MI error bits. For 1992 * mirror mode, we need to 1993 * clear errors on both banks. 1994 */ 1995 MC_LOG("Clearing MI errors\n"); 1996 MAC_CLEAR_ERRS(mcp, i, 1997 MAC_CNTL_MI_ERRS); 1998 1999 if (IS_MIRROR(mcp, i)) { 2000 MC_LOG("Clearing " 2001 "Mirror MI errs\n"); 2002 MAC_CLEAR_ERRS(mcp, 2003 i^1, 2004 MAC_CNTL_MI_ERRS); 2005 } 2006 } 2007 } else if (stat & MAC_STAT_MI_ERRS) { 2008 /* 2009 * MI errors detected but we cannot 2010 * report them since the HW patrol 2011 * is still running. 2012 * We will attempt to speed up the 2013 * scanning and hopefully the HW 2014 * can detect PRTL errors at the same 2015 * location that cause the HW patrol 2016 * to stop. 2017 */ 2018 mcp->mc_speedup_period[ebk] = 2; 2019 MAC_CMD(mcp, i, 0); 2020 } 2021 } else if (stat & (MAC_STAT_PTRL_ERRS | 2022 MAC_STAT_MI_ERRS)) { 2023 /* 2024 * HW Patrol has stopped and we found errors. 2025 * Proceed to collect and report error info. 2026 */ 2027 mcp->mc_speedup_period[ebk] = 0; 2028 rsaddr_info.mi_valid = 0; 2029 rsaddr_info.mi_injectrestart = 0; 2030 if (IS_MIRROR(mcp, i)) { 2031 mc_error_handler_mir(mcp, i, 2032 &rsaddr_info); 2033 } else { 2034 mc_error_handler(mcp, i, &rsaddr_info); 2035 } 2036 2037 error_count++; 2038 restart_patrol(mcp, i, &rsaddr_info); 2039 } else { 2040 /* 2041 * HW patrol scan has apparently stopped 2042 * but no errors detected/flagged. 2043 * Restart the HW patrol just to be sure. 2044 * In mirror mode, the odd bank might have 2045 * reported errors that caused the patrol to 2046 * stop. We'll defer the restart to the odd 2047 * bank in this case. 2048 */ 2049 if (!IS_MIRROR(mcp, i) || (i & 0x1)) 2050 restart_patrol(mcp, i, NULL); 2051 } 2052 } 2053 } 2054 if (error_count > 0) 2055 mcp->mc_last_error += error_count; 2056 else 2057 mcp->mc_last_error = 0; 2058 } 2059 2060 /* 2061 * mc_polling -- Check errors for only one instance, 2062 * but process errors for all instances to make sure we drain the errors 2063 * faster than they can be accumulated. 2064 * 2065 * Polling on each board should be done only once per each 2066 * mc_patrol_interval_sec. This is equivalent to setting mc_tick_left 2067 * to OPL_MAX_BOARDS and decrement by 1 on each timeout. 2068 * Once mc_tick_left becomes negative, the board becomes a candidate 2069 * for polling because it has waited for at least 2070 * mc_patrol_interval_sec's long. If mc_timeout_period is calculated 2071 * differently, this has to be updated accordingly. 2072 */ 2073 2074 static void 2075 mc_polling(void) 2076 { 2077 int i, scan_error; 2078 mc_opl_t *mcp; 2079 2080 2081 scan_error = 1; 2082 for (i = 0; i < OPL_MAX_BOARDS; i++) { 2083 mutex_enter(&mcmutex); 2084 if ((mcp = mc_instances[i]) == NULL) { 2085 mutex_exit(&mcmutex); 2086 continue; 2087 } 2088 mutex_enter(&mcp->mc_lock); 2089 mutex_exit(&mcmutex); 2090 if (!(mcp->mc_status & MC_POLL_RUNNING)) { 2091 mutex_exit(&mcp->mc_lock); 2092 continue; 2093 } 2094 if (scan_error && mcp->mc_tick_left <= 0) { 2095 mc_check_errors_func((void *)mcp); 2096 mcp->mc_tick_left = OPL_MAX_BOARDS; 2097 scan_error = 0; 2098 } else { 2099 mcp->mc_tick_left--; 2100 } 2101 mc_process_scf_log(mcp); 2102 mutex_exit(&mcp->mc_lock); 2103 } 2104 } 2105 2106 static void 2107 get_ptrl_start_address(mc_opl_t *mcp, int bank, mc_addr_t *maddr) 2108 { 2109 maddr->ma_bd = mcp->mc_board_num; 2110 maddr->ma_bank = bank; 2111 maddr->ma_dimm_addr = 0; 2112 } 2113 2114 typedef struct mc_mem_range { 2115 uint64_t addr; 2116 uint64_t size; 2117 } mc_mem_range_t; 2118 2119 static int 2120 get_base_address(mc_opl_t *mcp) 2121 { 2122 mc_mem_range_t *mem_range; 2123 int len; 2124 2125 if (ddi_getlongprop(DDI_DEV_T_ANY, mcp->mc_dip, DDI_PROP_DONTPASS, 2126 "sb-mem-ranges", (caddr_t)&mem_range, &len) != DDI_SUCCESS) { 2127 return (DDI_FAILURE); 2128 } 2129 2130 mcp->mc_start_address = mem_range->addr; 2131 mcp->mc_size = mem_range->size; 2132 2133 kmem_free(mem_range, len); 2134 return (DDI_SUCCESS); 2135 } 2136 2137 struct mc_addr_spec { 2138 uint32_t bank; 2139 uint32_t phys_hi; 2140 uint32_t phys_lo; 2141 }; 2142 2143 #define REGS_PA(m, i) ((((uint64_t)m[i].phys_hi)<<32) | m[i].phys_lo) 2144 2145 static char *mc_tbl_name[] = { 2146 "cs0-mc-pa-trans-table", 2147 "cs1-mc-pa-trans-table" 2148 }; 2149 2150 /* 2151 * This routine performs a rangecheck for a given PA 2152 * to see if it belongs to the memory range for this board. 2153 * Return 1 if it is valid (within the range) and 0 otherwise 2154 */ 2155 static int 2156 mc_rangecheck_pa(mc_opl_t *mcp, uint64_t pa) 2157 { 2158 if ((pa < mcp->mc_start_address) || (mcp->mc_start_address + 2159 mcp->mc_size <= pa)) 2160 return (0); 2161 else 2162 return (1); 2163 } 2164 2165 static void 2166 mc_memlist_delete(struct memlist *mlist) 2167 { 2168 struct memlist *ml; 2169 2170 for (ml = mlist; ml; ml = mlist) { 2171 mlist = ml->next; 2172 kmem_free(ml, sizeof (struct memlist)); 2173 } 2174 } 2175 2176 static struct memlist * 2177 mc_memlist_dup(struct memlist *mlist) 2178 { 2179 struct memlist *hl = NULL, *tl, **mlp; 2180 2181 if (mlist == NULL) 2182 return (NULL); 2183 2184 mlp = &hl; 2185 tl = *mlp; 2186 for (; mlist; mlist = mlist->next) { 2187 *mlp = kmem_alloc(sizeof (struct memlist), KM_SLEEP); 2188 (*mlp)->address = mlist->address; 2189 (*mlp)->size = mlist->size; 2190 (*mlp)->prev = tl; 2191 tl = *mlp; 2192 mlp = &((*mlp)->next); 2193 } 2194 *mlp = NULL; 2195 2196 return (hl); 2197 } 2198 2199 2200 static struct memlist * 2201 mc_memlist_del_span(struct memlist *mlist, uint64_t base, uint64_t len) 2202 { 2203 uint64_t end; 2204 struct memlist *ml, *tl, *nlp; 2205 2206 if (mlist == NULL) 2207 return (NULL); 2208 2209 end = base + len; 2210 if ((end <= mlist->address) || (base == end)) 2211 return (mlist); 2212 2213 for (tl = ml = mlist; ml; tl = ml, ml = nlp) { 2214 uint64_t mend; 2215 2216 nlp = ml->next; 2217 2218 if (end <= ml->address) 2219 break; 2220 2221 mend = ml->address + ml->size; 2222 if (base < mend) { 2223 if (base <= ml->address) { 2224 ml->address = end; 2225 if (end >= mend) 2226 ml->size = 0ull; 2227 else 2228 ml->size = mend - ml->address; 2229 } else { 2230 ml->size = base - ml->address; 2231 if (end < mend) { 2232 struct memlist *nl; 2233 /* 2234 * splitting an memlist entry. 2235 */ 2236 nl = kmem_alloc(sizeof (struct memlist), 2237 KM_SLEEP); 2238 nl->address = end; 2239 nl->size = mend - nl->address; 2240 if ((nl->next = nlp) != NULL) 2241 nlp->prev = nl; 2242 nl->prev = ml; 2243 ml->next = nl; 2244 nlp = nl; 2245 } 2246 } 2247 if (ml->size == 0ull) { 2248 if (ml == mlist) { 2249 if ((mlist = nlp) != NULL) 2250 nlp->prev = NULL; 2251 kmem_free(ml, sizeof (struct memlist)); 2252 if (mlist == NULL) 2253 break; 2254 ml = nlp; 2255 } else { 2256 if ((tl->next = nlp) != NULL) 2257 nlp->prev = tl; 2258 kmem_free(ml, sizeof (struct memlist)); 2259 ml = tl; 2260 } 2261 } 2262 } 2263 } 2264 2265 return (mlist); 2266 } 2267 2268 static void 2269 mc_get_mlist(mc_opl_t *mcp) 2270 { 2271 struct memlist *mlist; 2272 2273 memlist_read_lock(); 2274 mlist = mc_memlist_dup(phys_install); 2275 memlist_read_unlock(); 2276 2277 if (mlist) { 2278 mlist = mc_memlist_del_span(mlist, 0ull, mcp->mc_start_address); 2279 } 2280 2281 if (mlist) { 2282 uint64_t startpa, endpa; 2283 2284 startpa = mcp->mc_start_address + mcp->mc_size; 2285 endpa = ptob(physmax + 1); 2286 if (endpa > startpa) { 2287 mlist = mc_memlist_del_span(mlist, startpa, 2288 endpa - startpa); 2289 } 2290 } 2291 2292 if (mlist) { 2293 mcp->mlist = mlist; 2294 } 2295 } 2296 2297 int 2298 mc_board_add(mc_opl_t *mcp) 2299 { 2300 struct mc_addr_spec *macaddr; 2301 cs_status_t *cs_status; 2302 int len, len1, i, bk, cc; 2303 mc_rsaddr_info_t rsaddr; 2304 uint32_t mirr; 2305 int nbanks = 0; 2306 uint64_t nbytes = 0; 2307 int mirror_mode = 0; 2308 int ret; 2309 2310 /* 2311 * Get configurations from "pseudo-mc" node which includes: 2312 * board# : LSB number 2313 * mac-addr : physical base address of MAC registers 2314 * csX-mac-pa-trans-table: translation table from DIMM address 2315 * to physical address or vice versa. 2316 */ 2317 mcp->mc_board_num = (int)ddi_getprop(DDI_DEV_T_ANY, mcp->mc_dip, 2318 DDI_PROP_DONTPASS, "board#", -1); 2319 2320 if (mcp->mc_board_num == -1) { 2321 return (DDI_FAILURE); 2322 } 2323 2324 /* 2325 * Get start address in this CAB. It can be gotten from 2326 * "sb-mem-ranges" property. 2327 */ 2328 2329 if (get_base_address(mcp) == DDI_FAILURE) { 2330 return (DDI_FAILURE); 2331 } 2332 /* get mac-pa trans tables */ 2333 for (i = 0; i < MC_TT_CS; i++) { 2334 len = MC_TT_ENTRIES; 2335 cc = ddi_getlongprop_buf(DDI_DEV_T_ANY, mcp->mc_dip, 2336 DDI_PROP_DONTPASS, mc_tbl_name[i], 2337 (caddr_t)mcp->mc_trans_table[i], &len); 2338 2339 if (cc != DDI_SUCCESS) { 2340 bzero(mcp->mc_trans_table[i], MC_TT_ENTRIES); 2341 } 2342 } 2343 mcp->mlist = NULL; 2344 2345 mc_get_mlist(mcp); 2346 2347 /* initialize bank informations */ 2348 cc = ddi_getlongprop(DDI_DEV_T_ANY, mcp->mc_dip, DDI_PROP_DONTPASS, 2349 "mc-addr", (caddr_t)&macaddr, &len); 2350 if (cc != DDI_SUCCESS) { 2351 cmn_err(CE_WARN, "Cannot get mc-addr. err=%d\n", cc); 2352 return (DDI_FAILURE); 2353 } 2354 2355 cc = ddi_getlongprop(DDI_DEV_T_ANY, mcp->mc_dip, DDI_PROP_DONTPASS, 2356 "cs-status", (caddr_t)&cs_status, &len1); 2357 2358 if (cc != DDI_SUCCESS) { 2359 if (len > 0) 2360 kmem_free(macaddr, len); 2361 cmn_err(CE_WARN, "Cannot get cs-status. err=%d\n", cc); 2362 return (DDI_FAILURE); 2363 } 2364 /* get the physical board number for a given logical board number */ 2365 mcp->mc_phys_board_num = mc_opl_get_physical_board(mcp->mc_board_num); 2366 2367 if (mcp->mc_phys_board_num < 0) { 2368 if (len > 0) 2369 kmem_free(macaddr, len); 2370 cmn_err(CE_WARN, "Unable to obtain the physical board number"); 2371 return (DDI_FAILURE); 2372 } 2373 2374 mutex_init(&mcp->mc_lock, NULL, MUTEX_DRIVER, NULL); 2375 2376 for (i = 0; i < len1 / sizeof (cs_status_t); i++) { 2377 nbytes += ((uint64_t)cs_status[i].cs_avail_hi << 32) | 2378 ((uint64_t)cs_status[i].cs_avail_low); 2379 } 2380 if (len1 > 0) 2381 kmem_free(cs_status, len1); 2382 nbanks = len / sizeof (struct mc_addr_spec); 2383 2384 if (nbanks > 0) 2385 nbytes /= nbanks; 2386 else { 2387 /* No need to free macaddr because len must be 0 */ 2388 mcp->mc_status |= MC_MEMORYLESS; 2389 return (DDI_SUCCESS); 2390 } 2391 2392 for (i = 0; i < BANKNUM_PER_SB; i++) { 2393 mcp->mc_scf_retry[i] = 0; 2394 mcp->mc_period[i] = 0; 2395 mcp->mc_speedup_period[i] = 0; 2396 } 2397 2398 /* 2399 * Get the memory size here. Let it be B (bytes). 2400 * Let T be the time in u.s. to scan 64 bytes. 2401 * If we want to complete 1 round of scanning in P seconds. 2402 * 2403 * B * T * 10^(-6) = P 2404 * --------------- 2405 * 64 2406 * 2407 * T = P * 64 * 10^6 2408 * ------------- 2409 * B 2410 * 2411 * = P * 64 * 10^6 2412 * ------------- 2413 * B 2414 * 2415 * The timing bits are set in PTRL_CNTL[28:26] where 2416 * 2417 * 0 - 1 m.s 2418 * 1 - 512 u.s. 2419 * 10 - 256 u.s. 2420 * 11 - 128 u.s. 2421 * 100 - 64 u.s. 2422 * 101 - 32 u.s. 2423 * 110 - 0 u.s. 2424 * 111 - reserved. 2425 * 2426 * 2427 * a[0] = 110, a[1] = 101, ... a[6] = 0 2428 * 2429 * cs-status property is int x 7 2430 * 0 - cs# 2431 * 1 - cs-status 2432 * 2 - cs-avail.hi 2433 * 3 - cs-avail.lo 2434 * 4 - dimm-capa.hi 2435 * 5 - dimm-capa.lo 2436 * 6 - #of dimms 2437 */ 2438 2439 if (nbytes > 0) { 2440 int i; 2441 uint64_t ms; 2442 ms = ((uint64_t)mc_scan_period * 64 * 1000000)/nbytes; 2443 mcp->mc_speed = mc_scan_speeds[MC_MAX_SPEEDS - 1].mc_speeds; 2444 for (i = 0; i < MC_MAX_SPEEDS - 1; i++) { 2445 if (ms < mc_scan_speeds[i + 1].mc_period) { 2446 mcp->mc_speed = mc_scan_speeds[i].mc_speeds; 2447 break; 2448 } 2449 } 2450 } else 2451 mcp->mc_speed = 0; 2452 2453 2454 for (i = 0; i < len / sizeof (struct mc_addr_spec); i++) { 2455 struct mc_bank *bankp; 2456 uint32_t reg; 2457 2458 /* 2459 * setup bank 2460 */ 2461 bk = macaddr[i].bank; 2462 bankp = &(mcp->mc_bank[bk]); 2463 bankp->mcb_status = BANK_INSTALLED; 2464 bankp->mcb_reg_base = REGS_PA(macaddr, i); 2465 2466 reg = LD_MAC_REG(MAC_PTRL_CNTL(mcp, bk)); 2467 bankp->mcb_ptrl_cntl = (reg & MAC_CNTL_PTRL_PRESERVE_BITS); 2468 2469 /* 2470 * check if mirror mode 2471 */ 2472 mirr = LD_MAC_REG(MAC_MIRR(mcp, bk)); 2473 2474 if (mirr & MAC_MIRR_MIRROR_MODE) { 2475 MC_LOG("Mirror -> /LSB%d/B%d\n", mcp->mc_board_num, 2476 bk); 2477 bankp->mcb_status |= BANK_MIRROR_MODE; 2478 mirror_mode = 1; 2479 /* 2480 * The following bit is only used for 2481 * error injection. We should clear it 2482 */ 2483 if (mirr & MAC_MIRR_BANK_EXCLUSIVE) 2484 ST_MAC_REG(MAC_MIRR(mcp, bk), 0); 2485 } 2486 2487 /* 2488 * restart if not mirror mode or the other bank 2489 * of the mirror is not running 2490 */ 2491 if (!(mirr & MAC_MIRR_MIRROR_MODE) || 2492 !(mcp->mc_bank[bk^1].mcb_status & BANK_PTRL_RUNNING)) { 2493 MC_LOG("Starting up /LSB%d/B%d\n", mcp->mc_board_num, 2494 bk); 2495 get_ptrl_start_address(mcp, bk, &rsaddr.mi_restartaddr); 2496 rsaddr.mi_valid = 0; 2497 rsaddr.mi_injectrestart = 0; 2498 restart_patrol(mcp, bk, &rsaddr); 2499 } else { 2500 MC_LOG("Not starting up /LSB%d/B%d\n", 2501 mcp->mc_board_num, bk); 2502 } 2503 bankp->mcb_status |= BANK_PTRL_RUNNING; 2504 } 2505 if (len > 0) 2506 kmem_free(macaddr, len); 2507 2508 ret = ndi_prop_update_int(DDI_DEV_T_NONE, mcp->mc_dip, "mirror-mode", 2509 mirror_mode); 2510 if (ret != DDI_PROP_SUCCESS) { 2511 cmn_err(CE_WARN, "Unable to update mirror-mode property"); 2512 } 2513 2514 mcp->mc_dimm_list = mc_get_dimm_list(mcp); 2515 2516 /* 2517 * set interval in HZ. 2518 */ 2519 mcp->mc_last_error = 0; 2520 2521 /* restart memory patrol checking */ 2522 mcp->mc_status |= MC_POLL_RUNNING; 2523 2524 return (DDI_SUCCESS); 2525 } 2526 2527 int 2528 mc_board_del(mc_opl_t *mcp) 2529 { 2530 int i; 2531 scf_log_t *p; 2532 2533 /* 2534 * cleanup mac state 2535 */ 2536 mutex_enter(&mcp->mc_lock); 2537 if (mcp->mc_status & MC_MEMORYLESS) { 2538 mutex_exit(&mcp->mc_lock); 2539 mutex_destroy(&mcp->mc_lock); 2540 return (DDI_SUCCESS); 2541 } 2542 for (i = 0; i < BANKNUM_PER_SB; i++) { 2543 if (mcp->mc_bank[i].mcb_status & BANK_INSTALLED) { 2544 mcp->mc_bank[i].mcb_status &= ~BANK_INSTALLED; 2545 } 2546 } 2547 2548 /* stop memory patrol checking */ 2549 mcp->mc_status &= ~MC_POLL_RUNNING; 2550 2551 /* just throw away all the scf logs */ 2552 for (i = 0; i < BANKNUM_PER_SB; i++) { 2553 while ((p = mcp->mc_scf_log[i]) != NULL) { 2554 mcp->mc_scf_log[i] = p->sl_next; 2555 mcp->mc_scf_total[i]--; 2556 kmem_free(p, sizeof (scf_log_t)); 2557 } 2558 } 2559 2560 if (mcp->mlist) 2561 mc_memlist_delete(mcp->mlist); 2562 2563 if (mcp->mc_dimm_list) 2564 mc_free_dimm_list(mcp->mc_dimm_list); 2565 2566 mutex_exit(&mcp->mc_lock); 2567 2568 mutex_destroy(&mcp->mc_lock); 2569 return (DDI_SUCCESS); 2570 } 2571 2572 int 2573 mc_suspend(mc_opl_t *mcp, uint32_t flag) 2574 { 2575 /* stop memory patrol checking */ 2576 mutex_enter(&mcp->mc_lock); 2577 if (mcp->mc_status & MC_MEMORYLESS) { 2578 mutex_exit(&mcp->mc_lock); 2579 return (DDI_SUCCESS); 2580 } 2581 2582 mcp->mc_status &= ~MC_POLL_RUNNING; 2583 2584 mcp->mc_status |= flag; 2585 mutex_exit(&mcp->mc_lock); 2586 2587 return (DDI_SUCCESS); 2588 } 2589 2590 void 2591 opl_mc_update_mlist(void) 2592 { 2593 int i; 2594 mc_opl_t *mcp; 2595 2596 /* 2597 * memory information is not updated until 2598 * the post attach/detach stage during DR. 2599 * This interface is used by dr_mem to inform 2600 * mc-opl to update the mlist. 2601 */ 2602 2603 mutex_enter(&mcmutex); 2604 for (i = 0; i < OPL_MAX_BOARDS; i++) { 2605 if ((mcp = mc_instances[i]) == NULL) 2606 continue; 2607 mutex_enter(&mcp->mc_lock); 2608 if (mcp->mlist) 2609 mc_memlist_delete(mcp->mlist); 2610 mcp->mlist = NULL; 2611 mc_get_mlist(mcp); 2612 mutex_exit(&mcp->mc_lock); 2613 } 2614 mutex_exit(&mcmutex); 2615 } 2616 2617 /* caller must clear the SUSPEND bits or this will do nothing */ 2618 2619 int 2620 mc_resume(mc_opl_t *mcp, uint32_t flag) 2621 { 2622 int i; 2623 uint64_t basepa; 2624 2625 mutex_enter(&mcp->mc_lock); 2626 if (mcp->mc_status & MC_MEMORYLESS) { 2627 mutex_exit(&mcp->mc_lock); 2628 return (DDI_SUCCESS); 2629 } 2630 basepa = mcp->mc_start_address; 2631 if (get_base_address(mcp) == DDI_FAILURE) { 2632 mutex_exit(&mcp->mc_lock); 2633 return (DDI_FAILURE); 2634 } 2635 2636 if (basepa != mcp->mc_start_address) { 2637 if (mcp->mlist) 2638 mc_memlist_delete(mcp->mlist); 2639 mcp->mlist = NULL; 2640 mc_get_mlist(mcp); 2641 } 2642 2643 mcp->mc_status &= ~flag; 2644 2645 if (mcp->mc_status & (MC_SOFT_SUSPENDED | MC_DRIVER_SUSPENDED)) { 2646 mutex_exit(&mcp->mc_lock); 2647 return (DDI_SUCCESS); 2648 } 2649 2650 if (!(mcp->mc_status & MC_POLL_RUNNING)) { 2651 /* restart memory patrol checking */ 2652 mcp->mc_status |= MC_POLL_RUNNING; 2653 for (i = 0; i < BANKNUM_PER_SB; i++) { 2654 if (mcp->mc_bank[i].mcb_status & BANK_INSTALLED) { 2655 restart_patrol(mcp, i, NULL); 2656 } 2657 } 2658 } 2659 mutex_exit(&mcp->mc_lock); 2660 2661 return (DDI_SUCCESS); 2662 } 2663 2664 static mc_opl_t * 2665 mc_pa_to_mcp(uint64_t pa) 2666 { 2667 mc_opl_t *mcp; 2668 int i; 2669 2670 ASSERT(MUTEX_HELD(&mcmutex)); 2671 for (i = 0; i < OPL_MAX_BOARDS; i++) { 2672 if ((mcp = mc_instances[i]) == NULL) 2673 continue; 2674 /* if mac patrol is suspended, we cannot rely on it */ 2675 if (!(mcp->mc_status & MC_POLL_RUNNING) || 2676 (mcp->mc_status & MC_SOFT_SUSPENDED)) 2677 continue; 2678 if (mc_rangecheck_pa(mcp, pa)) { 2679 return (mcp); 2680 } 2681 } 2682 return (NULL); 2683 } 2684 2685 /* 2686 * Get Physical Board number from Logical one. 2687 */ 2688 static int 2689 mc_opl_get_physical_board(int sb) 2690 { 2691 if (&opl_get_physical_board) { 2692 return (opl_get_physical_board(sb)); 2693 } 2694 2695 cmn_err(CE_NOTE, "!opl_get_physical_board() not loaded\n"); 2696 return (-1); 2697 } 2698 2699 /* ARGSUSED */ 2700 int 2701 mc_get_mem_unum(int synd_code, uint64_t flt_addr, char *buf, int buflen, 2702 int *lenp) 2703 { 2704 int i; 2705 int j; 2706 int sb; 2707 int bank; 2708 int cs; 2709 mc_opl_t *mcp; 2710 char memb_num; 2711 2712 mutex_enter(&mcmutex); 2713 2714 if (((mcp = mc_pa_to_mcp(flt_addr)) == NULL) || 2715 (!pa_is_valid(mcp, flt_addr))) { 2716 mutex_exit(&mcmutex); 2717 if (snprintf(buf, buflen, "UNKNOWN") >= buflen) { 2718 return (ENOSPC); 2719 } else { 2720 if (lenp) 2721 *lenp = strlen(buf); 2722 } 2723 return (0); 2724 } 2725 2726 bank = pa_to_bank(mcp, flt_addr - mcp->mc_start_address); 2727 sb = mcp->mc_phys_board_num; 2728 cs = pa_to_cs(mcp, flt_addr - mcp->mc_start_address); 2729 2730 if (sb == -1) { 2731 mutex_exit(&mcmutex); 2732 return (ENXIO); 2733 } 2734 2735 if (plat_model == MODEL_DC) { 2736 i = BD_BK_SLOT_TO_INDEX(0, bank, 0); 2737 j = (cs == 0) ? i : i + 2; 2738 snprintf(buf, buflen, "/%s%02d/MEM%s MEM%s", 2739 model_names[plat_model].unit_name, sb, 2740 mc_dc_dimm_unum_table[j], 2741 mc_dc_dimm_unum_table[j + 1]); 2742 } else { 2743 i = BD_BK_SLOT_TO_INDEX(sb, bank, 0); 2744 j = (cs == 0) ? i : i + 2; 2745 memb_num = mc_ff_dimm_unum_table[i][0]; 2746 snprintf(buf, buflen, "/%s/%s%c/MEM%s MEM%s", 2747 model_names[plat_model].unit_name, 2748 model_names[plat_model].mem_name, memb_num, 2749 &mc_ff_dimm_unum_table[j][1], 2750 &mc_ff_dimm_unum_table[j + 1][1]); 2751 } 2752 if (lenp) { 2753 *lenp = strlen(buf); 2754 } 2755 mutex_exit(&mcmutex); 2756 return (0); 2757 } 2758 2759 int 2760 opl_mc_suspend(void) 2761 { 2762 mc_opl_t *mcp; 2763 int i; 2764 2765 mutex_enter(&mcmutex); 2766 for (i = 0; i < OPL_MAX_BOARDS; i++) { 2767 if ((mcp = mc_instances[i]) == NULL) 2768 continue; 2769 mc_suspend(mcp, MC_SOFT_SUSPENDED); 2770 } 2771 mutex_exit(&mcmutex); 2772 2773 return (0); 2774 } 2775 2776 int 2777 opl_mc_resume(void) 2778 { 2779 mc_opl_t *mcp; 2780 int i; 2781 2782 mutex_enter(&mcmutex); 2783 for (i = 0; i < OPL_MAX_BOARDS; i++) { 2784 if ((mcp = mc_instances[i]) == NULL) 2785 continue; 2786 mc_resume(mcp, MC_SOFT_SUSPENDED); 2787 } 2788 mutex_exit(&mcmutex); 2789 2790 return (0); 2791 } 2792 static void 2793 insert_mcp(mc_opl_t *mcp) 2794 { 2795 mutex_enter(&mcmutex); 2796 if (mc_instances[mcp->mc_board_num] != NULL) { 2797 MC_LOG("mc-opl instance for board# %d already exists\n", 2798 mcp->mc_board_num); 2799 } 2800 mc_instances[mcp->mc_board_num] = mcp; 2801 mutex_exit(&mcmutex); 2802 } 2803 2804 static void 2805 delete_mcp(mc_opl_t *mcp) 2806 { 2807 mutex_enter(&mcmutex); 2808 mc_instances[mcp->mc_board_num] = 0; 2809 mutex_exit(&mcmutex); 2810 } 2811 2812 /* Error injection interface */ 2813 2814 static void 2815 mc_lock_va(uint64_t pa, caddr_t new_va) 2816 { 2817 tte_t tte; 2818 2819 vtag_flushpage(new_va, (uint64_t)ksfmmup); 2820 sfmmu_memtte(&tte, pa >> PAGESHIFT, PROC_DATA|HAT_NOSYNC, TTE8K); 2821 tte.tte_intlo |= TTE_LCK_INT; 2822 sfmmu_dtlb_ld_kva(new_va, &tte); 2823 } 2824 2825 static void 2826 mc_unlock_va(caddr_t va) 2827 { 2828 vtag_flushpage(va, (uint64_t)ksfmmup); 2829 } 2830 2831 /* ARGSUSED */ 2832 int 2833 mc_inject_error(int error_type, uint64_t pa, uint32_t flags) 2834 { 2835 mc_opl_t *mcp; 2836 int bank; 2837 uint32_t dimm_addr; 2838 uint32_t cntl; 2839 mc_rsaddr_info_t rsaddr; 2840 uint32_t data, stat; 2841 int both_sides = 0; 2842 uint64_t pa0; 2843 int extra_injection_needed = 0; 2844 extern void cpu_flush_ecache(void); 2845 2846 MC_LOG("HW mc_inject_error(%x, %lx, %x)\n", error_type, pa, flags); 2847 2848 mutex_enter(&mcmutex); 2849 if ((mcp = mc_pa_to_mcp(pa)) == NULL) { 2850 mutex_exit(&mcmutex); 2851 MC_LOG("mc_inject_error: invalid pa\n"); 2852 return (ENOTSUP); 2853 } 2854 2855 mutex_enter(&mcp->mc_lock); 2856 mutex_exit(&mcmutex); 2857 2858 if (mcp->mc_status & (MC_SOFT_SUSPENDED | MC_DRIVER_SUSPENDED)) { 2859 mutex_exit(&mcp->mc_lock); 2860 MC_LOG("mc-opl has been suspended. No error injection.\n"); 2861 return (EBUSY); 2862 } 2863 2864 /* convert pa to offset within the board */ 2865 MC_LOG("pa %lx, offset %lx\n", pa, pa - mcp->mc_start_address); 2866 2867 if (!pa_is_valid(mcp, pa)) { 2868 mutex_exit(&mcp->mc_lock); 2869 return (EINVAL); 2870 } 2871 2872 pa0 = pa - mcp->mc_start_address; 2873 2874 bank = pa_to_bank(mcp, pa0); 2875 2876 if (flags & MC_INJECT_FLAG_OTHER) 2877 bank = bank ^ 1; 2878 2879 if (MC_INJECT_MIRROR(error_type) && !IS_MIRROR(mcp, bank)) { 2880 mutex_exit(&mcp->mc_lock); 2881 MC_LOG("Not mirror mode\n"); 2882 return (EINVAL); 2883 } 2884 2885 dimm_addr = pa_to_dimm(mcp, pa0); 2886 2887 MC_LOG("injecting error to /LSB%d/B%d/%x\n", mcp->mc_board_num, bank, 2888 dimm_addr); 2889 2890 2891 switch (error_type) { 2892 case MC_INJECT_INTERMITTENT_MCE: 2893 case MC_INJECT_PERMANENT_MCE: 2894 case MC_INJECT_MUE: 2895 both_sides = 1; 2896 } 2897 2898 if (flags & MC_INJECT_FLAG_RESET) 2899 ST_MAC_REG(MAC_EG_CNTL(mcp, bank), 0); 2900 2901 ST_MAC_REG(MAC_EG_ADD(mcp, bank), dimm_addr & MAC_EG_ADD_MASK); 2902 2903 if (both_sides) { 2904 ST_MAC_REG(MAC_EG_CNTL(mcp, bank^1), 0); 2905 ST_MAC_REG(MAC_EG_ADD(mcp, bank^1), dimm_addr & 2906 MAC_EG_ADD_MASK); 2907 } 2908 2909 switch (error_type) { 2910 case MC_INJECT_SUE: 2911 extra_injection_needed = 1; 2912 /*FALLTHROUGH*/ 2913 case MC_INJECT_UE: 2914 case MC_INJECT_MUE: 2915 if (flags & MC_INJECT_FLAG_PATH) { 2916 cntl = MAC_EG_ADD_FIX | MAC_EG_FORCE_READ00 | 2917 MAC_EG_FORCE_READ16 | MAC_EG_RDERR_ONCE; 2918 } else { 2919 cntl = MAC_EG_ADD_FIX | MAC_EG_FORCE_DERR00 | 2920 MAC_EG_FORCE_DERR16 | MAC_EG_DERR_ONCE; 2921 } 2922 flags |= MC_INJECT_FLAG_ST; 2923 break; 2924 case MC_INJECT_INTERMITTENT_CE: 2925 case MC_INJECT_INTERMITTENT_MCE: 2926 if (flags & MC_INJECT_FLAG_PATH) { 2927 cntl = MAC_EG_ADD_FIX |MAC_EG_FORCE_READ00 | 2928 MAC_EG_RDERR_ONCE; 2929 } else { 2930 cntl = MAC_EG_ADD_FIX | MAC_EG_FORCE_DERR16 | 2931 MAC_EG_DERR_ONCE; 2932 } 2933 extra_injection_needed = 1; 2934 flags |= MC_INJECT_FLAG_ST; 2935 break; 2936 case MC_INJECT_PERMANENT_CE: 2937 case MC_INJECT_PERMANENT_MCE: 2938 if (flags & MC_INJECT_FLAG_PATH) { 2939 cntl = MAC_EG_ADD_FIX | MAC_EG_FORCE_READ00 | 2940 MAC_EG_RDERR_ALWAYS; 2941 } else { 2942 cntl = MAC_EG_ADD_FIX | MAC_EG_FORCE_DERR16 | 2943 MAC_EG_DERR_ALWAYS; 2944 } 2945 flags |= MC_INJECT_FLAG_ST; 2946 break; 2947 case MC_INJECT_CMPE: 2948 data = 0xabcdefab; 2949 stphys(pa, data); 2950 cpu_flush_ecache(); 2951 MC_LOG("CMPE: writing data %x to %lx\n", data, pa); 2952 ST_MAC_REG(MAC_MIRR(mcp, bank), MAC_MIRR_BANK_EXCLUSIVE); 2953 stphys(pa, data ^ 0xffffffff); 2954 membar_sync(); 2955 cpu_flush_ecache(); 2956 ST_MAC_REG(MAC_MIRR(mcp, bank), 0); 2957 MC_LOG("CMPE: write new data %xto %lx\n", data, pa); 2958 cntl = 0; 2959 break; 2960 case MC_INJECT_NOP: 2961 cntl = 0; 2962 break; 2963 default: 2964 MC_LOG("mc_inject_error: invalid option\n"); 2965 cntl = 0; 2966 } 2967 2968 if (cntl) { 2969 ST_MAC_REG(MAC_EG_CNTL(mcp, bank), cntl & MAC_EG_SETUP_MASK); 2970 ST_MAC_REG(MAC_EG_CNTL(mcp, bank), cntl); 2971 2972 if (both_sides) { 2973 ST_MAC_REG(MAC_EG_CNTL(mcp, bank^1), cntl & 2974 MAC_EG_SETUP_MASK); 2975 ST_MAC_REG(MAC_EG_CNTL(mcp, bank^1), cntl); 2976 } 2977 } 2978 2979 /* 2980 * For all injection cases except compare error, we 2981 * must write to the PA to trigger the error. 2982 */ 2983 2984 if (flags & MC_INJECT_FLAG_ST) { 2985 data = 0xf0e0d0c0; 2986 MC_LOG("Writing %x to %lx\n", data, pa); 2987 stphys(pa, data); 2988 cpu_flush_ecache(); 2989 } 2990 2991 2992 if (flags & MC_INJECT_FLAG_LD) { 2993 if (flags & MC_INJECT_FLAG_PREFETCH) { 2994 /* 2995 * Use strong prefetch operation to 2996 * inject MI errors. 2997 */ 2998 page_t *pp; 2999 extern void mc_prefetch(caddr_t); 3000 3001 MC_LOG("prefetch\n"); 3002 3003 pp = page_numtopp_nolock(pa >> PAGESHIFT); 3004 if (pp != NULL) { 3005 caddr_t va, va1; 3006 3007 va = ppmapin(pp, PROT_READ|PROT_WRITE, 3008 (caddr_t)-1); 3009 kpreempt_disable(); 3010 mc_lock_va((uint64_t)pa, va); 3011 va1 = va + (pa & (PAGESIZE - 1)); 3012 mc_prefetch(va1); 3013 mc_unlock_va(va); 3014 kpreempt_enable(); 3015 ppmapout(va); 3016 3017 /* 3018 * For MI errors, we need one extra 3019 * injection for HW patrol to stop. 3020 */ 3021 extra_injection_needed = 1; 3022 } else { 3023 cmn_err(CE_WARN, "Cannot find page structure" 3024 " for PA %lx\n", pa); 3025 } 3026 } else { 3027 MC_LOG("Reading from %lx\n", pa); 3028 data = ldphys(pa); 3029 MC_LOG("data = %x\n", data); 3030 } 3031 3032 if (extra_injection_needed) { 3033 /* 3034 * These are the injection cases where the 3035 * requested injected errors will not cause the HW 3036 * patrol to stop. For these cases, we need to inject 3037 * an extra 'real' PTRL error to force the 3038 * HW patrol to stop so that we can report the 3039 * errors injected. Note that we cannot read 3040 * and report error status while the HW patrol 3041 * is running. 3042 */ 3043 ST_MAC_REG(MAC_EG_CNTL(mcp, bank), 3044 cntl & MAC_EG_SETUP_MASK); 3045 ST_MAC_REG(MAC_EG_CNTL(mcp, bank), cntl); 3046 3047 if (both_sides) { 3048 ST_MAC_REG(MAC_EG_CNTL(mcp, bank^1), cntl & 3049 MAC_EG_SETUP_MASK); 3050 ST_MAC_REG(MAC_EG_CNTL(mcp, bank^1), cntl); 3051 } 3052 data = 0xf0e0d0c0; 3053 MC_LOG("Writing %x to %lx\n", data, pa); 3054 stphys(pa, data); 3055 cpu_flush_ecache(); 3056 } 3057 } 3058 3059 if (flags & MC_INJECT_FLAG_RESTART) { 3060 MC_LOG("Restart patrol\n"); 3061 rsaddr.mi_restartaddr.ma_bd = mcp->mc_board_num; 3062 rsaddr.mi_restartaddr.ma_bank = bank; 3063 rsaddr.mi_restartaddr.ma_dimm_addr = dimm_addr; 3064 rsaddr.mi_valid = 1; 3065 rsaddr.mi_injectrestart = 1; 3066 restart_patrol(mcp, bank, &rsaddr); 3067 } 3068 3069 if (flags & MC_INJECT_FLAG_POLL) { 3070 int running; 3071 int ebank = (IS_MIRROR(mcp, bank)) ? MIRROR_IDX(bank) : bank; 3072 3073 MC_LOG("Poll patrol error\n"); 3074 stat = LD_MAC_REG(MAC_PTRL_STAT(mcp, bank)); 3075 cntl = LD_MAC_REG(MAC_PTRL_CNTL(mcp, bank)); 3076 running = cntl & MAC_CNTL_PTRL_START; 3077 3078 if (!running && 3079 (stat & (MAC_STAT_PTRL_ERRS|MAC_STAT_MI_ERRS))) { 3080 /* 3081 * HW patrol stopped and we have errors to 3082 * report. Do it. 3083 */ 3084 mcp->mc_speedup_period[ebank] = 0; 3085 rsaddr.mi_valid = 0; 3086 rsaddr.mi_injectrestart = 0; 3087 if (IS_MIRROR(mcp, bank)) { 3088 mc_error_handler_mir(mcp, bank, &rsaddr); 3089 } else { 3090 mc_error_handler(mcp, bank, &rsaddr); 3091 } 3092 3093 restart_patrol(mcp, bank, &rsaddr); 3094 } else { 3095 /* 3096 * We are expecting to report injected 3097 * errors but the HW patrol is still running. 3098 * Speed up the scanning 3099 */ 3100 mcp->mc_speedup_period[ebank] = 2; 3101 MAC_CMD(mcp, bank, 0); 3102 restart_patrol(mcp, bank, NULL); 3103 } 3104 } 3105 3106 mutex_exit(&mcp->mc_lock); 3107 return (0); 3108 } 3109 3110 void 3111 mc_stphysio(uint64_t pa, uint32_t data) 3112 { 3113 MC_LOG("0x%x -> pa(%lx)\n", data, pa); 3114 stphysio(pa, data); 3115 3116 /* force the above write to be processed by mac patrol */ 3117 data = ldphysio(pa); 3118 MC_LOG("pa(%lx) = 0x%x\n", pa, data); 3119 } 3120 3121 uint32_t 3122 mc_ldphysio(uint64_t pa) 3123 { 3124 uint32_t rv; 3125 3126 rv = ldphysio(pa); 3127 MC_LOG("pa(%lx) = 0x%x\n", pa, rv); 3128 return (rv); 3129 } 3130 3131 #define isdigit(ch) ((ch) >= '0' && (ch) <= '9') 3132 3133 /* 3134 * parse_unum_memory -- extract the board number and the DIMM name from 3135 * the unum. 3136 * 3137 * Return 0 for success and non-zero for a failure. 3138 */ 3139 int 3140 parse_unum_memory(char *unum, int *board, char *dname) 3141 { 3142 char *c; 3143 char x, y, z; 3144 3145 if ((c = strstr(unum, "CMU")) != NULL) { 3146 /* DC Model */ 3147 c += 3; 3148 *board = (uint8_t)stoi(&c); 3149 if ((c = strstr(c, "MEM")) == NULL) { 3150 return (1); 3151 } 3152 c += 3; 3153 if (strlen(c) < 3) { 3154 return (2); 3155 } 3156 if ((!isdigit(c[0])) || (!(isdigit(c[1]))) || 3157 ((c[2] != 'A') && (c[2] != 'B'))) { 3158 return (3); 3159 } 3160 x = c[0]; 3161 y = c[1]; 3162 z = c[2]; 3163 } else if ((c = strstr(unum, "MBU_")) != NULL) { 3164 /* FF1/FF2 Model */ 3165 c += 4; 3166 if ((c[0] != 'A') && (c[0] != 'B')) { 3167 return (4); 3168 } 3169 if ((c = strstr(c, "MEMB")) == NULL) { 3170 return (5); 3171 } 3172 c += 4; 3173 3174 x = c[0]; 3175 *board = ((uint8_t)stoi(&c)) / 4; 3176 if ((c = strstr(c, "MEM")) == NULL) { 3177 return (6); 3178 } 3179 c += 3; 3180 if (strlen(c) < 2) { 3181 return (7); 3182 } 3183 if ((!isdigit(c[0])) || ((c[1] != 'A') && (c[1] != 'B'))) { 3184 return (8); 3185 } 3186 y = c[0]; 3187 z = c[1]; 3188 } else { 3189 return (9); 3190 } 3191 if (*board < 0) { 3192 return (10); 3193 } 3194 dname[0] = x; 3195 dname[1] = y; 3196 dname[2] = z; 3197 dname[3] = '\0'; 3198 return (0); 3199 } 3200 3201 /* 3202 * mc_get_mem_sid_dimm -- Get the serial-ID for a given board and 3203 * the DIMM name. 3204 */ 3205 int 3206 mc_get_mem_sid_dimm(mc_opl_t *mcp, char *dname, char *buf, 3207 int buflen, int *lenp) 3208 { 3209 int ret = ENODEV; 3210 mc_dimm_info_t *d = NULL; 3211 3212 if ((d = mcp->mc_dimm_list) == NULL) 3213 return (ENOTSUP); 3214 3215 for (; d != NULL; d = d->md_next) { 3216 if (strcmp(d->md_dimmname, dname) == 0) { 3217 break; 3218 } 3219 } 3220 if (d != NULL) { 3221 *lenp = strlen(d->md_serial) + strlen(d->md_partnum); 3222 if (buflen <= *lenp) { 3223 cmn_err(CE_WARN, "mc_get_mem_sid_dimm: " 3224 "buflen is smaller than %d\n", *lenp); 3225 ret = ENOSPC; 3226 } else { 3227 snprintf(buf, buflen, "%s:%s", 3228 d->md_serial, d->md_partnum); 3229 ret = 0; 3230 } 3231 } 3232 MC_LOG("mc_get_mem_sid_dimm: Ret=%d Name=%s Serial-ID=%s\n", 3233 ret, dname, (ret == 0) ? buf : ""); 3234 return (ret); 3235 } 3236 3237 int 3238 mc_set_mem_sid(mc_opl_t *mcp, char *buf, int buflen, int sb, 3239 int bank, uint32_t mf_type, uint32_t d_slot) 3240 { 3241 int lenp = buflen; 3242 int id; 3243 int ret; 3244 char *dimmnm; 3245 3246 if (mf_type == FLT_TYPE_PERMANENT_CE) { 3247 if (plat_model == MODEL_DC) { 3248 id = BD_BK_SLOT_TO_INDEX(0, bank, d_slot); 3249 dimmnm = mc_dc_dimm_unum_table[id]; 3250 } else { 3251 id = BD_BK_SLOT_TO_INDEX(sb, bank, d_slot); 3252 dimmnm = mc_ff_dimm_unum_table[id]; 3253 } 3254 if ((ret = mc_get_mem_sid_dimm(mcp, dimmnm, buf, buflen, 3255 &lenp)) != 0) { 3256 return (ret); 3257 } 3258 } else { 3259 return (1); 3260 } 3261 3262 return (0); 3263 } 3264 3265 /* 3266 * mc_get_mem_sid -- get the DIMM serial-ID corresponding to the unum. 3267 */ 3268 int 3269 mc_get_mem_sid(char *unum, char *buf, int buflen, int *lenp) 3270 { 3271 int i; 3272 int ret = ENODEV; 3273 int board; 3274 char dname[MCOPL_MAX_DIMMNAME + 1]; 3275 mc_opl_t *mcp; 3276 3277 MC_LOG("mc_get_mem_sid: unum=%s buflen=%d\n", unum, buflen); 3278 if ((ret = parse_unum_memory(unum, &board, dname)) != 0) { 3279 MC_LOG("mc_get_mem_sid: unum(%s) parsing failed ret=%d\n", 3280 unum, ret); 3281 return (EINVAL); 3282 } 3283 3284 if (board < 0) { 3285 MC_LOG("mc_get_mem_sid: Invalid board=%d dimm=%s\n", 3286 board, dname); 3287 return (EINVAL); 3288 } 3289 3290 mutex_enter(&mcmutex); 3291 /* 3292 * return ENOENT if we can not find the matching board. 3293 */ 3294 ret = ENOENT; 3295 for (i = 0; i < OPL_MAX_BOARDS; i++) { 3296 if ((mcp = mc_instances[i]) == NULL) 3297 continue; 3298 mutex_enter(&mcp->mc_lock); 3299 if (mcp->mc_phys_board_num != board) { 3300 mutex_exit(&mcp->mc_lock); 3301 continue; 3302 } 3303 ret = mc_get_mem_sid_dimm(mcp, dname, buf, buflen, lenp); 3304 if (ret == 0) { 3305 mutex_exit(&mcp->mc_lock); 3306 break; 3307 } 3308 mutex_exit(&mcp->mc_lock); 3309 } 3310 mutex_exit(&mcmutex); 3311 return (ret); 3312 } 3313 3314 /* 3315 * mc_get_mem_offset -- get the offset in a DIMM for a given physical address. 3316 */ 3317 int 3318 mc_get_mem_offset(uint64_t paddr, uint64_t *offp) 3319 { 3320 int i; 3321 int ret = ENODEV; 3322 mc_addr_t maddr; 3323 mc_opl_t *mcp; 3324 3325 mutex_enter(&mcmutex); 3326 for (i = 0; ((i < OPL_MAX_BOARDS) && (ret != 0)); i++) { 3327 if ((mcp = mc_instances[i]) == NULL) 3328 continue; 3329 mutex_enter(&mcp->mc_lock); 3330 if (!pa_is_valid(mcp, paddr)) { 3331 mutex_exit(&mcp->mc_lock); 3332 continue; 3333 } 3334 if (pa_to_maddr(mcp, paddr, &maddr) == 0) { 3335 *offp = maddr.ma_dimm_addr; 3336 ret = 0; 3337 } 3338 mutex_exit(&mcp->mc_lock); 3339 } 3340 mutex_exit(&mcmutex); 3341 MC_LOG("mc_get_mem_offset: Ret=%d paddr=0x%lx offset=0x%lx\n", 3342 ret, paddr, *offp); 3343 return (ret); 3344 } 3345 3346 /* 3347 * dname_to_bankslot - Get the bank and slot number from the DIMM name. 3348 */ 3349 int 3350 dname_to_bankslot(char *dname, int *bank, int *slot) 3351 { 3352 int i; 3353 int tsz; 3354 char **tbl; 3355 3356 if (plat_model == MODEL_DC) { /* DC */ 3357 tbl = mc_dc_dimm_unum_table; 3358 tsz = OPL_MAX_DIMMS; 3359 } else { 3360 tbl = mc_ff_dimm_unum_table; 3361 tsz = 2 * OPL_MAX_DIMMS; 3362 } 3363 3364 for (i = 0; i < tsz; i++) { 3365 if (strcmp(dname, tbl[i]) == 0) { 3366 break; 3367 } 3368 } 3369 if (i == tsz) { 3370 return (1); 3371 } 3372 *bank = INDEX_TO_BANK(i); 3373 *slot = INDEX_TO_SLOT(i); 3374 return (0); 3375 } 3376 3377 /* 3378 * mc_get_mem_addr -- get the physical address of a DIMM corresponding 3379 * to the unum and sid. 3380 */ 3381 int 3382 mc_get_mem_addr(char *unum, char *sid, uint64_t offset, uint64_t *paddr) 3383 { 3384 int board; 3385 int bank; 3386 int slot; 3387 int i; 3388 int ret = ENODEV; 3389 char dname[MCOPL_MAX_DIMMNAME + 1]; 3390 mc_addr_t maddr; 3391 mc_opl_t *mcp; 3392 3393 MC_LOG("mc_get_mem_addr: unum=%s sid=%s offset=0x%lx\n", 3394 unum, sid, offset); 3395 if (parse_unum_memory(unum, &board, dname) != 0) { 3396 MC_LOG("mc_get_mem_sid: unum(%s) parsing failed ret=%d\n", 3397 unum, ret); 3398 return (EINVAL); 3399 } 3400 3401 if (board < 0) { 3402 MC_LOG("mc_get_mem_addr: Invalid board=%d dimm=%s\n", 3403 board, dname); 3404 return (EINVAL); 3405 } 3406 3407 mutex_enter(&mcmutex); 3408 for (i = 0; i < OPL_MAX_BOARDS; i++) { 3409 if ((mcp = mc_instances[i]) == NULL) 3410 continue; 3411 mutex_enter(&mcp->mc_lock); 3412 if (mcp->mc_phys_board_num != board) { 3413 mutex_exit(&mcp->mc_lock); 3414 continue; 3415 } 3416 3417 ret = dname_to_bankslot(dname, &bank, &slot); 3418 MC_LOG("mc_get_mem_addr: bank=%d slot=%d\n", bank, slot); 3419 if (ret != 0) { 3420 MC_LOG("mc_get_mem_addr: dname_to_bankslot failed\n"); 3421 ret = ENODEV; 3422 } else { 3423 maddr.ma_bd = mcp->mc_board_num; 3424 maddr.ma_bank = bank; 3425 maddr.ma_dimm_addr = offset; 3426 ret = mcaddr_to_pa(mcp, &maddr, paddr); 3427 if (ret != 0) { 3428 MC_LOG("mc_get_mem_addr: " 3429 "mcaddr_to_pa failed\n"); 3430 ret = ENODEV; 3431 } 3432 mutex_exit(&mcp->mc_lock); 3433 break; 3434 } 3435 mutex_exit(&mcp->mc_lock); 3436 } 3437 mutex_exit(&mcmutex); 3438 MC_LOG("mc_get_mem_addr: Ret=%d, Paddr=0x%lx\n", ret, *paddr); 3439 return (ret); 3440 } 3441 3442 static void 3443 mc_free_dimm_list(mc_dimm_info_t *d) 3444 { 3445 mc_dimm_info_t *next; 3446 3447 while (d != NULL) { 3448 next = d->md_next; 3449 kmem_free(d, sizeof (mc_dimm_info_t)); 3450 d = next; 3451 } 3452 } 3453 3454 /* 3455 * mc_get_dimm_list -- get the list of dimms with serial-id info 3456 * from the SP. 3457 */ 3458 mc_dimm_info_t * 3459 mc_get_dimm_list(mc_opl_t *mcp) 3460 { 3461 uint32_t bufsz; 3462 uint32_t maxbufsz; 3463 int ret; 3464 int sexp; 3465 board_dimm_info_t *bd_dimmp; 3466 mc_dimm_info_t *dimm_list = NULL; 3467 3468 maxbufsz = bufsz = sizeof (board_dimm_info_t) + 3469 ((MCOPL_MAX_DIMMNAME + MCOPL_MAX_SERIAL + 3470 MCOPL_MAX_PARTNUM) * OPL_MAX_DIMMS); 3471 3472 bd_dimmp = (board_dimm_info_t *)kmem_alloc(bufsz, KM_SLEEP); 3473 ret = scf_get_dimminfo(mcp->mc_board_num, (void *)bd_dimmp, &bufsz); 3474 3475 MC_LOG("mc_get_dimm_list: scf_service_getinfo returned=%d\n", ret); 3476 if (ret == 0) { 3477 sexp = sizeof (board_dimm_info_t) + 3478 ((bd_dimmp->bd_dnamesz + bd_dimmp->bd_serialsz + 3479 bd_dimmp->bd_partnumsz) * bd_dimmp->bd_numdimms); 3480 3481 if ((bd_dimmp->bd_version == OPL_DIMM_INFO_VERSION) && 3482 (bd_dimmp->bd_dnamesz <= MCOPL_MAX_DIMMNAME) && 3483 (bd_dimmp->bd_serialsz <= MCOPL_MAX_SERIAL) && 3484 (bd_dimmp->bd_partnumsz <= MCOPL_MAX_PARTNUM) && 3485 (sexp <= bufsz)) { 3486 3487 #ifdef DEBUG 3488 if (oplmc_debug) 3489 mc_dump_dimm_info(bd_dimmp); 3490 #endif 3491 dimm_list = mc_prepare_dimmlist(bd_dimmp); 3492 3493 } else { 3494 cmn_err(CE_WARN, "DIMM info version mismatch\n"); 3495 } 3496 } 3497 kmem_free(bd_dimmp, maxbufsz); 3498 MC_LOG("mc_get_dimm_list: dimmlist=0x%p\n", dimm_list); 3499 return (dimm_list); 3500 } 3501 3502 /* 3503 * mc_prepare_dimmlist - Prepare the dimm list from the information 3504 * received from the SP. 3505 */ 3506 mc_dimm_info_t * 3507 mc_prepare_dimmlist(board_dimm_info_t *bd_dimmp) 3508 { 3509 char *dimm_name; 3510 char *serial; 3511 char *part; 3512 int dimm; 3513 int dnamesz = bd_dimmp->bd_dnamesz; 3514 int sersz = bd_dimmp->bd_serialsz; 3515 int partsz = bd_dimmp->bd_partnumsz; 3516 mc_dimm_info_t *dimm_list = NULL; 3517 mc_dimm_info_t *d; 3518 3519 dimm_name = (char *)(bd_dimmp + 1); 3520 for (dimm = 0; dimm < bd_dimmp->bd_numdimms; dimm++) { 3521 3522 d = (mc_dimm_info_t *)kmem_alloc(sizeof (mc_dimm_info_t), 3523 KM_SLEEP); 3524 3525 bcopy(dimm_name, d->md_dimmname, dnamesz); 3526 d->md_dimmname[dnamesz] = 0; 3527 3528 serial = dimm_name + dnamesz; 3529 bcopy(serial, d->md_serial, sersz); 3530 d->md_serial[sersz] = 0; 3531 3532 part = serial + sersz; 3533 bcopy(part, d->md_partnum, partsz); 3534 d->md_partnum[partsz] = 0; 3535 3536 d->md_next = dimm_list; 3537 dimm_list = d; 3538 dimm_name = part + partsz; 3539 } 3540 return (dimm_list); 3541 } 3542 3543 #ifdef DEBUG 3544 void 3545 mc_dump_dimm(char *buf, int dnamesz, int serialsz, int partnumsz) 3546 { 3547 char dname[MCOPL_MAX_DIMMNAME + 1]; 3548 char serial[MCOPL_MAX_SERIAL + 1]; 3549 char part[ MCOPL_MAX_PARTNUM + 1]; 3550 char *b; 3551 3552 b = buf; 3553 bcopy(b, dname, dnamesz); 3554 dname[dnamesz] = 0; 3555 3556 b += dnamesz; 3557 bcopy(b, serial, serialsz); 3558 serial[serialsz] = 0; 3559 3560 b += serialsz; 3561 bcopy(b, part, partnumsz); 3562 part[partnumsz] = 0; 3563 3564 printf("DIMM=%s Serial=%s PartNum=%s\n", dname, serial, part); 3565 } 3566 3567 void 3568 mc_dump_dimm_info(board_dimm_info_t *bd_dimmp) 3569 { 3570 int dimm; 3571 int dnamesz = bd_dimmp->bd_dnamesz; 3572 int sersz = bd_dimmp->bd_serialsz; 3573 int partsz = bd_dimmp->bd_partnumsz; 3574 char *buf; 3575 3576 printf("Version=%d Board=%02d DIMMs=%d NameSize=%d " 3577 "SerialSize=%d PartnumSize=%d\n", bd_dimmp->bd_version, 3578 bd_dimmp->bd_boardnum, bd_dimmp->bd_numdimms, bd_dimmp->bd_dnamesz, 3579 bd_dimmp->bd_serialsz, bd_dimmp->bd_partnumsz); 3580 printf("======================================================\n"); 3581 3582 buf = (char *)(bd_dimmp + 1); 3583 for (dimm = 0; dimm < bd_dimmp->bd_numdimms; dimm++) { 3584 mc_dump_dimm(buf, dnamesz, sersz, partsz); 3585 buf += dnamesz + sersz + partsz; 3586 } 3587 printf("======================================================\n"); 3588 } 3589 3590 3591 /* ARGSUSED */ 3592 static int 3593 mc_ioctl_debug(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, 3594 int *rvalp) 3595 { 3596 caddr_t buf; 3597 uint64_t pa; 3598 int rv = 0; 3599 int i; 3600 uint32_t flags; 3601 static uint32_t offset = 0; 3602 3603 3604 flags = (cmd >> 4) & 0xfffffff; 3605 3606 cmd &= 0xf; 3607 3608 MC_LOG("mc_ioctl(cmd = %x, flags = %x)\n", cmd, flags); 3609 3610 if (arg != NULL) { 3611 if (ddi_copyin((const void *)arg, (void *)&pa, 3612 sizeof (uint64_t), 0) < 0) { 3613 rv = EFAULT; 3614 return (rv); 3615 } 3616 buf = NULL; 3617 } else { 3618 buf = (caddr_t)kmem_alloc(PAGESIZE, KM_SLEEP); 3619 3620 pa = va_to_pa(buf); 3621 pa += offset; 3622 3623 offset += 64; 3624 if (offset >= PAGESIZE) 3625 offset = 0; 3626 } 3627 3628 switch (cmd) { 3629 case MCI_CE: 3630 mc_inject_error(MC_INJECT_INTERMITTENT_CE, pa, flags); 3631 break; 3632 case MCI_PERM_CE: 3633 mc_inject_error(MC_INJECT_PERMANENT_CE, pa, flags); 3634 break; 3635 case MCI_UE: 3636 mc_inject_error(MC_INJECT_UE, pa, flags); 3637 break; 3638 case MCI_M_CE: 3639 mc_inject_error(MC_INJECT_INTERMITTENT_MCE, pa, flags); 3640 break; 3641 case MCI_M_PCE: 3642 mc_inject_error(MC_INJECT_PERMANENT_MCE, pa, flags); 3643 break; 3644 case MCI_M_UE: 3645 mc_inject_error(MC_INJECT_MUE, pa, flags); 3646 break; 3647 case MCI_CMP: 3648 mc_inject_error(MC_INJECT_CMPE, pa, flags); 3649 break; 3650 case MCI_NOP: 3651 mc_inject_error(MC_INJECT_NOP, pa, flags); break; 3652 case MCI_SHOW_ALL: 3653 mc_debug_show_all = 1; 3654 break; 3655 case MCI_SHOW_NONE: 3656 mc_debug_show_all = 0; 3657 break; 3658 case MCI_ALLOC: 3659 /* 3660 * just allocate some kernel memory and never free it 3661 * 512 MB seems to be the maximum size supported. 3662 */ 3663 cmn_err(CE_NOTE, "Allocating kmem %d MB\n", flags * 512); 3664 for (i = 0; i < flags; i++) { 3665 buf = kmem_alloc(512 * 1024 * 1024, KM_SLEEP); 3666 cmn_err(CE_NOTE, "kmem buf %llx PA %llx\n", 3667 (u_longlong_t)buf, (u_longlong_t)va_to_pa(buf)); 3668 } 3669 break; 3670 case MCI_SUSPEND: 3671 (void) opl_mc_suspend(); 3672 break; 3673 case MCI_RESUME: 3674 (void) opl_mc_resume(); 3675 break; 3676 default: 3677 rv = ENXIO; 3678 } 3679 return (rv); 3680 } 3681 3682 #endif /* DEBUG */ 3683