1 /* SPDX-License-Identifier: GPL-2.0 */
3 * This file contains the Itanium PMU register description tables
4 * and pmc checker used by perfmon.c.
6 * Copyright (C) 2002-2003 Hewlett Packard Co
7 * Stephane Eranian <eranian@hpl.hp.com>
9 static int pfm_ita_pmc_check(struct task_struct
*task
, pfm_context_t
*ctx
, unsigned int cnum
, unsigned long *val
, struct pt_regs
*regs
);
11 static pfm_reg_desc_t pfm_ita_pmc_desc
[PMU_MAX_PMCS
]={
12 /* pmc0 */ { PFM_REG_CONTROL
, 0, 0x1UL
, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
13 /* pmc1 */ { PFM_REG_CONTROL
, 0, 0x0UL
, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
14 /* pmc2 */ { PFM_REG_CONTROL
, 0, 0x0UL
, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
15 /* pmc3 */ { PFM_REG_CONTROL
, 0, 0x0UL
, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
16 /* pmc4 */ { PFM_REG_COUNTING
, 6, 0x0UL
, -1UL, NULL
, NULL
, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
17 /* pmc5 */ { PFM_REG_COUNTING
, 6, 0x0UL
, -1UL, NULL
, NULL
, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
18 /* pmc6 */ { PFM_REG_COUNTING
, 6, 0x0UL
, -1UL, NULL
, NULL
, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
19 /* pmc7 */ { PFM_REG_COUNTING
, 6, 0x0UL
, -1UL, NULL
, NULL
, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
20 /* pmc8 */ { PFM_REG_CONFIG
, 0, 0xf00000003ffffff8UL
, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
21 /* pmc9 */ { PFM_REG_CONFIG
, 0, 0xf00000003ffffff8UL
, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
22 /* pmc10 */ { PFM_REG_MONITOR
, 6, 0x0UL
, -1UL, NULL
, NULL
, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
23 /* pmc11 */ { PFM_REG_MONITOR
, 6, 0x0000000010000000UL
, -1UL, NULL
, pfm_ita_pmc_check
, {RDEP(2)|RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
24 /* pmc12 */ { PFM_REG_MONITOR
, 6, 0x0UL
, -1UL, NULL
, NULL
, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
25 /* pmc13 */ { PFM_REG_CONFIG
, 0, 0x0003ffff00000001UL
, -1UL, NULL
, pfm_ita_pmc_check
, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
26 { PFM_REG_END
, 0, 0x0UL
, -1UL, NULL
, NULL
, {0,}, {0,}}, /* end marker */
29 static pfm_reg_desc_t pfm_ita_pmd_desc
[PMU_MAX_PMDS
]={
30 /* pmd0 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
31 /* pmd1 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
32 /* pmd2 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
33 /* pmd3 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(2)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
34 /* pmd4 */ { PFM_REG_COUNTING
, 0, 0UL, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
35 /* pmd5 */ { PFM_REG_COUNTING
, 0, 0UL, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
36 /* pmd6 */ { PFM_REG_COUNTING
, 0, 0UL, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
37 /* pmd7 */ { PFM_REG_COUNTING
, 0, 0UL, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
38 /* pmd8 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
39 /* pmd9 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(8)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
40 /* pmd10 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(8)|RDEP(9)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
41 /* pmd11 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
42 /* pmd12 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
43 /* pmd13 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
44 /* pmd14 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
45 /* pmd15 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
46 /* pmd16 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
47 /* pmd17 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(2)|RDEP(3),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
48 { PFM_REG_END
, 0, 0UL, -1UL, NULL
, NULL
, {0,}, {0,}}, /* end marker */
52 pfm_ita_pmc_check(struct task_struct
*task
, pfm_context_t
*ctx
, unsigned int cnum
, unsigned long *val
, struct pt_regs
*regs
)
58 if (ctx
== NULL
) return -EINVAL
;
60 is_loaded
= ctx
->ctx_state
== PFM_CTX_LOADED
|| ctx
->ctx_state
== PFM_CTX_MASKED
;
63 * we must clear the (instruction) debug registers if pmc13.ta bit is cleared
64 * before they are written (fl_using_dbreg==0) to avoid picking up stale information.
66 if (cnum
== 13 && is_loaded
&& ((*val
& 0x1) == 0UL) && ctx
->ctx_fl_using_dbreg
== 0) {
68 DPRINT(("pmc[%d]=0x%lx has active pmc13.ta cleared, clearing ibr\n", cnum
, *val
));
70 /* don't mix debug with perfmon */
71 if (task
&& (task
->thread
.flags
& IA64_THREAD_DBG_VALID
) != 0) return -EINVAL
;
74 * a count of 0 will mark the debug registers as in use and also
75 * ensure that they are properly cleared.
77 ret
= pfm_write_ibr_dbr(1, ctx
, NULL
, 0, regs
);
82 * we must clear the (data) debug registers if pmc11.pt bit is cleared
83 * before they are written (fl_using_dbreg==0) to avoid picking up stale information.
85 if (cnum
== 11 && is_loaded
&& ((*val
>> 28)& 0x1) == 0 && ctx
->ctx_fl_using_dbreg
== 0) {
87 DPRINT(("pmc[%d]=0x%lx has active pmc11.pt cleared, clearing dbr\n", cnum
, *val
));
89 /* don't mix debug with perfmon */
90 if (task
&& (task
->thread
.flags
& IA64_THREAD_DBG_VALID
) != 0) return -EINVAL
;
93 * a count of 0 will mark the debug registers as in use and also
94 * ensure that they are properly cleared.
96 ret
= pfm_write_ibr_dbr(0, ctx
, NULL
, 0, regs
);
103 * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
105 static pmu_config_t pmu_conf_ita
={
106 .pmu_name
= "Itanium",
108 .ovfl_val
= (1UL << 32) - 1,
109 .pmd_desc
= pfm_ita_pmd_desc
,
110 .pmc_desc
= pfm_ita_pmc_desc
,
113 .use_rr_dbregs
= 1, /* debug register are use for range retrictions */