diff options
author | Robert Richter <robert.richter@amd.com> | 2009-06-03 14:10:39 -0400 |
---|---|---|
committer | Robert Richter <robert.richter@amd.com> | 2009-06-11 14:16:00 -0400 |
commit | c572ae4efd1b0a5cc76c5e6aae05c1b182b6a69c (patch) | |
tree | 0e57db0103215742c6e882eb16da9db7ea6a047f /arch | |
parent | 1a245c45343651a87ff63afc5ddeb8e24d731835 (diff) |
x86/oprofile: use 64 bit values in IBS functions
The IBS code internally uses 32 bit values (a low and a high value) to
represent a 64 bit value. This patch changes this and now 64 bit
values are used instead. 64 bit MSR functions can be used now.
No functional changes.
Signed-off-by: Robert Richter <robert.richter@amd.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/oprofile/op_model_amd.c | 131 |
1 files changed, 61 insertions, 70 deletions
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 9bf901762411..6493ef7ae9ad 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c | |||
@@ -35,16 +35,18 @@ static unsigned long reset_value[NUM_COUNTERS]; | |||
35 | #ifdef CONFIG_OPROFILE_IBS | 35 | #ifdef CONFIG_OPROFILE_IBS |
36 | 36 | ||
37 | /* IbsFetchCtl bits/masks */ | 37 | /* IbsFetchCtl bits/masks */ |
38 | #define IBS_FETCH_HIGH_VALID_BIT (1UL << 17) /* bit 49 */ | 38 | #define IBS_FETCH_RAND_EN (1ULL<<57) |
39 | #define IBS_FETCH_HIGH_ENABLE (1UL << 16) /* bit 48 */ | 39 | #define IBS_FETCH_VAL (1ULL<<49) |
40 | #define IBS_FETCH_LOW_MAX_CNT_MASK 0x0000FFFFUL /* MaxCnt mask */ | 40 | #define IBS_FETCH_ENABLE (1ULL<<48) |
41 | #define IBS_FETCH_CNT_MASK 0xFFFF0000ULL | ||
41 | 42 | ||
42 | /*IbsOpCtl bits */ | 43 | /*IbsOpCtl bits */ |
43 | #define IBS_OP_LOW_VALID_BIT (1ULL<<18) /* bit 18 */ | 44 | #define IBS_OP_CNT_CTL (1ULL<<19) |
44 | #define IBS_OP_LOW_ENABLE (1ULL<<17) /* bit 17 */ | 45 | #define IBS_OP_VAL (1ULL<<18) |
46 | #define IBS_OP_ENABLE (1ULL<<17) | ||
45 | 47 | ||
46 | #define IBS_FETCH_SIZE 6 | 48 | #define IBS_FETCH_SIZE 6 |
47 | #define IBS_OP_SIZE 12 | 49 | #define IBS_OP_SIZE 12 |
48 | 50 | ||
49 | static int has_ibs; /* AMD Family10h and later */ | 51 | static int has_ibs; /* AMD Family10h and later */ |
50 | 52 | ||
@@ -126,66 +128,63 @@ static inline int | |||
126 | op_amd_handle_ibs(struct pt_regs * const regs, | 128 | op_amd_handle_ibs(struct pt_regs * const regs, |
127 | struct op_msrs const * const msrs) | 129 | struct op_msrs const * const msrs) |
128 | { | 130 | { |
129 | u32 low, high; | 131 | u64 val, ctl; |
130 | u64 msr; | ||
131 | struct op_entry entry; | 132 | struct op_entry entry; |
132 | 133 | ||
133 | if (!has_ibs) | 134 | if (!has_ibs) |
134 | return 1; | 135 | return 1; |
135 | 136 | ||
136 | if (ibs_config.fetch_enabled) { | 137 | if (ibs_config.fetch_enabled) { |
137 | rdmsr(MSR_AMD64_IBSFETCHCTL, low, high); | 138 | rdmsrl(MSR_AMD64_IBSFETCHCTL, ctl); |
138 | if (high & IBS_FETCH_HIGH_VALID_BIT) { | 139 | if (ctl & IBS_FETCH_VAL) { |
139 | rdmsrl(MSR_AMD64_IBSFETCHLINAD, msr); | 140 | rdmsrl(MSR_AMD64_IBSFETCHLINAD, val); |
140 | oprofile_write_reserve(&entry, regs, msr, | 141 | oprofile_write_reserve(&entry, regs, val, |
141 | IBS_FETCH_CODE, IBS_FETCH_SIZE); | 142 | IBS_FETCH_CODE, IBS_FETCH_SIZE); |
142 | oprofile_add_data(&entry, (u32)msr); | 143 | oprofile_add_data(&entry, (u32)val); |
143 | oprofile_add_data(&entry, (u32)(msr >> 32)); | 144 | oprofile_add_data(&entry, (u32)(val >> 32)); |
144 | oprofile_add_data(&entry, low); | 145 | oprofile_add_data(&entry, (u32)ctl); |
145 | oprofile_add_data(&entry, high); | 146 | oprofile_add_data(&entry, (u32)(ctl >> 32)); |
146 | rdmsrl(MSR_AMD64_IBSFETCHPHYSAD, msr); | 147 | rdmsrl(MSR_AMD64_IBSFETCHPHYSAD, val); |
147 | oprofile_add_data(&entry, (u32)msr); | 148 | oprofile_add_data(&entry, (u32)val); |
148 | oprofile_add_data(&entry, (u32)(msr >> 32)); | 149 | oprofile_add_data(&entry, (u32)(val >> 32)); |
149 | oprofile_write_commit(&entry); | 150 | oprofile_write_commit(&entry); |
150 | 151 | ||
151 | /* reenable the IRQ */ | 152 | /* reenable the IRQ */ |
152 | high &= ~IBS_FETCH_HIGH_VALID_BIT; | 153 | ctl &= ~(IBS_FETCH_VAL | IBS_FETCH_CNT_MASK); |
153 | high |= IBS_FETCH_HIGH_ENABLE; | 154 | ctl |= IBS_FETCH_ENABLE; |
154 | low &= IBS_FETCH_LOW_MAX_CNT_MASK; | 155 | wrmsrl(MSR_AMD64_IBSFETCHCTL, ctl); |
155 | wrmsr(MSR_AMD64_IBSFETCHCTL, low, high); | ||
156 | } | 156 | } |
157 | } | 157 | } |
158 | 158 | ||
159 | if (ibs_config.op_enabled) { | 159 | if (ibs_config.op_enabled) { |
160 | rdmsr(MSR_AMD64_IBSOPCTL, low, high); | 160 | rdmsrl(MSR_AMD64_IBSOPCTL, ctl); |
161 | if (low & IBS_OP_LOW_VALID_BIT) { | 161 | if (ctl & IBS_OP_VAL) { |
162 | rdmsrl(MSR_AMD64_IBSOPRIP, msr); | 162 | rdmsrl(MSR_AMD64_IBSOPRIP, val); |
163 | oprofile_write_reserve(&entry, regs, msr, | 163 | oprofile_write_reserve(&entry, regs, val, |
164 | IBS_OP_CODE, IBS_OP_SIZE); | 164 | IBS_OP_CODE, IBS_OP_SIZE); |
165 | oprofile_add_data(&entry, (u32)msr); | 165 | oprofile_add_data(&entry, (u32)val); |
166 | oprofile_add_data(&entry, (u32)(msr >> 32)); | 166 | oprofile_add_data(&entry, (u32)(val >> 32)); |
167 | rdmsrl(MSR_AMD64_IBSOPDATA, msr); | 167 | rdmsrl(MSR_AMD64_IBSOPDATA, val); |
168 | oprofile_add_data(&entry, (u32)msr); | 168 | oprofile_add_data(&entry, (u32)val); |
169 | oprofile_add_data(&entry, (u32)(msr >> 32)); | 169 | oprofile_add_data(&entry, (u32)(val >> 32)); |
170 | rdmsrl(MSR_AMD64_IBSOPDATA2, msr); | 170 | rdmsrl(MSR_AMD64_IBSOPDATA2, val); |
171 | oprofile_add_data(&entry, (u32)msr); | 171 | oprofile_add_data(&entry, (u32)val); |
172 | oprofile_add_data(&entry, (u32)(msr >> 32)); | 172 | oprofile_add_data(&entry, (u32)(val >> 32)); |
173 | rdmsrl(MSR_AMD64_IBSOPDATA3, msr); | 173 | rdmsrl(MSR_AMD64_IBSOPDATA3, val); |
174 | oprofile_add_data(&entry, (u32)msr); | 174 | oprofile_add_data(&entry, (u32)val); |
175 | oprofile_add_data(&entry, (u32)(msr >> 32)); | 175 | oprofile_add_data(&entry, (u32)(val >> 32)); |
176 | rdmsrl(MSR_AMD64_IBSDCLINAD, msr); | 176 | rdmsrl(MSR_AMD64_IBSDCLINAD, val); |
177 | oprofile_add_data(&entry, (u32)msr); | 177 | oprofile_add_data(&entry, (u32)val); |
178 | oprofile_add_data(&entry, (u32)(msr >> 32)); | 178 | oprofile_add_data(&entry, (u32)(val >> 32)); |
179 | rdmsrl(MSR_AMD64_IBSDCPHYSAD, msr); | 179 | rdmsrl(MSR_AMD64_IBSDCPHYSAD, val); |
180 | oprofile_add_data(&entry, (u32)msr); | 180 | oprofile_add_data(&entry, (u32)val); |
181 | oprofile_add_data(&entry, (u32)(msr >> 32)); | 181 | oprofile_add_data(&entry, (u32)(val >> 32)); |
182 | oprofile_write_commit(&entry); | 182 | oprofile_write_commit(&entry); |
183 | 183 | ||
184 | /* reenable the IRQ */ | 184 | /* reenable the IRQ */ |
185 | high = 0; | 185 | ctl &= ~IBS_OP_VAL & 0xFFFFFFFF; |
186 | low &= ~IBS_OP_LOW_VALID_BIT; | 186 | ctl |= IBS_OP_ENABLE; |
187 | low |= IBS_OP_LOW_ENABLE; | 187 | wrmsrl(MSR_AMD64_IBSOPCTL, ctl); |
188 | wrmsr(MSR_AMD64_IBSOPCTL, low, high); | ||
189 | } | 188 | } |
190 | } | 189 | } |
191 | 190 | ||
@@ -194,39 +193,31 @@ op_amd_handle_ibs(struct pt_regs * const regs, | |||
194 | 193 | ||
195 | static inline void op_amd_start_ibs(void) | 194 | static inline void op_amd_start_ibs(void) |
196 | { | 195 | { |
197 | unsigned int low, high; | 196 | u64 val; |
198 | if (has_ibs && ibs_config.fetch_enabled) { | 197 | if (has_ibs && ibs_config.fetch_enabled) { |
199 | low = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF; | 198 | val = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF; |
200 | high = ((ibs_config.rand_en & 0x1) << 25) /* bit 57 */ | 199 | val |= ibs_config.rand_en ? IBS_FETCH_RAND_EN : 0; |
201 | + IBS_FETCH_HIGH_ENABLE; | 200 | val |= IBS_FETCH_ENABLE; |
202 | wrmsr(MSR_AMD64_IBSFETCHCTL, low, high); | 201 | wrmsrl(MSR_AMD64_IBSFETCHCTL, val); |
203 | } | 202 | } |
204 | 203 | ||
205 | if (has_ibs && ibs_config.op_enabled) { | 204 | if (has_ibs && ibs_config.op_enabled) { |
206 | low = ((ibs_config.max_cnt_op >> 4) & 0xFFFF) | 205 | val = (ibs_config.max_cnt_op >> 4) & 0xFFFF; |
207 | + ((ibs_config.dispatched_ops & 0x1) << 19) /* bit 19 */ | 206 | val |= ibs_config.dispatched_ops ? IBS_OP_CNT_CTL : 0; |
208 | + IBS_OP_LOW_ENABLE; | 207 | val |= IBS_OP_ENABLE; |
209 | high = 0; | 208 | wrmsrl(MSR_AMD64_IBSOPCTL, val); |
210 | wrmsr(MSR_AMD64_IBSOPCTL, low, high); | ||
211 | } | 209 | } |
212 | } | 210 | } |
213 | 211 | ||
214 | static void op_amd_stop_ibs(void) | 212 | static void op_amd_stop_ibs(void) |
215 | { | 213 | { |
216 | unsigned int low, high; | 214 | if (has_ibs && ibs_config.fetch_enabled) |
217 | if (has_ibs && ibs_config.fetch_enabled) { | ||
218 | /* clear max count and enable */ | 215 | /* clear max count and enable */ |
219 | low = 0; | 216 | wrmsrl(MSR_AMD64_IBSFETCHCTL, 0); |
220 | high = 0; | ||
221 | wrmsr(MSR_AMD64_IBSFETCHCTL, low, high); | ||
222 | } | ||
223 | 217 | ||
224 | if (has_ibs && ibs_config.op_enabled) { | 218 | if (has_ibs && ibs_config.op_enabled) |
225 | /* clear max count and enable */ | 219 | /* clear max count and enable */ |
226 | low = 0; | 220 | wrmsrl(MSR_AMD64_IBSOPCTL, 0); |
227 | high = 0; | ||
228 | wrmsr(MSR_AMD64_IBSOPCTL, low, high); | ||
229 | } | ||
230 | } | 221 | } |
231 | 222 | ||
232 | #else | 223 | #else |