1bc81ea3adrian/*-
2bc81ea3adrian * Copyright (c) 2010 George V. Neville-Neil <gnn@freebsd.org>
3bc81ea3adrian * Copyright (c) 2015 Adrian Chadd <adrian@freebsd.org>
4bc81ea3adrian * All rights reserved.
5bc81ea3adrian *
6bc81ea3adrian * Redistribution and use in source and binary forms, with or without
7bc81ea3adrian * modification, are permitted provided that the following conditions
8bc81ea3adrian * are met:
9bc81ea3adrian * 1. Redistributions of source code must retain the above copyright
10bc81ea3adrian *    notice, this list of conditions and the following disclaimer.
11bc81ea3adrian * 2. Redistributions in binary form must reproduce the above copyright
12bc81ea3adrian *    notice, this list of conditions and the following disclaimer in the
13bc81ea3adrian *    documentation and/or other materials provided with the distribution.
14bc81ea3adrian *
15bc81ea3adrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16bc81ea3adrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17bc81ea3adrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18bc81ea3adrian * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19bc81ea3adrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20bc81ea3adrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21bc81ea3adrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22bc81ea3adrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23bc81ea3adrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24bc81ea3adrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25bc81ea3adrian * SUCH DAMAGE.
26bc81ea3adrian *
27bc81ea3adrian */
28bc81ea3adrian
29bc81ea3adrian#include <sys/cdefs.h>
30bc81ea3adrian__FBSDID("$FreeBSD$");
31bc81ea3adrian
32bc81ea3adrian#include <sys/param.h>
33bc81ea3adrian#include <sys/systm.h>
34bc81ea3adrian#include <sys/pmc.h>
35bc81ea3adrian#include <sys/pmckern.h>
36bc81ea3adrian
37bc81ea3adrian#include <machine/cpu.h>
38bc81ea3adrian#include <machine/cpufunc.h>
39bc81ea3adrian#include <machine/pmc_mdep.h>
40bc81ea3adrian
41bc81ea3adrian#define	MIPS74K_PMC_CAPS	(PMC_CAP_INTERRUPT | PMC_CAP_USER |     \
42bc81ea3adrian				 PMC_CAP_SYSTEM | PMC_CAP_EDGE |	\
43bc81ea3adrian				 PMC_CAP_THRESHOLD | PMC_CAP_READ |	\
44bc81ea3adrian				 PMC_CAP_WRITE | PMC_CAP_INVERT |	\
45bc81ea3adrian				 PMC_CAP_QUALIFIER)
46bc81ea3adrian
47bc81ea3adrian/* 0x1 - Exception_enable */
48bc81ea3adrian#define MIPS74K_PMC_INTERRUPT_ENABLE      0x10 /* Enable interrupts */
49bc81ea3adrian#define MIPS74K_PMC_USER_ENABLE           0x08 /* Count in USER mode */
50bc81ea3adrian#define MIPS74K_PMC_SUPER_ENABLE          0x04 /* Count in SUPERVISOR mode */
51bc81ea3adrian#define MIPS74K_PMC_KERNEL_ENABLE         0x02 /* Count in KERNEL mode */
52bc81ea3adrian#define MIPS74K_PMC_ENABLE (MIPS74K_PMC_USER_ENABLE |	   \
53bc81ea3adrian			    MIPS74K_PMC_SUPER_ENABLE |	   \
54bc81ea3adrian			    MIPS74K_PMC_KERNEL_ENABLE)
55bc81ea3adrian
56bc81ea3adrian#define MIPS74K_PMC_SELECT 5 /* Which bit position the event starts at. */
57bc81ea3adrian
58bc81ea3adrianconst struct mips_event_code_map mips_event_codes[] = {
59bc81ea3adrian	{ PMC_EV_MIPS74K_CYCLES, MIPS_CTR_ALL, 0 },
60bc81ea3adrian	{ PMC_EV_MIPS74K_INSTR_EXECUTED, MIPS_CTR_ALL, 1 },
61bc81ea3adrian	{ PMC_EV_MIPS74K_PREDICTED_JR_31, MIPS_CTR_0, 2 },
62bc81ea3adrian	{ PMC_EV_MIPS74K_JR_31_MISPREDICTIONS, MIPS_CTR_1, 2 },
63bc81ea3adrian	{ PMC_EV_MIPS74K_REDIRECT_STALLS, MIPS_CTR_0, 3 },
64bc81ea3adrian	{ PMC_EV_MIPS74K_JR_31_NO_PREDICTIONS, MIPS_CTR_1, 3 },
65bc81ea3adrian	{ PMC_EV_MIPS74K_ITLB_ACCESSES, MIPS_CTR_0, 4 },
66bc81ea3adrian	{ PMC_EV_MIPS74K_ITLB_MISSES, MIPS_CTR_1, 4 },
67bc81ea3adrian	{ PMC_EV_MIPS74K_JTLB_INSN_MISSES, MIPS_CTR_1, 5 },
68bc81ea3adrian	{ PMC_EV_MIPS74K_ICACHE_ACCESSES, MIPS_CTR_0, 6 },
69bc81ea3adrian	{ PMC_EV_MIPS74K_ICACHE_MISSES, MIPS_CTR_1, 6 },
70bc81ea3adrian	{ PMC_EV_MIPS74K_ICACHE_MISS_STALLS, MIPS_CTR_0, 7 },
71bc81ea3adrian	{ PMC_EV_MIPS74K_UNCACHED_IFETCH_STALLS, MIPS_CTR_0, 8 },
72bc81ea3adrian	{ PMC_EV_MIPS74K_PDTRACE_BACK_STALLS, MIPS_CTR_1, 8 },
73bc81ea3adrian	{ PMC_EV_MIPS74K_IFU_REPLAYS, MIPS_CTR_0, 9 },
74bc81ea3adrian	{ PMC_EV_MIPS74K_KILLED_FETCH_SLOTS, MIPS_CTR_1, 9 },
75bc81ea3adrian	{ PMC_EV_MIPS74K_IFU_IDU_MISS_PRED_UPSTREAM_CYCLES, MIPS_CTR_0, 11 },
76bc81ea3adrian	{ PMC_EV_MIPS74K_IFU_IDU_NO_FETCH_CYCLES, MIPS_CTR_1, 11 },
77bc81ea3adrian	{ PMC_EV_MIPS74K_IFU_IDU_CLOGED_DOWNSTREAM_CYCLES, MIPS_CTR_0, 12 },
78bc81ea3adrian	{ PMC_EV_MIPS74K_DDQ0_FULL_DR_STALLS, MIPS_CTR_0, 13 },
79bc81ea3adrian	{ PMC_EV_MIPS74K_DDQ1_FULL_DR_STALLS, MIPS_CTR_1, 13 },
80bc81ea3adrian	{ PMC_EV_MIPS74K_ALCB_FULL_DR_STALLS, MIPS_CTR_0, 14 },
81bc81ea3adrian	{ PMC_EV_MIPS74K_AGCB_FULL_DR_STALLS, MIPS_CTR_1, 14 },
82bc81ea3adrian	{ PMC_EV_MIPS74K_CLDQ_FULL_DR_STALLS, MIPS_CTR_0, 15 },
83bc81ea3adrian	{ PMC_EV_MIPS74K_IODQ_FULL_DR_STALLS, MIPS_CTR_1, 15 },
84bc81ea3adrian	{ PMC_EV_MIPS74K_ALU_EMPTY_CYCLES, MIPS_CTR_0, 16 },
85bc81ea3adrian	{ PMC_EV_MIPS74K_AGEN_EMPTY_CYCLES, MIPS_CTR_1, 16 },
86bc81ea3adrian	{ PMC_EV_MIPS74K_ALU_OPERANDS_NOT_READY_CYCLES, MIPS_CTR_0, 17 },
87bc81ea3adrian	{ PMC_EV_MIPS74K_AGEN_OPERANDS_NOT_READY_CYCLES, MIPS_CTR_1, 17 },
88bc81ea3adrian	{ PMC_EV_MIPS74K_ALU_NO_ISSUES_CYCLES, MIPS_CTR_0, 18 },
89bc81ea3adrian	{ PMC_EV_MIPS74K_AGEN_NO_ISSUES_CYCLES, MIPS_CTR_1, 18 },
90bc81ea3adrian	{ PMC_EV_MIPS74K_ALU_BUBBLE_CYCLES, MIPS_CTR_0, 19 },
91bc81ea3adrian	{ PMC_EV_MIPS74K_AGEN_BUBBLE_CYCLES, MIPS_CTR_1, 19 },
92bc81ea3adrian	{ PMC_EV_MIPS74K_SINGLE_ISSUE_CYCLES, MIPS_CTR_0, 20 },
93bc81ea3adrian	{ PMC_EV_MIPS74K_DUAL_ISSUE_CYCLES, MIPS_CTR_1, 20 },
94bc81ea3adrian	{ PMC_EV_MIPS74K_OOO_ALU_ISSUE_CYCLES, MIPS_CTR_0, 21 },
95bc81ea3adrian	{ PMC_EV_MIPS74K_OOO_AGEN_ISSUE_CYCLES, MIPS_CTR_1, 21 },
96bc81ea3adrian	{ PMC_EV_MIPS74K_JALR_JALR_HB_INSNS, MIPS_CTR_0, 22 },
97bc81ea3adrian	{ PMC_EV_MIPS74K_DCACHE_LINE_REFILL_REQUESTS, MIPS_CTR_1, 22 },
98bc81ea3adrian	{ PMC_EV_MIPS74K_DCACHE_LOAD_ACCESSES, MIPS_CTR_0, 23 },
99bc81ea3adrian	{ PMC_EV_MIPS74K_DCACHE_ACCESSES, MIPS_CTR_1, 23 },
100bc81ea3adrian	{ PMC_EV_MIPS74K_DCACHE_WRITEBACKS, MIPS_CTR_0, 24 },
101bc81ea3adrian	{ PMC_EV_MIPS74K_DCACHE_MISSES, MIPS_CTR_1, 24 },
102bc81ea3adrian	{ PMC_EV_MIPS74K_JTLB_DATA_ACCESSES, MIPS_CTR_0, 25 },
103bc81ea3adrian	{ PMC_EV_MIPS74K_JTLB_DATA_MISSES, MIPS_CTR_1, 25 },
104bc81ea3adrian	{ PMC_EV_MIPS74K_LOAD_STORE_REPLAYS, MIPS_CTR_0, 26 },
105bc81ea3adrian	{ PMC_EV_MIPS74K_VA_TRANSALTION_CORNER_CASES, MIPS_CTR_1, 26 },
106bc81ea3adrian	{ PMC_EV_MIPS74K_LOAD_STORE_BLOCKED_CYCLES, MIPS_CTR_0, 27 },
107bc81ea3adrian	{ PMC_EV_MIPS74K_LOAD_STORE_NO_FILL_REQUESTS, MIPS_CTR_1, 27 },
108bc81ea3adrian	{ PMC_EV_MIPS74K_L2_CACHE_WRITEBACKS, MIPS_CTR_0, 28 },
109bc81ea3adrian	{ PMC_EV_MIPS74K_L2_CACHE_ACCESSES, MIPS_CTR_1, 28 },
110bc81ea3adrian	{ PMC_EV_MIPS74K_L2_CACHE_MISSES, MIPS_CTR_0, 29 },
111bc81ea3adrian	{ PMC_EV_MIPS74K_L2_CACHE_MISS_CYCLES, MIPS_CTR_1, 29 },
112bc81ea3adrian	{ PMC_EV_MIPS74K_FSB_FULL_STALLS, MIPS_CTR_0, 30 },
113bc81ea3adrian	{ PMC_EV_MIPS74K_FSB_OVER_50_FULL, MIPS_CTR_1, 30 },
114bc81ea3adrian	{ PMC_EV_MIPS74K_LDQ_FULL_STALLS, MIPS_CTR_0, 31 },
115bc81ea3adrian	{ PMC_EV_MIPS74K_LDQ_OVER_50_FULL, MIPS_CTR_1, 31 },
116bc81ea3adrian	{ PMC_EV_MIPS74K_WBB_FULL_STALLS, MIPS_CTR_0, 32 },
117bc81ea3adrian	{ PMC_EV_MIPS74K_WBB_OVER_50_FULL, MIPS_CTR_1, 32 },
118bc81ea3adrian	{ PMC_EV_MIPS74K_LOAD_MISS_CONSUMER_REPLAYS, MIPS_CTR_0, 35 },
119bc81ea3adrian	{ PMC_EV_MIPS74K_CP1_CP2_LOAD_INSNS, MIPS_CTR_1, 35 },
120bc81ea3adrian	{ PMC_EV_MIPS74K_JR_NON_31_INSNS, MIPS_CTR_0, 36 },
121bc81ea3adrian	{ PMC_EV_MIPS74K_MISPREDICTED_JR_31_INSNS, MIPS_CTR_1, 36 },
122bc81ea3adrian	{ PMC_EV_MIPS74K_BRANCH_INSNS, MIPS_CTR_0, 37 },
123bc81ea3adrian	{ PMC_EV_MIPS74K_CP1_CP2_COND_BRANCH_INSNS, MIPS_CTR_1, 37 },
124bc81ea3adrian	{ PMC_EV_MIPS74K_BRANCH_LIKELY_INSNS, MIPS_CTR_0, 38 },
125bc81ea3adrian	{ PMC_EV_MIPS74K_MISPREDICTED_BRANCH_LIKELY_INSNS, MIPS_CTR_1, 38 },
126bc81ea3adrian	{ PMC_EV_MIPS74K_COND_BRANCH_INSNS, MIPS_CTR_0, 39 },
127bc81ea3adrian	{ PMC_EV_MIPS74K_MISPREDICTED_BRANCH_INSNS, MIPS_CTR_1, 39 },
128bc81ea3adrian	{ PMC_EV_MIPS74K_INTEGER_INSNS, MIPS_CTR_0, 40 },
129bc81ea3adrian	{ PMC_EV_MIPS74K_FPU_INSNS, MIPS_CTR_1, 40 },
130bc81ea3adrian	{ PMC_EV_MIPS74K_LOAD_INSNS, MIPS_CTR_0, 41 },
131bc81ea3adrian	{ PMC_EV_MIPS74K_STORE_INSNS, MIPS_CTR_1, 41 },
132bc81ea3adrian	{ PMC_EV_MIPS74K_J_JAL_INSNS, MIPS_CTR_0, 42 },
133bc81ea3adrian	{ PMC_EV_MIPS74K_MIPS16_INSNS, MIPS_CTR_1, 42 },
134bc81ea3adrian	{ PMC_EV_MIPS74K_NOP_INSNS, MIPS_CTR_0, 43 },
135bc81ea3adrian	{ PMC_EV_MIPS74K_NT_MUL_DIV_INSNS, MIPS_CTR_1, 43 },
136bc81ea3adrian	{ PMC_EV_MIPS74K_DSP_INSNS, MIPS_CTR_0, 44 },
137bc81ea3adrian	{ PMC_EV_MIPS74K_ALU_DSP_SATURATION_INSNS, MIPS_CTR_1, 44 },
138bc81ea3adrian	{ PMC_EV_MIPS74K_DSP_BRANCH_INSNS, MIPS_CTR_0, 45 },
139bc81ea3adrian	{ PMC_EV_MIPS74K_MDU_DSP_SATURATION_INSNS, MIPS_CTR_1, 45 },
140bc81ea3adrian	{ PMC_EV_MIPS74K_UNCACHED_LOAD_INSNS, MIPS_CTR_0, 46 },
141bc81ea3adrian	{ PMC_EV_MIPS74K_UNCACHED_STORE_INSNS, MIPS_CTR_1, 46 },
142bc81ea3adrian	{ PMC_EV_MIPS74K_EJTAG_INSN_TRIGGERS, MIPS_CTR_0, 49 },
143bc81ea3adrian	{ PMC_EV_MIPS74K_CP1_BRANCH_MISPREDICTIONS, MIPS_CTR_0, 50 },
144bc81ea3adrian	{ PMC_EV_MIPS74K_SC_INSNS, MIPS_CTR_0, 51 },
145bc81ea3adrian	{ PMC_EV_MIPS74K_FAILED_SC_INSNS, MIPS_CTR_1, 51 },
146bc81ea3adrian	{ PMC_EV_MIPS74K_PREFETCH_INSNS, MIPS_CTR_0, 52 },
147bc81ea3adrian	{ PMC_EV_MIPS74K_CACHE_HIT_PREFETCH_INSNS, MIPS_CTR_1, 52 },
148bc81ea3adrian	{ PMC_EV_MIPS74K_NO_INSN_CYCLES, MIPS_CTR_0, 53 },
149bc81ea3adrian	{ PMC_EV_MIPS74K_LOAD_MISS_INSNS, MIPS_CTR_1, 53 },
150bc81ea3adrian	{ PMC_EV_MIPS74K_ONE_INSN_CYCLES, MIPS_CTR_0, 54 },
151bc81ea3adrian	{ PMC_EV_MIPS74K_TWO_INSNS_CYCLES, MIPS_CTR_1, 54 },
152bc81ea3adrian	{ PMC_EV_MIPS74K_GFIFO_BLOCKED_CYCLES, MIPS_CTR_0, 55 },
153bc81ea3adrian	{ PMC_EV_MIPS74K_CP1_CP2_STORE_INSNS, MIPS_CTR_1, 55 },
154bc81ea3adrian	{ PMC_EV_MIPS74K_MISPREDICTION_STALLS, MIPS_CTR_0, 56 },
155bc81ea3adrian	{ PMC_EV_MIPS74K_MISPREDICTED_BRANCH_INSNS_CYCLES, MIPS_CTR_0, 57 },
156bc81ea3adrian	{ PMC_EV_MIPS74K_EXCEPTIONS_TAKEN, MIPS_CTR_0, 58 },
157bc81ea3adrian	{ PMC_EV_MIPS74K_GRADUATION_REPLAYS, MIPS_CTR_1, 58 },
158bc81ea3adrian	{ PMC_EV_MIPS74K_COREEXTEND_EVENTS, MIPS_CTR_0, 59 },
159bc81ea3adrian	{ PMC_EV_MIPS74K_ISPRAM_EVENTS, MIPS_CTR_0, 62 },
160bc81ea3adrian	{ PMC_EV_MIPS74K_DSPRAM_EVENTS, MIPS_CTR_1, 62 },
161bc81ea3adrian	{ PMC_EV_MIPS74K_L2_CACHE_SINGLE_BIT_ERRORS, MIPS_CTR_0, 63 },
162bc81ea3adrian	{ PMC_EV_MIPS74K_SYSTEM_EVENT_0, MIPS_CTR_0, 64 },
163bc81ea3adrian	{ PMC_EV_MIPS74K_SYSTEM_EVENT_1, MIPS_CTR_1, 64 },
164bc81ea3adrian	{ PMC_EV_MIPS74K_SYSTEM_EVENT_2, MIPS_CTR_0, 65 },
165bc81ea3adrian	{ PMC_EV_MIPS74K_SYSTEM_EVENT_3, MIPS_CTR_1, 65 },
166bc81ea3adrian	{ PMC_EV_MIPS74K_SYSTEM_EVENT_4, MIPS_CTR_0, 66 },
167bc81ea3adrian	{ PMC_EV_MIPS74K_SYSTEM_EVENT_5, MIPS_CTR_1, 66 },
168bc81ea3adrian	{ PMC_EV_MIPS74K_SYSTEM_EVENT_6, MIPS_CTR_0, 67 },
169bc81ea3adrian	{ PMC_EV_MIPS74K_SYSTEM_EVENT_7, MIPS_CTR_1, 67 },
170bc81ea3adrian	{ PMC_EV_MIPS74K_OCP_ALL_REQUESTS, MIPS_CTR_0, 68 },
171bc81ea3adrian	{ PMC_EV_MIPS74K_OCP_ALL_CACHEABLE_REQUESTS, MIPS_CTR_1, 68 },
172bc81ea3adrian	{ PMC_EV_MIPS74K_OCP_READ_REQUESTS, MIPS_CTR_0, 69 },
173bc81ea3adrian	{ PMC_EV_MIPS74K_OCP_READ_CACHEABLE_REQUESTS, MIPS_CTR_1, 69 },
174bc81ea3adrian	{ PMC_EV_MIPS74K_OCP_WRITE_REQUESTS, MIPS_CTR_0, 70 },
175bc81ea3adrian	{ PMC_EV_MIPS74K_OCP_WRITE_CACHEABLE_REQUESTS, MIPS_CTR_1, 70 },
176bc81ea3adrian	{ PMC_EV_MIPS74K_FSB_LESS_25_FULL, MIPS_CTR_0, 74 },
177bc81ea3adrian	{ PMC_EV_MIPS74K_FSB_25_50_FULL, MIPS_CTR_1, 74 },
178bc81ea3adrian	{ PMC_EV_MIPS74K_LDQ_LESS_25_FULL, MIPS_CTR_0, 75 },
179bc81ea3adrian	{ PMC_EV_MIPS74K_LDQ_25_50_FULL, MIPS_CTR_1, 75 },
180bc81ea3adrian	{ PMC_EV_MIPS74K_WBB_LESS_25_FULL, MIPS_CTR_0, 76 },
181bc81ea3adrian	{ PMC_EV_MIPS74K_WBB_25_50_FULL, MIPS_CTR_1, 76 },
182bc81ea3adrian};
183bc81ea3adrian
1844274755pfgconst int mips_event_codes_size = nitems(mips_event_codes);
185bc81ea3adrian
186bc81ea3adrianstruct mips_pmc_spec mips_pmc_spec = {
187bc81ea3adrian	.ps_cpuclass = PMC_CLASS_MIPS74K,
188bc81ea3adrian	.ps_cputype = PMC_CPU_MIPS_74K,
189bc81ea3adrian	.ps_capabilities = MIPS74K_PMC_CAPS,
190bc81ea3adrian	.ps_counter_width = 32
191bc81ea3adrian};
192bc81ea3adrian
193bc81ea3adrian/*
194bc81ea3adrian * Performance Count Register N
195bc81ea3adrian */
196bc81ea3adrianuint64_t
197bc81ea3adrianmips_pmcn_read(unsigned int pmc)
198bc81ea3adrian{
199bc81ea3adrian	uint32_t reg = 0;
200bc81ea3adrian
201bc81ea3adrian	KASSERT(pmc < mips_npmcs, ("[mips74k,%d] illegal PMC number %d",
202bc81ea3adrian				   __LINE__, pmc));
203bc81ea3adrian
204bc81ea3adrian	/* The counter value is the next value after the control register. */
205bc81ea3adrian	switch (pmc) {
206bc81ea3adrian	case 0:
207bc81ea3adrian		reg = mips_rd_perfcnt1();
208bc81ea3adrian		break;
209bc81ea3adrian	case 1:
210bc81ea3adrian		reg = mips_rd_perfcnt3();
211bc81ea3adrian		break;
212bc81ea3adrian	default:
213bc81ea3adrian		return 0;
214bc81ea3adrian	}
215bc81ea3adrian	return (reg);
216bc81ea3adrian}
217bc81ea3adrian
218bc81ea3adrianuint64_t
219bc81ea3adrianmips_pmcn_write(unsigned int pmc, uint64_t reg)
220bc81ea3adrian{
221bc81ea3adrian
222bc81ea3adrian	KASSERT(pmc < mips_npmcs, ("[mips74k,%d] illegal PMC number %d",
223bc81ea3adrian				   __LINE__, pmc));
224bc81ea3adrian
225bc81ea3adrian	switch (pmc) {
226bc81ea3adrian	case 0:
227bc81ea3adrian		mips_wr_perfcnt1(reg);
228bc81ea3adrian		break;
229bc81ea3adrian	case 1:
230bc81ea3adrian		mips_wr_perfcnt3(reg);
231bc81ea3adrian		break;
232bc81ea3adrian	default:
233bc81ea3adrian		return 0;
234bc81ea3adrian	}
235bc81ea3adrian	return (reg);
236bc81ea3adrian}
237bc81ea3adrian
238bc81ea3adrianuint32_t
239bc81ea3adrianmips_get_perfctl(int cpu, int ri, uint32_t event, uint32_t caps)
240bc81ea3adrian{
241bc81ea3adrian	uint32_t config;
242bc81ea3adrian
243bc81ea3adrian	config = event;
244bc81ea3adrian
245bc81ea3adrian	config <<= MIPS74K_PMC_SELECT;
246bc81ea3adrian
247bc81ea3adrian	if (caps & PMC_CAP_SYSTEM)
248bc81ea3adrian		config |= (MIPS74K_PMC_SUPER_ENABLE |
249bc81ea3adrian			   MIPS74K_PMC_KERNEL_ENABLE);
250bc81ea3adrian	if (caps & PMC_CAP_USER)
251bc81ea3adrian		config |= MIPS74K_PMC_USER_ENABLE;
252bc81ea3adrian	if ((caps & (PMC_CAP_USER | PMC_CAP_SYSTEM)) == 0)
253bc81ea3adrian		config |= MIPS74K_PMC_ENABLE;
254bc81ea3adrian	if (caps & PMC_CAP_INTERRUPT)
255bc81ea3adrian		config |= MIPS74K_PMC_INTERRUPT_ENABLE;
256bc81ea3adrian
2574f7fc38bz	PMCDBG2(MDP,ALL,2,"mips74k-get_perfctl ri=%d -> config=0x%x", ri, config);
258bc81ea3adrian
259bc81ea3adrian	return (config);
260bc81ea3adrian}
261