gcpu.c revision 2d39cb4c2c63a5cd31332527611ae6366103b733
/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <mdb/mdb_modapi.h>
#include <generic_cpu/gcpu.h>
#include <sys/cpu_module_impl.h>
#include <sys/cpu_module_ms_impl.h>
typedef struct cmi_hdl_impl {
void *cmih_hdlpriv; /* cmi_hw.c private data */
void *cmih_spec; /* cmi_hdl_{set,get}_specific */
void *cmih_cmi; /* cpu mod control structure */
void *cmih_cmidata; /* cpu mod private data */
void *cmih_mcdata; /* Memory-controller data */
typedef struct cmi_hdl_ent {
volatile uint32_t cmae_refcnt;
typedef struct cmi {
} cmi_t;
typedef struct cms {
} cms_t;
struct cms_ctl {
void *cs_cmsdata;
};
#define CMI_MAX_STRANDS_PER_CHIP (CMI_MAX_CORES_PER_CHIP * \
#define CMI_HDL_ARR_IDX_CORE(coreid) \
#define CMI_HDL_ARR_IDX_STRAND(strandid) \
struct cmih_walk_state {
};
/*
* Advance the <chipid,coreid,strandid> tuple to the next strand entry
* Return true upon sucessful result. Otherwise return false if already reach
* the highest strand.
*/
static boolean_t
{
/* Check for end of the table */
return (B_FALSE);
/* increment the strand id */
if (carry == 0)
return (B_TRUE);
/* increment the core id */
if (carry == 0)
return (B_TRUE);
/* increment the chip id */
return (B_TRUE);
}
/*
* Lookup for the hdl entry of a given <chip,core,strand>
*/
static cmi_hdl_ent_t *
{
return (NULL); /* chip is not present */
}
/* forward decls */
static void
static int
{
int i;
struct cmih_walk_state *awsp;
void *pg;
mdb_warn("cmihdl is a global walker\n");
return (WALK_ERR);
}
/* table of chipid entries */
mdb_warn("read of cmi_chip_tab failed");
return (WALK_ERR);
mdb_warn("Unexpected cmi_chip_tab size (exp=%ld, actual=%ld)",
return (WALK_ERR);
}
/* read the per-chip table that contains all strands of the chip */
for (i = 0; i < CMI_CHIPID_ARR_SZ; i++) {
continue; /* this chip(i) is not present */
mdb_warn("read of cmi_hdl(%i) array at 0x%p failed",
return (WALK_ERR);
}
}
/* Look up the hdl of the first strand <0,0,0> */
return (WALK_NEXT);
}
static int
{
int rv;
return (WALK_DONE);
}
return (rv);
}
static void
{
int i;
for (i = 0; i < CMI_CHIPID_ARR_SZ; i++) {
/* free the per-chip table */
sizeof (cmi_hdl_ent_t));
}
}
}
}
struct cmihdl_cb {
int mod_cpuid;
int mod_chipid;
int mod_coreid;
int mod_strandid;
};
static int
{
int rv;
mdb_warn("Read of cpu_t at 0x%p failed",
hdl->cmih_hdlpriv);
return (WALK_ERR);
}
} else {
}
return (rv);
} else {
return (WALK_DONE);
} else {
return (WALK_NEXT);
}
}
}
static int
{
mdb_warn("Read of cmi_t at 0x%p failed",
return (0);
}
mdb_warn("Read of modctl at 0x%p failed",
return (0);
}
mdb_warn("Read of cmi module name at 0x%p "
return (0);
}
}
}
mdb_warn("Read of struct cms_ctl at 0x%p failed",
return (0);
}
return (0);
}
mdb_warn("Read of modctl at 0x%p failed",
return (0);
}
mdb_warn("Read of cms module name at 0x%p "
return (0);
}
}
}
return (0);
}
if (native) {
mdb_warn("Read of cpu_t at 0x%p failed",
hdl->cmih_hdlpriv);
return (0);
}
}
if (native) {
} else {
}
if (native)
return (1);
}
#define HDRFMT "%-16s %3s %3s %8s %3s %2s %-13s %-24s\n"
static int
{
/*
* If an address is given it must be that of a cmi handle.
* Otherwise if the user has specified -c <cpuid> or
* Otherwise we'll walk and callback to this dcmd.
*/
if (!(flags & DCMD_ADDRSPEC)) {
char *p, *buf;
int len;
if (argc == 0)
'c', MDB_OPT_STR, &p,
return (DCMD_USAGE);
return (DCMD_USAGE);
} else {
}
/* Native cpuid */
} else {
/* Comma-separated triplet chip,core,strand. */
char *q = buf;
*p = '\0';
return (DCMD_USAGE);
}
*p = '\0';
return (DCMD_USAGE);
}
}
mdb_warn("cmi_hdl walk failed\n");
return (DCMD_ERR);
}
mdb_warn("No handle found for cpuid %d\n",
} else {
mdb_warn("No handle found for chip %d "
}
return (DCMD_ERR);
}
}
if (DCMD_HDRSPEC(flags)) {
char ul[] = "----------------------------";
"MODULE", "MODEL-SPECIFIC",
p - 16, p - 3, p - 3, p - 8, p - 3, p - 2, p - 13, p - 24);
}
sizeof (cmi_hdl_impl_t)) {
return (DCMD_ERR);
}
return (DCMD_ERR);
}
return (DCMD_OK);
}
/*ARGSUSED*/
static int
{
static const char *const whatstrs[] = {
"ntv-cyc-poll", /* GCPU_MPT_WHAT_CYC_ERR */
"poll-poked", /* GCPU_MPT_WHAT_POKE_ERR */
"unfaulting", /* GCPU_MPT_WHAT_UNFAULTING */
"#MC", /* GCPU_MPT_WHAT_MC_ERR */
"CMCI-int", /* GCPU_MPT_WHAT_CMCI_ERR */
"xpv-virq-nrec", /* GCPU_MPT_WHAT_XPV_VIRQ */
"xpv-virq-lgout", /* GCPU_MPT_WHAT_XPV_VIRQ_LOGOUT */
};
const char *what;
return (DCMD_USAGE);
return (DCMD_ERR);
}
if (DCMD_HDRSPEC(flags)) {
mdb_printf("%<u>%?s%</u> %<u>%?s%</u> %<u>%15s%</u> "
"%<u>%4s%</u>\n", "ADDR", "WHEN", "WHAT", "NERR");
}
else
what = "???";
return (DCMD_OK);
}
typedef struct mptwalk_data {
static int
{
mdb_warn("the address of a poll trace array must be "
"specified\n");
return (WALK_ERR);
}
mdb_warn("failed to read gcpu_poll_trace_nent from kernel");
return (WALK_ERR);
}
mw->mw_tracesz) {
mdb_warn("failed to read poll trace array from kernel");
return (WALK_ERR);
}
latest = 0;
mw->mw_curtrace = 0;
mw->mw_curtrace = i;
}
}
if (latest == 0) {
return (WALK_DONE); /* trace array is empty */
}
return (WALK_NEXT);
}
static int
{
return (rv);
return (WALK_DONE);
return (WALK_NEXT);
}
static void
{
}
static const mdb_dcmd_t dcmds[] = {
{ "cmihdl", ": -c <cpuid>|<chip,core,strand> ",
"dump a cmi_handle_t", cmihdl },
{ NULL }
};
static const mdb_walker_t walkers[] = {
{ "cmihdl", "walks cpu module interface handle list",
{ "gcpu_poll_trace", "walks poll trace buffers in reverse "
{ NULL }
};
const mdb_modinfo_t *
_mdb_init(void)
{
return (&modinfo);
}