oplhwd.c revision b0b09e93d0f18a419f77ec47f70539d245832ee7
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/mdb_modapi.h>
#include <sys/dditypes.h>
#include <sys/machcpuvar.h>
/*
* print hardware descriptor
*/
/* Verbosity bits */
/* A nice mix of most of what you want */
static char *hwd_stat_decode(int stat)
{
switch (stat) {
case HWD_STAT_UNKNOWN:
return ("UNKNOWN");
case HWD_STAT_PRESENT:
return ("PRESENT");
case HWD_STAT_MISS:
return ("MISS");
case HWD_STAT_MISCONFIG:
return ("MISCONFIG");
case HWD_STAT_PASS:
return ("PASS");
case HWD_STAT_FAIL:
return ("FAIL_XSCF");
case HWD_STAT_FAIL_OBP:
return ("FAIL_OBP");
case HWD_STAT_FAIL_OS:
return ("FAIL_OS");
default:
return ("?");
}
}
static void
{
int i, j;
mdb_printf("\nMemory:\tstart\t0x%llx\tsize\t0x%llx\tmirror mode %d\n",
mdb_printf("\tdivision mode\t0x%x\tpiece number\t0x%llx",
/* banks */
for (i = 0; i < HWD_BANKS_PER_CMU; i++) {
mdb_printf("\tBank %d\tstatus\t0x%x (%s)\n",
continue;
}
mdb_printf("\tBank %d\tstatus\t0x%x (%s)\treg addr\t0x%llx\n",
if (v & DUMP_MEM_BANKS) {
mdb_printf("\t\tcs status\t0x%x 0x%x\n",
mdb_printf("\t\tMAC OCD\tDIMM OCDs\n");
mdb_printf("\t\t%x\t%x %x %x %x %x %x %x %x\n",
}
}
/* chunks */
for (i = 0; i < HWD_MAX_MEM_CHUNKS; i++) {
continue;
mdb_printf("\tchunk %d\tstart\t0x%llx\tsize\t0x%llx\n",
}
/* dimms */
for (i = 0; i < HWD_DIMMS_PER_CMU; i++) {
if (v & DUMP_MEM_DIMMS)
mdb_printf("\tDIMM %d\tstatus\t0x%x (%s)\n",
continue;
}
mdb_printf("\tDIMM %d\tstatus\t0x%x (%s)\tcapacity\t0x%llx\n",
mdb_printf("\t\trank\t%x\tavailable capacity\t0x%llx\n",
}
/* cs */
for (i = 0; i < 2; i++) {
mdb_printf("\tCS %d:\tstatus\t0x%x (%s)\n",
continue;
}
mdb_printf("\tCS %d:\tstatus\t0x%x (%s)\tavailable\t0x%llx\n",
mdb_printf("\t\tno of dimms\t%x\tdimm capacity\t0x%llx\n",
mdb_printf("\t\tPA <-> MAC conversion\n\t\t");
for (j = 0; j < 20; j++)
mdb_printf("\n\t\t");
for (j = 20; j < 40; j++)
mdb_printf("\n\t\t");
for (j = 40; j < 60; j++)
mdb_printf("\n\t\t");
for (j = 60; j < 64; j++)
mdb_printf("\n");
}
}
/* ARGSUSED */
static void
{
mdb_printf("\nChip %d:\tstatus\t0x%x (%s)\tportid\t%x\n",
chipp->chip_portid);
return;
mdb_printf("\tCore %d:\tstatus\t0x%x (%s)\tconfig\t0x%llx\n",
corep->core_config);
continue;
if (v & DUMP_CORES) {
mdb_printf("\t\tfrequency\t0x%llx\tversion\t0x%llx\n",
mdb_printf("\t\t(manuf/impl/mask: %x/%x/%x)\n",
mdb_printf("\t\t\tSize\tLinesize\tAssoc\n");
mdb_printf("\t\tL1I$\t%x\t%x\t\t%x\n",
mdb_printf("\t\tL1D$\t%x\t%x\t\t%x\n",
mdb_printf("\t\tL2$\t%x\t%x\t\t%x",
mdb_printf("\tsharing\t%x\n",
mdb_printf("\t\tITLB entries\t0x%x\tDTLB entries "
}
mdb_printf("\t\tCPU %d:\tstatus\t0x%x (%s)\tcpuid"
if (v & DUMP_COMP_NAME)
mdb_printf("\t\t\tcomponent name:%s\n",
}
}
}
/* ARGSUSED */
static void
{
int lf;
mdb_printf("\nPCI CH %d:\tstatus\t0x%x (%s)\n",
mdb_printf("\tleaf %d:\tstatus\t0x%x (%s)\n",
continue;
}
mdb_printf("\tleaf %d:\tstatus\t0x%x (%s)\tportid 0x%x",
mdb_printf("\ttype0x%x\n)",
mdb_printf("\t\t\tOffset\t\tSize\n");
mdb_printf("\t\tcfgio\t0x%llx\t0x%llx\t\t%x\n",
mdb_printf("\t\tmem32\t0x%llx\t0x%llx\t\t%x\n",
mdb_printf("\t\tmem64\t0x%llx\t0x%llx\t\t%x\n",
}
}
/* ARGSUSED */
static void
{
/* A flag for whether or not to dump stuff that is missing */
int mv = 0;
if (v & DUMP_MISSING)
mv = 1;
mdb_warn("failed to read opl_board_cfg at %p",
return;
}
return;
}
/* We always need the header, for offsets */
mdb_warn("failed to read hwd_header_t at %p\n",
return;
}
/* Figure out the inside pointers, in case we need them... */
/* The sb data is what we will surely be dumping */
return;
}
if (v & DUMP_HDR) {
/* Print the interesting stuff from the header */
mdb_printf("\t\tversion\t%x.%x\tDID\t%x\tmagic\t0x%x\n\n",
mdb_printf("\tstatus offset = 0x%x\t(addr=%llx)\n",
mdb_printf("\tdomain offset = 0x%x\t(addr=%llx)\n",
mdb_printf("\tboard offset = 0x%x\t(addr=%llx)\n",
}
if (v & DUMP_SB_STAT) {
int i;
mdb_warn("failed to read hwd_sb_status_t at %p\n",
statusp);
return;
}
mdb_printf("\nSTATUS:\tBoard\tStatus\n");
for (i = 0; i < HWD_SBS_PER_DOMAIN; i++) {
continue;
mdb_printf("\t%d\t0x%x (%s)\n", i,
}
}
/* Domain Info */
if (v & DUMP_DINFO) {
mdb_warn("failed to read hwd_domain_info_t at %p\n",
dinfop);
return;
}
mdb_printf("\nDomain info:\tReset reason\t0x%x",
mdb_printf("\tSystem freq\t0x%llx\tStick freq\t0x%llx\n",
mdb_printf("\tSCF timeout \t0x%x\tModel info\t%x",
if (hwd_dinfo.dinf_dr_status == 0)
mdb_printf("\tDR capable\n");
else
mdb_printf("\tNOT DR capable (%x)\n",
mdb_printf("\tMAC address\t%02x.%02x.%02x.%02x.%02x.%02x",
mdb_printf("\tcpu_start_time\t0x%llx\n",
mdb_printf("\tcfg policy\t%x\tdiag lvl\t%x\tboot mode\t%x\n",
mdb_printf("\tBanner name\t%s\n",
mdb_printf("\tPlatform token\t%s\n",
mdb_printf("\tFloating bd bitmap\t%04x\n",
mdb_printf("\tChassis Serial#\t%s\n",
mdb_printf("\tBrand Control\t%d\n",
}
/* SB info */
if (v & DUMP_SB_INFO) {
mdb_printf("\nBoard:\tstatus =0x%x (%s)\tmode =0x%x (%s)\
}
/* CMU Chan info */
if (v & DUMP_CMU_CHAN) {
mdb_printf("\nCMU CH: status\t0x%x (%s)\tportid=0x%x"
" LSB = 0x%x\n",
if (v & DUMP_COMP_NAME)
mdb_printf("\tcomponent name:%s\n",
/* scf_interface */
mdb_printf("\tscf:\tstatus\t0x%x (%s)\n",
if (v & DUMP_COMP_NAME)
mdb_printf("\t\tcomponent name:%s\n",
/* serial */
mdb_printf("\tserial:\tstatus\t0x%x (%s)\n",
if (v & DUMP_COMP_NAME)
mdb_printf("\t\tcomponent name:%s\n",
/* fmem */
mdb_printf("\tfmem[0]\tstatus\t0x%x (%s)",
mdb_printf("\tused %x\tversion %x.%x.%x\n",
if (v & DUMP_COMP_NAME)
mdb_printf("\t\tcomponent name:%s\n",
mdb_printf("\tfmem[1]\tstatus\t0x%x (%s)",
mdb_printf("\tused %x\tversion %x.%x.%x\n",
if (v & DUMP_COMP_NAME)
mdb_printf("\t\tcomponent name:%s\n",
}
/* CMU SC info */
if (v & DUMP_SCS) {
int sc;
mdb_printf("\nSC %d:\tstatus\t0x%x (%s)\n",
else {
mdb_printf("\nSC %d:\tstatus\t0x%x (%s)\t",
mdb_printf("register addr\t0x%llx\n",
}
}
}
if (v & DUMP_MEM)
if (v & DUMP_CHIPS) {
int ch;
mdb_printf("\nChip %d: status\t0x%x (%s)\n",
ch,
"MISS");
continue;
}
mv);
}
}
if (v & DUMP_PCI_CH) {
int ch;
mdb_printf("\nPCI CH %d:\tstatus\t0x%x (%s)\n",
"MISS");
continue;
}
}
}
}
/*
* oplhwd dcmd - Print out the per-board HWD, nicely formatted.
*/
/*ARGSUSED*/
static int
{
int bdi;
/*
* Either use the board number, or get an arg for it, or
* show all of them.
*/
if (flags & DCMD_ADDRSPEC) {
} else {
bdi = -1;
}
return (DCMD_USAGE);
mdb_warn("unable to reference opl_boards\n");
return (DCMD_ERR);
}
if (bdi < 0) {
/* get active boards */
} else {
}
return (DCMD_OK);
}
/*
* ::oplhwd help
*/
static void
oplhwd_help(void)
{
mdb_printf("oplhwd will dump HWD only for a particular board"
" on which,");
mdb_printf("an earlier DR operation has been executed.\n");
mdb_printf("-b NUM \tlist oplhwd entry for a board\n"
"-s \t\tlist oplhwd entry with SB status\n"
"-d \t\tlist oplhwd entry with Domain info.\n"
"-i \t\tlist oplhwd entry with SB info.\n"
"-h \t\tlist oplhwd entry with Chips details\n"
"-o \t\tlist oplhwd entry with Core details\n"
"-m \t\tlist oplhwd entry with Memory info.\n"
"-k \t\tlist oplhwd entry with Memory Bank info.\n"
"-r \t\tlist oplhwd entry with SC info.\n"
"-c \t\tlist oplhwd entry with CMU channels\n"
"-p \t\tlist oplhwd entry with PCI channels\n"
"-a \t\tlist oplhwd entry with all possible info.\n"
"-C \t\tlist oplhwd entry with component names\n"
"-v \t\tlist oplhwd entry in verbose mode\n");
}
/*
* MDB module linkage information:
*
* We declare a list of structures describing our dcmds, and a function
* named _mdb_init to return a pointer to our module information.
*/
static const mdb_dcmd_t dcmds[] = {
{ "oplhwd", "?[ -b NUM ] [ -sdihomkrcp ] [ -a ] [ -C ] [ -v ]",
"dump hardware descriptor for SUNW,SPARC-Enterprise",
oplhwd, oplhwd_help },
{ NULL }
};
static const mdb_modinfo_t modinfo = {
};
const mdb_modinfo_t *
_mdb_init(void)
{
return (&modinfo);
}