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 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/mdb_modapi.h> 29 #include <sys/types.h> 30 #include <sys/dditypes.h> 31 #include <sys/fcode.h> 32 #include <sys/machcpuvar.h> 33 #include <sys/opl.h> 34 #include <sys/opl_cfg.h> 35 36 static uintptr_t tmptr; 37 38 /* 39 * print hardware descriptor 40 */ 41 42 /* Verbosity bits */ 43 #define DUMP_HDR 0x00001 /* Header */ 44 #define DUMP_SB_STAT 0x00002 /* System Board Status */ 45 #define DUMP_DINFO 0x00004 /* Domain Information */ 46 #define DUMP_SB_INFO 0x00008 /* System Board Information */ 47 #define DUMP_CMU_CHAN 0x00010 /* CPU/Memory Channel */ 48 #define DUMP_CHIPS 0x00020 /* Phyiscal CPUs */ 49 #define DUMP_MEM 0x00040 /* Memory Information */ 50 #define DUMP_PCI_CH 0x00080 /* PCI Channel */ 51 #define DUMP_MEM_BANKS 0x00100 /* Memory Banks */ 52 #define DUMP_MEM_CHUNKS 0x00200 /* Memory Chunks */ 53 #define DUMP_MEM_DIMMS 0x00400 /* Memory DIMMS */ 54 #define DUMP_MEM_CS 0x00800 /* Memory CS */ 55 #define DUMP_CORES 0x01000 /* CPU Cores Information */ 56 #define DUMP_SCS 0x02000 /* SC Information */ 57 #define DUMP_MISSING 0x10000 /* Miscellenous Information */ 58 #define DUMP_COMP_NAME 0x20000 /* Component Name */ 59 60 61 /* A nice mix of most of what you want */ 62 #define DUMP_ALL (DUMP_HDR | DUMP_SB_STAT | DUMP_DINFO | \ 63 DUMP_SB_INFO | DUMP_CMU_CHAN | DUMP_CHIPS | \ 64 DUMP_MEM | DUMP_PCI_CH | DUMP_MEM_BANKS | \ 65 DUMP_CORES | DUMP_SCS) 66 67 68 #define DUMP_VERBOSE (DUMP_ALL | DUMP_MEM_CHUNKS | DUMP_MEM_CS) 69 #define DUMP_FULL (DUMP_VERBOSE | DUMP_MISSING | DUMP_COMP_NAME) 70 71 72 #define MIA(stat) ((stat) == HWD_STAT_MISS) 73 #define DONT_BOTHER(stat, v) (MIA(stat) && (v != HWD_STAT_PRESENT)) 74 75 static char *hwd_stat_decode(int stat) 76 { 77 switch (stat) { 78 case HWD_STAT_UNKNOWN: 79 return ("UNKNOWN"); 80 case HWD_STAT_PRESENT: 81 return ("PRESENT"); 82 case HWD_STAT_MISS: 83 return ("MISS"); 84 case HWD_STAT_MISCONFIG: 85 return ("MISCONFIG"); 86 case HWD_STAT_PASS: 87 return ("PASS"); 88 case HWD_STAT_FAIL: 89 return ("FAIL_XSCF"); 90 case HWD_STAT_FAIL_OBP: 91 return ("FAIL_OBP"); 92 case HWD_STAT_FAIL_OS: 93 return ("FAIL_OS"); 94 default: 95 return ("?"); 96 } 97 } 98 99 static void 100 dumpmemhwd(hwd_memory_t *memp, int v, int mv) 101 { 102 int i, j; 103 104 mdb_printf("\nMemory:\tstart\t0x%llx\tsize\t0x%llx\tmirror mode %d\n", 105 memp->mem_start_address, memp->mem_size, memp->mem_mirror_mode); 106 mdb_printf("\tdivision mode\t0x%x\tpiece number\t0x%llx", 107 memp->mem_division_mode, memp->mem_piece_number); 108 mdb_printf("\tcs interleave %d\n", memp->mem_cs_interleave); 109 110 /* banks */ 111 for (i = 0; i < HWD_BANKS_PER_CMU; i++) { 112 if (DONT_BOTHER(memp->mem_banks[i].bank_status, mv)) { 113 mdb_printf("\tBank %d\tstatus\t0x%x (%s)\n", 114 i, memp->mem_banks[i].bank_status, 115 hwd_stat_decode(memp->mem_banks[i].bank_status)); 116 continue; 117 } 118 mdb_printf("\tBank %d\tstatus\t0x%x (%s)\treg addr\t0x%llx\n", 119 i, memp->mem_banks[i].bank_status, 120 hwd_stat_decode(memp->mem_banks[i].bank_status), 121 memp->mem_banks[i].bank_register_address); 122 if (v & DUMP_MEM_BANKS) { 123 mdb_printf("\t\tcs status\t0x%x 0x%x\n", 124 memp->mem_banks[i].bank_cs_status[0], 125 memp->mem_banks[i].bank_cs_status[1]); 126 mdb_printf("\t\tMAC OCD\tDIMM OCDs\n"); 127 mdb_printf("\t\t%x\t%x %x %x %x %x %x %x %x\n", 128 memp->mem_banks[i].bank_mac_ocd, 129 memp->mem_banks[i].bank_dimm_ocd[0][0], 130 memp->mem_banks[i].bank_dimm_ocd[0][1], 131 memp->mem_banks[i].bank_dimm_ocd[1][0], 132 memp->mem_banks[i].bank_dimm_ocd[1][1], 133 memp->mem_banks[i].bank_dimm_ocd[2][0], 134 memp->mem_banks[i].bank_dimm_ocd[2][1], 135 memp->mem_banks[i].bank_dimm_ocd[3][0], 136 memp->mem_banks[i].bank_dimm_ocd[3][1]); 137 } 138 } 139 /* chunks */ 140 for (i = 0; i < HWD_MAX_MEM_CHUNKS; i++) { 141 if ((memp->mem_chunks[i].chnk_start_address == 0) && (mv != 1)) 142 continue; 143 mdb_printf("\tchunk %d\tstart\t0x%llx\tsize\t0x%llx\n", 144 i, memp->mem_chunks[i].chnk_start_address, 145 memp->mem_chunks[i].chnk_size); 146 } 147 /* dimms */ 148 for (i = 0; i < HWD_DIMMS_PER_CMU; i++) { 149 if (DONT_BOTHER(memp->mem_dimms[i].dimm_status, mv)) { 150 if (v & DUMP_MEM_DIMMS) 151 mdb_printf("\tDIMM %d\tstatus\t0x%x (%s)\n", 152 i, memp->mem_dimms[i].dimm_status, 153 hwd_stat_decode( 154 memp->mem_dimms[i].dimm_status)); 155 continue; 156 } 157 mdb_printf("\tDIMM %d\tstatus\t0x%x (%s)\tcapacity\t0x%llx\n", 158 i, memp->mem_dimms[i].dimm_status, 159 hwd_stat_decode(memp->mem_dimms[i].dimm_status), 160 memp->mem_dimms[i].dimm_capacity); 161 mdb_printf("\t\trank\t%x\tavailable capacity\t0x%llx\n", 162 memp->mem_dimms[i].dimm_rank, 163 memp->mem_dimms[i].dimm_available_capacity); 164 } 165 /* cs */ 166 for (i = 0; i < 2; i++) { 167 if (DONT_BOTHER(memp->mem_cs[i].cs_status, mv)) { 168 mdb_printf("\tCS %d:\tstatus\t0x%x (%s)\n", 169 i, memp->mem_cs[i].cs_status, 170 hwd_stat_decode(memp->mem_cs[i].cs_status)); 171 continue; 172 } 173 mdb_printf("\tCS %d:\tstatus\t0x%x (%s)\tavailable\t0x%llx\n", 174 i, memp->mem_cs[i].cs_status, 175 hwd_stat_decode(memp->mem_cs[i].cs_status), 176 memp->mem_cs[i].cs_available_capacity); 177 mdb_printf("\t\tno of dimms\t%x\tdimm capacity\t0x%llx\n", 178 memp->mem_cs[i].cs_number_of_dimms, 179 memp->mem_cs[i].cs_dimm_capacity); 180 mdb_printf("\t\tPA <-> MAC conversion\n\t\t"); 181 for (j = 0; j < 20; j++) 182 mdb_printf("%02x ", memp->mem_cs[i].cs_pa_mac_table[j]); 183 mdb_printf("\n\t\t"); 184 for (j = 20; j < 40; j++) 185 mdb_printf("%02x ", memp->mem_cs[i].cs_pa_mac_table[j]); 186 mdb_printf("\n\t\t"); 187 for (j = 40; j < 60; j++) 188 mdb_printf("%02x ", memp->mem_cs[i].cs_pa_mac_table[j]); 189 mdb_printf("\n\t\t"); 190 for (j = 60; j < 64; j++) 191 mdb_printf("%02x ", memp->mem_cs[i].cs_pa_mac_table[j]); 192 mdb_printf("\n"); 193 } 194 } 195 196 /* ARGSUSED */ 197 static void 198 dumpchiphwd(hwd_cpu_chip_t *chipp, int ch, int v, int mv) 199 { 200 int cp, co; 201 hwd_cpu_t *cpup; 202 hwd_core_t *corep; 203 204 mdb_printf("\nChip %d:\tstatus\t0x%x (%s)\tportid\t%x\n", 205 ch, chipp->chip_status, hwd_stat_decode(chipp->chip_status), 206 chipp->chip_portid); 207 208 if (MIA(chipp->chip_status)) 209 return; 210 211 for (co = 0; co < HWD_CORES_PER_CPU_CHIP; co++) { 212 corep = &chipp->chip_cores[co]; 213 214 mdb_printf("\tCore %d:\tstatus\t0x%x (%s)\tconfig\t0x%llx\n", 215 co, corep->core_status, 216 hwd_stat_decode(corep->core_status), 217 corep->core_config); 218 219 if (MIA(corep->core_status)) 220 continue; 221 222 if (v & DUMP_CORES) { 223 mdb_printf("\t\tfrequency\t0x%llx\tversion\t0x%llx\n", 224 corep->core_frequency, corep->core_version); 225 mdb_printf("\t\t(manuf/impl/mask: %x/%x/%x)\n", 226 corep->core_manufacturer, 227 corep->core_implementation, corep->core_mask); 228 mdb_printf("\t\t\tSize\tLinesize\tAssoc\n"); 229 mdb_printf("\t\tL1I$\t%x\t%x\t\t%x\n", 230 corep->core_l1_icache_size, 231 corep->core_l1_icache_line_size, 232 corep->core_l1_icache_associativity); 233 mdb_printf("\t\tL1D$\t%x\t%x\t\t%x\n", 234 corep->core_l1_dcache_size, 235 corep->core_l1_dcache_line_size, 236 corep->core_l1_dcache_associativity); 237 mdb_printf("\t\tL2$\t%x\t%x\t\t%x", 238 corep->core_l2_cache_size, 239 corep->core_l2_cache_line_size, 240 corep->core_l2_cache_associativity); 241 mdb_printf("\tsharing\t%x\n", 242 corep->core_l2_cache_sharing); 243 mdb_printf("\t\tITLB entries\t0x%x\tDTLB entries " 244 "0x%x\n", corep->core_num_itlb_entries, 245 corep->core_num_dtlb_entries); 246 } 247 248 for (cp = 0; cp < HWD_CPUS_PER_CORE; cp++) { 249 cpup = &corep->core_cpus[cp]; 250 mdb_printf("\t\tCPU %d:\tstatus\t0x%x (%s)\tcpuid" 251 " = 0x%x\n", cp, cpup->cpu_status, 252 hwd_stat_decode(cpup->cpu_status), 253 cpup->cpu_cpuid); 254 if (v & DUMP_COMP_NAME) 255 mdb_printf("\t\t\tcomponent name:%s\n", 256 cpup->cpu_component_name); 257 } 258 } 259 } 260 261 /* ARGSUSED */ 262 static void 263 dumppcihwd(hwd_pci_ch_t *pcip, int ch, int v, int mv) 264 { 265 int lf; 266 hwd_leaf_t *leafp; 267 268 mdb_printf("\nPCI CH %d:\tstatus\t0x%x (%s)\n", 269 ch, pcip->pci_status, hwd_stat_decode(pcip->pci_status)); 270 271 for (lf = 0; lf < HWD_LEAVES_PER_PCI_CHANNEL; lf++) { 272 leafp = &pcip->pci_leaf[lf]; 273 274 if (DONT_BOTHER(leafp->leaf_status, mv)) { 275 mdb_printf("\tleaf %d:\tstatus\t0x%x (%s)\n", 276 lf, leafp->leaf_status, 277 hwd_stat_decode(leafp->leaf_status)); 278 continue; 279 } 280 mdb_printf("\tleaf %d:\tstatus\t0x%x (%s)\tportid 0x%x", 281 lf, leafp->leaf_status, 282 hwd_stat_decode(leafp->leaf_status), leafp->leaf_port_id); 283 mdb_printf("\ttype0x%x\n)", 284 leafp->leaf_slot_type); 285 mdb_printf("\t\t\tOffset\t\tSize\n"); 286 mdb_printf("\t\tcfgio\t0x%llx\t0x%llx\t\t%x\n", 287 leafp->leaf_cfgio_offset, 288 leafp->leaf_cfgio_size); 289 mdb_printf("\t\tmem32\t0x%llx\t0x%llx\t\t%x\n", 290 leafp->leaf_mem32_offset, 291 leafp->leaf_mem32_size); 292 mdb_printf("\t\tmem64\t0x%llx\t0x%llx\t\t%x\n", 293 leafp->leaf_mem64_offset, 294 leafp->leaf_mem64_size); 295 } 296 } 297 298 /* ARGSUSED */ 299 static void 300 dumpahwd(int bd, int v) 301 { 302 opl_board_cfg_t boardcfg; 303 hwd_header_t hwd_hdr; 304 hwd_sb_status_t hwd_sb_status; 305 hwd_domain_info_t hwd_dinfo; 306 hwd_sb_t hwd_sb; 307 caddr_t statusp, dinfop, sbp = NULL; 308 309 /* A flag for whether or not to dump stuff that is missing */ 310 int mv = 0; 311 312 if (v & DUMP_MISSING) 313 mv = 1; 314 315 bzero(&boardcfg, sizeof (opl_board_cfg_t)); 316 bzero(&hwd_hdr, sizeof (hwd_header_t)); 317 bzero(&hwd_sb_status, sizeof (hwd_sb_status_t)); 318 bzero(&hwd_dinfo, sizeof (hwd_domain_info_t)); 319 bzero(&hwd_sb, sizeof (hwd_sb_t)); 320 321 322 if (mdb_vread(&boardcfg, sizeof (opl_board_cfg_t), 323 tmptr + (bd * sizeof (opl_board_cfg_t))) == -1) { 324 mdb_warn("failed to read opl_board_cfg at %p", 325 (tmptr + (bd * sizeof (opl_board_cfg_t)))); 326 return; 327 } 328 329 if (boardcfg.cfg_hwd == NULL) { 330 mdb_printf("Board %d has no HWD info\n", bd); 331 return; 332 } 333 334 mdb_printf("Board %d:\thwd pointer\t%8llx\n", bd, boardcfg.cfg_hwd); 335 336 /* We always need the header, for offsets */ 337 if (mdb_vread(&hwd_hdr, sizeof (hwd_header_t), 338 (uintptr_t)boardcfg.cfg_hwd) == -1) { 339 mdb_warn("failed to read hwd_header_t at %p\n", 340 boardcfg.cfg_hwd); 341 return; 342 } 343 344 /* Figure out the inside pointers, in case we need them... */ 345 statusp = (caddr_t)boardcfg.cfg_hwd + hwd_hdr.hdr_sb_status_offset; 346 dinfop = (caddr_t)boardcfg.cfg_hwd + hwd_hdr.hdr_domain_info_offset; 347 sbp = (caddr_t)boardcfg.cfg_hwd + hwd_hdr.hdr_sb_info_offset; 348 349 /* The sb data is what we will surely be dumping */ 350 if (mdb_vread(&hwd_sb, sizeof (hwd_sb_t), (uintptr_t)sbp) == -1) { 351 mdb_warn("failed to read hwd_sb_t at %p\n", sbp); 352 return; 353 } 354 355 if (v & DUMP_HDR) { 356 /* Print the interesting stuff from the header */ 357 mdb_printf("\t\tversion\t%x.%x\tDID\t%x\tmagic\t0x%x\n\n", 358 hwd_hdr.hdr_version.major, hwd_hdr.hdr_version.minor, 359 hwd_hdr.hdr_domain_id, hwd_hdr.hdr_magic); 360 mdb_printf("\tstatus offset = 0x%x\t(addr=%llx)\n", 361 hwd_hdr.hdr_sb_status_offset, statusp); 362 mdb_printf("\tdomain offset = 0x%x\t(addr=%llx)\n", 363 hwd_hdr.hdr_domain_info_offset, dinfop); 364 mdb_printf("\tboard offset = 0x%x\t(addr=%llx)\n", 365 hwd_hdr.hdr_sb_info_offset, sbp); 366 } 367 368 if (v & DUMP_SB_STAT) { 369 int i; 370 if (mdb_vread(&hwd_sb_status, sizeof (hwd_sb_status_t), 371 (uintptr_t)statusp) == -1) { 372 mdb_warn("failed to read hwd_sb_status_t at %p\n", 373 statusp); 374 return; 375 } 376 mdb_printf("\nSTATUS:\tBoard\tStatus\n"); 377 for (i = 0; i < HWD_SBS_PER_DOMAIN; i++) { 378 if (DONT_BOTHER(hwd_sb_status.sb_status[i], mv)) 379 continue; 380 mdb_printf("\t%d\t0x%x (%s)\n", i, 381 hwd_sb_status.sb_status[i], 382 hwd_stat_decode(hwd_sb_status.sb_status[i])); 383 } 384 } 385 386 /* Domain Info */ 387 if (v & DUMP_DINFO) { 388 if (mdb_vread(&hwd_dinfo, sizeof (hwd_domain_info_t), 389 (uintptr_t)dinfop) == -1) { 390 mdb_warn("failed to read hwd_domain_info_t at %p\n", 391 dinfop); 392 return; 393 } 394 mdb_printf("\nDomain info:\tReset reason\t0x%x", 395 hwd_dinfo.dinf_reset_factor); 396 mdb_printf("\tHost ID 0x%x\n", hwd_dinfo.dinf_host_id); 397 mdb_printf("\tSystem freq\t0x%llx\tStick freq\t0x%llx\n", 398 hwd_dinfo.dinf_system_frequency, 399 hwd_dinfo.dinf_stick_frequency); 400 mdb_printf("\tSCF timeout \t0x%x\tModel info\t%x", 401 hwd_dinfo.dinf_scf_command_timeout, 402 hwd_dinfo.dinf_model_info); 403 if (hwd_dinfo.dinf_dr_status == 0) 404 mdb_printf("\tDR capable\n"); 405 else 406 mdb_printf("\tNOT DR capable (%x)\n", 407 hwd_dinfo.dinf_dr_status); 408 mdb_printf("\tMAC address\t%02x.%02x.%02x.%02x.%02x.%02x", 409 hwd_dinfo.dinf_mac_address[0], 410 hwd_dinfo.dinf_mac_address[1], 411 hwd_dinfo.dinf_mac_address[2], 412 hwd_dinfo.dinf_mac_address[3], 413 hwd_dinfo.dinf_mac_address[4], 414 hwd_dinfo.dinf_mac_address[5]); 415 mdb_printf("\tcpu_start_time\t0x%llx\n", 416 hwd_dinfo.dinf_cpu_start_time); 417 mdb_printf("\tcfg policy\t%x\tdiag lvl\t%x\tboot mode\t%x\n", 418 hwd_dinfo.dinf_config_policy, hwd_dinfo.dinf_diag_level, 419 hwd_dinfo.dinf_boot_mode); 420 mdb_printf("\tBanner name\t%s\n", 421 hwd_dinfo.dinf_banner_name); 422 mdb_printf("\tPlatform token\t%s\n", 423 hwd_dinfo.dinf_platform_token); 424 mdb_printf("\tFloating bd bitmap\t%04x\n", 425 hwd_dinfo.dinf_floating_board_bitmap); 426 mdb_printf("\tChassis Serial#\t%s\n", 427 hwd_dinfo.dinf_chassis_sn); 428 mdb_printf("\tBrand Control\t%d\n", 429 hwd_dinfo.dinf_brand_control); 430 431 } 432 433 /* SB info */ 434 if (v & DUMP_SB_INFO) { 435 mdb_printf("\nBoard:\tstatus =0x%x (%s)\tmode =0x%x (%s)\ 436 \tPSB =0x%x\n", hwd_sb.sb_status, 437 hwd_stat_decode(hwd_sb.sb_status), 438 hwd_sb.sb_mode, (hwd_sb.sb_mode == 0 ? "PSB" : "XSB"), 439 hwd_sb.sb_psb_number); 440 } 441 442 /* CMU Chan info */ 443 if (v & DUMP_CMU_CHAN) { 444 hwd_cmu_chan_t *cmup; 445 cmup = &hwd_sb.sb_cmu.cmu_ch; 446 447 mdb_printf("\nCMU CH: status\t0x%x (%s)\tportid=0x%x" 448 " LSB = 0x%x\n", 449 cmup->chan_status, hwd_stat_decode(cmup->chan_status), 450 cmup->chan_portid, ((cmup->chan_portid) >> 4)); 451 452 if (v & DUMP_COMP_NAME) 453 mdb_printf("\tcomponent name:%s\n", 454 cmup->chan_component_name); 455 456 /* scf_interface */ 457 mdb_printf("\tscf:\tstatus\t0x%x (%s)\n", 458 cmup->chan_scf_interface.scf_status, 459 hwd_stat_decode(cmup->chan_scf_interface.scf_status)); 460 if (v & DUMP_COMP_NAME) 461 mdb_printf("\t\tcomponent name:%s\n", 462 cmup->chan_scf_interface.scf_component_name); 463 464 /* serial */ 465 mdb_printf("\tserial:\tstatus\t0x%x (%s)\n", 466 cmup->chan_serial.tty_status, 467 hwd_stat_decode(cmup->chan_serial.tty_status)); 468 if (v & DUMP_COMP_NAME) 469 mdb_printf("\t\tcomponent name:%s\n", 470 cmup->chan_serial.tty_component_name); 471 472 /* fmem */ 473 mdb_printf("\tfmem[0]\tstatus\t0x%x (%s)", 474 cmup->chan_fmem[0].fmem_status, 475 hwd_stat_decode(cmup->chan_fmem[0].fmem_status)); 476 mdb_printf("\tused %x\tversion %x.%x.%x\n", 477 cmup->chan_fmem[0].fmem_used, 478 cmup->chan_fmem[0].fmem_version.fver_major, 479 cmup->chan_fmem[0].fmem_version.fver_minor, 480 cmup->chan_fmem[0].fmem_version.fver_local); 481 if (v & DUMP_COMP_NAME) 482 mdb_printf("\t\tcomponent name:%s\n", 483 cmup->chan_fmem[0].fmem_component_name); 484 mdb_printf("\tfmem[1]\tstatus\t0x%x (%s)", 485 cmup->chan_fmem[1].fmem_status, 486 hwd_stat_decode(cmup->chan_fmem[1].fmem_status)); 487 mdb_printf("\tused %x\tversion %x.%x.%x\n", 488 cmup->chan_fmem[1].fmem_used, 489 cmup->chan_fmem[1].fmem_version.fver_major, 490 cmup->chan_fmem[1].fmem_version.fver_minor, 491 cmup->chan_fmem[1].fmem_version.fver_local); 492 if (v & DUMP_COMP_NAME) 493 mdb_printf("\t\tcomponent name:%s\n", 494 cmup->chan_fmem[1].fmem_component_name); 495 496 } 497 498 /* CMU SC info */ 499 if (v & DUMP_SCS) { 500 hwd_sc_t *scp; 501 int sc; 502 503 for (sc = 0; sc < HWD_SCS_PER_CMU; sc++) { 504 505 scp = &hwd_sb.sb_cmu.cmu_scs[sc]; 506 507 if (DONT_BOTHER(scp->sc_status, mv)) 508 mdb_printf("\nSC %d:\tstatus\t0x%x (%s)\n", 509 sc, scp->sc_status, 510 hwd_stat_decode(scp->sc_status)); 511 else { 512 mdb_printf("\nSC %d:\tstatus\t0x%x (%s)\t", 513 sc, scp->sc_status, 514 hwd_stat_decode(scp->sc_status)); 515 mdb_printf("register addr\t0x%llx\n", 516 scp->sc_register_address); 517 } 518 } 519 520 } 521 522 if (v & DUMP_MEM) 523 dumpmemhwd(&hwd_sb.sb_cmu.cmu_memory, v, mv); 524 525 if (v & DUMP_CHIPS) { 526 int ch; 527 for (ch = 0; ch < HWD_CPU_CHIPS_PER_CMU; ch++) { 528 if (MIA(hwd_sb.sb_cmu.cmu_cpu_chips[ch].chip_status)) { 529 mdb_printf("\nChip %d: status\t0x%x (%s)\n", 530 ch, 531 hwd_sb.sb_cmu.cmu_cpu_chips[ch].chip_status, 532 "MISS"); 533 continue; 534 } 535 dumpchiphwd(&hwd_sb.sb_cmu.cmu_cpu_chips[ch], ch, v, 536 mv); 537 } 538 } 539 540 if (v & DUMP_PCI_CH) { 541 int ch; 542 for (ch = 0; ch < HWD_CPU_CHIPS_PER_CMU; ch++) { 543 if (MIA(hwd_sb.sb_pci_ch[ch].pci_status)) { 544 mdb_printf("\nPCI CH %d:\tstatus\t0x%x (%s)\n", 545 ch, hwd_sb.sb_pci_ch[ch].pci_status, 546 "MISS"); 547 continue; 548 } 549 dumppcihwd(&hwd_sb.sb_pci_ch[ch], ch, v, mv); 550 } 551 } 552 } 553 554 /* 555 * oplhwd dcmd - Print out the per-board HWD, nicely formatted. 556 */ 557 /*ARGSUSED*/ 558 static int 559 oplhwd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 560 { 561 int bdi; 562 uint64_t v_mode = DUMP_HDR; 563 uint_t obits = 0; 564 GElf_Sym tmsym; 565 uint64_t bdo; 566 567 /* 568 * Either use the board number, or get an arg for it, or 569 * show all of them. 570 */ 571 572 if (flags & DCMD_ADDRSPEC) { 573 bdi = addr; 574 } else { 575 bdi = -1; 576 } 577 578 bdo = bdi; 579 if (mdb_getopts(argc, argv, 580 'a', MDB_OPT_SETBITS, DUMP_FULL, &obits, /* All possible info */ 581 'b', MDB_OPT_UINT64, &bdo, /* board number */ 582 'd', MDB_OPT_SETBITS, DUMP_DINFO, &obits, /* domain info */ 583 's', MDB_OPT_SETBITS, DUMP_SB_STAT, &obits, /* SB status */ 584 'i', MDB_OPT_SETBITS, DUMP_SB_INFO, &obits, /* SB info */ 585 'c', MDB_OPT_SETBITS, DUMP_CMU_CHAN, &obits, /* CMU chan */ 586 'h', MDB_OPT_SETBITS, DUMP_CHIPS, &obits, /* chips */ 587 'm', MDB_OPT_SETBITS, DUMP_MEM, &obits, /* memory */ 588 'p', MDB_OPT_SETBITS, DUMP_PCI_CH, &obits, /* PCI chans */ 589 'k', MDB_OPT_SETBITS, DUMP_MEM_BANKS, &obits, /* banks */ 590 'o', MDB_OPT_SETBITS, DUMP_CORES, &obits, /* core details */ 591 'r', MDB_OPT_SETBITS, DUMP_SCS, &obits, /* SC info */ 592 'C', MDB_OPT_SETBITS, DUMP_COMP_NAME, &obits, /* SC info */ 593 'v', MDB_OPT_SETBITS, DUMP_VERBOSE, &obits, /* all of the above */ 594 NULL) != argc) 595 return (DCMD_USAGE); 596 bdi = bdo; 597 v_mode |= obits; 598 599 if (mdb_lookup_by_obj("opl_cfg", "opl_boards", &tmsym) == -1) { 600 mdb_warn("unable to reference opl_boards\n"); 601 return (DCMD_ERR); 602 } 603 604 tmptr = (uintptr_t)tmsym.st_value; 605 mdb_printf("Board %d:\tboardcfg \t%8llx\n", 0, tmptr); 606 607 if (bdi < 0) { 608 /* get active boards */ 609 for (bdi = 0; bdi < OPL_MAX_BOARDS; bdi++) 610 dumpahwd(bdi, v_mode); 611 } else { 612 dumpahwd(bdi, v_mode); 613 } 614 return (DCMD_OK); 615 } 616 617 /* 618 * ::oplhwd help 619 */ 620 static void 621 oplhwd_help(void) 622 { 623 mdb_printf("oplhwd will dump HWD only for a particular board" 624 " on which,"); 625 mdb_printf("an earlier DR operation has been executed.\n"); 626 mdb_printf("-b NUM \tlist oplhwd entry for a board\n" 627 "-s \t\tlist oplhwd entry with SB status\n" 628 "-d \t\tlist oplhwd entry with Domain info.\n" 629 "-i \t\tlist oplhwd entry with SB info.\n" 630 "-h \t\tlist oplhwd entry with Chips details\n" 631 "-o \t\tlist oplhwd entry with Core details\n" 632 "-m \t\tlist oplhwd entry with Memory info.\n" 633 "-k \t\tlist oplhwd entry with Memory Bank info.\n" 634 "-r \t\tlist oplhwd entry with SC info.\n" 635 "-c \t\tlist oplhwd entry with CMU channels\n" 636 "-p \t\tlist oplhwd entry with PCI channels\n" 637 "-a \t\tlist oplhwd entry with all possible info.\n" 638 "-C \t\tlist oplhwd entry with component names\n" 639 "-v \t\tlist oplhwd entry in verbose mode\n"); 640 } 641 642 /* 643 * MDB module linkage information: 644 * 645 * We declare a list of structures describing our dcmds, and a function 646 * named _mdb_init to return a pointer to our module information. 647 */ 648 649 static const mdb_dcmd_t dcmds[] = { 650 { "oplhwd", "?[ -b NUM ] [ -sdihomkrcp ] [ -a ] [ -C ] [ -v ]", 651 "dump hardware descriptor for SUNW,SPARC-Enterprise", 652 oplhwd, oplhwd_help }, 653 { NULL } 654 }; 655 656 static const mdb_modinfo_t modinfo = { 657 MDB_API_VERSION, dcmds, NULL 658 }; 659 660 const mdb_modinfo_t * 661 _mdb_init(void) 662 { 663 return (&modinfo); 664 } 665