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