/*
* 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.
*/
/*
* 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 {
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 void
{
if (verbose) {
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
{ MSR_P4_LBSTK_TOS, KDI_MSR_READ },
{ MSR_P4_LBSTK_0, KDI_MSR_READ },
{ MSR_P4_LBSTK_1, KDI_MSR_READ },
{ MSR_P4_LBSTK_2, KDI_MSR_READ },
{ MSR_P4_LBSTK_3, KDI_MSR_READ },
{ NULL }
};
"Intel Pentium 4 (pre-Prescott)",
};
{ MSR_P6M_LBSTK_0, KDI_MSR_READ },
{ MSR_P6M_LBSTK_1, KDI_MSR_READ },
{ MSR_P6M_LBSTK_2, KDI_MSR_READ },
{ MSR_P6M_LBSTK_3, KDI_MSR_READ },
{ MSR_P6M_LBSTK_4, KDI_MSR_READ },
{ MSR_P6M_LBSTK_5, KDI_MSR_READ },
{ MSR_P6M_LBSTK_6, KDI_MSR_READ },
{ MSR_P6M_LBSTK_7, KDI_MSR_READ },
{ NULL }
};
"Intel Pentium M",
};
#endif /* __amd64 */
{ NULL }
};
"Intel Pentium 4 (Prescott)",
};
{ NULL }
};
"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));
}
};
/*ARGSUSED*/
static int
{
warn("branch tracing unavailable on unknown P4 CPU "
return (DCMD_ERR);
}
return (DCMD_USAGE);
}
{ 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);
}