aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRobert Richter <robert.richter@amd.com>2009-06-03 14:10:39 -0400
committerRobert Richter <robert.richter@amd.com>2009-06-11 14:16:00 -0400
commitc572ae4efd1b0a5cc76c5e6aae05c1b182b6a69c (patch)
tree0e57db0103215742c6e882eb16da9db7ea6a047f /arch
parent1a245c45343651a87ff63afc5ddeb8e24d731835 (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.c131
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
49static int has_ibs; /* AMD Family10h and later */ 51static int has_ibs; /* AMD Family10h and later */
50 52
@@ -126,66 +128,63 @@ static inline int
126op_amd_handle_ibs(struct pt_regs * const regs, 128op_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
195static inline void op_amd_start_ibs(void) 194static 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
214static void op_amd_stop_ibs(void) 212static 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