1e829eb6dSJoseph Koshy /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni *
4e829eb6dSJoseph Koshy * Copyright (c) 2008 Joseph Koshy
5e829eb6dSJoseph Koshy * All rights reserved.
6e829eb6dSJoseph Koshy *
7e829eb6dSJoseph Koshy * Redistribution and use in source and binary forms, with or without
8e829eb6dSJoseph Koshy * modification, are permitted provided that the following conditions
9e829eb6dSJoseph Koshy * are met:
10e829eb6dSJoseph Koshy * 1. Redistributions of source code must retain the above copyright
11e829eb6dSJoseph Koshy * notice, this list of conditions and the following disclaimer.
12e829eb6dSJoseph Koshy * 2. Redistributions in binary form must reproduce the above copyright
13e829eb6dSJoseph Koshy * notice, this list of conditions and the following disclaimer in the
14e829eb6dSJoseph Koshy * documentation and/or other materials provided with the distribution.
15e829eb6dSJoseph Koshy *
16e829eb6dSJoseph Koshy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17e829eb6dSJoseph Koshy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18e829eb6dSJoseph Koshy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19e829eb6dSJoseph Koshy * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20e829eb6dSJoseph Koshy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21e829eb6dSJoseph Koshy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22e829eb6dSJoseph Koshy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23e829eb6dSJoseph Koshy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24e829eb6dSJoseph Koshy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25e829eb6dSJoseph Koshy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26e829eb6dSJoseph Koshy * SUCH DAMAGE.
27e829eb6dSJoseph Koshy */
28e829eb6dSJoseph Koshy
29e829eb6dSJoseph Koshy /*
30e829eb6dSJoseph Koshy * Common code for handling Intel CPUs.
31e829eb6dSJoseph Koshy */
32e829eb6dSJoseph Koshy
33e829eb6dSJoseph Koshy #include <sys/param.h>
34e829eb6dSJoseph Koshy #include <sys/pmc.h>
35e829eb6dSJoseph Koshy #include <sys/pmckern.h>
36e829eb6dSJoseph Koshy #include <sys/systm.h>
37e829eb6dSJoseph Koshy
38e829eb6dSJoseph Koshy #include <machine/cpu.h>
395113aa0aSJung-uk Kim #include <machine/cputypes.h>
40e829eb6dSJoseph Koshy #include <machine/md_var.h>
41e829eb6dSJoseph Koshy #include <machine/specialreg.h>
42e829eb6dSJoseph Koshy
43e829eb6dSJoseph Koshy static int
intel_switch_in(struct pmc_cpu * pc,struct pmc_process * pp)44e829eb6dSJoseph Koshy intel_switch_in(struct pmc_cpu *pc, struct pmc_process *pp)
45e829eb6dSJoseph Koshy {
46e829eb6dSJoseph Koshy (void) pc;
47e829eb6dSJoseph Koshy
484a3690dfSJohn Baldwin PMCDBG3(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp,
49e829eb6dSJoseph Koshy pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS);
50e829eb6dSJoseph Koshy
51e829eb6dSJoseph Koshy /* allow the RDPMC instruction if needed */
52e829eb6dSJoseph Koshy if (pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS)
53e829eb6dSJoseph Koshy load_cr4(rcr4() | CR4_PCE);
54e829eb6dSJoseph Koshy
554a3690dfSJohn Baldwin PMCDBG1(MDP,SWI,1, "cr4=0x%jx", (uintmax_t) rcr4());
56e829eb6dSJoseph Koshy
57e829eb6dSJoseph Koshy return 0;
58e829eb6dSJoseph Koshy }
59e829eb6dSJoseph Koshy
60e829eb6dSJoseph Koshy static int
intel_switch_out(struct pmc_cpu * pc,struct pmc_process * pp)61e829eb6dSJoseph Koshy intel_switch_out(struct pmc_cpu *pc, struct pmc_process *pp)
62e829eb6dSJoseph Koshy {
63e829eb6dSJoseph Koshy (void) pc;
64e829eb6dSJoseph Koshy (void) pp; /* can be NULL */
65e829eb6dSJoseph Koshy
664a3690dfSJohn Baldwin PMCDBG3(MDP,SWO,1, "pc=%p pp=%p cr4=0x%jx", pc, pp,
67e829eb6dSJoseph Koshy (uintmax_t) rcr4());
68e829eb6dSJoseph Koshy
69e829eb6dSJoseph Koshy /* always turn off the RDPMC instruction */
70e829eb6dSJoseph Koshy load_cr4(rcr4() & ~CR4_PCE);
71e829eb6dSJoseph Koshy
72e829eb6dSJoseph Koshy return 0;
73e829eb6dSJoseph Koshy }
74e829eb6dSJoseph Koshy
75e829eb6dSJoseph Koshy struct pmc_mdep *
pmc_intel_initialize(void)76e829eb6dSJoseph Koshy pmc_intel_initialize(void)
77e829eb6dSJoseph Koshy {
78e829eb6dSJoseph Koshy struct pmc_mdep *pmc_mdep;
79e829eb6dSJoseph Koshy enum pmc_cputype cputype;
80ef013ceeSRyan Moeller int error, family, model, nclasses, ncpus, stepping, verov;
81e829eb6dSJoseph Koshy
825113aa0aSJung-uk Kim KASSERT(cpu_vendor_id == CPU_VENDOR_INTEL,
83e829eb6dSJoseph Koshy ("[intel,%d] Initializing non-intel processor", __LINE__));
84e829eb6dSJoseph Koshy
854a3690dfSJohn Baldwin PMCDBG1(MDP,INI,0, "intel-initialize cpuid=0x%x", cpu_id);
86e829eb6dSJoseph Koshy
87e829eb6dSJoseph Koshy cputype = -1;
88e829eb6dSJoseph Koshy nclasses = 2;
89e1bd42c2SDavide Italiano error = 0;
90026346c8SAttilio Rao verov = 0;
91ef013ceeSRyan Moeller family = CPUID_TO_FAMILY(cpu_id);
92ef013ceeSRyan Moeller model = CPUID_TO_MODEL(cpu_id);
93ef013ceeSRyan Moeller stepping = CPUID_TO_STEPPING(cpu_id);
940cfab8ddSJoseph Koshy
951791cad0SAlexander Motin snprintf(pmc_cpuid, sizeof(pmc_cpuid), "GenuineIntel-%d-%02X-%X",
96ef013ceeSRyan Moeller family, model, stepping);
97ef013ceeSRyan Moeller
98e829eb6dSJoseph Koshy switch (cpu_id & 0xF00) {
99ca43b2aeSMitchell Horne case 0x600:
1000cfab8ddSJoseph Koshy switch (model) {
1010cfab8ddSJoseph Koshy case 0xE:
1020cfab8ddSJoseph Koshy cputype = PMC_CPU_INTEL_CORE;
1030cfab8ddSJoseph Koshy break;
1040cfab8ddSJoseph Koshy case 0xF:
105026346c8SAttilio Rao /* Per Intel document 315338-020. */
106026346c8SAttilio Rao if (stepping == 0x7) {
107026346c8SAttilio Rao cputype = PMC_CPU_INTEL_CORE;
108026346c8SAttilio Rao verov = 1;
109026346c8SAttilio Rao } else {
1100cfab8ddSJoseph Koshy cputype = PMC_CPU_INTEL_CORE2;
1110cfab8ddSJoseph Koshy nclasses = 3;
112026346c8SAttilio Rao }
1130cfab8ddSJoseph Koshy break;
1140cfab8ddSJoseph Koshy case 0x17:
1150cfab8ddSJoseph Koshy cputype = PMC_CPU_INTEL_CORE2EXTREME;
1160cfab8ddSJoseph Koshy nclasses = 3;
1170cfab8ddSJoseph Koshy break;
118597979c4SJeff Roberson case 0x1A:
1194b226201SSean Bruno case 0x1E: /*
1204b226201SSean Bruno * Per Intel document 253669-032 9/2009,
1214b226201SSean Bruno * pages A-2 and A-57
1224b226201SSean Bruno */
1234b226201SSean Bruno case 0x1F: /*
1244b226201SSean Bruno * Per Intel document 253669-032 9/2009,
1254b226201SSean Bruno * pages A-2 and A-57
1264b226201SSean Bruno */
127597979c4SJeff Roberson cputype = PMC_CPU_INTEL_COREI7;
1281fa7f10bSFabien Thomas nclasses = 5;
1291fa7f10bSFabien Thomas break;
13049fe48abSKonstantin Belousov case 0x2E:
13149fe48abSKonstantin Belousov cputype = PMC_CPU_INTEL_NEHALEM_EX;
13249fe48abSKonstantin Belousov nclasses = 3;
13349fe48abSKonstantin Belousov break;
1341fa7f10bSFabien Thomas case 0x25: /* Per Intel document 253669-033US 12/2009. */
1351fa7f10bSFabien Thomas case 0x2C: /* Per Intel document 253669-033US 12/2009. */
1361fa7f10bSFabien Thomas cputype = PMC_CPU_INTEL_WESTMERE;
1371fa7f10bSFabien Thomas nclasses = 5;
138597979c4SJeff Roberson break;
13949fe48abSKonstantin Belousov case 0x2F: /* Westmere-EX, seen in wild */
14049fe48abSKonstantin Belousov cputype = PMC_CPU_INTEL_WESTMERE_EX;
14149fe48abSKonstantin Belousov nclasses = 3;
14249fe48abSKonstantin Belousov break;
14378d763a2SDavide Italiano case 0x2A: /* Per Intel document 253669-039US 05/2011. */
14478d763a2SDavide Italiano cputype = PMC_CPU_INTEL_SANDYBRIDGE;
1454f35e8cbSMitchell Horne nclasses = 3;
14678d763a2SDavide Italiano break;
147fabe02f5SSean Bruno case 0x2D: /* Per Intel document 253669-044US 08/2012. */
148fabe02f5SSean Bruno cputype = PMC_CPU_INTEL_SANDYBRIDGE_XEON;
149fabe02f5SSean Bruno nclasses = 3;
150fabe02f5SSean Bruno break;
1511e862e5aSFabien Thomas case 0x3A: /* Per Intel document 253669-043US 05/2012. */
1521e862e5aSFabien Thomas cputype = PMC_CPU_INTEL_IVYBRIDGE;
1531e862e5aSFabien Thomas nclasses = 3;
1541e862e5aSFabien Thomas break;
1553f929d8cSSean Bruno case 0x3E: /* Per Intel document 325462-045US 01/2013. */
1563f929d8cSSean Bruno cputype = PMC_CPU_INTEL_IVYBRIDGE_XEON;
1573f929d8cSSean Bruno nclasses = 3;
1583f929d8cSSean Bruno break;
159fe109d31SAlexander Motin case 0x3D:
160fe109d31SAlexander Motin case 0x47:
161fe109d31SAlexander Motin cputype = PMC_CPU_INTEL_BROADWELL;
162fe109d31SAlexander Motin nclasses = 3;
163fe109d31SAlexander Motin break;
164fe109d31SAlexander Motin case 0x4f:
165fe109d31SAlexander Motin case 0x56:
166fe109d31SAlexander Motin cputype = PMC_CPU_INTEL_BROADWELL_XEON;
167fe109d31SAlexander Motin nclasses = 3;
168fe109d31SAlexander Motin break;
169fe109d31SAlexander Motin case 0x3C: /* Per Intel document 325462-045US 01/2013. */
170fe109d31SAlexander Motin case 0x45: /* Per Intel document 325462-045US 09/2014. */
171fe109d31SAlexander Motin cputype = PMC_CPU_INTEL_HASWELL;
172fe109d31SAlexander Motin nclasses = 3;
173fe109d31SAlexander Motin break;
174fe109d31SAlexander Motin case 0x3F: /* Per Intel document 325462-045US 09/2014. */
175fe109d31SAlexander Motin case 0x46: /* Per Intel document 325462-045US 09/2014. */
176fe109d31SAlexander Motin /* Should 46 be XEON. probably its own? */
177fe109d31SAlexander Motin cputype = PMC_CPU_INTEL_HASWELL_XEON;
178fe109d31SAlexander Motin nclasses = 3;
179fe109d31SAlexander Motin break;
18007ff05c2SRuslan Bukin /* Skylake */
181f19bae41SRandall Stewart case 0x4e:
182f19bae41SRandall Stewart case 0x5e:
18307ff05c2SRuslan Bukin /* Kabylake */
18407ff05c2SRuslan Bukin case 0x8E: /* Per Intel document 325462-063US July 2017. */
18507ff05c2SRuslan Bukin case 0x9E: /* Per Intel document 325462-063US July 2017. */
186913c07a0SAlexander Motin /* Cometlake */
187913c07a0SAlexander Motin case 0xA5:
188913c07a0SAlexander Motin case 0xA6:
189f19bae41SRandall Stewart cputype = PMC_CPU_INTEL_SKYLAKE;
190f19bae41SRandall Stewart nclasses = 3;
191f19bae41SRandall Stewart break;
192b99b705dSKonstantin Belousov case 0x55: /* SDM rev 63 */
193b99b705dSKonstantin Belousov cputype = PMC_CPU_INTEL_SKYLAKE_XEON;
194b99b705dSKonstantin Belousov nclasses = 3;
195b99b705dSKonstantin Belousov break;
196913c07a0SAlexander Motin /* Icelake */
197913c07a0SAlexander Motin case 0x7D:
198913c07a0SAlexander Motin case 0x7E:
199913c07a0SAlexander Motin /* Tigerlake */
200913c07a0SAlexander Motin case 0x8C:
201913c07a0SAlexander Motin case 0x8D:
202913c07a0SAlexander Motin /* Rocketlake */
203913c07a0SAlexander Motin case 0xA7:
204913c07a0SAlexander Motin cputype = PMC_CPU_INTEL_ICELAKE;
205913c07a0SAlexander Motin nclasses = 3;
206913c07a0SAlexander Motin break;
207913c07a0SAlexander Motin case 0x6A:
208913c07a0SAlexander Motin case 0x6C:
209913c07a0SAlexander Motin cputype = PMC_CPU_INTEL_ICELAKE_XEON;
210913c07a0SAlexander Motin nclasses = 3;
211913c07a0SAlexander Motin break;
212fe109d31SAlexander Motin case 0x97:
213fe109d31SAlexander Motin case 0x9A:
214fe109d31SAlexander Motin cputype = PMC_CPU_INTEL_ALDERLAKE;
2154f35e8cbSMitchell Horne nclasses = 3;
216cc0c1555SSean Bruno break;
21713260178SAlexander Motin case 0x1C: /* Per Intel document 320047-002. */
21813260178SAlexander Motin case 0x26:
21913260178SAlexander Motin case 0x27:
22013260178SAlexander Motin case 0x35:
22113260178SAlexander Motin case 0x36:
22213260178SAlexander Motin cputype = PMC_CPU_INTEL_ATOM;
22313260178SAlexander Motin nclasses = 3;
22413260178SAlexander Motin break;
225d852f79bSKonstantin Belousov case 0x37:
226d852f79bSKonstantin Belousov case 0x4A:
227e8f021a3SHiren Panchasara case 0x4D: /* Per Intel document 330061-001 01/2014. */
228d852f79bSKonstantin Belousov case 0x5A:
229d852f79bSKonstantin Belousov case 0x5D:
230e8f021a3SHiren Panchasara cputype = PMC_CPU_INTEL_ATOM_SILVERMONT;
231e8f021a3SHiren Panchasara nclasses = 3;
232e8f021a3SHiren Panchasara break;
2338e6d2a15SMarcin Wojtas case 0x5C: /* Per Intel document 325462-071US 10/2019. */
234bbdddb80SAlexander Motin case 0x5F:
2358e6d2a15SMarcin Wojtas cputype = PMC_CPU_INTEL_ATOM_GOLDMONT;
2368e6d2a15SMarcin Wojtas nclasses = 3;
2378e6d2a15SMarcin Wojtas break;
23813260178SAlexander Motin case 0x7A:
23913260178SAlexander Motin cputype = PMC_CPU_INTEL_ATOM_GOLDMONT_P;
24013260178SAlexander Motin nclasses = 3;
24113260178SAlexander Motin break;
24213260178SAlexander Motin case 0x86:
24313260178SAlexander Motin case 0x96:
24413260178SAlexander Motin cputype = PMC_CPU_INTEL_ATOM_TREMONT;
24513260178SAlexander Motin nclasses = 3;
24613260178SAlexander Motin break;
247e829eb6dSJoseph Koshy }
248e829eb6dSJoseph Koshy break;
249e829eb6dSJoseph Koshy }
250e92a1350SMatt Macy
251e829eb6dSJoseph Koshy
252e829eb6dSJoseph Koshy if ((int) cputype == -1) {
253e829eb6dSJoseph Koshy printf("pmc: Unknown Intel CPU.\n");
254e829eb6dSJoseph Koshy return (NULL);
255e829eb6dSJoseph Koshy }
256e829eb6dSJoseph Koshy
257f5f9340bSFabien Thomas /* Allocate base class and initialize machine dependent struct */
258f5f9340bSFabien Thomas pmc_mdep = pmc_mdep_alloc(nclasses);
259e829eb6dSJoseph Koshy
260e829eb6dSJoseph Koshy pmc_mdep->pmd_cputype = cputype;
261e829eb6dSJoseph Koshy pmc_mdep->pmd_switch_in = intel_switch_in;
262e829eb6dSJoseph Koshy pmc_mdep->pmd_switch_out = intel_switch_out;
263e829eb6dSJoseph Koshy
264e829eb6dSJoseph Koshy ncpus = pmc_cpu_max();
2651c12d03fSDavide Italiano error = pmc_tsc_initialize(pmc_mdep, ncpus);
2661c12d03fSDavide Italiano if (error)
2671c12d03fSDavide Italiano goto error;
268fe109d31SAlexander Motin
2698399d923SMitchell Horne MPASS(nclasses >= PMC_MDEP_CLASS_INDEX_IAF);
270026346c8SAttilio Rao error = pmc_core_initialize(pmc_mdep, ncpus, verov);
2711c12d03fSDavide Italiano if (error) {
2721c12d03fSDavide Italiano pmc_tsc_finalize(pmc_mdep);
273ef902782SOleksandr Tymoshenko goto error;
2741c12d03fSDavide Italiano }
275ef902782SOleksandr Tymoshenko
2761fa7f10bSFabien Thomas /*
2771fa7f10bSFabien Thomas * Init the uncore class.
2781fa7f10bSFabien Thomas */
2791fa7f10bSFabien Thomas switch (cputype) {
2801fa7f10bSFabien Thomas /*
2811fa7f10bSFabien Thomas * Intel Corei7 and Westmere processors.
2821fa7f10bSFabien Thomas */
2831fa7f10bSFabien Thomas case PMC_CPU_INTEL_COREI7:
2841fa7f10bSFabien Thomas case PMC_CPU_INTEL_WESTMERE:
2854f35e8cbSMitchell Horne #ifdef notyet
2864f35e8cbSMitchell Horne /*
2874f35e8cbSMitchell Horne * TODO: re-enable uncore class on these processors.
2884f35e8cbSMitchell Horne *
2894f35e8cbSMitchell Horne * The uncore unit was reworked beginning with Sandy Bridge, including
2904f35e8cbSMitchell Horne * the MSRs required to program it. In particular, we need to:
2914f35e8cbSMitchell Horne * - Parse the MSR_UNC_CBO_CONFIG MSR for number of C-box units in the
2924f35e8cbSMitchell Horne * system
2934f35e8cbSMitchell Horne * - Support reading and writing to ARB and C-box units, depending on
2944f35e8cbSMitchell Horne * the requested event
2954f35e8cbSMitchell Horne * - Create some kind of mapping between C-box <--> CPU
2964f35e8cbSMitchell Horne *
2974f35e8cbSMitchell Horne * Also TODO: support other later changes to these interfaces, to
2984f35e8cbSMitchell Horne * enable the uncore class on generations newer than Broadwell.
2994f35e8cbSMitchell Horne * Skylake+ appears to use newer addresses for the uncore MSRs.
3004f35e8cbSMitchell Horne */
3014f35e8cbSMitchell Horne case PMC_CPU_INTEL_HASWELL:
302bc346409SRui Paulo case PMC_CPU_INTEL_BROADWELL:
3034f35e8cbSMitchell Horne case PMC_CPU_INTEL_SANDYBRIDGE:
3044f35e8cbSMitchell Horne #endif
3058399d923SMitchell Horne MPASS(nclasses >= PMC_MDEP_CLASS_INDEX_UCF);
3061fa7f10bSFabien Thomas error = pmc_uncore_initialize(pmc_mdep, ncpus);
3071fa7f10bSFabien Thomas break;
3081fa7f10bSFabien Thomas default:
3091fa7f10bSFabien Thomas break;
3101fa7f10bSFabien Thomas }
311e829eb6dSJoseph Koshy error:
312e829eb6dSJoseph Koshy if (error) {
313e1bd42c2SDavide Italiano pmc_mdep_free(pmc_mdep);
314e829eb6dSJoseph Koshy pmc_mdep = NULL;
315e829eb6dSJoseph Koshy }
316e829eb6dSJoseph Koshy
317e829eb6dSJoseph Koshy return (pmc_mdep);
318e829eb6dSJoseph Koshy }
319e829eb6dSJoseph Koshy
320e829eb6dSJoseph Koshy void
pmc_intel_finalize(struct pmc_mdep * md)321e829eb6dSJoseph Koshy pmc_intel_finalize(struct pmc_mdep *md)
322e829eb6dSJoseph Koshy {
323e829eb6dSJoseph Koshy pmc_tsc_finalize(md);
324e829eb6dSJoseph Koshy
3250cfab8ddSJoseph Koshy pmc_core_finalize(md);
3261fa7f10bSFabien Thomas
3271fa7f10bSFabien Thomas /*
3281fa7f10bSFabien Thomas * Uncore.
3291fa7f10bSFabien Thomas */
3301fa7f10bSFabien Thomas switch (md->pmd_cputype) {
3311fa7f10bSFabien Thomas case PMC_CPU_INTEL_COREI7:
3321fa7f10bSFabien Thomas case PMC_CPU_INTEL_WESTMERE:
3334f35e8cbSMitchell Horne #ifdef notyet
3344f35e8cbSMitchell Horne case PMC_CPU_INTEL_HASWELL:
3354f35e8cbSMitchell Horne case PMC_CPU_INTEL_BROADWELL:
3364f35e8cbSMitchell Horne case PMC_CPU_INTEL_SANDYBRIDGE:
3374f35e8cbSMitchell Horne #endif
3381fa7f10bSFabien Thomas pmc_uncore_finalize(md);
3391fa7f10bSFabien Thomas break;
3401fa7f10bSFabien Thomas default:
3411fa7f10bSFabien Thomas break;
3421fa7f10bSFabien Thomas }
343e829eb6dSJoseph Koshy }
344