hwpmc: remove unused pre-table driven bits for intel
Intel now provides comprehensive tables for all performance counters and the various valid configuration permutations as text .json files. Libpmc has been converted to use these and hwpmc_core has been greatly simplified by moving to passthrough of the table values. The one gotcha is that said tables don't support pentium pro and and pentium IV. There's very few users of hwpmc on _amd64_ kernels on new hardware. It is unlikely that anyone is doing low level optimization on 15 year old Intel hardware. Nonetheless, if someone feels strongly enough to populate the corresponding tables for p4 and ppro I will reinstate the files in to the build. Code for the K8 counters and !x86 architectures remains unchanged.
This commit is contained in:
parent
7d1c2b74a0
commit
e92a1350b5
2098
lib/libpmc/libpmc.c
2098
lib/libpmc/libpmc.c
File diff suppressed because it is too large
Load Diff
@ -43,7 +43,6 @@ struct pmc_mdep;
|
|||||||
|
|
||||||
#include <dev/hwpmc/hwpmc_amd.h>
|
#include <dev/hwpmc/hwpmc_amd.h>
|
||||||
#include <dev/hwpmc/hwpmc_core.h>
|
#include <dev/hwpmc/hwpmc_core.h>
|
||||||
#include <dev/hwpmc/hwpmc_piv.h>
|
|
||||||
#include <dev/hwpmc/hwpmc_tsc.h>
|
#include <dev/hwpmc/hwpmc_tsc.h>
|
||||||
#include <dev/hwpmc/hwpmc_uncore.h>
|
#include <dev/hwpmc/hwpmc_uncore.h>
|
||||||
|
|
||||||
@ -78,7 +77,6 @@ union pmc_md_op_pmcallocate {
|
|||||||
struct pmc_md_iap_op_pmcallocate pm_iap;
|
struct pmc_md_iap_op_pmcallocate pm_iap;
|
||||||
struct pmc_md_ucf_op_pmcallocate pm_ucf;
|
struct pmc_md_ucf_op_pmcallocate pm_ucf;
|
||||||
struct pmc_md_ucp_op_pmcallocate pm_ucp;
|
struct pmc_md_ucp_op_pmcallocate pm_ucp;
|
||||||
struct pmc_md_p4_op_pmcallocate pm_p4;
|
|
||||||
uint64_t __pad[4];
|
uint64_t __pad[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -94,7 +92,6 @@ union pmc_md_pmc {
|
|||||||
struct pmc_md_iap_pmc pm_iap;
|
struct pmc_md_iap_pmc pm_iap;
|
||||||
struct pmc_md_ucf_pmc pm_ucf;
|
struct pmc_md_ucf_pmc pm_ucf;
|
||||||
struct pmc_md_ucp_pmc pm_ucp;
|
struct pmc_md_ucp_pmc pm_ucp;
|
||||||
struct pmc_md_p4_pmc pm_p4;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PMC_TRAPFRAME_TO_PC(TF) ((TF)->tf_rip)
|
#define PMC_TRAPFRAME_TO_PC(TF) ((TF)->tf_rip)
|
||||||
|
@ -316,7 +316,6 @@ dev/hwpmc/hwpmc_amd.c optional hwpmc
|
|||||||
dev/hwpmc/hwpmc_intel.c optional hwpmc
|
dev/hwpmc/hwpmc_intel.c optional hwpmc
|
||||||
dev/hwpmc/hwpmc_core.c optional hwpmc
|
dev/hwpmc/hwpmc_core.c optional hwpmc
|
||||||
dev/hwpmc/hwpmc_uncore.c optional hwpmc
|
dev/hwpmc/hwpmc_uncore.c optional hwpmc
|
||||||
dev/hwpmc/hwpmc_piv.c optional hwpmc
|
|
||||||
dev/hwpmc/hwpmc_tsc.c optional hwpmc
|
dev/hwpmc/hwpmc_tsc.c optional hwpmc
|
||||||
dev/hwpmc/hwpmc_x86.c optional hwpmc
|
dev/hwpmc/hwpmc_x86.c optional hwpmc
|
||||||
dev/hyperv/input/hv_kbd.c optional hyperv
|
dev/hyperv/input/hv_kbd.c optional hyperv
|
||||||
|
@ -234,9 +234,6 @@ dev/hwpmc/hwpmc_amd.c optional hwpmc
|
|||||||
dev/hwpmc/hwpmc_intel.c optional hwpmc
|
dev/hwpmc/hwpmc_intel.c optional hwpmc
|
||||||
dev/hwpmc/hwpmc_core.c optional hwpmc
|
dev/hwpmc/hwpmc_core.c optional hwpmc
|
||||||
dev/hwpmc/hwpmc_uncore.c optional hwpmc
|
dev/hwpmc/hwpmc_uncore.c optional hwpmc
|
||||||
dev/hwpmc/hwpmc_pentium.c optional hwpmc
|
|
||||||
dev/hwpmc/hwpmc_piv.c optional hwpmc
|
|
||||||
dev/hwpmc/hwpmc_ppro.c optional hwpmc
|
|
||||||
dev/hwpmc/hwpmc_tsc.c optional hwpmc
|
dev/hwpmc/hwpmc_tsc.c optional hwpmc
|
||||||
dev/hwpmc/hwpmc_x86.c optional hwpmc
|
dev/hwpmc/hwpmc_x86.c optional hwpmc
|
||||||
dev/hyperv/pcib/vmbus_pcib.c optional hyperv pci
|
dev/hyperv/pcib/vmbus_pcib.c optional hyperv pci
|
||||||
|
@ -242,8 +242,7 @@ iaf_allocate_pmc(int cpu, int ri, struct pmc *pm,
|
|||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
ev = pm->pm_event;
|
ev = pm->pm_event;
|
||||||
if (ev < PMC_EV_IAF_FIRST || ev > PMC_EV_IAF_LAST)
|
|
||||||
return (EINVAL);
|
|
||||||
|
|
||||||
if (ev == PMC_EV_IAF_INSTR_RETIRED_ANY && ri != 0)
|
if (ev == PMC_EV_IAF_INSTR_RETIRED_ANY && ri != 0)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
@ -97,30 +97,8 @@ pmc_intel_initialize(void)
|
|||||||
snprintf(pmc_cpuid, sizeof(pmc_cpuid), "GenuineIntel-%d-%02X",
|
snprintf(pmc_cpuid, sizeof(pmc_cpuid), "GenuineIntel-%d-%02X",
|
||||||
(cpu_id & 0xF00) >> 8, model);
|
(cpu_id & 0xF00) >> 8, model);
|
||||||
switch (cpu_id & 0xF00) {
|
switch (cpu_id & 0xF00) {
|
||||||
#if defined(__i386__)
|
|
||||||
case 0x500: /* Pentium family processors */
|
|
||||||
cputype = PMC_CPU_INTEL_P5;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case 0x600: /* Pentium Pro, Celeron, Pentium II & III */
|
case 0x600: /* Pentium Pro, Celeron, Pentium II & III */
|
||||||
switch (model) {
|
switch (model) {
|
||||||
#if defined(__i386__)
|
|
||||||
case 0x1:
|
|
||||||
cputype = PMC_CPU_INTEL_P6;
|
|
||||||
break;
|
|
||||||
case 0x3: case 0x5:
|
|
||||||
cputype = PMC_CPU_INTEL_PII;
|
|
||||||
break;
|
|
||||||
case 0x6: case 0x16:
|
|
||||||
cputype = PMC_CPU_INTEL_CL;
|
|
||||||
break;
|
|
||||||
case 0x7: case 0x8: case 0xA: case 0xB:
|
|
||||||
cputype = PMC_CPU_INTEL_PIII;
|
|
||||||
break;
|
|
||||||
case 0x9: case 0xD:
|
|
||||||
cputype = PMC_CPU_INTEL_PM;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case 0xE:
|
case 0xE:
|
||||||
cputype = PMC_CPU_INTEL_CORE;
|
cputype = PMC_CPU_INTEL_CORE;
|
||||||
break;
|
break;
|
||||||
@ -223,13 +201,8 @@ pmc_intel_initialize(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#if defined(__i386__) || defined(__amd64__)
|
|
||||||
case 0xF00: /* P4 */
|
|
||||||
if (model >= 0 && model <= 6) /* known models */
|
|
||||||
cputype = PMC_CPU_INTEL_PIV;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((int) cputype == -1) {
|
if ((int) cputype == -1) {
|
||||||
printf("pmc: Unknown Intel CPU.\n");
|
printf("pmc: Unknown Intel CPU.\n");
|
||||||
@ -248,7 +221,6 @@ pmc_intel_initialize(void)
|
|||||||
if (error)
|
if (error)
|
||||||
goto error;
|
goto error;
|
||||||
switch (cputype) {
|
switch (cputype) {
|
||||||
#if defined(__i386__) || defined(__amd64__)
|
|
||||||
/*
|
/*
|
||||||
* Intel Core, Core 2 and Atom processors.
|
* Intel Core, Core 2 and Atom processors.
|
||||||
*/
|
*/
|
||||||
@ -274,37 +246,6 @@ pmc_intel_initialize(void)
|
|||||||
error = pmc_core_initialize(pmc_mdep, ncpus, verov);
|
error = pmc_core_initialize(pmc_mdep, ncpus, verov);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
|
||||||
* Intel Pentium 4 Processors, and P4/EMT64 processors.
|
|
||||||
*/
|
|
||||||
|
|
||||||
case PMC_CPU_INTEL_PIV:
|
|
||||||
error = pmc_p4_initialize(pmc_mdep, ncpus);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__i386__)
|
|
||||||
/*
|
|
||||||
* P6 Family Processors
|
|
||||||
*/
|
|
||||||
|
|
||||||
case PMC_CPU_INTEL_P6:
|
|
||||||
case PMC_CPU_INTEL_CL:
|
|
||||||
case PMC_CPU_INTEL_PII:
|
|
||||||
case PMC_CPU_INTEL_PIII:
|
|
||||||
case PMC_CPU_INTEL_PM:
|
|
||||||
error = pmc_p6_initialize(pmc_mdep, ncpus);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Intel Pentium PMCs.
|
|
||||||
*/
|
|
||||||
|
|
||||||
case PMC_CPU_INTEL_P5:
|
|
||||||
error = pmc_p5_initialize(pmc_mdep, ncpus);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
KASSERT(0, ("[intel,%d] Unknown CPU type", __LINE__));
|
KASSERT(0, ("[intel,%d] Unknown CPU type", __LINE__));
|
||||||
}
|
}
|
||||||
@ -317,7 +258,6 @@ pmc_intel_initialize(void)
|
|||||||
/*
|
/*
|
||||||
* Init the uncore class.
|
* Init the uncore class.
|
||||||
*/
|
*/
|
||||||
#if defined(__i386__) || defined(__amd64__)
|
|
||||||
switch (cputype) {
|
switch (cputype) {
|
||||||
/*
|
/*
|
||||||
* Intel Corei7 and Westmere processors.
|
* Intel Corei7 and Westmere processors.
|
||||||
@ -332,7 +272,6 @@ pmc_intel_initialize(void)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
error:
|
error:
|
||||||
if (error) {
|
if (error) {
|
||||||
pmc_mdep_free(pmc_mdep);
|
pmc_mdep_free(pmc_mdep);
|
||||||
@ -348,7 +287,6 @@ pmc_intel_finalize(struct pmc_mdep *md)
|
|||||||
pmc_tsc_finalize(md);
|
pmc_tsc_finalize(md);
|
||||||
|
|
||||||
switch (md->pmd_cputype) {
|
switch (md->pmd_cputype) {
|
||||||
#if defined(__i386__) || defined(__amd64__)
|
|
||||||
case PMC_CPU_INTEL_ATOM:
|
case PMC_CPU_INTEL_ATOM:
|
||||||
case PMC_CPU_INTEL_ATOM_SILVERMONT:
|
case PMC_CPU_INTEL_ATOM_SILVERMONT:
|
||||||
case PMC_CPU_INTEL_BROADWELL:
|
case PMC_CPU_INTEL_BROADWELL:
|
||||||
@ -370,23 +308,6 @@ pmc_intel_finalize(struct pmc_mdep *md)
|
|||||||
case PMC_CPU_INTEL_IVYBRIDGE_XEON:
|
case PMC_CPU_INTEL_IVYBRIDGE_XEON:
|
||||||
pmc_core_finalize(md);
|
pmc_core_finalize(md);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PMC_CPU_INTEL_PIV:
|
|
||||||
pmc_p4_finalize(md);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#if defined(__i386__)
|
|
||||||
case PMC_CPU_INTEL_P6:
|
|
||||||
case PMC_CPU_INTEL_CL:
|
|
||||||
case PMC_CPU_INTEL_PII:
|
|
||||||
case PMC_CPU_INTEL_PIII:
|
|
||||||
case PMC_CPU_INTEL_PM:
|
|
||||||
pmc_p6_finalize(md);
|
|
||||||
break;
|
|
||||||
case PMC_CPU_INTEL_P5:
|
|
||||||
pmc_p5_finalize(md);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
KASSERT(0, ("[intel,%d] unknown CPU type", __LINE__));
|
KASSERT(0, ("[intel,%d] unknown CPU type", __LINE__));
|
||||||
}
|
}
|
||||||
@ -394,7 +315,6 @@ pmc_intel_finalize(struct pmc_mdep *md)
|
|||||||
/*
|
/*
|
||||||
* Uncore.
|
* Uncore.
|
||||||
*/
|
*/
|
||||||
#if defined(__i386__) || defined(__amd64__)
|
|
||||||
switch (md->pmd_cputype) {
|
switch (md->pmd_cputype) {
|
||||||
case PMC_CPU_INTEL_BROADWELL:
|
case PMC_CPU_INTEL_BROADWELL:
|
||||||
case PMC_CPU_INTEL_COREI7:
|
case PMC_CPU_INTEL_COREI7:
|
||||||
@ -406,5 +326,4 @@ pmc_intel_finalize(struct pmc_mdep *md)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
/*-
|
|
||||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
|
||||||
*
|
|
||||||
* Copyright (c) 2003-2005 Joseph Koshy
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
__FBSDID("$FreeBSD$");
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/lock.h>
|
|
||||||
#include <sys/mutex.h>
|
|
||||||
#include <sys/pmc.h>
|
|
||||||
#include <sys/pmckern.h>
|
|
||||||
#include <sys/smp.h>
|
|
||||||
#include <sys/systm.h>
|
|
||||||
|
|
||||||
#include <machine/cpufunc.h>
|
|
||||||
#include <machine/md_var.h>
|
|
||||||
#include <machine/pmc_mdep.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Intel Pentium PMCs
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
pmc_p5_initialize(struct pmc_mdep *pmc_mdep, int ncpus)
|
|
||||||
{
|
|
||||||
(void) pmc_mdep; (void) ncpus;
|
|
||||||
return (ENOSYS); /* nothing here yet */
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
pmc_p5_finalize(struct pmc_mdep *pmc_mdep)
|
|
||||||
{
|
|
||||||
(void) pmc_mdep;
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
/*-
|
|
||||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
|
||||||
*
|
|
||||||
* Copyright (c) 2005, Joseph Koshy
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Machine dependent interfaces */
|
|
||||||
|
|
||||||
#ifndef _DEV_HWPMC_PENTIUM_H_
|
|
||||||
#define _DEV_HWPMC_PENTIUM_H_ 1
|
|
||||||
|
|
||||||
/* Intel Pentium PMCs */
|
|
||||||
|
|
||||||
#define PENTIUM_NPMCS 2
|
|
||||||
#define PENTIUM_CESR_PC1 (1 << 25)
|
|
||||||
#define PENTIUM_CESR_CC1_MASK 0x01C00000
|
|
||||||
#define PENTIUM_CESR_TO_CC1(C) (((C) & 0x07) << 22)
|
|
||||||
#define PENTIUM_CESR_ES1_MASK 0x003F0000
|
|
||||||
#define PENTIUM_CESR_TO_ES1(E) (((E) & 0x3F) << 16)
|
|
||||||
#define PENTIUM_CESR_PC0 (1 << 9)
|
|
||||||
#define PENTIUM_CESR_CC0_MASK 0x000001C0
|
|
||||||
#define PENTIUM_CESR_TO_CC0(C) (((C) & 0x07) << 6)
|
|
||||||
#define PENTIUM_CESR_ES0_MASK 0x0000003F
|
|
||||||
#define PENTIUM_CESR_TO_ES0(E) ((E) & 0x3F)
|
|
||||||
#define PENTIUM_CESR_RESERVED 0xFC00FC00
|
|
||||||
|
|
||||||
#define PENTIUM_MSR_CESR 0x11
|
|
||||||
#define PENTIUM_MSR_CTR0 0x12
|
|
||||||
#define PENTIUM_MSR_CTR1 0x13
|
|
||||||
|
|
||||||
struct pmc_md_pentium_op_pmcallocate {
|
|
||||||
uint32_t pm_pentium_config;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef _KERNEL
|
|
||||||
|
|
||||||
/* MD extension for 'struct pmc' */
|
|
||||||
struct pmc_md_pentium_pmc {
|
|
||||||
uint32_t pm_pentium_cesr;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prototypes
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pmc_p5_initialize(struct pmc_mdep *_md, int _ncpus);
|
|
||||||
void pmc_p5_finalize(struct pmc_mdep *_md);
|
|
||||||
|
|
||||||
#endif /* _KERNEL */
|
|
||||||
#endif /* _DEV_HWPMC_PENTIUM_H_ */
|
|
File diff suppressed because it is too large
Load Diff
@ -1,127 +0,0 @@
|
|||||||
/*-
|
|
||||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
|
||||||
*
|
|
||||||
* Copyright (c) 2005, Joseph Koshy
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Machine dependent interfaces */
|
|
||||||
|
|
||||||
#ifndef _DEV_HWPMC_PIV_H_
|
|
||||||
#define _DEV_HWPMC_PIV_H_ 1
|
|
||||||
|
|
||||||
/* Intel P4 PMCs */
|
|
||||||
|
|
||||||
#define P4_NPMCS 18
|
|
||||||
#define P4_NESCR 45
|
|
||||||
#define P4_INVALID_PMC_INDEX -1
|
|
||||||
#define P4_MAX_ESCR_PER_EVENT 2
|
|
||||||
#define P4_MAX_PMC_PER_ESCR 3
|
|
||||||
|
|
||||||
#define P4_CCCR_OVF (1U << 31)
|
|
||||||
#define P4_CCCR_CASCADE (1 << 30)
|
|
||||||
#define P4_CCCR_OVF_PMI_T1 (1 << 27)
|
|
||||||
#define P4_CCCR_OVF_PMI_T0 (1 << 26)
|
|
||||||
#define P4_CCCR_FORCE_OVF (1 << 25)
|
|
||||||
#define P4_CCCR_EDGE (1 << 24)
|
|
||||||
#define P4_CCCR_THRESHOLD_SHIFT 20
|
|
||||||
#define P4_CCCR_THRESHOLD_MASK 0x00F00000
|
|
||||||
#define P4_CCCR_TO_THRESHOLD(C) (((C) << P4_CCCR_THRESHOLD_SHIFT) & \
|
|
||||||
P4_CCCR_THRESHOLD_MASK)
|
|
||||||
#define P4_CCCR_COMPLEMENT (1 << 19)
|
|
||||||
#define P4_CCCR_COMPARE (1 << 18)
|
|
||||||
#define P4_CCCR_ACTIVE_THREAD_SHIFT 16
|
|
||||||
#define P4_CCCR_ACTIVE_THREAD_MASK 0x00030000
|
|
||||||
#define P4_CCCR_TO_ACTIVE_THREAD(T) (((T) << P4_CCCR_ACTIVE_THREAD_SHIFT) & \
|
|
||||||
P4_CCCR_ACTIVE_THREAD_MASK)
|
|
||||||
#define P4_CCCR_ESCR_SELECT_SHIFT 13
|
|
||||||
#define P4_CCCR_ESCR_SELECT_MASK 0x0000E000
|
|
||||||
#define P4_CCCR_TO_ESCR_SELECT(E) (((E) << P4_CCCR_ESCR_SELECT_SHIFT) & \
|
|
||||||
P4_CCCR_ESCR_SELECT_MASK)
|
|
||||||
#define P4_CCCR_ENABLE (1 << 12)
|
|
||||||
#define P4_CCCR_VALID_BITS (P4_CCCR_OVF | P4_CCCR_CASCADE | \
|
|
||||||
P4_CCCR_OVF_PMI_T1 | P4_CCCR_OVF_PMI_T0 | P4_CCCR_FORCE_OVF | \
|
|
||||||
P4_CCCR_EDGE | P4_CCCR_THRESHOLD_MASK | P4_CCCR_COMPLEMENT | \
|
|
||||||
P4_CCCR_COMPARE | P4_CCCR_ESCR_SELECT_MASK | P4_CCCR_ENABLE)
|
|
||||||
|
|
||||||
#define P4_ESCR_EVENT_SELECT_SHIFT 25
|
|
||||||
#define P4_ESCR_EVENT_SELECT_MASK 0x7E000000
|
|
||||||
#define P4_ESCR_TO_EVENT_SELECT(E) (((E) << P4_ESCR_EVENT_SELECT_SHIFT) & \
|
|
||||||
P4_ESCR_EVENT_SELECT_MASK)
|
|
||||||
#define P4_ESCR_EVENT_MASK_SHIFT 9
|
|
||||||
#define P4_ESCR_EVENT_MASK_MASK 0x01FFFE00
|
|
||||||
#define P4_ESCR_TO_EVENT_MASK(M) (((M) << P4_ESCR_EVENT_MASK_SHIFT) & \
|
|
||||||
P4_ESCR_EVENT_MASK_MASK)
|
|
||||||
#define P4_ESCR_TAG_VALUE_SHIFT 5
|
|
||||||
#define P4_ESCR_TAG_VALUE_MASK 0x000001E0
|
|
||||||
#define P4_ESCR_TO_TAG_VALUE(T) (((T) << P4_ESCR_TAG_VALUE_SHIFT) & \
|
|
||||||
P4_ESCR_TAG_VALUE_MASK)
|
|
||||||
#define P4_ESCR_TAG_ENABLE 0x00000010
|
|
||||||
#define P4_ESCR_T0_OS 0x00000008
|
|
||||||
#define P4_ESCR_T0_USR 0x00000004
|
|
||||||
#define P4_ESCR_T1_OS 0x00000002
|
|
||||||
#define P4_ESCR_T1_USR 0x00000001
|
|
||||||
#define P4_ESCR_OS P4_ESCR_T0_OS
|
|
||||||
#define P4_ESCR_USR P4_ESCR_T0_USR
|
|
||||||
#define P4_ESCR_VALID_BITS (P4_ESCR_EVENT_SELECT_MASK | \
|
|
||||||
P4_ESCR_EVENT_MASK_MASK | P4_ESCR_TAG_VALUE_MASK | \
|
|
||||||
P4_ESCR_TAG_ENABLE | P4_ESCR_T0_OS | P4_ESCR_T0_USR | P4_ESCR_T1_OS \
|
|
||||||
P4_ESCR_T1_USR)
|
|
||||||
|
|
||||||
#define P4_PERFCTR_MASK 0xFFFFFFFFFFLL /* 40 bits */
|
|
||||||
#define P4_PERFCTR_OVERFLOWED(PMC) ((rdpmc(PMC) & (1LL << 39)) == 0)
|
|
||||||
|
|
||||||
#define P4_CCCR_MSR_FIRST 0x360 /* MSR_BPU_CCCR0 */
|
|
||||||
#define P4_PERFCTR_MSR_FIRST 0x300 /* MSR_BPU_COUNTER0 */
|
|
||||||
|
|
||||||
#define P4_RELOAD_COUNT_TO_PERFCTR_VALUE(V) (1 - (V))
|
|
||||||
#define P4_PERFCTR_VALUE_TO_RELOAD_COUNT(P) (1 - (P))
|
|
||||||
|
|
||||||
struct pmc_md_p4_op_pmcallocate {
|
|
||||||
uint32_t pm_p4_cccrconfig;
|
|
||||||
uint32_t pm_p4_escrconfig;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef _KERNEL
|
|
||||||
|
|
||||||
/* MD extension for 'struct pmc' */
|
|
||||||
struct pmc_md_p4_pmc {
|
|
||||||
uint32_t pm_p4_cccrvalue;
|
|
||||||
uint32_t pm_p4_escrvalue;
|
|
||||||
uint32_t pm_p4_escr;
|
|
||||||
uint32_t pm_p4_escrmsr;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prototypes
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pmc_p4_initialize(struct pmc_mdep *_md, int _ncpus);
|
|
||||||
void pmc_p4_finalize(struct pmc_mdep *md);
|
|
||||||
|
|
||||||
#endif /* _KERNEL */
|
|
||||||
#endif /* _DEV_HWPMC_PIV_H_ */
|
|
@ -1,870 +0,0 @@
|
|||||||
/*-
|
|
||||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
|
||||||
*
|
|
||||||
* Copyright (c) 2003-2005,2008 Joseph Koshy
|
|
||||||
* Copyright (c) 2007 The FreeBSD Foundation
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Portions of this software were developed by A. Joseph Koshy under
|
|
||||||
* sponsorship from the FreeBSD Foundation and Google, Inc.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
__FBSDID("$FreeBSD$");
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/bus.h>
|
|
||||||
#include <sys/lock.h>
|
|
||||||
#include <sys/mutex.h>
|
|
||||||
#include <sys/pmc.h>
|
|
||||||
#include <sys/pmckern.h>
|
|
||||||
#include <sys/smp.h>
|
|
||||||
#include <sys/systm.h>
|
|
||||||
|
|
||||||
#include <machine/intr_machdep.h>
|
|
||||||
#include <x86/apicvar.h>
|
|
||||||
#include <machine/cpu.h>
|
|
||||||
#include <machine/cpufunc.h>
|
|
||||||
#include <machine/cputypes.h>
|
|
||||||
#include <machine/md_var.h>
|
|
||||||
#include <machine/pmc_mdep.h>
|
|
||||||
#include <machine/specialreg.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PENTIUM PRO SUPPORT
|
|
||||||
*
|
|
||||||
* Quirks:
|
|
||||||
*
|
|
||||||
* - Both PMCs are enabled by a single bit P6_EVSEL_EN in performance
|
|
||||||
* counter '0'. This bit needs to be '1' if any of the two
|
|
||||||
* performance counters are in use. Perf counters can also be
|
|
||||||
* switched off by writing zeros to their EVSEL register.
|
|
||||||
*
|
|
||||||
* - While the width of these counters is 40 bits, we do not appear to
|
|
||||||
* have a way of writing 40 bits to the counter MSRs. A WRMSR
|
|
||||||
* instruction will sign extend bit 31 of the value being written to
|
|
||||||
* the perf counter -- a value of 0x80000000 written to an perf
|
|
||||||
* counter register will be sign extended to 0xFF80000000.
|
|
||||||
*
|
|
||||||
* This quirk primarily affects thread-mode PMCs in counting mode, as
|
|
||||||
* these PMCs read and write PMC registers at every context switch.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct p6pmc_descr {
|
|
||||||
struct pmc_descr pm_descr; /* common information */
|
|
||||||
uint32_t pm_pmc_msr;
|
|
||||||
uint32_t pm_evsel_msr;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct p6pmc_descr p6_pmcdesc[P6_NPMCS] = {
|
|
||||||
|
|
||||||
#define P6_PMC_CAPS (PMC_CAP_INTERRUPT | PMC_CAP_USER | PMC_CAP_SYSTEM | \
|
|
||||||
PMC_CAP_EDGE | PMC_CAP_THRESHOLD | PMC_CAP_READ | PMC_CAP_WRITE | \
|
|
||||||
PMC_CAP_INVERT | PMC_CAP_QUALIFIER)
|
|
||||||
|
|
||||||
/* PMC 0 */
|
|
||||||
{
|
|
||||||
.pm_descr =
|
|
||||||
{
|
|
||||||
.pd_name ="P6-0",
|
|
||||||
.pd_class = PMC_CLASS_P6,
|
|
||||||
.pd_caps = P6_PMC_CAPS,
|
|
||||||
.pd_width = 40
|
|
||||||
},
|
|
||||||
.pm_pmc_msr = P6_MSR_PERFCTR0,
|
|
||||||
.pm_evsel_msr = P6_MSR_EVSEL0
|
|
||||||
},
|
|
||||||
|
|
||||||
/* PMC 1 */
|
|
||||||
{
|
|
||||||
.pm_descr =
|
|
||||||
{
|
|
||||||
.pd_name ="P6-1",
|
|
||||||
.pd_class = PMC_CLASS_P6,
|
|
||||||
.pd_caps = P6_PMC_CAPS,
|
|
||||||
.pd_width = 40
|
|
||||||
},
|
|
||||||
.pm_pmc_msr = P6_MSR_PERFCTR1,
|
|
||||||
.pm_evsel_msr = P6_MSR_EVSEL1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static enum pmc_cputype p6_cputype;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* P6 Event descriptor
|
|
||||||
*
|
|
||||||
* The 'pm_flags' field has the following structure:
|
|
||||||
* - The upper 4 bits are used to track which counter an event is valid on.
|
|
||||||
* - The lower bits form a bitmask of flags indicating support for the event
|
|
||||||
* on a given CPU.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct p6_event_descr {
|
|
||||||
const enum pmc_event pm_event;
|
|
||||||
uint32_t pm_evsel;
|
|
||||||
uint32_t pm_flags;
|
|
||||||
uint32_t pm_unitmask;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define P6F_CTR(C) (1 << (28 + (C)))
|
|
||||||
#define P6F_CTR0 P6F_CTR(0)
|
|
||||||
#define P6F_CTR1 P6F_CTR(1)
|
|
||||||
#define P6F(CPU) (1 << ((CPU) - PMC_CPU_INTEL_P6))
|
|
||||||
#define _P6F(C) P6F(PMC_CPU_INTEL_##C)
|
|
||||||
#define P6F_P6 _P6F(P6)
|
|
||||||
#define P6F_CL _P6F(CL)
|
|
||||||
#define P6F_PII _P6F(PII)
|
|
||||||
#define P6F_PIII _P6F(PIII)
|
|
||||||
#define P6F_PM _P6F(PM)
|
|
||||||
#define P6F_ALL_CPUS (P6F_P6 | P6F_PII | P6F_CL | P6F_PIII | P6F_PM)
|
|
||||||
#define P6F_ALL_CTRS (P6F_CTR0 | P6F_CTR1)
|
|
||||||
#define P6F_ALL (P6F_ALL_CPUS | P6F_ALL_CTRS)
|
|
||||||
|
|
||||||
#define P6_EVENT_VALID_FOR_CPU(P,CPU) ((P)->pm_flags & P6F(CPU))
|
|
||||||
#define P6_EVENT_VALID_FOR_CTR(P,CTR) ((P)->pm_flags & P6F_CTR(CTR))
|
|
||||||
|
|
||||||
static const struct p6_event_descr p6_events[] = {
|
|
||||||
|
|
||||||
#define P6_EVDESCR(NAME, EVSEL, FLAGS, UMASK) \
|
|
||||||
{ \
|
|
||||||
.pm_event = PMC_EV_P6_##NAME, \
|
|
||||||
.pm_evsel = (EVSEL), \
|
|
||||||
.pm_flags = (FLAGS), \
|
|
||||||
.pm_unitmask = (UMASK) \
|
|
||||||
}
|
|
||||||
|
|
||||||
P6_EVDESCR(DATA_MEM_REFS, 0x43, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(DCU_LINES_IN, 0x45, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(DCU_M_LINES_IN, 0x46, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(DCU_M_LINES_OUT, 0x47, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(DCU_MISS_OUTSTANDING, 0x47, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(IFU_FETCH, 0x80, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(IFU_FETCH_MISS, 0x81, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(ITLB_MISS, 0x85, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(IFU_MEM_STALL, 0x86, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(ILD_STALL, 0x87, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(L2_IFETCH, 0x28, P6F_ALL, 0x0F),
|
|
||||||
P6_EVDESCR(L2_LD, 0x29, P6F_ALL, 0x0F),
|
|
||||||
P6_EVDESCR(L2_ST, 0x2A, P6F_ALL, 0x0F),
|
|
||||||
P6_EVDESCR(L2_LINES_IN, 0x24, P6F_ALL, 0x0F),
|
|
||||||
P6_EVDESCR(L2_LINES_OUT, 0x26, P6F_ALL, 0x0F),
|
|
||||||
P6_EVDESCR(L2_M_LINES_INM, 0x25, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(L2_M_LINES_OUTM, 0x27, P6F_ALL, 0x0F),
|
|
||||||
P6_EVDESCR(L2_RQSTS, 0x2E, P6F_ALL, 0x0F),
|
|
||||||
P6_EVDESCR(L2_ADS, 0x21, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(L2_DBUS_BUSY, 0x22, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(L2_DBUS_BUSY_RD, 0x23, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(BUS_DRDY_CLOCKS, 0x62, P6F_ALL, 0x20),
|
|
||||||
P6_EVDESCR(BUS_LOCK_CLOCKS, 0x63, P6F_ALL, 0x20),
|
|
||||||
P6_EVDESCR(BUS_REQ_OUTSTANDING, 0x60, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(BUS_TRAN_BRD, 0x65, P6F_ALL, 0x20),
|
|
||||||
P6_EVDESCR(BUS_TRAN_RFO, 0x66, P6F_ALL, 0x20),
|
|
||||||
P6_EVDESCR(BUS_TRANS_WB, 0x67, P6F_ALL, 0x20),
|
|
||||||
P6_EVDESCR(BUS_TRAN_IFETCH, 0x68, P6F_ALL, 0x20),
|
|
||||||
P6_EVDESCR(BUS_TRAN_INVAL, 0x69, P6F_ALL, 0x20),
|
|
||||||
P6_EVDESCR(BUS_TRAN_PWR, 0x6A, P6F_ALL, 0x20),
|
|
||||||
P6_EVDESCR(BUS_TRANS_P, 0x6B, P6F_ALL, 0x20),
|
|
||||||
P6_EVDESCR(BUS_TRANS_IO, 0x6C, P6F_ALL, 0x20),
|
|
||||||
P6_EVDESCR(BUS_TRAN_DEF, 0x6D, P6F_ALL, 0x20),
|
|
||||||
P6_EVDESCR(BUS_TRAN_BURST, 0x6E, P6F_ALL, 0x20),
|
|
||||||
P6_EVDESCR(BUS_TRAN_ANY, 0x70, P6F_ALL, 0x20),
|
|
||||||
P6_EVDESCR(BUS_TRAN_MEM, 0x6F, P6F_ALL, 0x20),
|
|
||||||
P6_EVDESCR(BUS_DATA_RCV, 0x64, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(BUS_BNR_DRV, 0x61, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(BUS_HIT_DRV, 0x7A, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(BUS_HITM_DRV, 0x7B, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(BUS_SNOOP_STALL, 0x7E, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(FLOPS, 0xC1, P6F_ALL_CPUS | P6F_CTR0, 0x00),
|
|
||||||
P6_EVDESCR(FP_COMPS_OPS_EXE, 0x10, P6F_ALL_CPUS | P6F_CTR0, 0x00),
|
|
||||||
P6_EVDESCR(FP_ASSIST, 0x11, P6F_ALL_CPUS | P6F_CTR1, 0x00),
|
|
||||||
P6_EVDESCR(MUL, 0x12, P6F_ALL_CPUS | P6F_CTR1, 0x00),
|
|
||||||
P6_EVDESCR(DIV, 0x13, P6F_ALL_CPUS | P6F_CTR1, 0x00),
|
|
||||||
P6_EVDESCR(CYCLES_DIV_BUSY, 0x14, P6F_ALL_CPUS | P6F_CTR0, 0x00),
|
|
||||||
P6_EVDESCR(LD_BLOCKS, 0x03, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(SB_DRAINS, 0x04, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(MISALIGN_MEM_REF, 0x05, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(EMON_KNI_PREF_DISPATCHED, 0x07, P6F_PIII | P6F_ALL_CTRS, 0x03),
|
|
||||||
P6_EVDESCR(EMON_KNI_PREF_MISS, 0x4B, P6F_PIII | P6F_ALL_CTRS, 0x03),
|
|
||||||
P6_EVDESCR(INST_RETIRED, 0xC0, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(UOPS_RETIRED, 0xC2, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(INST_DECODED, 0xD0, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(EMON_KNI_INST_RETIRED, 0xD8, P6F_PIII | P6F_ALL_CTRS, 0x01),
|
|
||||||
P6_EVDESCR(EMON_KNI_COMP_INST_RET, 0xD9, P6F_PIII | P6F_ALL_CTRS, 0x01),
|
|
||||||
P6_EVDESCR(HW_INT_RX, 0xC8, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(CYCLES_INT_MASKED, 0xC6, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(CYCLES_INT_PENDING_AND_MASKED, 0xC7, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(BR_INST_RETIRED, 0xC4, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(BR_MISS_PRED_RETIRED, 0xC5, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(BR_TAKEN_RETIRED, 0xC9, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(BR_MISS_PRED_TAKEN_RET, 0xCA, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(BR_INST_DECODED, 0xE0, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(BTB_MISSES, 0xE2, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(BR_BOGUS, 0xE4, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(BACLEARS, 0xE6, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(RESOURCE_STALLS, 0xA2, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(PARTIAL_RAT_STALLS, 0xD2, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(SEGMENT_REG_LOADS, 0x06, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(CPU_CLK_UNHALTED, 0x79, P6F_ALL, 0x00),
|
|
||||||
P6_EVDESCR(MMX_INSTR_EXEC, 0xB0,
|
|
||||||
P6F_ALL_CTRS | P6F_CL | P6F_PII, 0x00),
|
|
||||||
P6_EVDESCR(MMX_SAT_INSTR_EXEC, 0xB1,
|
|
||||||
P6F_ALL_CTRS | P6F_PII | P6F_PIII, 0x00),
|
|
||||||
P6_EVDESCR(MMX_UOPS_EXEC, 0xB2,
|
|
||||||
P6F_ALL_CTRS | P6F_PII | P6F_PIII, 0x0F),
|
|
||||||
P6_EVDESCR(MMX_INSTR_TYPE_EXEC, 0xB3,
|
|
||||||
P6F_ALL_CTRS | P6F_PII | P6F_PIII, 0x3F),
|
|
||||||
P6_EVDESCR(FP_MMX_TRANS, 0xCC,
|
|
||||||
P6F_ALL_CTRS | P6F_PII | P6F_PIII, 0x01),
|
|
||||||
P6_EVDESCR(MMX_ASSIST, 0xCD,
|
|
||||||
P6F_ALL_CTRS | P6F_PII | P6F_PIII, 0x00),
|
|
||||||
P6_EVDESCR(MMX_INSTR_RET, 0xCE, P6F_ALL_CTRS | P6F_PII, 0x00),
|
|
||||||
P6_EVDESCR(SEG_RENAME_STALLS, 0xD4,
|
|
||||||
P6F_ALL_CTRS | P6F_PII | P6F_PIII, 0x0F),
|
|
||||||
P6_EVDESCR(SEG_REG_RENAMES, 0xD5,
|
|
||||||
P6F_ALL_CTRS | P6F_PII | P6F_PIII, 0x0F),
|
|
||||||
P6_EVDESCR(RET_SEG_RENAMES, 0xD6,
|
|
||||||
P6F_ALL_CTRS | P6F_PII | P6F_PIII, 0x00),
|
|
||||||
P6_EVDESCR(EMON_EST_TRANS, 0x58, P6F_ALL_CTRS | P6F_PM, 0x02),
|
|
||||||
P6_EVDESCR(EMON_THERMAL_TRIP, 0x59, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(BR_INST_EXEC, 0x88, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(BR_MISSP_EXEC, 0x89, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(BR_BAC_MISSP_EXEC, 0x8A, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(BR_CND_EXEC, 0x8B, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(BR_CND_MISSP_EXEC, 0x8C, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(BR_IND_EXEC, 0x8D, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(BR_IND_MISSP_EXEC, 0x8E, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(BR_RET_EXEC, 0x8F, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(BR_RET_MISSP_EXEC, 0x90, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(BR_RET_BAC_MISSP_EXEC, 0x91, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(BR_CALL_EXEC, 0x92, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(BR_CALL_MISSP_EXEC, 0x93, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(BR_IND_CALL_EXEC, 0x94, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(EMON_SIMD_INSTR_RETIRED, 0xCE, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(EMON_SYNCH_UOPS, 0xD3, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(EMON_ESP_UOPS, 0xD7, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(EMON_FUSED_UOPS_RET, 0xDA, P6F_ALL_CTRS | P6F_PM, 0x03),
|
|
||||||
P6_EVDESCR(EMON_UNFUSION, 0xDB, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(EMON_PREF_RQSTS_UP, 0xF0, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(EMON_PREF_RQSTS_DN, 0xD8, P6F_ALL_CTRS | P6F_PM, 0x00),
|
|
||||||
P6_EVDESCR(EMON_SSE_SSE2_INST_RETIRED, 0xD8, P6F_ALL_CTRS | P6F_PM, 0x03),
|
|
||||||
P6_EVDESCR(EMON_SSE_SSE2_COMP_INST_RETIRED, 0xD9, P6F_ALL_CTRS | P6F_PM, 0x03)
|
|
||||||
|
|
||||||
#undef P6_EVDESCR
|
|
||||||
};
|
|
||||||
|
|
||||||
#define P6_NEVENTS (PMC_EV_P6_LAST - PMC_EV_P6_FIRST + 1)
|
|
||||||
|
|
||||||
static const struct p6_event_descr *
|
|
||||||
p6_find_event(enum pmc_event ev)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
|
|
||||||
for (n = 0; n < P6_NEVENTS; n++)
|
|
||||||
if (p6_events[n].pm_event == ev)
|
|
||||||
break;
|
|
||||||
if (n == P6_NEVENTS)
|
|
||||||
return NULL;
|
|
||||||
return &p6_events[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Per-CPU data structure for P6 class CPUs
|
|
||||||
*
|
|
||||||
* [common stuff]
|
|
||||||
* [flags for maintaining PMC start/stop state]
|
|
||||||
* [3 struct pmc_hw pointers]
|
|
||||||
* [3 struct pmc_hw structures]
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct p6_cpu {
|
|
||||||
struct pmc_hw pc_p6pmcs[P6_NPMCS];
|
|
||||||
uint32_t pc_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct p6_cpu **p6_pcpu;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If CTR1 is active, we need to keep the 'EN' bit if CTR0 set,
|
|
||||||
* with the rest of CTR0 being zero'ed out.
|
|
||||||
*/
|
|
||||||
#define P6_SYNC_CTR_STATE(PC) do { \
|
|
||||||
uint32_t _config, _enable; \
|
|
||||||
_enable = 0; \
|
|
||||||
if ((PC)->pc_state & 0x02) \
|
|
||||||
_enable |= P6_EVSEL_EN; \
|
|
||||||
if ((PC)->pc_state & 0x01) \
|
|
||||||
_config = rdmsr(P6_MSR_EVSEL0) | \
|
|
||||||
P6_EVSEL_EN; \
|
|
||||||
else \
|
|
||||||
_config = 0; \
|
|
||||||
wrmsr(P6_MSR_EVSEL0, _config | _enable); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define P6_MARK_STARTED(PC,RI) do { \
|
|
||||||
(PC)->pc_state |= (1 << ((RI)-1)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define P6_MARK_STOPPED(PC,RI) do { \
|
|
||||||
(PC)->pc_state &= ~(1<< ((RI)-1)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
static int
|
|
||||||
p6_pcpu_init(struct pmc_mdep *md, int cpu)
|
|
||||||
{
|
|
||||||
int first_ri, n;
|
|
||||||
struct p6_cpu *p6c;
|
|
||||||
struct pmc_cpu *pc;
|
|
||||||
struct pmc_hw *phw;
|
|
||||||
|
|
||||||
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
|
|
||||||
("[p6,%d] bad cpu %d", __LINE__, cpu));
|
|
||||||
|
|
||||||
PMCDBG1(MDP,INI,0,"p6-init cpu=%d", cpu);
|
|
||||||
|
|
||||||
p6c = malloc(sizeof (struct p6_cpu), M_PMC, M_WAITOK|M_ZERO);
|
|
||||||
pc = pmc_pcpu[cpu];
|
|
||||||
|
|
||||||
KASSERT(pc != NULL, ("[p6,%d] cpu %d null per-cpu", __LINE__, cpu));
|
|
||||||
|
|
||||||
phw = p6c->pc_p6pmcs;
|
|
||||||
p6_pcpu[cpu] = p6c;
|
|
||||||
|
|
||||||
first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_P6].pcd_ri;
|
|
||||||
|
|
||||||
for (n = 0; n < P6_NPMCS; n++, phw++) {
|
|
||||||
phw->phw_state = PMC_PHW_FLAG_IS_ENABLED |
|
|
||||||
PMC_PHW_CPU_TO_STATE(cpu) | PMC_PHW_INDEX_TO_STATE(n);
|
|
||||||
phw->phw_pmc = NULL;
|
|
||||||
pc->pc_hwpmcs[n + first_ri] = phw;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
p6_pcpu_fini(struct pmc_mdep *md, int cpu)
|
|
||||||
{
|
|
||||||
int first_ri, n;
|
|
||||||
struct p6_cpu *p6c;
|
|
||||||
struct pmc_cpu *pc;
|
|
||||||
|
|
||||||
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
|
|
||||||
("[p6,%d] bad cpu %d", __LINE__, cpu));
|
|
||||||
|
|
||||||
PMCDBG1(MDP,INI,0,"p6-cleanup cpu=%d", cpu);
|
|
||||||
|
|
||||||
p6c = p6_pcpu[cpu];
|
|
||||||
p6_pcpu[cpu] = NULL;
|
|
||||||
|
|
||||||
KASSERT(p6c != NULL, ("[p6,%d] null pcpu", __LINE__));
|
|
||||||
|
|
||||||
free(p6c, M_PMC);
|
|
||||||
|
|
||||||
first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_P6].pcd_ri;
|
|
||||||
pc = pmc_pcpu[cpu];
|
|
||||||
for (n = 0; n < P6_NPMCS; n++)
|
|
||||||
pc->pc_hwpmcs[n + first_ri] = NULL;
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
p6_read_pmc(int cpu, int ri, pmc_value_t *v)
|
|
||||||
{
|
|
||||||
struct pmc *pm;
|
|
||||||
struct p6pmc_descr *pd;
|
|
||||||
pmc_value_t tmp;
|
|
||||||
|
|
||||||
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
|
|
||||||
("[p6,%d] illegal cpu value %d", __LINE__, cpu));
|
|
||||||
KASSERT(ri >= 0 && ri < P6_NPMCS,
|
|
||||||
("[p6,%d] illegal row-index %d", __LINE__, ri));
|
|
||||||
|
|
||||||
pm = p6_pcpu[cpu]->pc_p6pmcs[ri].phw_pmc;
|
|
||||||
pd = &p6_pmcdesc[ri];
|
|
||||||
|
|
||||||
KASSERT(pm,
|
|
||||||
("[p6,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, ri));
|
|
||||||
|
|
||||||
tmp = rdmsr(pd->pm_pmc_msr) & P6_PERFCTR_READ_MASK;
|
|
||||||
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
|
|
||||||
*v = P6_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
|
|
||||||
else
|
|
||||||
*v = tmp;
|
|
||||||
|
|
||||||
PMCDBG4(MDP,REA,1, "p6-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri,
|
|
||||||
pd->pm_pmc_msr, *v);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
p6_write_pmc(int cpu, int ri, pmc_value_t v)
|
|
||||||
{
|
|
||||||
struct pmc *pm;
|
|
||||||
struct p6pmc_descr *pd;
|
|
||||||
|
|
||||||
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
|
|
||||||
("[p6,%d] illegal cpu value %d", __LINE__, cpu));
|
|
||||||
KASSERT(ri >= 0 && ri < P6_NPMCS,
|
|
||||||
("[p6,%d] illegal row-index %d", __LINE__, ri));
|
|
||||||
|
|
||||||
pm = p6_pcpu[cpu]->pc_p6pmcs[ri].phw_pmc;
|
|
||||||
pd = &p6_pmcdesc[ri];
|
|
||||||
|
|
||||||
KASSERT(pm,
|
|
||||||
("[p6,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, ri));
|
|
||||||
|
|
||||||
PMCDBG4(MDP,WRI,1, "p6-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri,
|
|
||||||
pd->pm_pmc_msr, v);
|
|
||||||
|
|
||||||
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
|
|
||||||
v = P6_RELOAD_COUNT_TO_PERFCTR_VALUE(v);
|
|
||||||
|
|
||||||
wrmsr(pd->pm_pmc_msr, v & P6_PERFCTR_WRITE_MASK);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
p6_config_pmc(int cpu, int ri, struct pmc *pm)
|
|
||||||
{
|
|
||||||
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
|
|
||||||
("[p6,%d] illegal CPU %d", __LINE__, cpu));
|
|
||||||
|
|
||||||
KASSERT(ri >= 0 && ri < P6_NPMCS,
|
|
||||||
("[p6,%d] illegal row-index %d", __LINE__, ri));
|
|
||||||
|
|
||||||
PMCDBG3(MDP,CFG,1, "p6-config cpu=%d ri=%d pm=%p", cpu, ri, pm);
|
|
||||||
|
|
||||||
KASSERT(p6_pcpu[cpu] != NULL, ("[p6,%d] null per-cpu %d", __LINE__,
|
|
||||||
cpu));
|
|
||||||
|
|
||||||
p6_pcpu[cpu]->pc_p6pmcs[ri].phw_pmc = pm;
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Retrieve a configured PMC pointer from hardware state.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
p6_get_config(int cpu, int ri, struct pmc **ppm)
|
|
||||||
{
|
|
||||||
|
|
||||||
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
|
|
||||||
("[p6,%d] illegal CPU %d", __LINE__, cpu));
|
|
||||||
KASSERT(ri >= 0 && ri < P6_NPMCS,
|
|
||||||
("[p6,%d] illegal row-index %d", __LINE__, ri));
|
|
||||||
|
|
||||||
*ppm = p6_pcpu[cpu]->pc_p6pmcs[ri].phw_pmc;
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A pmc may be allocated to a given row index if:
|
|
||||||
* - the event is valid for this CPU
|
|
||||||
* - the event is valid for this counter index
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
p6_allocate_pmc(int cpu, int ri, struct pmc *pm,
|
|
||||||
const struct pmc_op_pmcallocate *a)
|
|
||||||
{
|
|
||||||
uint32_t allowed_unitmask, caps, config, unitmask;
|
|
||||||
const struct p6pmc_descr *pd;
|
|
||||||
const struct p6_event_descr *pevent;
|
|
||||||
enum pmc_event ev;
|
|
||||||
|
|
||||||
(void) cpu;
|
|
||||||
|
|
||||||
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
|
|
||||||
("[p6,%d] illegal CPU %d", __LINE__, cpu));
|
|
||||||
KASSERT(ri >= 0 && ri < P6_NPMCS,
|
|
||||||
("[p6,%d] illegal row-index value %d", __LINE__, ri));
|
|
||||||
|
|
||||||
pd = &p6_pmcdesc[ri];
|
|
||||||
|
|
||||||
PMCDBG4(MDP,ALL,1, "p6-allocate ri=%d class=%d pmccaps=0x%x "
|
|
||||||
"reqcaps=0x%x", ri, pd->pm_descr.pd_class, pd->pm_descr.pd_caps,
|
|
||||||
pm->pm_caps);
|
|
||||||
|
|
||||||
/* check class */
|
|
||||||
if (pd->pm_descr.pd_class != a->pm_class)
|
|
||||||
return (EINVAL);
|
|
||||||
|
|
||||||
/* check requested capabilities */
|
|
||||||
caps = a->pm_caps;
|
|
||||||
if ((pd->pm_descr.pd_caps & caps) != caps)
|
|
||||||
return (EPERM);
|
|
||||||
|
|
||||||
ev = pm->pm_event;
|
|
||||||
|
|
||||||
if (ev < PMC_EV_P6_FIRST || ev > PMC_EV_P6_LAST)
|
|
||||||
return (EINVAL);
|
|
||||||
|
|
||||||
if ((pevent = p6_find_event(ev)) == NULL)
|
|
||||||
return (ESRCH);
|
|
||||||
|
|
||||||
if (!P6_EVENT_VALID_FOR_CPU(pevent, p6_cputype) ||
|
|
||||||
!P6_EVENT_VALID_FOR_CTR(pevent, (ri-1)))
|
|
||||||
return (EINVAL);
|
|
||||||
|
|
||||||
/* For certain events, Pentium M differs from the stock P6 */
|
|
||||||
allowed_unitmask = 0;
|
|
||||||
if (p6_cputype == PMC_CPU_INTEL_PM) {
|
|
||||||
if (ev == PMC_EV_P6_L2_LD || ev == PMC_EV_P6_L2_LINES_IN ||
|
|
||||||
ev == PMC_EV_P6_L2_LINES_OUT)
|
|
||||||
allowed_unitmask = P6_EVSEL_TO_UMASK(0x3F);
|
|
||||||
else if (ev == PMC_EV_P6_L2_M_LINES_OUTM)
|
|
||||||
allowed_unitmask = P6_EVSEL_TO_UMASK(0x30);
|
|
||||||
} else
|
|
||||||
allowed_unitmask = P6_EVSEL_TO_UMASK(pevent->pm_unitmask);
|
|
||||||
|
|
||||||
unitmask = a->pm_md.pm_ppro.pm_ppro_config & P6_EVSEL_UMASK_MASK;
|
|
||||||
if (unitmask & ~allowed_unitmask) /* disallow reserved bits */
|
|
||||||
return (EINVAL);
|
|
||||||
|
|
||||||
if (ev == PMC_EV_P6_MMX_UOPS_EXEC) /* hardcoded mask */
|
|
||||||
unitmask = P6_EVSEL_TO_UMASK(0x0F);
|
|
||||||
|
|
||||||
config = 0;
|
|
||||||
|
|
||||||
config |= P6_EVSEL_EVENT_SELECT(pevent->pm_evsel);
|
|
||||||
|
|
||||||
if (unitmask & (caps & PMC_CAP_QUALIFIER))
|
|
||||||
config |= unitmask;
|
|
||||||
|
|
||||||
if (caps & PMC_CAP_THRESHOLD)
|
|
||||||
config |= a->pm_md.pm_ppro.pm_ppro_config &
|
|
||||||
P6_EVSEL_CMASK_MASK;
|
|
||||||
|
|
||||||
/* set at least one of the 'usr' or 'os' caps */
|
|
||||||
if (caps & PMC_CAP_USER)
|
|
||||||
config |= P6_EVSEL_USR;
|
|
||||||
if (caps & PMC_CAP_SYSTEM)
|
|
||||||
config |= P6_EVSEL_OS;
|
|
||||||
if ((caps & (PMC_CAP_USER|PMC_CAP_SYSTEM)) == 0)
|
|
||||||
config |= (P6_EVSEL_USR|P6_EVSEL_OS);
|
|
||||||
|
|
||||||
if (caps & PMC_CAP_EDGE)
|
|
||||||
config |= P6_EVSEL_E;
|
|
||||||
if (caps & PMC_CAP_INVERT)
|
|
||||||
config |= P6_EVSEL_INV;
|
|
||||||
if (caps & PMC_CAP_INTERRUPT)
|
|
||||||
config |= P6_EVSEL_INT;
|
|
||||||
|
|
||||||
pm->pm_md.pm_ppro.pm_ppro_evsel = config;
|
|
||||||
|
|
||||||
PMCDBG1(MDP,ALL,2, "p6-allocate config=0x%x", config);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
p6_release_pmc(int cpu, int ri, struct pmc *pm)
|
|
||||||
{
|
|
||||||
(void) pm;
|
|
||||||
|
|
||||||
PMCDBG3(MDP,REL,1, "p6-release cpu=%d ri=%d pm=%p", cpu, ri, pm);
|
|
||||||
|
|
||||||
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
|
|
||||||
("[p6,%d] illegal CPU value %d", __LINE__, cpu));
|
|
||||||
KASSERT(ri >= 0 && ri < P6_NPMCS,
|
|
||||||
("[p6,%d] illegal row-index %d", __LINE__, ri));
|
|
||||||
|
|
||||||
KASSERT(p6_pcpu[cpu]->pc_p6pmcs[ri].phw_pmc == NULL,
|
|
||||||
("[p6,%d] PHW pmc non-NULL", __LINE__));
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
p6_start_pmc(int cpu, int ri)
|
|
||||||
{
|
|
||||||
uint32_t config;
|
|
||||||
struct pmc *pm;
|
|
||||||
struct p6_cpu *pc;
|
|
||||||
const struct p6pmc_descr *pd;
|
|
||||||
|
|
||||||
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
|
|
||||||
("[p6,%d] illegal CPU value %d", __LINE__, cpu));
|
|
||||||
KASSERT(ri >= 0 && ri < P6_NPMCS,
|
|
||||||
("[p6,%d] illegal row-index %d", __LINE__, ri));
|
|
||||||
|
|
||||||
pc = p6_pcpu[cpu];
|
|
||||||
pm = pc->pc_p6pmcs[ri].phw_pmc;
|
|
||||||
pd = &p6_pmcdesc[ri];
|
|
||||||
|
|
||||||
KASSERT(pm,
|
|
||||||
("[p6,%d] starting cpu%d,ri%d with no pmc configured",
|
|
||||||
__LINE__, cpu, ri));
|
|
||||||
|
|
||||||
PMCDBG2(MDP,STA,1, "p6-start cpu=%d ri=%d", cpu, ri);
|
|
||||||
|
|
||||||
config = pm->pm_md.pm_ppro.pm_ppro_evsel;
|
|
||||||
|
|
||||||
PMCDBG4(MDP,STA,2, "p6-start/2 cpu=%d ri=%d evselmsr=0x%x config=0x%x",
|
|
||||||
cpu, ri, pd->pm_evsel_msr, config);
|
|
||||||
|
|
||||||
P6_MARK_STARTED(pc, ri);
|
|
||||||
wrmsr(pd->pm_evsel_msr, config);
|
|
||||||
|
|
||||||
P6_SYNC_CTR_STATE(pc);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
p6_stop_pmc(int cpu, int ri)
|
|
||||||
{
|
|
||||||
struct pmc *pm;
|
|
||||||
struct p6_cpu *pc;
|
|
||||||
struct p6pmc_descr *pd;
|
|
||||||
|
|
||||||
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
|
|
||||||
("[p6,%d] illegal cpu value %d", __LINE__, cpu));
|
|
||||||
KASSERT(ri >= 0 && ri < P6_NPMCS,
|
|
||||||
("[p6,%d] illegal row index %d", __LINE__, ri));
|
|
||||||
|
|
||||||
pc = p6_pcpu[cpu];
|
|
||||||
pm = pc->pc_p6pmcs[ri].phw_pmc;
|
|
||||||
pd = &p6_pmcdesc[ri];
|
|
||||||
|
|
||||||
KASSERT(pm,
|
|
||||||
("[p6,%d] cpu%d ri%d no configured PMC to stop", __LINE__,
|
|
||||||
cpu, ri));
|
|
||||||
|
|
||||||
PMCDBG2(MDP,STO,1, "p6-stop cpu=%d ri=%d", cpu, ri);
|
|
||||||
|
|
||||||
wrmsr(pd->pm_evsel_msr, 0); /* stop hw */
|
|
||||||
P6_MARK_STOPPED(pc, ri); /* update software state */
|
|
||||||
|
|
||||||
P6_SYNC_CTR_STATE(pc); /* restart CTR1 if need be */
|
|
||||||
|
|
||||||
PMCDBG2(MDP,STO,2, "p6-stop/2 cpu=%d ri=%d", cpu, ri);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
p6_intr(int cpu, struct trapframe *tf)
|
|
||||||
{
|
|
||||||
int error, retval, ri;
|
|
||||||
uint32_t perf0cfg;
|
|
||||||
struct pmc *pm;
|
|
||||||
struct p6_cpu *pc;
|
|
||||||
pmc_value_t v;
|
|
||||||
|
|
||||||
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
|
|
||||||
("[p6,%d] CPU %d out of range", __LINE__, cpu));
|
|
||||||
|
|
||||||
retval = 0;
|
|
||||||
pc = p6_pcpu[cpu];
|
|
||||||
|
|
||||||
/* stop both PMCs */
|
|
||||||
perf0cfg = rdmsr(P6_MSR_EVSEL0);
|
|
||||||
wrmsr(P6_MSR_EVSEL0, perf0cfg & ~P6_EVSEL_EN);
|
|
||||||
|
|
||||||
for (ri = 0; ri < P6_NPMCS; ri++) {
|
|
||||||
|
|
||||||
if ((pm = pc->pc_p6pmcs[ri].phw_pmc) == NULL ||
|
|
||||||
!PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!P6_PMC_HAS_OVERFLOWED(ri))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
retval = 1;
|
|
||||||
|
|
||||||
if (pm->pm_state != PMC_STATE_RUNNING)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
error = pmc_process_interrupt(cpu, PMC_HR, pm, tf,
|
|
||||||
TRAPF_USERMODE(tf));
|
|
||||||
if (error)
|
|
||||||
P6_MARK_STOPPED(pc,ri);
|
|
||||||
|
|
||||||
/* reload sampling count */
|
|
||||||
v = pm->pm_sc.pm_reloadcount;
|
|
||||||
wrmsr(P6_MSR_PERFCTR0 + ri,
|
|
||||||
P6_RELOAD_COUNT_TO_PERFCTR_VALUE(v));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* On P6 processors, the LAPIC needs to have its PMC interrupt
|
|
||||||
* unmasked after a PMC interrupt.
|
|
||||||
*/
|
|
||||||
if (retval)
|
|
||||||
lapic_reenable_pmc();
|
|
||||||
|
|
||||||
if (retval)
|
|
||||||
counter_u64_add(pmc_stats.pm_intr_processed, 1);
|
|
||||||
else
|
|
||||||
counter_u64_add(pmc_stats.pm_intr_ignored, 1);
|
|
||||||
|
|
||||||
/* restart counters that can be restarted */
|
|
||||||
P6_SYNC_CTR_STATE(pc);
|
|
||||||
|
|
||||||
return (retval);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
p6_describe(int cpu, int ri, struct pmc_info *pi,
|
|
||||||
struct pmc **ppmc)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
size_t copied;
|
|
||||||
struct pmc_hw *phw;
|
|
||||||
struct p6pmc_descr *pd;
|
|
||||||
|
|
||||||
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
|
|
||||||
("[p6,%d] illegal CPU %d", __LINE__, cpu));
|
|
||||||
KASSERT(ri >= 0 && ri < P6_NPMCS,
|
|
||||||
("[p6,%d] row-index %d out of range", __LINE__, ri));
|
|
||||||
|
|
||||||
phw = pmc_pcpu[cpu]->pc_hwpmcs[ri];
|
|
||||||
pd = &p6_pmcdesc[ri];
|
|
||||||
|
|
||||||
KASSERT(phw == &p6_pcpu[cpu]->pc_p6pmcs[ri],
|
|
||||||
("[p6,%d] phw mismatch", __LINE__));
|
|
||||||
|
|
||||||
if ((error = copystr(pd->pm_descr.pd_name, pi->pm_name,
|
|
||||||
PMC_NAME_MAX, &copied)) != 0)
|
|
||||||
return (error);
|
|
||||||
|
|
||||||
pi->pm_class = pd->pm_descr.pd_class;
|
|
||||||
|
|
||||||
if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) {
|
|
||||||
pi->pm_enabled = TRUE;
|
|
||||||
*ppmc = phw->phw_pmc;
|
|
||||||
} else {
|
|
||||||
pi->pm_enabled = FALSE;
|
|
||||||
*ppmc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
p6_get_msr(int ri, uint32_t *msr)
|
|
||||||
{
|
|
||||||
KASSERT(ri >= 0 && ri < P6_NPMCS,
|
|
||||||
("[p6,%d ri %d out of range", __LINE__, ri));
|
|
||||||
|
|
||||||
*msr = p6_pmcdesc[ri].pm_pmc_msr - P6_MSR_PERFCTR0;
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
pmc_p6_initialize(struct pmc_mdep *md, int ncpus)
|
|
||||||
{
|
|
||||||
struct pmc_classdep *pcd;
|
|
||||||
|
|
||||||
KASSERT(cpu_vendor_id == CPU_VENDOR_INTEL,
|
|
||||||
("[p6,%d] Initializing non-intel processor", __LINE__));
|
|
||||||
|
|
||||||
PMCDBG0(MDP,INI,1, "p6-initialize");
|
|
||||||
|
|
||||||
/* Allocate space for pointers to per-cpu descriptors. */
|
|
||||||
p6_pcpu = malloc(sizeof(struct p6_cpu **) * ncpus, M_PMC,
|
|
||||||
M_ZERO|M_WAITOK);
|
|
||||||
|
|
||||||
/* Fill in the class dependent descriptor. */
|
|
||||||
pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_P6];
|
|
||||||
|
|
||||||
switch (md->pmd_cputype) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* P6 Family Processors
|
|
||||||
*/
|
|
||||||
case PMC_CPU_INTEL_P6:
|
|
||||||
case PMC_CPU_INTEL_CL:
|
|
||||||
case PMC_CPU_INTEL_PII:
|
|
||||||
case PMC_CPU_INTEL_PIII:
|
|
||||||
case PMC_CPU_INTEL_PM:
|
|
||||||
|
|
||||||
p6_cputype = md->pmd_cputype;
|
|
||||||
|
|
||||||
pcd->pcd_caps = P6_PMC_CAPS;
|
|
||||||
pcd->pcd_class = PMC_CLASS_P6;
|
|
||||||
pcd->pcd_num = P6_NPMCS;
|
|
||||||
pcd->pcd_ri = md->pmd_npmc;
|
|
||||||
pcd->pcd_width = 40;
|
|
||||||
|
|
||||||
pcd->pcd_allocate_pmc = p6_allocate_pmc;
|
|
||||||
pcd->pcd_config_pmc = p6_config_pmc;
|
|
||||||
pcd->pcd_describe = p6_describe;
|
|
||||||
pcd->pcd_get_config = p6_get_config;
|
|
||||||
pcd->pcd_get_msr = p6_get_msr;
|
|
||||||
pcd->pcd_pcpu_fini = p6_pcpu_fini;
|
|
||||||
pcd->pcd_pcpu_init = p6_pcpu_init;
|
|
||||||
pcd->pcd_read_pmc = p6_read_pmc;
|
|
||||||
pcd->pcd_release_pmc = p6_release_pmc;
|
|
||||||
pcd->pcd_start_pmc = p6_start_pmc;
|
|
||||||
pcd->pcd_stop_pmc = p6_stop_pmc;
|
|
||||||
pcd->pcd_write_pmc = p6_write_pmc;
|
|
||||||
|
|
||||||
md->pmd_pcpu_fini = NULL;
|
|
||||||
md->pmd_pcpu_init = NULL;
|
|
||||||
md->pmd_intr = p6_intr;
|
|
||||||
|
|
||||||
md->pmd_npmc += P6_NPMCS;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
KASSERT(0,("[p6,%d] Unknown CPU type", __LINE__));
|
|
||||||
return ENOSYS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
pmc_p6_finalize(struct pmc_mdep *md)
|
|
||||||
{
|
|
||||||
#if defined(INVARIANTS)
|
|
||||||
int i, ncpus;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
KASSERT(p6_pcpu != NULL, ("[p6,%d] NULL p6_pcpu", __LINE__));
|
|
||||||
|
|
||||||
#if defined(INVARIANTS)
|
|
||||||
ncpus = pmc_cpu_max();
|
|
||||||
for (i = 0; i < ncpus; i++)
|
|
||||||
KASSERT(p6_pcpu[i] == NULL, ("[p6,%d] non-null pcpu %d",
|
|
||||||
__LINE__, i));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
free(p6_pcpu, M_PMC);
|
|
||||||
p6_pcpu = NULL;
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
/*-
|
|
||||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
|
||||||
*
|
|
||||||
* Copyright (c) 2005, Joseph Koshy
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Machine dependent interfaces */
|
|
||||||
|
|
||||||
#ifndef _DEV_HWPMC_PPRO_H_
|
|
||||||
#define _DEV_HWPMC_PPRO_H_
|
|
||||||
|
|
||||||
/* Intel PPro, Celeron, P-II, P-III, Pentium-M PMCS */
|
|
||||||
|
|
||||||
#define P6_NPMCS 2 /* 2 PMCs */
|
|
||||||
|
|
||||||
#define P6_EVSEL_CMASK_MASK 0xFF000000
|
|
||||||
#define P6_EVSEL_TO_CMASK(C) (((C) & 0xFF) << 24)
|
|
||||||
#define P6_EVSEL_INV (1 << 23)
|
|
||||||
#define P6_EVSEL_EN (1 << 22)
|
|
||||||
#define P6_EVSEL_INT (1 << 20)
|
|
||||||
#define P6_EVSEL_PC (1 << 19)
|
|
||||||
#define P6_EVSEL_E (1 << 18)
|
|
||||||
#define P6_EVSEL_OS (1 << 17)
|
|
||||||
#define P6_EVSEL_USR (1 << 16)
|
|
||||||
#define P6_EVSEL_UMASK_MASK 0x0000FF00
|
|
||||||
#define P6_EVSEL_TO_UMASK(U) (((U) & 0xFF) << 8)
|
|
||||||
#define P6_EVSEL_EVENT_SELECT(ES) ((ES) & 0xFF)
|
|
||||||
#define P6_EVSEL_RESERVED (1 << 21)
|
|
||||||
|
|
||||||
#define P6_MSR_EVSEL0 0x0186
|
|
||||||
#define P6_MSR_EVSEL1 0x0187
|
|
||||||
#define P6_MSR_PERFCTR0 0x00C1
|
|
||||||
#define P6_MSR_PERFCTR1 0x00C2
|
|
||||||
|
|
||||||
#define P6_PERFCTR_READ_MASK 0xFFFFFFFFFFLL /* 40 bits */
|
|
||||||
#define P6_PERFCTR_WRITE_MASK 0xFFFFFFFFU /* 32 bits */
|
|
||||||
|
|
||||||
#define P6_RELOAD_COUNT_TO_PERFCTR_VALUE(R) (-(R))
|
|
||||||
#define P6_PERFCTR_VALUE_TO_RELOAD_COUNT(P) (-(P))
|
|
||||||
|
|
||||||
#define P6_PMC_HAS_OVERFLOWED(P) ((rdpmc(P) & (1LL << 39)) == 0)
|
|
||||||
|
|
||||||
struct pmc_md_ppro_op_pmcallocate {
|
|
||||||
uint32_t pm_ppro_config;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef _KERNEL
|
|
||||||
|
|
||||||
/* MD extension for 'struct pmc' */
|
|
||||||
struct pmc_md_ppro_pmc {
|
|
||||||
uint32_t pm_ppro_evsel;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prototypes
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pmc_p6_initialize(struct pmc_mdep *_md, int _ncpus);
|
|
||||||
void pmc_p6_finalize(struct pmc_mdep *_md);
|
|
||||||
|
|
||||||
#endif /* _KERNEL */
|
|
||||||
#endif /* _DEV_HWPMC_PPRO_H_ */
|
|
@ -207,9 +207,6 @@ ucf_allocate_pmc(int cpu, int ri, struct pmc *pm,
|
|||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
ev = pm->pm_event;
|
ev = pm->pm_event;
|
||||||
if (ev < PMC_EV_UCF_FIRST || ev > PMC_EV_UCF_LAST)
|
|
||||||
return (EINVAL);
|
|
||||||
|
|
||||||
flags = UCF_EN;
|
flags = UCF_EN;
|
||||||
|
|
||||||
pm->pm_md.pm_ucf.pm_ucf_ctrl = (flags << (ri * 4));
|
pm->pm_md.pm_ucf.pm_ucf_ctrl = (flags << (ri * 4));
|
||||||
@ -485,313 +482,6 @@ struct ucp_event_descr {
|
|||||||
|
|
||||||
#define UCP_F_CMASK 0xFF000000
|
#define UCP_F_CMASK 0xFF000000
|
||||||
|
|
||||||
static struct ucp_event_descr ucp_events[] = {
|
|
||||||
#undef UCPDESCR
|
|
||||||
#define UCPDESCR(N,EV,UM,FLAGS) { \
|
|
||||||
.ucp_ev = PMC_EV_UCP_EVENT_##N, \
|
|
||||||
.ucp_evcode = (EV), \
|
|
||||||
.ucp_umask = (UM), \
|
|
||||||
.ucp_flags = (FLAGS) \
|
|
||||||
}
|
|
||||||
|
|
||||||
UCPDESCR(00H_01H, 0x00, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(00H_02H, 0x00, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(00H_04H, 0x00, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(01H_01H, 0x01, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(01H_02H, 0x01, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(01H_04H, 0x01, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(02H_01H, 0x02, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(03H_01H, 0x03, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(03H_02H, 0x03, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(03H_04H, 0x03, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(03H_08H, 0x03, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(03H_10H, 0x03, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(03H_20H, 0x03, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(03H_40H, 0x03, 0x40, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(04H_01H, 0x04, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(04H_02H, 0x04, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(04H_04H, 0x04, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(04H_08H, 0x04, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(04H_10H, 0x04, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(05H_01H, 0x05, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(05H_02H, 0x05, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(05H_04H, 0x05, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(06H_01H, 0x06, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(06H_02H, 0x06, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(06H_04H, 0x06, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(06H_08H, 0x06, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(06H_10H, 0x06, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(06H_20H, 0x06, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(07H_01H, 0x07, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(07H_02H, 0x07, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(07H_04H, 0x07, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(07H_08H, 0x07, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(07H_10H, 0x07, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(07H_20H, 0x07, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(07H_24H, 0x07, 0x24, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(08H_01H, 0x08, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(08H_02H, 0x08, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(08H_04H, 0x08, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(08H_03H, 0x08, 0x03, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(09H_01H, 0x09, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(09H_02H, 0x09, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(09H_04H, 0x09, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(09H_03H, 0x09, 0x03, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(0AH_01H, 0x0A, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(0AH_02H, 0x0A, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(0AH_04H, 0x0A, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(0AH_08H, 0x0A, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(0AH_0FH, 0x0A, 0x0F, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(0BH_01H, 0x0B, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(0BH_02H, 0x0B, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(0BH_04H, 0x0B, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(0BH_08H, 0x0B, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(0BH_10H, 0x0B, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(0BH_1FH, 0x0B, 0x1F, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(0CH_01H, 0x0C, 0x01, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(0CH_02H, 0x0C, 0x02, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(0CH_04H_E, 0x0C, 0x04, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(0CH_04H_F, 0x0C, 0x04, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(0CH_04H_M, 0x0C, 0x04, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(0CH_04H_S, 0x0C, 0x04, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(0CH_08H_E, 0x0C, 0x08, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(0CH_08H_F, 0x0C, 0x08, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(0CH_08H_M, 0x0C, 0x08, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(0CH_08H_S, 0x0C, 0x08, UCP_F_FM | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(20H_01H, 0x20, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(20H_02H, 0x20, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(20H_04H, 0x20, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(20H_08H, 0x20, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(20H_10H, 0x20, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(20H_20H, 0x20, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(21H_01H, 0x21, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(21H_02H, 0x21, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(21H_04H, 0x21, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(22H_01H, 0x22, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM |
|
|
||||||
UCP_F_SB | UCP_F_HW),
|
|
||||||
UCPDESCR(22H_02H, 0x22, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM |
|
|
||||||
UCP_F_SB | UCP_F_HW),
|
|
||||||
UCPDESCR(22H_04H, 0x22, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM |
|
|
||||||
UCP_F_SB | UCP_F_HW),
|
|
||||||
UCPDESCR(22H_08H, 0x22, 0x08, UCP_F_FM | UCP_F_SB | UCP_F_HW),
|
|
||||||
UCPDESCR(22H_10H, 0x22, 0x10, UCP_F_FM | UCP_F_HW),
|
|
||||||
UCPDESCR(22H_20H, 0x22, 0x20, UCP_F_FM | UCP_F_SB | UCP_F_HW),
|
|
||||||
UCPDESCR(22H_40H, 0x22, 0x40, UCP_F_FM | UCP_F_SB | UCP_F_HW),
|
|
||||||
UCPDESCR(22H_80H, 0x22, 0x80, UCP_F_FM | UCP_F_SB | UCP_F_HW),
|
|
||||||
|
|
||||||
UCPDESCR(23H_01H, 0x23, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(23H_02H, 0x23, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(23H_04H, 0x23, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(24H_02H, 0x24, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(24H_04H, 0x24, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(25H_01H, 0x25, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(25H_02H, 0x25, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(25H_04H, 0x25, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(26H_01H, 0x26, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(27H_01H, 0x27, 0x01, UCP_F_FM | UCP_F_I7),
|
|
||||||
UCPDESCR(27H_02H, 0x27, 0x02, UCP_F_FM | UCP_F_I7),
|
|
||||||
UCPDESCR(27H_04H, 0x27, 0x04, UCP_F_FM | UCP_F_I7),
|
|
||||||
UCPDESCR(27H_08H, 0x27, 0x08, UCP_F_FM | UCP_F_I7),
|
|
||||||
UCPDESCR(27H_10H, 0x27, 0x10, UCP_F_FM | UCP_F_I7),
|
|
||||||
UCPDESCR(27H_20H, 0x27, 0x20, UCP_F_FM | UCP_F_I7),
|
|
||||||
|
|
||||||
UCPDESCR(28H_01H, 0x28, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(28H_02H, 0x28, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(28H_04H, 0x28, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(28H_08H, 0x28, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(28H_10H, 0x28, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(28H_20H, 0x28, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(29H_01H, 0x29, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(29H_02H, 0x29, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(29H_04H, 0x29, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(29H_08H, 0x29, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(29H_10H, 0x29, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(29H_20H, 0x29, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(2AH_01H, 0x2A, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2AH_02H, 0x2A, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2AH_04H, 0x2A, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2AH_07H, 0x2A, 0x07, UCP_F_FM | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(2BH_01H, 0x2B, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2BH_02H, 0x2B, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2BH_04H, 0x2B, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2BH_07H, 0x2B, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(2CH_01H, 0x2C, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2CH_02H, 0x2C, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2CH_04H, 0x2C, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2CH_07H, 0x2C, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(2DH_01H, 0x2D, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2DH_02H, 0x2D, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2DH_04H, 0x2D, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2DH_07H, 0x2D, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(2EH_01H, 0x2E, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2EH_02H, 0x2E, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2EH_04H, 0x2E, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2EH_07H, 0x2E, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(2FH_01H, 0x2F, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2FH_02H, 0x2F, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2FH_04H, 0x2F, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2FH_07H, 0x2F, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2FH_08H, 0x2F, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2FH_10H, 0x2F, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2FH_20H, 0x2F, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(2FH_38H, 0x2F, 0x38, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(30H_01H, 0x30, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(30H_02H, 0x30, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(30H_04H, 0x30, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(30H_07H, 0x30, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(31H_01H, 0x31, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(31H_02H, 0x31, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(31H_04H, 0x31, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(31H_07H, 0x31, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(32H_01H, 0x32, 0x01, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(32H_02H, 0x32, 0x02, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(32H_04H, 0x32, 0x04, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(32H_07H, 0x32, 0x07, UCP_F_FM | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(33H_01H, 0x33, 0x01, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(33H_02H, 0x33, 0x02, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(33H_04H, 0x33, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(33H_07H, 0x33, 0x07, UCP_F_FM | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(34H_01H, 0x34, 0x01, UCP_F_FM | UCP_F_WM | UCP_F_SB |
|
|
||||||
UCP_F_HW),
|
|
||||||
UCPDESCR(34H_02H, 0x34, 0x02, UCP_F_FM | UCP_F_WM | UCP_F_SB),
|
|
||||||
UCPDESCR(34H_04H, 0x34, 0x04, UCP_F_FM | UCP_F_WM | UCP_F_SB),
|
|
||||||
UCPDESCR(34H_06H, 0x34, 0x06, UCP_F_FM | UCP_F_HW),
|
|
||||||
UCPDESCR(34H_08H, 0x34, 0x08, UCP_F_FM | UCP_F_WM | UCP_F_SB |
|
|
||||||
UCP_F_HW),
|
|
||||||
UCPDESCR(34H_10H, 0x34, 0x10, UCP_F_FM | UCP_F_WM | UCP_F_SB |
|
|
||||||
UCP_F_HW),
|
|
||||||
UCPDESCR(34H_20H, 0x34, 0x20, UCP_F_FM | UCP_F_WM | UCP_F_SB |
|
|
||||||
UCP_F_HW),
|
|
||||||
UCPDESCR(34H_40H, 0x34, 0x40, UCP_F_FM | UCP_F_SB | UCP_F_HW),
|
|
||||||
UCPDESCR(34H_80H, 0x34, 0x80, UCP_F_FM | UCP_F_SB | UCP_F_HW),
|
|
||||||
|
|
||||||
UCPDESCR(35H_01H, 0x35, 0x01, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(35H_02H, 0x35, 0x02, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(35H_04H, 0x35, 0x04, UCP_F_FM | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(40H_01H, 0x40, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(40H_02H, 0x40, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(40H_04H, 0x40, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(40H_08H, 0x40, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(40H_10H, 0x40, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(40H_20H, 0x40, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(40H_07H, 0x40, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(40H_38H, 0x40, 0x38, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(41H_01H, 0x41, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(41H_02H, 0x41, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(41H_04H, 0x41, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(41H_08H, 0x41, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(41H_10H, 0x41, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(41H_20H, 0x41, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(41H_07H, 0x41, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(41H_38H, 0x41, 0x38, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(42H_01H, 0x42, 0x01, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(42H_02H, 0x42, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(42H_04H, 0x42, 0x04, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(42H_08H, 0x42, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(43H_01H, 0x43, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(43H_02H, 0x43, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(60H_01H, 0x60, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(60H_02H, 0x60, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(60H_04H, 0x60, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(61H_01H, 0x61, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(61H_02H, 0x61, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(61H_04H, 0x61, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(62H_01H, 0x62, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(62H_02H, 0x62, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(62H_04H, 0x62, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(63H_01H, 0x63, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(63H_02H, 0x63, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(63H_04H, 0x63, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(63H_08H, 0x63, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(63H_10H, 0x63, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(63H_20H, 0x63, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(64H_01H, 0x64, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(64H_02H, 0x64, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(64H_04H, 0x64, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(64H_08H, 0x64, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(64H_10H, 0x64, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(64H_20H, 0x64, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(65H_01H, 0x65, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(65H_02H, 0x65, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(65H_04H, 0x65, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(66H_01H, 0x66, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(66H_02H, 0x66, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
UCPDESCR(66H_04H, 0x66, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(67H_01H, 0x67, 0x01, UCP_F_FM | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(80H_01H, 0x80, 0x01, UCP_F_FM | UCP_F_WM | UCP_F_SB |
|
|
||||||
UCP_F_HW),
|
|
||||||
UCPDESCR(80H_02H, 0x80, 0x02, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(80H_04H, 0x80, 0x04, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(80H_08H, 0x80, 0x08, UCP_F_FM | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(81H_01H, 0x81, 0x01, UCP_F_FM | UCP_F_WM | UCP_F_SB |
|
|
||||||
UCP_F_HW),
|
|
||||||
UCPDESCR(81H_02H, 0x81, 0x02, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(81H_04H, 0x81, 0x04, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(81H_08H, 0x81, 0x08, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(81H_20H, 0x81, 0x20, UCP_F_FM | UCP_F_SB | UCP_F_HW),
|
|
||||||
UCPDESCR(81H_80H, 0x81, 0x80, UCP_F_FM | UCP_F_SB | UCP_F_HW),
|
|
||||||
|
|
||||||
UCPDESCR(82H_01H, 0x82, 0x01, UCP_F_FM | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(83H_01H, 0x83, 0x01, UCP_F_FM | UCP_F_WM | UCP_F_SB |
|
|
||||||
UCP_F_HW),
|
|
||||||
UCPDESCR(83H_02H, 0x83, 0x02, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(83H_04H, 0x83, 0x04, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(83H_08H, 0x83, 0x08, UCP_F_FM | UCP_F_WM),
|
|
||||||
|
|
||||||
UCPDESCR(84H_01H, 0x84, 0x01, UCP_F_FM | UCP_F_WM | UCP_F_SB |
|
|
||||||
UCP_F_HW),
|
|
||||||
UCPDESCR(84H_02H, 0x84, 0x02, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(84H_04H, 0x84, 0x04, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(84H_08H, 0x84, 0x08, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(85H_02H, 0x85, 0x02, UCP_F_FM | UCP_F_WM),
|
|
||||||
UCPDESCR(86H_01H, 0x86, 0x01, UCP_F_FM | UCP_F_WM)
|
|
||||||
};
|
|
||||||
|
|
||||||
static pmc_value_t
|
static pmc_value_t
|
||||||
ucp_perfctr_value_to_reload_count(pmc_value_t v)
|
ucp_perfctr_value_to_reload_count(pmc_value_t v)
|
||||||
{
|
{
|
||||||
@ -809,16 +499,16 @@ ucp_reload_count_to_perfctr_value(pmc_value_t rlc)
|
|||||||
* Counter specific event information for Sandybridge and Haswell
|
* Counter specific event information for Sandybridge and Haswell
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ucp_event_sb_hw_ok_on_counter(enum pmc_event pe, int ri)
|
ucp_event_sb_hw_ok_on_counter(uint8_t ev, int ri)
|
||||||
{
|
{
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
|
|
||||||
switch (pe) {
|
switch (ev) {
|
||||||
/*
|
/*
|
||||||
* Events valid only on counter 0.
|
* Events valid only on counter 0.
|
||||||
*/
|
*/
|
||||||
case PMC_EV_UCP_EVENT_80H_01H:
|
case 0x80:
|
||||||
case PMC_EV_UCP_EVENT_83H_01H:
|
case 0x83:
|
||||||
mask = (1 << 0);
|
mask = (1 << 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -833,10 +523,9 @@ static int
|
|||||||
ucp_allocate_pmc(int cpu, int ri, struct pmc *pm,
|
ucp_allocate_pmc(int cpu, int ri, struct pmc *pm,
|
||||||
const struct pmc_op_pmcallocate *a)
|
const struct pmc_op_pmcallocate *a)
|
||||||
{
|
{
|
||||||
int n;
|
uint8_t ev;
|
||||||
enum pmc_event ev;
|
uint32_t caps;
|
||||||
struct ucp_event_descr *ie;
|
const struct pmc_md_ucp_op_pmcallocate *ucp;
|
||||||
uint32_t caps, config, cpuflag, evsel;
|
|
||||||
|
|
||||||
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
|
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
|
||||||
("[uncore,%d] illegal CPU %d", __LINE__, cpu));
|
("[uncore,%d] illegal CPU %d", __LINE__, cpu));
|
||||||
@ -848,8 +537,8 @@ ucp_allocate_pmc(int cpu, int ri, struct pmc *pm,
|
|||||||
if ((UCP_PMC_CAPS & caps) != caps)
|
if ((UCP_PMC_CAPS & caps) != caps)
|
||||||
return (EPERM);
|
return (EPERM);
|
||||||
|
|
||||||
ev = pm->pm_event;
|
ucp = &a->pm_md.pm_ucp;
|
||||||
|
ev = UCP_EVSEL(ucp->pm_ucp_config);
|
||||||
switch (uncore_cputype) {
|
switch (uncore_cputype) {
|
||||||
case PMC_CPU_INTEL_HASWELL:
|
case PMC_CPU_INTEL_HASWELL:
|
||||||
case PMC_CPU_INTEL_SANDYBRIDGE:
|
case PMC_CPU_INTEL_SANDYBRIDGE:
|
||||||
@ -860,66 +549,7 @@ ucp_allocate_pmc(int cpu, int ri, struct pmc *pm,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pm->pm_md.pm_ucp.pm_ucp_evsel = ucp->pm_ucp_config | UCP_EN;
|
||||||
/*
|
|
||||||
* Look for an event descriptor with matching CPU and event id
|
|
||||||
* fields.
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (uncore_cputype) {
|
|
||||||
case PMC_CPU_INTEL_COREI7:
|
|
||||||
cpuflag = UCP_F_I7;
|
|
||||||
break;
|
|
||||||
case PMC_CPU_INTEL_HASWELL:
|
|
||||||
cpuflag = UCP_F_HW;
|
|
||||||
break;
|
|
||||||
case PMC_CPU_INTEL_SANDYBRIDGE:
|
|
||||||
cpuflag = UCP_F_SB;
|
|
||||||
break;
|
|
||||||
case PMC_CPU_INTEL_WESTMERE:
|
|
||||||
cpuflag = UCP_F_WM;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return (EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (n = 0, ie = ucp_events; n < nitems(ucp_events); n++, ie++)
|
|
||||||
if (ie->ucp_ev == ev && ie->ucp_flags & cpuflag)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (n == nitems(ucp_events))
|
|
||||||
return (EINVAL);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A matching event descriptor has been found, so start
|
|
||||||
* assembling the contents of the event select register.
|
|
||||||
*/
|
|
||||||
evsel = ie->ucp_evcode | UCP_EN;
|
|
||||||
|
|
||||||
config = a->pm_md.pm_ucp.pm_ucp_config & ~UCP_F_CMASK;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the event uses a fixed umask value, reject any umask
|
|
||||||
* bits set by the user.
|
|
||||||
*/
|
|
||||||
if (ie->ucp_flags & UCP_F_FM) {
|
|
||||||
|
|
||||||
if (UCP_UMASK(config) != 0)
|
|
||||||
return (EINVAL);
|
|
||||||
|
|
||||||
evsel |= (ie->ucp_umask << 8);
|
|
||||||
|
|
||||||
} else
|
|
||||||
return (EINVAL);
|
|
||||||
|
|
||||||
if (caps & PMC_CAP_THRESHOLD)
|
|
||||||
evsel |= (a->pm_md.pm_ucp.pm_ucp_config & UCP_F_CMASK);
|
|
||||||
if (caps & PMC_CAP_EDGE)
|
|
||||||
evsel |= UCP_EDGE;
|
|
||||||
if (caps & PMC_CAP_INVERT)
|
|
||||||
evsel |= UCP_INV;
|
|
||||||
|
|
||||||
pm->pm_md.pm_ucp.pm_ucp_evsel = evsel;
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -1074,7 +704,6 @@ ucp_start_pmc(int cpu, int ri)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
wrmsr(SELECTSEL(uncore_cputype) + ri, evsel);
|
wrmsr(SELECTSEL(uncore_cputype) + ri, evsel);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -56,7 +56,6 @@ struct pmc_md_ucp_op_pmcallocate {
|
|||||||
#define UCP_EN (1 << 22)
|
#define UCP_EN (1 << 22)
|
||||||
#define UCP_INV (1 << 23)
|
#define UCP_INV (1 << 23)
|
||||||
#define UCP_CMASK(C) (((C) & 0xFF) << 24)
|
#define UCP_CMASK(C) (((C) & 0xFF) << 24)
|
||||||
|
|
||||||
#ifdef _KERNEL
|
#ifdef _KERNEL
|
||||||
|
|
||||||
#define DCTL_FLAG_UNC_PMI (1ULL << 13)
|
#define DCTL_FLAG_UNC_PMI (1ULL << 13)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -57,9 +57,6 @@ struct pmc_mdep;
|
|||||||
|
|
||||||
#include <dev/hwpmc/hwpmc_amd.h> /* K7 and K8 */
|
#include <dev/hwpmc/hwpmc_amd.h> /* K7 and K8 */
|
||||||
#include <dev/hwpmc/hwpmc_core.h>
|
#include <dev/hwpmc/hwpmc_core.h>
|
||||||
#include <dev/hwpmc/hwpmc_piv.h>
|
|
||||||
#include <dev/hwpmc/hwpmc_ppro.h>
|
|
||||||
#include <dev/hwpmc/hwpmc_pentium.h>
|
|
||||||
#include <dev/hwpmc/hwpmc_tsc.h>
|
#include <dev/hwpmc/hwpmc_tsc.h>
|
||||||
#include <dev/hwpmc/hwpmc_uncore.h>
|
#include <dev/hwpmc/hwpmc_uncore.h>
|
||||||
|
|
||||||
@ -71,9 +68,6 @@ struct pmc_mdep;
|
|||||||
#define PMC_MDEP_CLASS_INDEX_TSC 1
|
#define PMC_MDEP_CLASS_INDEX_TSC 1
|
||||||
#define PMC_MDEP_CLASS_INDEX_K7 2
|
#define PMC_MDEP_CLASS_INDEX_K7 2
|
||||||
#define PMC_MDEP_CLASS_INDEX_K8 2
|
#define PMC_MDEP_CLASS_INDEX_K8 2
|
||||||
#define PMC_MDEP_CLASS_INDEX_P4 2
|
|
||||||
#define PMC_MDEP_CLASS_INDEX_P5 2
|
|
||||||
#define PMC_MDEP_CLASS_INDEX_P6 2
|
|
||||||
#define PMC_MDEP_CLASS_INDEX_IAP 2
|
#define PMC_MDEP_CLASS_INDEX_IAP 2
|
||||||
#define PMC_MDEP_CLASS_INDEX_IAF 3
|
#define PMC_MDEP_CLASS_INDEX_IAF 3
|
||||||
#define PMC_MDEP_CLASS_INDEX_UCP 4
|
#define PMC_MDEP_CLASS_INDEX_UCP 4
|
||||||
@ -89,9 +83,6 @@ union pmc_md_op_pmcallocate {
|
|||||||
struct pmc_md_iap_op_pmcallocate pm_iap;
|
struct pmc_md_iap_op_pmcallocate pm_iap;
|
||||||
struct pmc_md_ucf_op_pmcallocate pm_ucf;
|
struct pmc_md_ucf_op_pmcallocate pm_ucf;
|
||||||
struct pmc_md_ucp_op_pmcallocate pm_ucp;
|
struct pmc_md_ucp_op_pmcallocate pm_ucp;
|
||||||
struct pmc_md_p4_op_pmcallocate pm_p4;
|
|
||||||
struct pmc_md_pentium_op_pmcallocate pm_pentium;
|
|
||||||
struct pmc_md_ppro_op_pmcallocate pm_ppro;
|
|
||||||
uint64_t __pad[4];
|
uint64_t __pad[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -108,9 +99,6 @@ union pmc_md_pmc {
|
|||||||
struct pmc_md_iap_pmc pm_iap;
|
struct pmc_md_iap_pmc pm_iap;
|
||||||
struct pmc_md_ucf_pmc pm_ucf;
|
struct pmc_md_ucf_pmc pm_ucf;
|
||||||
struct pmc_md_ucp_pmc pm_ucp;
|
struct pmc_md_ucp_pmc pm_ucp;
|
||||||
struct pmc_md_p4_pmc pm_p4;
|
|
||||||
struct pmc_md_pentium_pmc pm_pentium;
|
|
||||||
struct pmc_md_ppro_pmc pm_ppro;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pmc;
|
struct pmc;
|
||||||
|
@ -13,7 +13,7 @@ SRCS+= hwpmc_arm64.c hwpmc_arm64_md.c
|
|||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if ${MACHINE_CPUARCH} == "amd64"
|
.if ${MACHINE_CPUARCH} == "amd64"
|
||||||
SRCS+= hwpmc_amd.c hwpmc_core.c hwpmc_intel.c hwpmc_piv.c hwpmc_tsc.c
|
SRCS+= hwpmc_amd.c hwpmc_core.c hwpmc_intel.c hwpmc_tsc.c
|
||||||
SRCS+= hwpmc_x86.c hwpmc_uncore.c
|
SRCS+= hwpmc_x86.c hwpmc_uncore.c
|
||||||
SRCS+= device_if.h bus_if.h
|
SRCS+= device_if.h bus_if.h
|
||||||
.endif
|
.endif
|
||||||
@ -23,8 +23,8 @@ SRCS+= hwpmc_arm.c
|
|||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if ${MACHINE_CPUARCH} == "i386"
|
.if ${MACHINE_CPUARCH} == "i386"
|
||||||
SRCS+= hwpmc_amd.c hwpmc_core.c hwpmc_intel.c hwpmc_piv.c hwpmc_ppro.c
|
SRCS+= hwpmc_amd.c hwpmc_core.c hwpmc_intel.c
|
||||||
SRCS+= hwpmc_pentium.c hwpmc_tsc.c hwpmc_x86.c hwpmc_uncore.c
|
SRCS+= hwpmc_tsc.c hwpmc_x86.c hwpmc_uncore.c
|
||||||
SRCS+= device_if.h bus_if.h
|
SRCS+= device_if.h bus_if.h
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user