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