kvm_cpu_p4.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* This plugin supports debugging functionality unique to Intel processors based
* on the NetBurst (P4) microarchitecture. It also supports the Pentium M, a
* processor which uses the P6 family code but provides a P4-style branch
* tracing stack.
*/
#include <kmdb/kvm_cpu_impl.h>
#include <kmdb/kmdb_dpi.h>
#include <kmdb/kmdb_kdi.h>
#include <mdb/mdb_debug.h>
#include <sys/x86_archext.h>
/*
* As of this writing, Intel has three different flavors of branch stack.
* They're essentially the same, but the MSR addresses, stack size, and access
* methods differ. We've got one kmt_p4_flavor_t for each type of branch
* stack.
*/
typedef struct kmt_p4_flavor {
const char *p4f_name; /* name for CPU support */
intptr_t, int); /* dumper for CPU branch stk */
typedef struct kmt_cpu_p4 {
} kmt_cpu_p4_t;
/* See 07/04 AP-485 Intel Processor Identification and the CPUID Instruction */
static kmt_cpu_p4_t kmt_cpu_p4;
static void
{
if (verbose) {
char buf[80];
char *c;
c--);
if (*c == '>') {
while (c > buf && *c != '<')
c--;
if (*c == '<')
*c = '\0';
}
mdb_printf("\t%<b>%-#32a%8T%s%</b>\n",
} else {
}
break;
}
mdb_printf("\n");
} else {
}
}
#ifndef __amd64
static int
int verbose)
{
int i;
}
return (0);
}
#endif /* !__amd64 */
static int
int verbose)
{
int i;
}
return (0);
}
#ifndef __amd64
static const kmdb_msr_t kmt_p4orig_msrs[] = {
{ MSR_P4_LBSTK_0, KMDB_MSR_READ },
{ MSR_P4_LBSTK_1, KMDB_MSR_READ },
{ MSR_P4_LBSTK_2, KMDB_MSR_READ },
{ MSR_P4_LBSTK_3, KMDB_MSR_READ },
{ NULL }
};
static const kmt_p4_flavor_t kmt_p4_original = {
"Intel Pentium 4 (pre-Prescott)",
};
static const kmdb_msr_t kmt_p6m_msrs[] = {
{ MSR_P6M_LBSTK_0, KMDB_MSR_READ },
{ MSR_P6M_LBSTK_1, KMDB_MSR_READ },
{ MSR_P6M_LBSTK_2, KMDB_MSR_READ },
{ MSR_P6M_LBSTK_3, KMDB_MSR_READ },
{ MSR_P6M_LBSTK_4, KMDB_MSR_READ },
{ MSR_P6M_LBSTK_5, KMDB_MSR_READ },
{ MSR_P6M_LBSTK_6, KMDB_MSR_READ },
{ MSR_P6M_LBSTK_7, KMDB_MSR_READ },
{ NULL }
};
static const kmt_p4_flavor_t kmt_p6_m = {
"Intel Pentium M",
};
#endif /* __amd64 */
static const kmdb_msr_t kmt_prp4_msrs[] = {
{ NULL }
};
static const kmt_p4_flavor_t kmt_p4_prescott = {
"Intel Pentium 4 (Prescott)",
};
static const kmdb_msr_t kmt_p4unk_msrs[] = {
{ NULL }
};
static const kmt_p4_flavor_t kmt_p4_unknown = {
"Unrecognized Intel Pentium 4",
kmt_p4unk_msrs, NULL, 0,
0, 0, 0
};
/*ARGSUSED*/
static void
{
/* Leave LBR on */
}
/*ARGSUSED*/
static const char *
{
}
/*ARGSUSED*/
static void
{
}
static int
{
(void) kmdb_dpi_set_register("eflags",
return (mdb_tgt_add_fault(t, KMT_TRAP_ALL,
kmt_p4_btf_clear, p4));
}
static kmt_cpu_ops_t kmt_p4_ops = {
};
/*ARGSUSED*/
static int
{
warn("branch tracing unavailable on unknown P4 CPU "
return (DCMD_ERR);
}
return (DCMD_USAGE);
}
static const mdb_dcmd_t kmt_p4_dcmds[] = {
{ NULL }
};
/*ARGSUSED*/
const kmt_p4_flavor_t *
{
if (vendor != X86_VENDOR_Intel)
return (NULL);
#ifndef __amd64
if (family == KMT_CPU_FAMILY_P6) {
return (&kmt_p6_m);
else
return (NULL);
}
return (&kmt_p4_original);
#endif /* !__amd64 */
if (family == KMT_CPU_FAMILY_P4) {
/*
* If this is a model 3, then we've got a Prescott. On the
* other hand, this could be the future, and Intel could have
* released a whizzy new processor. Users shouldn't have to
* wait for us to patch the debugger for each new P4 model,
* so we'll try to use this CPU as a Prescott. In the past,
* when Intel has changed the branch stack, they've done it by
* moving the MSRs, returning #gp's for the old ones. Our
* Prescott check will therefore be an attempt to read the
* Prescott MSRs. This attempt should fail if Intel has changed
* the branch stack again.
*/
return (&kmt_p4_prescott);
else
return (&kmt_p4_unknown);
}
return (NULL);
}
{
return (NULL); /* errno is set for us */
NULL) {
return (NULL);
}
return (cpu);
}