/*
* 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
*/
/*
*/
/*
* x86-specific routines used by the CPU Performance counter driver.
*/
#include <sys/privregs.h>
#include <sys/x86_archext.h>
#include <sys/machcpuvar.h>
#include <sys/archsystm.h>
#include <sys/cpc_pcbe.h>
#include <sys/cpc_impl.h>
/* Do threads share performance monitoring hardware? */
static int strands_perfmon_shared = 0;
extern int kcpc_counts_include_idle; /* Project Private /etc/system variable */
int
{
if (x86_type != X86_TYPE_P6)
return (0);
return (ipltospl(APIC_PCINT_IPL));
}
void
kcpc_hw_rem_ovf_intr(void)
{
}
/*
*/
/*ARGSUSED*/
static int
{
int active_cpus_cnt;
return (0);
/*
* If any CPU-bound contexts exist, we don't need to invalidate
* anything, as no per-LWP contexts can coexist.
*/
if (kcpc_cpuctx || dtrace_cpc_in_use)
return (0);
/*
* If this chip now has more than 1 active cpu, we must invalidate all
* contexts in the system.
*/
if (active_cpus_cnt > 1)
}
return (0);
}
static int setup_registered;
void
{
/*
* Intel processors that support Architectural
* Performance Monitoring Version 3 have per strand
* performance monitoring hardware.
* Hence we can allow use of performance counters on
* multiple strands on the same core simultaneously.
*/
(void) __cpuid_insn(&cpuid);
} else {
(void) __cpuid_insn(&cpuid);
if (versionid < 3) {
}
}
} else {
}
}
if (strands_perfmon_shared) {
if (setup_registered == 0) {
setup_registered = 1;
}
}
return;
}
void
{
}
#define BITS(v, u, l) \
(((v) >> (l)) & ((1 << (1 + (u) - (l))) - 1))
/*
* Examine the processor and load an appropriate PCBE.
*/
int
kcpc_hw_load_pcbe(void)
{
}
/*
* Called by the generic framework to check if it's OK to bind a set to a CPU.
*/
int
{
if (!strands_perfmon_shared)
return (0);
/*
* Only one logical CPU on each Pentium 4 HT CPU may be bound to at
* once.
*
* This loop is protected by holding cpu_lock, in order to properly
* access the cpu_t of the desired cpu.
*/
return (-1);
}
if (p == cpu)
continue;
return (-1);
}
}
return (0);
}
/*
* Called by the generic framework to check if it's OK to bind a set to an LWP.
*/
int
kcpc_hw_lwp_hook(void)
{
group_iter_t i;
if (!strands_perfmon_shared)
return (0);
/*
* Only one CPU per chip may be online.
*/
return (0);
}
group_iter_init(&i);
return (-1);
}
}
return (0);
}