2 * This file contains the Itanium PMU register description tables
3 * and pmc checker used by perfmon.c.
5 * Copyright (C) 2002-2003 Hewlett Packard Co
6 * Stephane Eranian <eranian@hpl.hp.com>
8 static int pfm_ita_pmc_check(struct task_struct
*task
, pfm_context_t
*ctx
, unsigned int cnum
, unsigned long *val
, struct pt_regs
*regs
);
10 static pfm_reg_desc_t pfm_ita_pmc_desc
[PMU_MAX_PMCS
]={
11 /* pmc0 */ { PFM_REG_CONTROL
, 0, 0x1UL
, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
12 /* pmc1 */ { PFM_REG_CONTROL
, 0, 0x0UL
, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
13 /* pmc2 */ { PFM_REG_CONTROL
, 0, 0x0UL
, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
14 /* pmc3 */ { PFM_REG_CONTROL
, 0, 0x0UL
, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
15 /* pmc4 */ { PFM_REG_COUNTING
, 6, 0x0UL
, -1UL, NULL
, NULL
, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
16 /* pmc5 */ { PFM_REG_COUNTING
, 6, 0x0UL
, -1UL, NULL
, NULL
, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
17 /* pmc6 */ { PFM_REG_COUNTING
, 6, 0x0UL
, -1UL, NULL
, NULL
, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
18 /* pmc7 */ { PFM_REG_COUNTING
, 6, 0x0UL
, -1UL, NULL
, NULL
, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
19 /* pmc8 */ { PFM_REG_CONFIG
, 0, 0xf00000003ffffff8UL
, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
20 /* pmc9 */ { PFM_REG_CONFIG
, 0, 0xf00000003ffffff8UL
, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
21 /* pmc10 */ { PFM_REG_MONITOR
, 6, 0x0UL
, -1UL, NULL
, NULL
, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
22 /* 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}},
23 /* 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}},
24 /* pmc13 */ { PFM_REG_CONFIG
, 0, 0x0003ffff00000001UL
, -1UL, NULL
, pfm_ita_pmc_check
, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
25 { PFM_REG_END
, 0, 0x0UL
, -1UL, NULL
, NULL
, {0,}, {0,}}, /* end marker */
28 static pfm_reg_desc_t pfm_ita_pmd_desc
[PMU_MAX_PMDS
]={
29 /* pmd0 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
30 /* pmd1 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
31 /* pmd2 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
32 /* pmd3 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(2)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
33 /* pmd4 */ { PFM_REG_COUNTING
, 0, 0UL, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
34 /* pmd5 */ { PFM_REG_COUNTING
, 0, 0UL, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
35 /* pmd6 */ { PFM_REG_COUNTING
, 0, 0UL, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
36 /* pmd7 */ { PFM_REG_COUNTING
, 0, 0UL, -1UL, NULL
, NULL
, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
37 /* 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}},
38 /* 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}},
39 /* 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}},
40 /* 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}},
41 /* 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}},
42 /* 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}},
43 /* 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}},
44 /* 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}},
45 /* 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}},
46 /* pmd17 */ { PFM_REG_BUFFER
, 0, 0UL, -1UL, NULL
, NULL
, {RDEP(2)|RDEP(3),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
47 { PFM_REG_END
, 0, 0UL, -1UL, NULL
, NULL
, {0,}, {0,}}, /* end marker */
51 pfm_ita_pmc_check(struct task_struct
*task
, pfm_context_t
*ctx
, unsigned int cnum
, unsigned long *val
, struct pt_regs
*regs
)
57 if (ctx
== NULL
) return -EINVAL
;
59 is_loaded
= ctx
->ctx_state
== PFM_CTX_LOADED
|| ctx
->ctx_state
== PFM_CTX_MASKED
;
62 * we must clear the (instruction) debug registers if pmc13.ta bit is cleared
63 * before they are written (fl_using_dbreg==0) to avoid picking up stale information.
65 if (cnum
== 13 && is_loaded
&& ((*val
& 0x1) == 0UL) && ctx
->ctx_fl_using_dbreg
== 0) {
67 DPRINT(("pmc[%d]=0x%lx has active pmc13.ta cleared, clearing ibr\n", cnum
, *val
));
69 /* don't mix debug with perfmon */
70 if (task
&& (task
->thread
.flags
& IA64_THREAD_DBG_VALID
) != 0) return -EINVAL
;
73 * a count of 0 will mark the debug registers as in use and also
74 * ensure that they are properly cleared.
76 ret
= pfm_write_ibr_dbr(1, ctx
, NULL
, 0, regs
);
81 * we must clear the (data) debug registers if pmc11.pt bit is cleared
82 * before they are written (fl_using_dbreg==0) to avoid picking up stale information.
84 if (cnum
== 11 && is_loaded
&& ((*val
>> 28)& 0x1) == 0 && ctx
->ctx_fl_using_dbreg
== 0) {
86 DPRINT(("pmc[%d]=0x%lx has active pmc11.pt cleared, clearing dbr\n", cnum
, *val
));
88 /* don't mix debug with perfmon */
89 if (task
&& (task
->thread
.flags
& IA64_THREAD_DBG_VALID
) != 0) return -EINVAL
;
92 * a count of 0 will mark the debug registers as in use and also
93 * ensure that they are properly cleared.
95 ret
= pfm_write_ibr_dbr(0, ctx
, NULL
, 0, regs
);
102 * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
104 static pmu_config_t pmu_conf_ita
={
105 .pmu_name
= "Itanium",
107 .ovfl_val
= (1UL << 32) - 1,
108 .pmd_desc
= pfm_ita_pmd_desc
,
109 .pmc_desc
= pfm_ita_pmc_desc
,
112 .use_rr_dbregs
= 1, /* debug register are use for range retrictions */