2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2003-2007 Joseph Koshy
5 * Copyright (c) 2007 The FreeBSD Foundation
8 * Portions of this software were developed by A. Joseph Koshy under
9 * sponsorship from the FreeBSD Foundation and Google, Inc.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
36 #include <sys/param.h>
39 #include <sys/mutex.h>
41 #include <sys/pmckern.h>
43 #include <sys/systm.h>
44 #include <machine/intr_machdep.h>
45 #if (__FreeBSD_version >= 1100000)
46 #include <x86/apicvar.h>
48 #include <machine/apicvar.h>
50 #include <machine/cpu.h>
51 #include <machine/cpufunc.h>
52 #include <machine/cputypes.h>
53 #include <machine/md_var.h>
54 #include <machine/specialreg.h>
59 * The P4 has 18 PMCs, divided into 4 groups with 4,4,4 and 6 PMCs
60 * respectively. Each PMC comprises of two model specific registers:
61 * a counter configuration control register (CCCR) and a counter
62 * register that holds the actual event counts.
64 * Configuring an event requires the use of one of 45 event selection
65 * control registers (ESCR). Events are associated with specific
66 * ESCRs. Each PMC group has a set of ESCRs it can use.
68 * - The BPU counter group (4 PMCs) can use the 16 ESCRs:
69 * BPU_ESCR{0,1}, IS_ESCR{0,1}, MOB_ESCR{0,1}, ITLB_ESCR{0,1},
70 * PMH_ESCR{0,1}, IX_ESCR{0,1}, FSB_ESCR{0,}, BSU_ESCR{0,1}.
72 * - The MS counter group (4 PMCs) can use the 6 ESCRs: MS_ESCR{0,1},
73 * TC_ESCR{0,1}, TBPU_ESCR{0,1}.
75 * - The FLAME counter group (4 PMCs) can use the 10 ESCRs:
76 * FLAME_ESCR{0,1}, FIRM_ESCR{0,1}, SAAT_ESCR{0,1}, U2L_ESCR{0,1},
79 * - The IQ counter group (6 PMCs) can use the 13 ESCRs: IQ_ESCR{0,1},
80 * ALF_ESCR{0,1}, RAT_ESCR{0,1}, SSU_ESCR0, CRU_ESCR{0,1,2,3,4,5}.
82 * Even-numbered ESCRs can be used with counters 0, 1 and 4 (if
83 * present) of a counter group. Odd-numbers ESCRs can be used with
84 * counters 2, 3 and 5 (if present) of a counter group. The
85 * 'p4_escrs[]' table describes these restrictions in a form that
86 * function 'p4_allocate()' uses for making allocation decisions.
88 * SYSTEM-MODE AND THREAD-MODE ALLOCATION
90 * In addition to remembering the state of PMC rows
91 * ('FREE','STANDALONE', or 'THREAD'), we similar need to track the
92 * state of ESCR rows. If an ESCR is allocated to a system-mode PMC
93 * on a CPU we cannot allocate this to a thread-mode PMC. On a
94 * multi-cpu (multiple physical CPUs) system, ESCR allocation on each
95 * CPU is tracked by the pc_escrs[] array.
97 * Each system-mode PMC that is using an ESCR records its row-index in
98 * the appropriate entry and system-mode allocation attempts check
99 * that an ESCR is available using this array. Process-mode PMCs do
100 * not use the pc_escrs[] array, since ESCR row itself would have been
101 * marked as in 'THREAD' mode.
103 * HYPERTHREADING SUPPORT
105 * When HTT is enabled, the FreeBSD kernel treats the two 'logical'
106 * cpus as independent CPUs and can schedule kernel threads on them
107 * independently. However, the two logical CPUs share the same set of
108 * PMC resources. We need to ensure that:
109 * - PMCs that use the PMC_F_DESCENDANTS semantics are handled correctly,
111 * - Threads of multi-threaded processes that get scheduled on the same
112 * physical CPU are handled correctly.
116 * Not all HTT capable systems will have HTT enabled. We detect the
117 * presence of HTT by detecting if 'p4_init()' was called for a secondary
120 * Note that hwpmc(4) cannot currently deal with a change in HTT status once
123 * Handling HTT READ / WRITE / START / STOP
125 * PMC resources are shared across the CPUs in an HTT pair. We
126 * designate the lower numbered CPU in a HTT pair as the 'primary'
127 * CPU. In each primary CPU's state we keep track of a 'runcount'
128 * which reflects the number of PMC-using processes that have been
129 * scheduled on its secondary CPU. Process-mode PMC operations will
130 * actually 'start' or 'stop' hardware only if these are the first or
131 * last processes respectively to use the hardware. PMC values
132 * written by a 'write' operation are saved and are transferred to
133 * hardware at PMC 'start' time if the runcount is 0. If the runcount
134 * is greater than 0 at the time of a 'start' operation, we keep track
135 * of the actual hardware value at the time of the 'start' operation
136 * and use this to adjust the final readings at PMC 'stop' or 'read'
139 * Execution sequences:
141 * Case 1: CPUx +...- (no overlap)
145 * Case 2: CPUx +........- (partial overlap)
149 * Case 3: CPUx +..............- (fully overlapped)
154 * 'CPU[xy]' : one of the two logical processors on a HTT CPU.
155 * 'RC' : run count (#threads per physical core).
156 * '+' : point in time when a thread is put on a CPU.
157 * '-' : point in time where a thread is taken off a CPU.
159 * Handling HTT CONFIG
161 * Different processes attached to the same PMC may get scheduled on
162 * the two logical processors in the package. We keep track of config
163 * and de-config operations using the CFGFLAGS fields of the per-physical
168 P4_PMC(BPU_COUNTER0) \
169 P4_PMC(BPU_COUNTER1) \
170 P4_PMC(BPU_COUNTER2) \
171 P4_PMC(BPU_COUNTER3) \
172 P4_PMC(MS_COUNTER0) \
173 P4_PMC(MS_COUNTER1) \
174 P4_PMC(MS_COUNTER2) \
175 P4_PMC(MS_COUNTER3) \
176 P4_PMC(FLAME_COUNTER0) \
177 P4_PMC(FLAME_COUNTER1) \
178 P4_PMC(FLAME_COUNTER2) \
179 P4_PMC(FLAME_COUNTER3) \
180 P4_PMC(IQ_COUNTER0) \
181 P4_PMC(IQ_COUNTER1) \
182 P4_PMC(IQ_COUNTER2) \
183 P4_PMC(IQ_COUNTER3) \
184 P4_PMC(IQ_COUNTER4) \
185 P4_PMC(IQ_COUNTER5) \
190 #define P4_PMC(N) P4_PMC_##N ,
195 * P4 ESCR descriptors
199 P4_ESCR(BSU_ESCR0, 0x3A0, BPU_COUNTER0, BPU_COUNTER1, NONE) \
200 P4_ESCR(BSU_ESCR1, 0x3A1, BPU_COUNTER2, BPU_COUNTER3, NONE) \
201 P4_ESCR(FSB_ESCR0, 0x3A2, BPU_COUNTER0, BPU_COUNTER1, NONE) \
202 P4_ESCR(FSB_ESCR1, 0x3A3, BPU_COUNTER2, BPU_COUNTER3, NONE) \
203 P4_ESCR(FIRM_ESCR0, 0x3A4, FLAME_COUNTER0, FLAME_COUNTER1, NONE) \
204 P4_ESCR(FIRM_ESCR1, 0x3A5, FLAME_COUNTER2, FLAME_COUNTER3, NONE) \
205 P4_ESCR(FLAME_ESCR0, 0x3A6, FLAME_COUNTER0, FLAME_COUNTER1, NONE) \
206 P4_ESCR(FLAME_ESCR1, 0x3A7, FLAME_COUNTER2, FLAME_COUNTER3, NONE) \
207 P4_ESCR(DAC_ESCR0, 0x3A8, FLAME_COUNTER0, FLAME_COUNTER1, NONE) \
208 P4_ESCR(DAC_ESCR1, 0x3A9, FLAME_COUNTER2, FLAME_COUNTER3, NONE) \
209 P4_ESCR(MOB_ESCR0, 0x3AA, BPU_COUNTER0, BPU_COUNTER1, NONE) \
210 P4_ESCR(MOB_ESCR1, 0x3AB, BPU_COUNTER2, BPU_COUNTER3, NONE) \
211 P4_ESCR(PMH_ESCR0, 0x3AC, BPU_COUNTER0, BPU_COUNTER1, NONE) \
212 P4_ESCR(PMH_ESCR1, 0x3AD, BPU_COUNTER2, BPU_COUNTER3, NONE) \
213 P4_ESCR(SAAT_ESCR0, 0x3AE, FLAME_COUNTER0, FLAME_COUNTER1, NONE) \
214 P4_ESCR(SAAT_ESCR1, 0x3AF, FLAME_COUNTER2, FLAME_COUNTER3, NONE) \
215 P4_ESCR(U2L_ESCR0, 0x3B0, FLAME_COUNTER0, FLAME_COUNTER1, NONE) \
216 P4_ESCR(U2L_ESCR1, 0x3B1, FLAME_COUNTER2, FLAME_COUNTER3, NONE) \
217 P4_ESCR(BPU_ESCR0, 0x3B2, BPU_COUNTER0, BPU_COUNTER1, NONE) \
218 P4_ESCR(BPU_ESCR1, 0x3B3, BPU_COUNTER2, BPU_COUNTER3, NONE) \
219 P4_ESCR(IS_ESCR0, 0x3B4, BPU_COUNTER0, BPU_COUNTER1, NONE) \
220 P4_ESCR(IS_ESCR1, 0x3B5, BPU_COUNTER2, BPU_COUNTER3, NONE) \
221 P4_ESCR(ITLB_ESCR0, 0x3B6, BPU_COUNTER0, BPU_COUNTER1, NONE) \
222 P4_ESCR(ITLB_ESCR1, 0x3B7, BPU_COUNTER2, BPU_COUNTER3, NONE) \
223 P4_ESCR(CRU_ESCR0, 0x3B8, IQ_COUNTER0, IQ_COUNTER1, IQ_COUNTER4) \
224 P4_ESCR(CRU_ESCR1, 0x3B9, IQ_COUNTER2, IQ_COUNTER3, IQ_COUNTER5) \
225 P4_ESCR(IQ_ESCR0, 0x3BA, IQ_COUNTER0, IQ_COUNTER1, IQ_COUNTER4) \
226 P4_ESCR(IQ_ESCR1, 0x3BB, IQ_COUNTER1, IQ_COUNTER3, IQ_COUNTER5) \
227 P4_ESCR(RAT_ESCR0, 0x3BC, IQ_COUNTER0, IQ_COUNTER1, IQ_COUNTER4) \
228 P4_ESCR(RAT_ESCR1, 0x3BD, IQ_COUNTER2, IQ_COUNTER3, IQ_COUNTER5) \
229 P4_ESCR(SSU_ESCR0, 0x3BE, IQ_COUNTER0, IQ_COUNTER2, IQ_COUNTER4) \
230 P4_ESCR(MS_ESCR0, 0x3C0, MS_COUNTER0, MS_COUNTER1, NONE) \
231 P4_ESCR(MS_ESCR1, 0x3C1, MS_COUNTER2, MS_COUNTER3, NONE) \
232 P4_ESCR(TBPU_ESCR0, 0x3C2, MS_COUNTER0, MS_COUNTER1, NONE) \
233 P4_ESCR(TBPU_ESCR1, 0x3C3, MS_COUNTER2, MS_COUNTER3, NONE) \
234 P4_ESCR(TC_ESCR0, 0x3C4, MS_COUNTER0, MS_COUNTER1, NONE) \
235 P4_ESCR(TC_ESCR1, 0x3C5, MS_COUNTER2, MS_COUNTER3, NONE) \
236 P4_ESCR(IX_ESCR0, 0x3C8, BPU_COUNTER0, BPU_COUNTER1, NONE) \
237 P4_ESCR(IX_ESCR1, 0x3C9, BPU_COUNTER2, BPU_COUNTER3, NONE) \
238 P4_ESCR(ALF_ESCR0, 0x3CA, IQ_COUNTER0, IQ_COUNTER1, IQ_COUNTER4) \
239 P4_ESCR(ALF_ESCR1, 0x3CB, IQ_COUNTER2, IQ_COUNTER3, IQ_COUNTER5) \
240 P4_ESCR(CRU_ESCR2, 0x3CC, IQ_COUNTER0, IQ_COUNTER1, IQ_COUNTER4) \
241 P4_ESCR(CRU_ESCR3, 0x3CD, IQ_COUNTER2, IQ_COUNTER3, IQ_COUNTER5) \
242 P4_ESCR(CRU_ESCR4, 0x3E0, IQ_COUNTER0, IQ_COUNTER1, IQ_COUNTER4) \
243 P4_ESCR(CRU_ESCR5, 0x3E1, IQ_COUNTER2, IQ_COUNTER3, IQ_COUNTER5) \
244 P4_ESCR(NONE, ~0, NONE, NONE, NONE)
247 #define P4_ESCR(N, MSR, P1, P2, P3) P4_ESCR_##N ,
252 struct pmc_p4escr_descr {
253 const char pm_escrname[PMC_NAME_MAX];
255 const enum pmc_p4pmc pm_pmcs[P4_MAX_PMC_PER_ESCR];
258 static struct pmc_p4escr_descr p4_escrs[] =
260 #define P4_ESCR(N, MSR, P1, P2, P3) \
263 .pm_escr_msr = (MSR), \
278 * P4 Event descriptor
281 struct p4_event_descr {
282 const enum pmc_event pm_event;
283 const uint32_t pm_escr_eventselect;
284 const uint32_t pm_cccr_select;
285 const char pm_is_ti_event;
286 enum pmc_p4escr pm_escrs[P4_MAX_ESCR_PER_EVENT];
289 static struct p4_event_descr p4_events[] = {
291 #define P4_EVDESCR(NAME, ESCREVENTSEL, CCCRSEL, TI_EVENT, ESCR0, ESCR1) \
293 .pm_event = PMC_EV_P4_##NAME, \
294 .pm_escr_eventselect = (ESCREVENTSEL), \
295 .pm_cccr_select = (CCCRSEL), \
296 .pm_is_ti_event = (TI_EVENT), \
304 P4_EVDESCR(TC_DELIVER_MODE, 0x01, 0x01, TRUE, TC_ESCR0, TC_ESCR1),
305 P4_EVDESCR(BPU_FETCH_REQUEST, 0x03, 0x00, FALSE, BPU_ESCR0, BPU_ESCR1),
306 P4_EVDESCR(ITLB_REFERENCE, 0x18, 0x03, FALSE, ITLB_ESCR0, ITLB_ESCR1),
307 P4_EVDESCR(MEMORY_CANCEL, 0x02, 0x05, FALSE, DAC_ESCR0, DAC_ESCR1),
308 P4_EVDESCR(MEMORY_COMPLETE, 0x08, 0x02, FALSE, SAAT_ESCR0, SAAT_ESCR1),
309 P4_EVDESCR(LOAD_PORT_REPLAY, 0x04, 0x02, FALSE, SAAT_ESCR0, SAAT_ESCR1),
310 P4_EVDESCR(STORE_PORT_REPLAY, 0x05, 0x02, FALSE, SAAT_ESCR0, SAAT_ESCR1),
311 P4_EVDESCR(MOB_LOAD_REPLAY, 0x03, 0x02, FALSE, MOB_ESCR0, MOB_ESCR1),
312 P4_EVDESCR(PAGE_WALK_TYPE, 0x01, 0x04, TRUE, PMH_ESCR0, PMH_ESCR1),
313 P4_EVDESCR(BSQ_CACHE_REFERENCE, 0x0C, 0x07, FALSE, BSU_ESCR0, BSU_ESCR1),
314 P4_EVDESCR(IOQ_ALLOCATION, 0x03, 0x06, FALSE, FSB_ESCR0, FSB_ESCR1),
315 P4_EVDESCR(IOQ_ACTIVE_ENTRIES, 0x1A, 0x06, FALSE, FSB_ESCR1, NONE),
316 P4_EVDESCR(FSB_DATA_ACTIVITY, 0x17, 0x06, TRUE, FSB_ESCR0, FSB_ESCR1),
317 P4_EVDESCR(BSQ_ALLOCATION, 0x05, 0x07, FALSE, BSU_ESCR0, NONE),
318 P4_EVDESCR(BSQ_ACTIVE_ENTRIES, 0x06, 0x07, FALSE, BSU_ESCR1, NONE),
319 /* BSQ_ACTIVE_ENTRIES inherits CPU specificity from BSQ_ALLOCATION */
320 P4_EVDESCR(SSE_INPUT_ASSIST, 0x34, 0x01, TRUE, FIRM_ESCR0, FIRM_ESCR1),
321 P4_EVDESCR(PACKED_SP_UOP, 0x08, 0x01, TRUE, FIRM_ESCR0, FIRM_ESCR1),
322 P4_EVDESCR(PACKED_DP_UOP, 0x0C, 0x01, TRUE, FIRM_ESCR0, FIRM_ESCR1),
323 P4_EVDESCR(SCALAR_SP_UOP, 0x0A, 0x01, TRUE, FIRM_ESCR0, FIRM_ESCR1),
324 P4_EVDESCR(SCALAR_DP_UOP, 0x0E, 0x01, TRUE, FIRM_ESCR0, FIRM_ESCR1),
325 P4_EVDESCR(64BIT_MMX_UOP, 0x02, 0x01, TRUE, FIRM_ESCR0, FIRM_ESCR1),
326 P4_EVDESCR(128BIT_MMX_UOP, 0x1A, 0x01, TRUE, FIRM_ESCR0, FIRM_ESCR1),
327 P4_EVDESCR(X87_FP_UOP, 0x04, 0x01, TRUE, FIRM_ESCR0, FIRM_ESCR1),
328 P4_EVDESCR(X87_SIMD_MOVES_UOP, 0x2E, 0x01, TRUE, FIRM_ESCR0, FIRM_ESCR1),
329 P4_EVDESCR(GLOBAL_POWER_EVENTS, 0x13, 0x06, FALSE, FSB_ESCR0, FSB_ESCR1),
330 P4_EVDESCR(TC_MS_XFER, 0x05, 0x00, FALSE, MS_ESCR0, MS_ESCR1),
331 P4_EVDESCR(UOP_QUEUE_WRITES, 0x09, 0x00, FALSE, MS_ESCR0, MS_ESCR1),
332 P4_EVDESCR(RETIRED_MISPRED_BRANCH_TYPE,
333 0x05, 0x02, FALSE, TBPU_ESCR0, TBPU_ESCR1),
334 P4_EVDESCR(RETIRED_BRANCH_TYPE, 0x04, 0x02, FALSE, TBPU_ESCR0, TBPU_ESCR1),
335 P4_EVDESCR(RESOURCE_STALL, 0x01, 0x01, FALSE, ALF_ESCR0, ALF_ESCR1),
336 P4_EVDESCR(WC_BUFFER, 0x05, 0x05, TRUE, DAC_ESCR0, DAC_ESCR1),
337 P4_EVDESCR(B2B_CYCLES, 0x16, 0x03, TRUE, FSB_ESCR0, FSB_ESCR1),
338 P4_EVDESCR(BNR, 0x08, 0x03, TRUE, FSB_ESCR0, FSB_ESCR1),
339 P4_EVDESCR(SNOOP, 0x06, 0x03, TRUE, FSB_ESCR0, FSB_ESCR1),
340 P4_EVDESCR(RESPONSE, 0x04, 0x03, TRUE, FSB_ESCR0, FSB_ESCR1),
341 P4_EVDESCR(FRONT_END_EVENT, 0x08, 0x05, FALSE, CRU_ESCR2, CRU_ESCR3),
342 P4_EVDESCR(EXECUTION_EVENT, 0x0C, 0x05, FALSE, CRU_ESCR2, CRU_ESCR3),
343 P4_EVDESCR(REPLAY_EVENT, 0x09, 0x05, FALSE, CRU_ESCR2, CRU_ESCR3),
344 P4_EVDESCR(INSTR_RETIRED, 0x02, 0x04, FALSE, CRU_ESCR0, CRU_ESCR1),
345 P4_EVDESCR(UOPS_RETIRED, 0x01, 0x04, FALSE, CRU_ESCR0, CRU_ESCR1),
346 P4_EVDESCR(UOP_TYPE, 0x02, 0x02, FALSE, RAT_ESCR0, RAT_ESCR1),
347 P4_EVDESCR(BRANCH_RETIRED, 0x06, 0x05, FALSE, CRU_ESCR2, CRU_ESCR3),
348 P4_EVDESCR(MISPRED_BRANCH_RETIRED, 0x03, 0x04, FALSE, CRU_ESCR0, CRU_ESCR1),
349 P4_EVDESCR(X87_ASSIST, 0x03, 0x05, FALSE, CRU_ESCR2, CRU_ESCR3),
350 P4_EVDESCR(MACHINE_CLEAR, 0x02, 0x05, FALSE, CRU_ESCR2, CRU_ESCR3)
355 #define P4_EVENT_IS_TI(E) ((E)->pm_is_ti_event == TRUE)
357 #define P4_NEVENTS (PMC_EV_P4_LAST - PMC_EV_P4_FIRST + 1)
364 struct pmc_descr pm_descr; /* common information */
365 enum pmc_p4pmc pm_pmcnum; /* PMC number */
366 uint32_t pm_pmc_msr; /* PERFCTR MSR address */
367 uint32_t pm_cccr_msr; /* CCCR MSR address */
370 static struct p4pmc_descr p4_pmcdesc[P4_NPMCS] = {
371 #define P4_PMC_CAPS (PMC_CAP_INTERRUPT | PMC_CAP_USER | PMC_CAP_SYSTEM | \
372 PMC_CAP_EDGE | PMC_CAP_THRESHOLD | PMC_CAP_READ | PMC_CAP_WRITE | \
373 PMC_CAP_INVERT | PMC_CAP_QUALIFIER | PMC_CAP_PRECISE | \
374 PMC_CAP_TAGGING | PMC_CAP_CASCADE)
376 #define P4_PMCDESCR(N, PMC, CCCR) \
381 .pd_class = PMC_CLASS_P4, \
382 .pd_caps = P4_PMC_CAPS, \
385 .pm_pmcnum = P4_PMC_##N, \
386 .pm_cccr_msr = (CCCR), \
387 .pm_pmc_msr = (PMC) \
390 P4_PMCDESCR(BPU_COUNTER0, 0x300, 0x360),
391 P4_PMCDESCR(BPU_COUNTER1, 0x301, 0x361),
392 P4_PMCDESCR(BPU_COUNTER2, 0x302, 0x362),
393 P4_PMCDESCR(BPU_COUNTER3, 0x303, 0x363),
394 P4_PMCDESCR(MS_COUNTER0, 0x304, 0x364),
395 P4_PMCDESCR(MS_COUNTER1, 0x305, 0x365),
396 P4_PMCDESCR(MS_COUNTER2, 0x306, 0x366),
397 P4_PMCDESCR(MS_COUNTER3, 0x307, 0x367),
398 P4_PMCDESCR(FLAME_COUNTER0, 0x308, 0x368),
399 P4_PMCDESCR(FLAME_COUNTER1, 0x309, 0x369),
400 P4_PMCDESCR(FLAME_COUNTER2, 0x30A, 0x36A),
401 P4_PMCDESCR(FLAME_COUNTER3, 0x30B, 0x36B),
402 P4_PMCDESCR(IQ_COUNTER0, 0x30C, 0x36C),
403 P4_PMCDESCR(IQ_COUNTER1, 0x30D, 0x36D),
404 P4_PMCDESCR(IQ_COUNTER2, 0x30E, 0x36E),
405 P4_PMCDESCR(IQ_COUNTER3, 0x30F, 0x36F),
406 P4_PMCDESCR(IQ_COUNTER4, 0x310, 0x370),
407 P4_PMCDESCR(IQ_COUNTER5, 0x311, 0x371),
413 #define P4_NHTT 2 /* logical processors/chip */
415 static int p4_system_has_htt;
418 * Per-CPU data structure for P4 class CPUs
420 * [19 struct pmc_hw structures]
421 * [45 ESCRs status bytes]
422 * [per-cpu spin mutex]
423 * [19 flag fields for holding config flags and a runcount]
424 * [19*2 hw value fields] (Thread mode PMC support)
426 * [19*2 EIP values] (Sampling mode PMCs)
427 * [19*2 pmc value fields] (Thread mode PMC support))
431 struct pmc_hw pc_p4pmcs[P4_NPMCS];
432 char pc_escrs[P4_NESCR];
433 struct mtx pc_mtx; /* spin lock */
434 uint32_t pc_intrflag; /* NMI handler flags */
435 unsigned int pc_intrlock; /* NMI handler spin lock */
436 unsigned char pc_flags[P4_NPMCS]; /* 4 bits each: {cfg,run}count */
438 pmc_value_t pc_hw[P4_NPMCS * P4_NHTT];
439 uintptr_t pc_ip[P4_NPMCS * P4_NHTT];
441 pmc_value_t pc_pmc_values[P4_NPMCS * P4_NHTT];
444 static struct p4_cpu **p4_pcpu;
446 #define P4_PCPU_PMC_VALUE(PC,RI,CPU) (PC)->pc_pmc_values[(RI)*((CPU) & 1)]
447 #define P4_PCPU_HW_VALUE(PC,RI,CPU) (PC)->pc_si.pc_hw[(RI)*((CPU) & 1)]
448 #define P4_PCPU_SAVED_IP(PC,RI,CPU) (PC)->pc_si.pc_ip[(RI)*((CPU) & 1)]
450 #define P4_PCPU_GET_FLAGS(PC,RI,MASK) ((PC)->pc_flags[(RI)] & (MASK))
451 #define P4_PCPU_SET_FLAGS(PC,RI,MASK,VAL) do { \
453 _tmp = (PC)->pc_flags[(RI)]; \
455 _tmp |= (VAL) & (MASK); \
456 (PC)->pc_flags[(RI)] = _tmp; \
459 #define P4_PCPU_GET_RUNCOUNT(PC,RI) P4_PCPU_GET_FLAGS(PC,RI,0x0F)
460 #define P4_PCPU_SET_RUNCOUNT(PC,RI,V) P4_PCPU_SET_FLAGS(PC,RI,0x0F,V)
462 #define P4_PCPU_GET_CFGFLAGS(PC,RI) (P4_PCPU_GET_FLAGS(PC,RI,0xF0) >> 4)
463 #define P4_PCPU_SET_CFGFLAGS(PC,RI,C) P4_PCPU_SET_FLAGS(PC,RI,0xF0,((C) <<4))
465 #define P4_CPU_TO_FLAG(C) (P4_CPU_IS_HTT_SECONDARY(cpu) ? 0x2 : 0x1)
467 #define P4_PCPU_GET_INTRFLAG(PC,I) ((PC)->pc_intrflag & (1 << (I)))
468 #define P4_PCPU_SET_INTRFLAG(PC,I,V) do { \
472 (PC)->pc_intrflag |= __mask; \
474 (PC)->pc_intrflag &= ~__mask; \
478 * A minimal spin lock implementation for use inside the NMI handler.
480 * We don't want to use a regular spin lock here, because curthread
481 * may not be consistent at the time the handler is invoked.
483 #define P4_PCPU_ACQ_INTR_SPINLOCK(PC) do { \
484 while (!atomic_cmpset_acq_int(&pc->pc_intrlock, 0, 1)) \
487 #define P4_PCPU_REL_INTR_SPINLOCK(PC) \
488 atomic_store_rel_int(&pc->pc_intrlock, 0);
490 /* ESCR row disposition */
491 static int p4_escrdisp[P4_NESCR];
493 #define P4_ESCR_ROW_DISP_IS_THREAD(E) (p4_escrdisp[(E)] > 0)
494 #define P4_ESCR_ROW_DISP_IS_STANDALONE(E) (p4_escrdisp[(E)] < 0)
495 #define P4_ESCR_ROW_DISP_IS_FREE(E) (p4_escrdisp[(E)] == 0)
497 #define P4_ESCR_MARK_ROW_STANDALONE(E) do { \
498 KASSERT(p4_escrdisp[(E)] <= 0, ("[p4,%d] row disposition error",\
500 atomic_add_int(&p4_escrdisp[(E)], -1); \
501 KASSERT(p4_escrdisp[(E)] >= (-pmc_cpu_max_active()), \
502 ("[p4,%d] row disposition error", __LINE__)); \
505 #define P4_ESCR_UNMARK_ROW_STANDALONE(E) do { \
506 atomic_add_int(&p4_escrdisp[(E)], 1); \
507 KASSERT(p4_escrdisp[(E)] <= 0, ("[p4,%d] row disposition error",\
511 #define P4_ESCR_MARK_ROW_THREAD(E) do { \
512 KASSERT(p4_escrdisp[(E)] >= 0, ("[p4,%d] row disposition error", \
514 atomic_add_int(&p4_escrdisp[(E)], 1); \
517 #define P4_ESCR_UNMARK_ROW_THREAD(E) do { \
518 atomic_add_int(&p4_escrdisp[(E)], -1); \
519 KASSERT(p4_escrdisp[(E)] >= 0, ("[p4,%d] row disposition error", \
523 #define P4_PMC_IS_STOPPED(cccr) ((rdmsr(cccr) & P4_CCCR_ENABLE) == 0)
525 #define P4_CPU_IS_HTT_SECONDARY(cpu) \
526 (p4_system_has_htt ? ((cpu) & 1) : 0)
527 #define P4_TO_HTT_PRIMARY(cpu) \
528 (p4_system_has_htt ? ((cpu) & ~1) : (cpu))
530 #define P4_CCCR_Tx_MASK (~(P4_CCCR_OVF_PMI_T0|P4_CCCR_OVF_PMI_T1| \
531 P4_CCCR_ENABLE|P4_CCCR_OVF))
532 #define P4_ESCR_Tx_MASK (~(P4_ESCR_T0_OS|P4_ESCR_T0_USR|P4_ESCR_T1_OS| \
539 static struct p4_event_descr *
540 p4_find_event(enum pmc_event ev)
544 for (n = 0; n < P4_NEVENTS; n++)
545 if (p4_events[n].pm_event == ev)
549 return (&p4_events[n]);
553 * Initialize per-cpu state
557 p4_pcpu_init(struct pmc_mdep *md, int cpu)
560 int n, first_ri, phycpu;
563 struct pmc_cpu *pc, *plc;
565 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
566 ("[p4,%d] insane cpu number %d", __LINE__, cpu));
568 PMCDBG2(MDP,INI,0, "p4-init cpu=%d is-primary=%d", cpu,
569 pmc_cpu_is_primary(cpu) != 0);
571 first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_P4].pcd_ri;
574 * The two CPUs in an HT pair share their per-cpu state.
576 * For HT capable CPUs, we assume that the two logical
577 * processors in the HT pair get two consecutive CPU ids
578 * starting with an even id #.
580 * The primary CPU (the even numbered CPU of the pair) would
581 * have been initialized prior to the initialization for the
585 if (!pmc_cpu_is_primary(cpu) && (cpu & 1)) {
587 p4_system_has_htt = 1;
589 phycpu = P4_TO_HTT_PRIMARY(cpu);
590 pc = pmc_pcpu[phycpu];
593 KASSERT(plc != pc, ("[p4,%d] per-cpu config error", __LINE__));
595 PMCDBG3(MDP,INI,1, "p4-init cpu=%d phycpu=%d pc=%p", cpu,
597 KASSERT(pc, ("[p4,%d] Null Per-Cpu state cpu=%d phycpu=%d",
598 __LINE__, cpu, phycpu));
600 /* PMCs are shared with the physical CPU. */
601 for (n = 0; n < P4_NPMCS; n++)
602 plc->pc_hwpmcs[n + first_ri] =
603 pc->pc_hwpmcs[n + first_ri];
608 p4c = malloc(sizeof(struct p4_cpu), M_PMC, M_WAITOK|M_ZERO);
612 KASSERT(pc != NULL, ("[p4,%d] cpu %d null per-cpu", __LINE__, cpu));
615 phw = p4c->pc_p4pmcs;
617 for (n = 0; n < P4_NPMCS; n++, phw++) {
618 phw->phw_state = PMC_PHW_FLAG_IS_ENABLED |
619 PMC_PHW_CPU_TO_STATE(cpu) | PMC_PHW_INDEX_TO_STATE(n);
621 pc->pc_hwpmcs[n + first_ri] = phw;
624 pescr = p4c->pc_escrs;
625 for (n = 0; n < P4_NESCR; n++)
626 *pescr++ = P4_INVALID_PMC_INDEX;
628 mtx_init(&p4c->pc_mtx, "p4-pcpu", "pmc-leaf", MTX_SPIN);
634 * Destroy per-cpu state.
638 p4_pcpu_fini(struct pmc_mdep *md, int cpu)
644 PMCDBG1(MDP,INI,0, "p4-cleanup cpu=%d", cpu);
647 first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_P4].pcd_ri;
649 for (i = 0; i < P4_NPMCS; i++)
650 pc->pc_hwpmcs[i + first_ri] = NULL;
652 if (!pmc_cpu_is_primary(cpu) && (cpu & 1))
657 KASSERT(p4c != NULL, ("[p4,%d] NULL pcpu", __LINE__));
659 /* Turn off all PMCs on this CPU */
660 for (i = 0; i < P4_NPMCS - 1; i++)
661 wrmsr(P4_CCCR_MSR_FIRST + i,
662 rdmsr(P4_CCCR_MSR_FIRST + i) & ~P4_CCCR_ENABLE);
664 mtx_destroy(&p4c->pc_mtx);
678 p4_read_pmc(int cpu, int ri, pmc_value_t *v)
684 struct p4pmc_descr *pd;
686 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
687 ("[p4,%d] illegal CPU value %d", __LINE__, cpu));
688 KASSERT(ri >= 0 && ri < P4_NPMCS,
689 ("[p4,%d] illegal row-index %d", __LINE__, ri));
691 pc = p4_pcpu[P4_TO_HTT_PRIMARY(cpu)];
692 pm = pc->pc_p4pmcs[ri].phw_pmc;
693 pd = &p4_pmcdesc[ri];
696 ("[p4,%d] No owner for HWPMC [cpu%d,pmc%d]", __LINE__, cpu, ri));
698 KASSERT(pd->pm_descr.pd_class == PMC_TO_CLASS(pm),
699 ("[p4,%d] class mismatch pd %d != id class %d", __LINE__,
700 pd->pm_descr.pd_class, PMC_TO_CLASS(pm)));
702 mode = PMC_TO_MODE(pm);
704 PMCDBG3(MDP,REA,1, "p4-read cpu=%d ri=%d mode=%d", cpu, ri, mode);
706 KASSERT(pd->pm_descr.pd_class == PMC_CLASS_P4,
707 ("[p4,%d] unknown PMC class %d", __LINE__, pd->pm_descr.pd_class));
709 tmp = rdmsr(p4_pmcdesc[ri].pm_pmc_msr);
711 if (PMC_IS_VIRTUAL_MODE(mode)) {
712 if (tmp < P4_PCPU_HW_VALUE(pc,ri,cpu)) /* 40 bit overflow */
713 tmp += (P4_PERFCTR_MASK + 1) -
714 P4_PCPU_HW_VALUE(pc,ri,cpu);
716 tmp -= P4_PCPU_HW_VALUE(pc,ri,cpu);
717 tmp += P4_PCPU_PMC_VALUE(pc,ri,cpu);
720 if (PMC_IS_SAMPLING_MODE(mode)) /* undo transformation */
721 *v = P4_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
725 PMCDBG1(MDP,REA,2, "p4-read -> %jx", *v);
735 p4_write_pmc(int cpu, int ri, pmc_value_t v)
740 const struct pmc_hw *phw;
741 const struct p4pmc_descr *pd;
743 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
744 ("[amd,%d] illegal CPU value %d", __LINE__, cpu));
745 KASSERT(ri >= 0 && ri < P4_NPMCS,
746 ("[amd,%d] illegal row-index %d", __LINE__, ri));
748 pc = p4_pcpu[P4_TO_HTT_PRIMARY(cpu)];
749 phw = &pc->pc_p4pmcs[ri];
751 pd = &p4_pmcdesc[ri];
754 ("[p4,%d] No owner for HWPMC [cpu%d,pmc%d]", __LINE__,
757 mode = PMC_TO_MODE(pm);
759 PMCDBG4(MDP,WRI,1, "p4-write cpu=%d ri=%d mode=%d v=%jx", cpu, ri,
763 * write the PMC value to the register/saved value: for
764 * sampling mode PMCs, the value to be programmed into the PMC
765 * counter is -(C+1) where 'C' is the requested sample rate.
767 if (PMC_IS_SAMPLING_MODE(mode))
768 v = P4_RELOAD_COUNT_TO_PERFCTR_VALUE(v);
770 if (PMC_IS_SYSTEM_MODE(mode))
771 wrmsr(pd->pm_pmc_msr, v);
773 P4_PCPU_PMC_VALUE(pc,ri,cpu) = v;
779 * Configure a PMC 'pm' on the given CPU and row-index.
781 * 'pm' may be NULL to indicate de-configuration.
783 * On HTT systems, a PMC may get configured twice, once for each
784 * "logical" CPU. We track this using the CFGFLAGS field of the
785 * per-cpu state; this field is a bit mask with one bit each for
786 * logical CPUs 0 & 1.
790 p4_config_pmc(int cpu, int ri, struct pmc *pm)
794 int cfgflags, cpuflag;
796 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
797 ("[p4,%d] illegal CPU %d", __LINE__, cpu));
799 KASSERT(ri >= 0 && ri < P4_NPMCS,
800 ("[p4,%d] illegal row-index %d", __LINE__, ri));
802 PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
804 pc = p4_pcpu[P4_TO_HTT_PRIMARY(cpu)];
805 phw = &pc->pc_p4pmcs[ri];
807 KASSERT(pm == NULL || phw->phw_pmc == NULL ||
808 (p4_system_has_htt && phw->phw_pmc == pm),
809 ("[p4,%d] hwpmc not unconfigured before re-config", __LINE__));
811 mtx_lock_spin(&pc->pc_mtx);
812 cfgflags = P4_PCPU_GET_CFGFLAGS(pc,ri);
814 KASSERT((cfgflags & ~0x3) == 0,
815 ("[p4,%d] illegal cfgflags cfg=%#x on cpu=%d ri=%d", __LINE__,
818 KASSERT(cfgflags == 0 || phw->phw_pmc,
819 ("[p4,%d] cpu=%d ri=%d pmc configured with zero cfg count",
822 cpuflag = P4_CPU_TO_FLAG(cpu);
824 if (pm) { /* config */
828 KASSERT(phw->phw_pmc == pm,
829 ("[p4,%d] cpu=%d ri=%d config %p != hw %p",
830 __LINE__, cpu, ri, pm, phw->phw_pmc));
833 } else { /* unconfig */
834 cfgflags &= ~cpuflag;
840 KASSERT((cfgflags & ~0x3) == 0,
841 ("[p4,%d] illegal runcount cfg=%#x on cpu=%d ri=%d", __LINE__,
844 P4_PCPU_SET_CFGFLAGS(pc,ri,cfgflags);
846 mtx_unlock_spin(&pc->pc_mtx);
852 * Retrieve a configured PMC pointer from hardware state.
856 p4_get_config(int cpu, int ri, struct pmc **ppm)
861 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
862 ("[p4,%d] illegal CPU %d", __LINE__, cpu));
863 KASSERT(ri >= 0 && ri < P4_NPMCS,
864 ("[p4,%d] illegal row-index %d", __LINE__, ri));
866 pc = p4_pcpu[P4_TO_HTT_PRIMARY(cpu)];
868 mtx_lock_spin(&pc->pc_mtx);
869 cfgflags = P4_PCPU_GET_CFGFLAGS(pc,ri);
870 mtx_unlock_spin(&pc->pc_mtx);
872 if (cfgflags & P4_CPU_TO_FLAG(cpu))
873 *ppm = pc->pc_p4pmcs[ri].phw_pmc; /* PMC config'ed on this CPU */
883 * The allocation strategy differs between HTT and non-HTT systems.
886 * - Given the desired event and the PMC row-index, lookup the
887 * list of valid ESCRs for the event.
888 * - For each valid ESCR:
889 * - Check if the ESCR is free and the ESCR row is in a compatible
890 * mode (i.e., system or process))
891 * - Check if the ESCR is usable with a P4 PMC at the desired row-index.
892 * If everything matches, we determine the appropriate bit values for the
893 * ESCR and CCCR registers.
897 * - Process mode PMCs require special care. The FreeBSD scheduler could
898 * schedule any two processes on the same physical CPU. We need to ensure
899 * that a given PMC row-index is never allocated to two different
900 * PMCs owned by different user-processes.
901 * This is ensured by always allocating a PMC from a 'FREE' PMC row
902 * if the system has HTT active.
903 * - A similar check needs to be done for ESCRs; we do not want two PMCs
904 * using the same ESCR to be scheduled at the same time. Thus ESCR
905 * allocation is also restricted to FREE rows if the system has HTT
907 * - Thirdly, some events are 'thread-independent' terminology, i.e.,
908 * the PMC hardware cannot distinguish between events caused by
909 * different logical CPUs. This makes it impossible to assign events
910 * to a given thread of execution. If the system has HTT enabled,
911 * these events are not allowed for process-mode PMCs.
915 p4_allocate_pmc(int cpu, int ri, struct pmc *pm,
916 const struct pmc_op_pmcallocate *a)
919 uint32_t caps, cccrvalue, escrvalue, tflags;
920 enum pmc_p4escr escr;
922 struct p4_event_descr *pevent;
923 const struct p4pmc_descr *pd;
925 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
926 ("[p4,%d] illegal CPU %d", __LINE__, cpu));
927 KASSERT(ri >= 0 && ri < P4_NPMCS,
928 ("[p4,%d] illegal row-index value %d", __LINE__, ri));
930 pd = &p4_pmcdesc[ri];
932 PMCDBG4(MDP,ALL,1, "p4-allocate ri=%d class=%d pmccaps=0x%x "
933 "reqcaps=0x%x", ri, pd->pm_descr.pd_class, pd->pm_descr.pd_caps,
937 if (pd->pm_descr.pd_class != a->pm_class)
940 /* check requested capabilities */
942 if ((pd->pm_descr.pd_caps & caps) != caps)
946 * If the system has HTT enabled, and the desired allocation
947 * mode is process-private, and the PMC row disposition is not
948 * FREE (0), decline the allocation.
951 if (p4_system_has_htt &&
952 PMC_IS_VIRTUAL_MODE(PMC_TO_MODE(pm)) &&
953 pmc_getrowdisp(ri) != 0)
956 KASSERT(pd->pm_descr.pd_class == PMC_CLASS_P4,
957 ("[p4,%d] unknown PMC class %d", __LINE__,
958 pd->pm_descr.pd_class));
960 if (pm->pm_event < PMC_EV_P4_FIRST ||
961 pm->pm_event > PMC_EV_P4_LAST)
964 if ((pevent = p4_find_event(pm->pm_event)) == NULL)
967 PMCDBG4(MDP,ALL,2, "pevent={ev=%d,escrsel=0x%x,cccrsel=0x%x,isti=%d}",
968 pevent->pm_event, pevent->pm_escr_eventselect,
969 pevent->pm_cccr_select, pevent->pm_is_ti_event);
972 * Some PMC events are 'thread independent'and therefore
973 * cannot be used for process-private modes if HTT is being
977 if (P4_EVENT_IS_TI(pevent) &&
978 PMC_IS_VIRTUAL_MODE(PMC_TO_MODE(pm)) &&
982 pc = p4_pcpu[P4_TO_HTT_PRIMARY(cpu)];
986 /* look for a suitable ESCR for this event */
987 for (n = 0; n < P4_MAX_ESCR_PER_EVENT && !found; n++) {
988 if ((escr = pevent->pm_escrs[n]) == P4_ESCR_NONE)
989 break; /* out of ESCRs */
991 * Check ESCR row disposition.
993 * If the request is for a system-mode PMC, then the
994 * ESCR row should not be in process-virtual mode, and
995 * should also be free on the current CPU.
998 if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm))) {
999 if (P4_ESCR_ROW_DISP_IS_THREAD(escr) ||
1000 pc->pc_escrs[escr] != P4_INVALID_PMC_INDEX)
1005 * If the request is for a process-virtual PMC, and if
1006 * HTT is not enabled, we can use an ESCR row that is
1007 * either FREE or already in process mode.
1009 * If HTT is enabled, then we need to ensure that a
1010 * given ESCR is never allocated to two PMCS that
1011 * could run simultaneously on the two logical CPUs of
1012 * a CPU package. We ensure this be only allocating
1013 * ESCRs from rows marked as 'FREE'.
1016 if (PMC_IS_VIRTUAL_MODE(PMC_TO_MODE(pm))) {
1017 if (p4_system_has_htt) {
1018 if (!P4_ESCR_ROW_DISP_IS_FREE(escr))
1021 if (P4_ESCR_ROW_DISP_IS_STANDALONE(escr))
1026 * We found a suitable ESCR for this event. Now check if
1027 * this escr can work with the PMC at row-index 'ri'.
1030 for (m = 0; m < P4_MAX_PMC_PER_ESCR; m++)
1031 if (p4_escrs[escr].pm_pmcs[m] == pd->pm_pmcnum) {
1040 KASSERT((int) escr >= 0 && escr < P4_NESCR,
1041 ("[p4,%d] illegal ESCR value %d", __LINE__, escr));
1043 /* mark ESCR row mode */
1044 if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm))) {
1045 pc->pc_escrs[escr] = ri; /* mark ESCR as in use on this cpu */
1046 P4_ESCR_MARK_ROW_STANDALONE(escr);
1048 KASSERT(pc->pc_escrs[escr] == P4_INVALID_PMC_INDEX,
1049 ("[p4,%d] escr[%d] already in use", __LINE__, escr));
1050 P4_ESCR_MARK_ROW_THREAD(escr);
1053 pm->pm_md.pm_p4.pm_p4_escrmsr = p4_escrs[escr].pm_escr_msr;
1054 pm->pm_md.pm_p4.pm_p4_escr = escr;
1056 cccrvalue = P4_CCCR_TO_ESCR_SELECT(pevent->pm_cccr_select);
1057 escrvalue = P4_ESCR_TO_EVENT_SELECT(pevent->pm_escr_eventselect);
1060 if (caps & PMC_CAP_THRESHOLD)
1061 cccrvalue |= (a->pm_md.pm_p4.pm_p4_cccrconfig &
1062 P4_CCCR_THRESHOLD_MASK) | P4_CCCR_COMPARE;
1064 if (caps & PMC_CAP_EDGE)
1065 cccrvalue |= P4_CCCR_EDGE;
1067 if (caps & PMC_CAP_INVERT)
1068 cccrvalue |= P4_CCCR_COMPLEMENT;
1070 if (p4_system_has_htt)
1071 cccrvalue |= a->pm_md.pm_p4.pm_p4_cccrconfig &
1072 P4_CCCR_ACTIVE_THREAD_MASK;
1073 else /* no HTT; thread field should be '11b' */
1074 cccrvalue |= P4_CCCR_TO_ACTIVE_THREAD(0x3);
1076 if (caps & PMC_CAP_CASCADE)
1077 cccrvalue |= P4_CCCR_CASCADE;
1079 /* On HTT systems the PMI T0 field may get moved to T1 at pmc start */
1080 if (caps & PMC_CAP_INTERRUPT)
1081 cccrvalue |= P4_CCCR_OVF_PMI_T0;
1084 if (caps & PMC_CAP_QUALIFIER)
1085 escrvalue |= a->pm_md.pm_p4.pm_p4_escrconfig &
1086 P4_ESCR_EVENT_MASK_MASK;
1087 if (caps & PMC_CAP_TAGGING)
1088 escrvalue |= (a->pm_md.pm_p4.pm_p4_escrconfig &
1089 P4_ESCR_TAG_VALUE_MASK) | P4_ESCR_TAG_ENABLE;
1090 if (caps & PMC_CAP_QUALIFIER)
1091 escrvalue |= (a->pm_md.pm_p4.pm_p4_escrconfig &
1092 P4_ESCR_EVENT_MASK_MASK);
1094 /* HTT: T0_{OS,USR} bits may get moved to T1 at pmc start */
1096 if (caps & PMC_CAP_SYSTEM)
1097 tflags |= P4_ESCR_T0_OS;
1098 if (caps & PMC_CAP_USER)
1099 tflags |= P4_ESCR_T0_USR;
1101 tflags = (P4_ESCR_T0_OS|P4_ESCR_T0_USR);
1102 escrvalue |= tflags;
1104 pm->pm_md.pm_p4.pm_p4_cccrvalue = cccrvalue;
1105 pm->pm_md.pm_p4.pm_p4_escrvalue = escrvalue;
1107 PMCDBG5(MDP,ALL,2, "p4-allocate cccrsel=0x%x cccrval=0x%x "
1108 "escr=%d escrmsr=0x%x escrval=0x%x", pevent->pm_cccr_select,
1109 cccrvalue, escr, pm->pm_md.pm_p4.pm_p4_escrmsr, escrvalue);
1119 p4_release_pmc(int cpu, int ri, struct pmc *pm)
1121 enum pmc_p4escr escr;
1124 KASSERT(ri >= 0 && ri < P4_NPMCS,
1125 ("[p4,%d] illegal row-index %d", __LINE__, ri));
1127 escr = pm->pm_md.pm_p4.pm_p4_escr;
1129 PMCDBG3(MDP,REL,1, "p4-release cpu=%d ri=%d escr=%d", cpu, ri, escr);
1131 if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm))) {
1132 pc = p4_pcpu[P4_TO_HTT_PRIMARY(cpu)];
1134 KASSERT(pc->pc_p4pmcs[ri].phw_pmc == NULL,
1135 ("[p4,%d] releasing configured PMC ri=%d", __LINE__, ri));
1137 P4_ESCR_UNMARK_ROW_STANDALONE(escr);
1138 KASSERT(pc->pc_escrs[escr] == ri,
1139 ("[p4,%d] escr[%d] not allocated to ri %d", __LINE__,
1141 pc->pc_escrs[escr] = P4_INVALID_PMC_INDEX; /* mark as free */
1143 P4_ESCR_UNMARK_ROW_THREAD(escr);
1153 p4_start_pmc(int cpu, int ri)
1158 struct p4pmc_descr *pd;
1159 uint32_t cccrvalue, cccrtbits, escrvalue, escrmsr, escrtbits;
1161 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
1162 ("[p4,%d] illegal CPU value %d", __LINE__, cpu));
1163 KASSERT(ri >= 0 && ri < P4_NPMCS,
1164 ("[p4,%d] illegal row-index %d", __LINE__, ri));
1166 pc = p4_pcpu[P4_TO_HTT_PRIMARY(cpu)];
1167 pm = pc->pc_p4pmcs[ri].phw_pmc;
1168 pd = &p4_pmcdesc[ri];
1171 ("[p4,%d] starting cpu%d,pmc%d with null pmc", __LINE__, cpu, ri));
1173 PMCDBG2(MDP,STA,1, "p4-start cpu=%d ri=%d", cpu, ri);
1175 KASSERT(pd->pm_descr.pd_class == PMC_CLASS_P4,
1176 ("[p4,%d] wrong PMC class %d", __LINE__,
1177 pd->pm_descr.pd_class));
1179 /* retrieve the desired CCCR/ESCR values from the PMC */
1180 cccrvalue = pm->pm_md.pm_p4.pm_p4_cccrvalue;
1181 escrvalue = pm->pm_md.pm_p4.pm_p4_escrvalue;
1182 escrmsr = pm->pm_md.pm_p4.pm_p4_escrmsr;
1184 /* extract and zero the logical processor selection bits */
1185 cccrtbits = cccrvalue & P4_CCCR_OVF_PMI_T0;
1186 escrtbits = escrvalue & (P4_ESCR_T0_OS|P4_ESCR_T0_USR);
1187 cccrvalue &= ~P4_CCCR_OVF_PMI_T0;
1188 escrvalue &= ~(P4_ESCR_T0_OS|P4_ESCR_T0_USR);
1190 if (P4_CPU_IS_HTT_SECONDARY(cpu)) { /* shift T0 bits to T1 position */
1195 /* start system mode PMCs directly */
1196 if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm))) {
1197 wrmsr(escrmsr, escrvalue | escrtbits);
1198 wrmsr(pd->pm_cccr_msr, cccrvalue | cccrtbits | P4_CCCR_ENABLE);
1205 * On HTT machines, the same PMC could be scheduled on the
1206 * same physical CPU twice (once for each logical CPU), for
1207 * example, if two threads of a multi-threaded process get
1208 * scheduled on the same CPU.
1212 mtx_lock_spin(&pc->pc_mtx);
1214 rc = P4_PCPU_GET_RUNCOUNT(pc,ri);
1215 KASSERT(rc == 0 || rc == 1,
1216 ("[p4,%d] illegal runcount cpu=%d ri=%d rc=%d", __LINE__, cpu, ri,
1219 if (rc == 0) { /* 1st CPU and the non-HTT case */
1221 KASSERT(P4_PMC_IS_STOPPED(pd->pm_cccr_msr),
1222 ("[p4,%d] cpu=%d ri=%d cccr=0x%x not stopped", __LINE__,
1223 cpu, ri, pd->pm_cccr_msr));
1225 /* write out the low 40 bits of the saved value to hardware */
1226 wrmsr(pd->pm_pmc_msr,
1227 P4_PCPU_PMC_VALUE(pc,ri,cpu) & P4_PERFCTR_MASK);
1229 } else if (rc == 1) { /* 2nd CPU */
1232 * Stop the PMC and retrieve the CCCR and ESCR values
1233 * from their MSRs, and turn on the additional T[0/1]
1234 * bits for the 2nd CPU.
1237 cccrvalue = rdmsr(pd->pm_cccr_msr);
1238 wrmsr(pd->pm_cccr_msr, cccrvalue & ~P4_CCCR_ENABLE);
1240 /* check that the configuration bits read back match the PMC */
1241 KASSERT((cccrvalue & P4_CCCR_Tx_MASK) ==
1242 (pm->pm_md.pm_p4.pm_p4_cccrvalue & P4_CCCR_Tx_MASK),
1243 ("[p4,%d] Extra CCCR bits cpu=%d rc=%d ri=%d "
1244 "cccr=0x%x PMC=0x%x", __LINE__, cpu, rc, ri,
1245 cccrvalue & P4_CCCR_Tx_MASK,
1246 pm->pm_md.pm_p4.pm_p4_cccrvalue & P4_CCCR_Tx_MASK));
1247 KASSERT(cccrvalue & P4_CCCR_ENABLE,
1248 ("[p4,%d] 2nd cpu rc=%d cpu=%d ri=%d not running",
1249 __LINE__, rc, cpu, ri));
1250 KASSERT((cccrvalue & cccrtbits) == 0,
1251 ("[p4,%d] CCCR T0/T1 mismatch rc=%d cpu=%d ri=%d"
1252 "cccrvalue=0x%x tbits=0x%x", __LINE__, rc, cpu, ri,
1253 cccrvalue, cccrtbits));
1255 escrvalue = rdmsr(escrmsr);
1257 KASSERT((escrvalue & P4_ESCR_Tx_MASK) ==
1258 (pm->pm_md.pm_p4.pm_p4_escrvalue & P4_ESCR_Tx_MASK),
1259 ("[p4,%d] Extra ESCR bits cpu=%d rc=%d ri=%d "
1260 "escr=0x%x pm=0x%x", __LINE__, cpu, rc, ri,
1261 escrvalue & P4_ESCR_Tx_MASK,
1262 pm->pm_md.pm_p4.pm_p4_escrvalue & P4_ESCR_Tx_MASK));
1263 KASSERT((escrvalue & escrtbits) == 0,
1264 ("[p4,%d] ESCR T0/T1 mismatch rc=%d cpu=%d ri=%d "
1265 "escrmsr=0x%x escrvalue=0x%x tbits=0x%x", __LINE__,
1266 rc, cpu, ri, escrmsr, escrvalue, escrtbits));
1269 /* Enable the correct bits for this CPU. */
1270 escrvalue |= escrtbits;
1271 cccrvalue |= cccrtbits | P4_CCCR_ENABLE;
1273 /* Save HW value at the time of starting hardware */
1274 P4_PCPU_HW_VALUE(pc,ri,cpu) = rdmsr(pd->pm_pmc_msr);
1276 /* Program the ESCR and CCCR and start the PMC */
1277 wrmsr(escrmsr, escrvalue);
1278 wrmsr(pd->pm_cccr_msr, cccrvalue);
1281 P4_PCPU_SET_RUNCOUNT(pc,ri,rc);
1283 mtx_unlock_spin(&pc->pc_mtx);
1285 PMCDBG6(MDP,STA,2,"p4-start cpu=%d rc=%d ri=%d escr=%d "
1286 "escrmsr=0x%x escrvalue=0x%x", cpu, rc,
1287 ri, pm->pm_md.pm_p4.pm_p4_escr, escrmsr, escrvalue);
1288 PMCDBG2(MDP,STA,2,"cccr_config=0x%x v=%jx",
1289 cccrvalue, P4_PCPU_HW_VALUE(pc,ri,cpu));
1299 p4_stop_pmc(int cpu, int ri)
1302 uint32_t cccrvalue, cccrtbits, escrvalue, escrmsr, escrtbits;
1305 struct p4pmc_descr *pd;
1308 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
1309 ("[p4,%d] illegal CPU value %d", __LINE__, cpu));
1310 KASSERT(ri >= 0 && ri < P4_NPMCS,
1311 ("[p4,%d] illegal row index %d", __LINE__, ri));
1313 pd = &p4_pmcdesc[ri];
1314 pc = p4_pcpu[P4_TO_HTT_PRIMARY(cpu)];
1315 pm = pc->pc_p4pmcs[ri].phw_pmc;
1318 ("[p4,%d] null pmc for cpu%d, ri%d", __LINE__, cpu, ri));
1320 PMCDBG2(MDP,STO,1, "p4-stop cpu=%d ri=%d", cpu, ri);
1322 if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm))) {
1323 wrmsr(pd->pm_cccr_msr,
1324 pm->pm_md.pm_p4.pm_p4_cccrvalue & ~P4_CCCR_ENABLE);
1331 * On HTT machines, this PMC may be in use by two threads
1332 * running on two logical CPUS. Thus we look at the
1333 * 'runcount' field and only turn off the appropriate TO/T1
1334 * bits (and keep the PMC running) if two logical CPUs were
1340 cccrtbits = P4_CCCR_OVF_PMI_T0;
1341 escrtbits = P4_ESCR_T0_OS | P4_ESCR_T0_USR;
1342 if (P4_CPU_IS_HTT_SECONDARY(cpu)) {
1347 mtx_lock_spin(&pc->pc_mtx);
1349 rc = P4_PCPU_GET_RUNCOUNT(pc,ri);
1351 KASSERT(rc == 2 || rc == 1,
1352 ("[p4,%d] illegal runcount cpu=%d ri=%d rc=%d", __LINE__, cpu, ri,
1357 P4_PCPU_SET_RUNCOUNT(pc,ri,rc);
1360 cccrvalue = rdmsr(pd->pm_cccr_msr);
1361 wrmsr(pd->pm_cccr_msr, cccrvalue & ~P4_CCCR_ENABLE);
1363 escrmsr = pm->pm_md.pm_p4.pm_p4_escrmsr;
1364 escrvalue = rdmsr(escrmsr);
1366 /* The current CPU should be running on this PMC */
1367 KASSERT(escrvalue & escrtbits,
1368 ("[p4,%d] ESCR T0/T1 mismatch cpu=%d rc=%d ri=%d escrmsr=0x%x "
1369 "escrvalue=0x%x tbits=0x%x", __LINE__, cpu, rc, ri, escrmsr,
1370 escrvalue, escrtbits));
1371 KASSERT(PMC_IS_COUNTING_MODE(PMC_TO_MODE(pm)) ||
1372 (cccrvalue & cccrtbits),
1373 ("[p4,%d] CCCR T0/T1 mismatch cpu=%d ri=%d cccrvalue=0x%x "
1374 "tbits=0x%x", __LINE__, cpu, ri, cccrvalue, cccrtbits));
1376 /* get the current hardware reading */
1377 tmp = rdmsr(pd->pm_pmc_msr);
1379 if (rc == 1) { /* need to keep the PMC running */
1380 escrvalue &= ~escrtbits;
1381 cccrvalue &= ~cccrtbits;
1382 wrmsr(escrmsr, escrvalue);
1383 wrmsr(pd->pm_cccr_msr, cccrvalue);
1386 mtx_unlock_spin(&pc->pc_mtx);
1388 PMCDBG5(MDP,STO,2, "p4-stop cpu=%d rc=%d ri=%d escrmsr=0x%x "
1389 "escrval=0x%x", cpu, rc, ri, escrmsr, escrvalue);
1390 PMCDBG2(MDP,STO,2, "cccrval=0x%x v=%jx", cccrvalue, tmp);
1392 if (tmp < P4_PCPU_HW_VALUE(pc,ri,cpu)) /* 40 bit counter overflow */
1393 tmp += (P4_PERFCTR_MASK + 1) - P4_PCPU_HW_VALUE(pc,ri,cpu);
1395 tmp -= P4_PCPU_HW_VALUE(pc,ri,cpu);
1397 P4_PCPU_PMC_VALUE(pc,ri,cpu) += tmp;
1403 * Handle an interrupt.
1405 * The hardware sets the CCCR_OVF whenever a counter overflow occurs,
1406 * so the handler examines all the 18 CCCR registers, processing the
1407 * counters that have overflowed.
1409 * On HTT machines, the CCCR register is shared and will interrupt
1410 * both logical processors if so configured. Thus multiple logical
1411 * CPUs could enter the NMI service routine at the same time. These
1412 * will get serialized using a per-cpu spinlock dedicated for use in
1417 p4_intr(int cpu, struct trapframe *tf)
1419 uint32_t cccrval, ovf_mask, ovf_partner;
1420 int did_interrupt, error, ri;
1425 PMCDBG3(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf,
1426 TRAPF_USERMODE(tf));
1428 pc = p4_pcpu[P4_TO_HTT_PRIMARY(cpu)];
1430 ovf_mask = P4_CPU_IS_HTT_SECONDARY(cpu) ?
1431 P4_CCCR_OVF_PMI_T1 : P4_CCCR_OVF_PMI_T0;
1432 ovf_mask |= P4_CCCR_OVF;
1433 if (p4_system_has_htt)
1434 ovf_partner = P4_CPU_IS_HTT_SECONDARY(cpu) ?
1435 P4_CCCR_OVF_PMI_T0 : P4_CCCR_OVF_PMI_T1;
1440 if (p4_system_has_htt)
1441 P4_PCPU_ACQ_INTR_SPINLOCK(pc);
1444 * Loop through all CCCRs, looking for ones that have
1445 * interrupted this CPU.
1447 for (ri = 0; ri < P4_NPMCS; ri++) {
1450 * Check if our partner logical CPU has already marked
1451 * this PMC has having interrupted it. If so, reset
1452 * the flag and process the interrupt, but leave the
1455 if (p4_system_has_htt && P4_PCPU_GET_INTRFLAG(pc,ri)) {
1456 P4_PCPU_SET_INTRFLAG(pc,ri,0);
1460 * Ignore de-configured or stopped PMCs.
1461 * Ignore PMCs not in sampling mode.
1463 pm = pc->pc_p4pmcs[ri].phw_pmc;
1465 pm->pm_state != PMC_STATE_RUNNING ||
1466 !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) {
1469 (void) pmc_process_interrupt(cpu, PMC_HR, pm, tf,
1470 TRAPF_USERMODE(tf));
1475 * Fresh interrupt. Look for the CCCR_OVF bit
1476 * and the OVF_Tx bit for this logical
1477 * processor being set.
1479 cccrval = rdmsr(P4_CCCR_MSR_FIRST + ri);
1481 if ((cccrval & ovf_mask) != ovf_mask)
1485 * If the other logical CPU would also have been
1486 * interrupted due to the PMC being shared, record
1487 * this fact in the per-cpu saved interrupt flag
1490 if (p4_system_has_htt && (cccrval & ovf_partner))
1491 P4_PCPU_SET_INTRFLAG(pc, ri, 1);
1493 v = rdmsr(P4_PERFCTR_MSR_FIRST + ri);
1495 PMCDBG2(MDP,INT, 2, "ri=%d v=%jx", ri, v);
1497 /* Stop the counter, and reset the overflow bit */
1498 cccrval &= ~(P4_CCCR_OVF | P4_CCCR_ENABLE);
1499 wrmsr(P4_CCCR_MSR_FIRST + ri, cccrval);
1504 * Ignore de-configured or stopped PMCs. Ignore PMCs
1505 * not in sampling mode.
1507 pm = pc->pc_p4pmcs[ri].phw_pmc;
1510 pm->pm_state != PMC_STATE_RUNNING ||
1511 !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) {
1516 * Process the interrupt. Re-enable the PMC if
1517 * processing was successful.
1519 error = pmc_process_interrupt(cpu, PMC_HR, pm, tf,
1520 TRAPF_USERMODE(tf));
1523 * Only the first processor executing the NMI handler
1524 * in a HTT pair will restart a PMC, and that too
1525 * only if there were no errors.
1527 v = P4_RELOAD_COUNT_TO_PERFCTR_VALUE(
1528 pm->pm_sc.pm_reloadcount);
1529 wrmsr(P4_PERFCTR_MSR_FIRST + ri, v);
1531 wrmsr(P4_CCCR_MSR_FIRST + ri,
1532 cccrval | P4_CCCR_ENABLE);
1535 /* allow the other CPU to proceed */
1536 if (p4_system_has_htt)
1537 P4_PCPU_REL_INTR_SPINLOCK(pc);
1540 * On Intel P4 CPUs, the PMC 'pcint' entry in the LAPIC gets
1541 * masked when a PMC interrupts the CPU. We need to unmask
1542 * the interrupt source explicitly.
1546 lapic_reenable_pmc();
1548 atomic_add_int(did_interrupt ? &pmc_stats.pm_intr_processed :
1549 &pmc_stats.pm_intr_ignored, 1);
1551 return (did_interrupt);
1555 * Describe a CPU's PMC state.
1559 p4_describe(int cpu, int ri, struct pmc_info *pi,
1564 const struct p4pmc_descr *pd;
1566 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
1567 ("[p4,%d] illegal CPU %d", __LINE__, cpu));
1568 KASSERT(ri >= 0 && ri < P4_NPMCS,
1569 ("[p4,%d] row-index %d out of range", __LINE__, ri));
1571 PMCDBG2(MDP,OPS,1,"p4-describe cpu=%d ri=%d", cpu, ri);
1573 if (P4_CPU_IS_HTT_SECONDARY(cpu))
1576 pd = &p4_pmcdesc[ri];
1578 if ((error = copystr(pd->pm_descr.pd_name, pi->pm_name,
1579 PMC_NAME_MAX, &copied)) != 0)
1582 pi->pm_class = pd->pm_descr.pd_class;
1584 if (p4_pcpu[cpu]->pc_p4pmcs[ri].phw_state & PMC_PHW_FLAG_IS_ENABLED) {
1585 pi->pm_enabled = TRUE;
1586 *ppmc = p4_pcpu[cpu]->pc_p4pmcs[ri].phw_pmc;
1588 pi->pm_enabled = FALSE;
1596 * Get MSR# for use with RDPMC.
1600 p4_get_msr(int ri, uint32_t *msr)
1602 KASSERT(ri >= 0 && ri < P4_NPMCS,
1603 ("[p4,%d] ri %d out of range", __LINE__, ri));
1605 *msr = p4_pmcdesc[ri].pm_pmc_msr - P4_PERFCTR_MSR_FIRST;
1607 PMCDBG2(MDP,OPS, 1, "ri=%d getmsr=0x%x", ri, *msr);
1614 pmc_p4_initialize(struct pmc_mdep *md, int ncpus)
1616 struct pmc_classdep *pcd;
1617 struct p4_event_descr *pe;
1619 KASSERT(md != NULL, ("[p4,%d] md is NULL", __LINE__));
1620 KASSERT(cpu_vendor_id == CPU_VENDOR_INTEL,
1621 ("[p4,%d] Initializing non-intel processor", __LINE__));
1623 PMCDBG0(MDP,INI,1, "p4-initialize");
1625 /* Allocate space for pointers to per-cpu descriptors. */
1626 p4_pcpu = malloc(sizeof(*p4_pcpu) * ncpus, M_PMC, M_ZERO | M_WAITOK);
1628 /* Fill in the class dependent descriptor. */
1629 pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_P4];
1631 switch (md->pmd_cputype) {
1632 case PMC_CPU_INTEL_PIV:
1634 pcd->pcd_caps = P4_PMC_CAPS;
1635 pcd->pcd_class = PMC_CLASS_P4;
1636 pcd->pcd_num = P4_NPMCS;
1637 pcd->pcd_ri = md->pmd_npmc;
1638 pcd->pcd_width = 40;
1640 pcd->pcd_allocate_pmc = p4_allocate_pmc;
1641 pcd->pcd_config_pmc = p4_config_pmc;
1642 pcd->pcd_describe = p4_describe;
1643 pcd->pcd_get_config = p4_get_config;
1644 pcd->pcd_get_msr = p4_get_msr;
1645 pcd->pcd_pcpu_fini = p4_pcpu_fini;
1646 pcd->pcd_pcpu_init = p4_pcpu_init;
1647 pcd->pcd_read_pmc = p4_read_pmc;
1648 pcd->pcd_release_pmc = p4_release_pmc;
1649 pcd->pcd_start_pmc = p4_start_pmc;
1650 pcd->pcd_stop_pmc = p4_stop_pmc;
1651 pcd->pcd_write_pmc = p4_write_pmc;
1653 md->pmd_pcpu_fini = NULL;
1654 md->pmd_pcpu_init = NULL;
1655 md->pmd_intr = p4_intr;
1656 md->pmd_npmc += P4_NPMCS;
1658 /* model specific configuration */
1659 if ((cpu_id & 0xFFF) < 0xF27) {
1662 * On P4 and Xeon with CPUID < (Family 15,
1663 * Model 2, Stepping 7), only one ESCR is
1664 * available for the IOQ_ALLOCATION event.
1667 pe = p4_find_event(PMC_EV_P4_IOQ_ALLOCATION);
1668 pe->pm_escrs[1] = P4_ESCR_NONE;
1674 KASSERT(0,("[p4,%d] Unknown CPU type", __LINE__));
1682 pmc_p4_finalize(struct pmc_mdep *md)
1684 #if defined(INVARIANTS)
1688 KASSERT(p4_pcpu != NULL,
1689 ("[p4,%d] NULL p4_pcpu", __LINE__));
1691 #if defined(INVARIANTS)
1692 ncpus = pmc_cpu_max();
1693 for (i = 0; i < ncpus; i++)
1694 KASSERT(p4_pcpu[i] == NULL, ("[p4,%d] non-null pcpu %d",
1698 free(p4_pcpu, M_PMC);