forked from spomile/LoopHPCs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimple-pebs.c
332 lines (272 loc) · 9.04 KB
/
simple-pebs.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
#include "simple-pebs.h"
#include "dbg\debug.h"
#include "checks\checks.h"
#define wrmsrl __writemsr
#define rdmsrl __readmsr
DWORD32 StaticMask[Multiplexing][MAX_PMCx][4]=
{
{
{ALL_BRANCHS, 0,STORE_PERIOD,0},
{ALL_STORES, 0,STORE_PERIOD,0},
#if MAX_PMCx >=3
{ALL_STORES , 0,0,0}, //PMC-ratio[0][2]
#endif
#if MAX_PMCx >=4
{ALL_LOADS, 0,0,0}, //PMC-ratio[0][3]
#endif
},
#if Multiplexing>=2
{
{ALL_BRANCHS, 0,STORE_PERIOD,0},
{ICACHE_Misses, 0,0,0},
#if MAX_PMCx >=3
{ALL_STORES , 0,0,0}, //PMC-ratio[1][2]
#endif
#if MAX_PMCx >=4
{ALL_LOADS, 0,0,0} //PMC-ratio[1][3]
#endif
},
#endif
#if Multiplexing>=3
{
{ALL_STORES, 0,STORE_PERIOD,0},
{ALL_BRANCHS, 0,STORE_PERIOD,0},
{L2_MISS , 0,0,0}, //PMC-ratio[2][2]
{L2_HIT, 0,0,0} //PMC-ratio[2][3]
},
#endif
#if Multiplexing>=4
{
{ALL_STORES, 0,STORE_PERIOD,0},
{ALL_BRANCHS, 0,STORE_PERIOD,0},
{L3_MISS , 0,0,0}, //PMC-ratio[3][2]
{L3_HIT, 0,0,0} //PMC-ratio[3][3]
}
#endif
};
/*
#define Mask_BR_CONDITIONAL 0x01C4 //Precise
#define Mask_BR_NOTTAKEN 0x10C4
#define Mask_NEAR_CALL 0x02C4 //Precise
#define Mask_NEAR_RETURN 0x08C4 //Precise
#define Mask_ALL_BRANCHS 0x00C4//Precise
// New Event
#define BR_MISP_RETIRED_CONDITIONAL 0x01C5
#define BR_MISP_RETIRED_NEAR_TAKEN 0x20C5
*/
/*
//------------ precious
#define ALL_BRANCHES_PS 0x04C4
#define Mask_ALL_LOADS 0x81D0
#define Mask_ALL_STORES 0x82D0
#define MEM_UOPS_RETIRED_STLB_MISS_LOADS 0x11D0
#define MEM_UOPS_RETIRED_STLB_MISS_STORES 0x12D0
#define L1_MISS 0x08D1
#define L2_MISS 0x10D1
#define L3_MISS 0x20D1
#define L1_HIT 0x01D1
#define L2_HIT 0x02D1
#define L3_HIT 0x04D1
#define BR_MISP_RETIRED_All_branches_PS 0x04C4
//------------ Non precious
#define ALL_BRANCHES 0x00C4
#define DTLB_LOAD_MISSES_MISS_CAUSES_A_WALK 0x0108
#define DTLB_STORE_MISSE_MISS_CAUSES_A_WALK 0x0149
#define BR_MISP_RETIRED_All_branches 0x00C5
//Feature Importance<0.01
#define LLC_Misses 0x412E
#define ICACHE_MISSES 0x0280
#define SMC 0x04C3
*/
/*****************************************************
Fixed counters
*****************************************************/
/* INST_RETIRED.ANY
is counted by a designated fixed counter, leaving the four
(eight when Hyperthreading is disabled) programmable counters available for other events.
*/
void init_instr(){
unsigned long long tmp;
tmp= rdmsrl(MSR_PERF_FIXED_CTR_CTRL);
tmp = tmp | 0x2;
wrmsrl(MSR_PERF_FIXED_CTR_CTRL, tmp);/*enable fixed counter for #instr*/
wrmsrl(MSR_FIXED_CTR0, 0);
}
unsigned long long get_inst( BOOLEAN bPrint)
{
if(bPrint)
{
MyDbgPrint("get_current_instr=%d ", rdmsrl(MSR_FIXED_CTR0));
}
return rdmsrl(MSR_FIXED_CTR0);
}
void init_cycle(){
unsigned long long tmp;
tmp=rdmsrl(MSR_PERF_FIXED_CTR_CTRL);
tmp = tmp | 0x20;
wrmsrl(MSR_PERF_FIXED_CTR_CTRL, tmp);/*enable fixed counter for #cycle*/
wrmsrl(MSR_FIXED_CTR1, 0);
}
unsigned long long get_cycle(BOOLEAN bPrint){
if(bPrint)
{
MyDbgPrint("get_current_cycle=%d ",rdmsrl(MSR_FIXED_CTR1));
}
return rdmsrl(MSR_FIXED_CTR1);
}
/*****************************************************
Programabled Counters
*****************************************************/
// Config _PMCx_NUM_ (4 or 8) pairs of ERFEVTSELx and PMCx;
void init_PMCx(int outset)
{
int i;
unsigned long long mask;
for (i=outset;i<MAX_PMCx;i++)
{
// Select the event for MSR_IA32_EVNTSELx
mask=StaticMask[Multiplex_Index][i][0]|StaticMask[Multiplex_Index][i][1]
| EVTSEL_EN | EVTSEL_USR;
wrmsrl(MSR_IA32_EVNTSEL0+i,mask);
__writemsr(MSR_IA32_PERFCTR0+i,-(int)StaticMask[Multiplex_Index][i][2]);
}
}
unsigned long long get_PMCx(int index, BOOLEAN bPrint)
{
unsigned long long PMCxValue=0;
if(index<=NumberofPEBS-1)
{
if(bPrint)
{
MyDbgPrint("PMC%d=%d",index,(rdmsrl(MSR_IA32_PERFCTR0+index)+StaticMask[Multiplex_Index][index][_COUNTER_DELTA_]) );
}
return rdmsrl(MSR_IA32_PERFCTR0+index)+StaticMask[Multiplex_Index][index][_COUNTER_DELTA_];
}
//Invalid PMCx
else
{
MyDbgPrint("[get_PMCx] NumberofPEBS=%d, Unused PMC%d",NumberofPEBS, index);
return 0;
}
}
void enable_PEB( )
{
int i;
unsigned long long tmp=1;
// DbgPrint("_PEB_PMCx =%d", _PEB_PMCx_);
for (i=0;i<4;i++)
{
if(tmp&_PEB_PMCx_)
{
DbgPrint("enable_PEB for PMC%d", i);
}
tmp=tmp<<1;
}
//First disable PMU to avoid races
__writemsr(MSR_IA32_PEBS_ENABLE, 0);
__writemsr(MSR_IA32_GLOBAL_CTRL, 0);
init_instr();
init_cycle();
init_PMCx(0);
//enable special PMU register again
wrmsrl(MSR_IA32_PEBS_ENABLE, _PEB_PMCx_);
tmp= rdmsrl(MSR_IA32_PERF_GLOBAL_CTRL);
// enable the fixed counter 0-1, and PMC 0-3.
//20-9-19
tmp = tmp | _Counter_;
wrmsrl(MSR_IA32_PERF_GLOBAL_CTRL, tmp);
return;
}
void disable_PEB()
{
LARGE_INTEGER pa;
UINT32* APIC;
int IndexofPMC;
DbgPrint("disable_PEB");
//get_instr(TRUE);
get_PMCx(PMC0,TRUE);
get_PMCx(PMC1,TRUE);
get_PMCx(PMC2,TRUE);
get_PMCx(PMC3,TRUE);
get_PMCx(PMC4,TRUE);
get_PMCx(PMC5,TRUE);
get_PMCx(PMC6,TRUE);
get_PMCx(PMC7,TRUE);
wrmsrl(MSR_IA32_PERF_GLOBAL_CTRL, 0);
wrmsrl(MSR_IA32_PEBS_ENABLE, 0);
//clear special PMU
for(IndexofPMC=0;IndexofPMC<MAX_PMCx;IndexofPMC++)
{
__writemsr(MSR_IA32_EVNTSEL0+IndexofPMC, 0);
__writemsr(MSR_IA32_PERFCTR0+IndexofPMC, 0);
}
//stop special PMU
__writemsr(MSR_PERF_FIXED_CTR_CTRL, 0);
//restore the APIC value
pa.QuadPart=PERF_COUNTER_APIC;
APIC=(UINT32*)MmMapIoSpace(pa,sizeof(UINT32),MmNonCached);
*APIC=ORIGINAL_APIC_VALUE;
MmUnmapIoSpace(APIC,sizeof(APIC));
//In a new thread, it must return at the end of function, otherwise, it will incur BoS.
return;
}
// Changed from BTS to PEBS
void FILL_DS_WITH_BUFFER(PTDS_BASE DS_BASE,PVOID64 PEBS_BUFFER)
{
int i;
//memset((void *)DS_BASE->pebs_base, 0, S_PEBS_BUFFER_SIZE);
DS_BASE->pebs_base=PEBS_BUFFER;
/* PEBS INDEX */
/* reset ds */
DS_BASE->pebs_index=PEBS_BUFFER;
/* PEBS MAX */
DS_BASE->pebs_max=DS_BASE->pebs_base+(SIZE_PEBS_BUFFER - 1) *pebs_record_size + 1;
/* PEBS Threshold */
DS_BASE->pebs_thresh=(UINT64)PEBS_BUFFER+(SIZE_PEBS_BUFFER -1) * pebs_record_size;
for (i=0;i<4;i++)
{
DS_BASE->pebs_reset[i]=-(int)StaticMask[Multiplex_Index][i][_PERIOD_];
// MyDbgPrint("DS_BASE->pebs_reset[%d]=%d",i,DS_BASE->pebs_reset[i]);
}
}
void setup_PEBDS()
{
LARGE_INTEGER pa;
UINT32* APIC;
// pdevice_ext ext;
// Allocate buffers
DS_BASE= (PTDS_BASE)ExAllocatePool(NonPagedPool,sizeof(TDS_BASE));
memset(DS_BASE, 0,sizeof(TDS_BASE));
PEBS_BUFFER=ExAllocatePool(NonPagedPool, pebs_record_size*SIZE_PEBS_BUFFER);
memset(PEBS_BUFFER, 0, pebs_record_size*SIZE_PEBS_BUFFER);
FILL_DS_WITH_BUFFER(DS_BASE,PEBS_BUFFER);
#ifdef _PMI_
/* change APIC */
pa.QuadPart=PERF_COUNTER_APIC;
APIC=(UINT32*)MmMapIoSpace(pa,sizeof(UINT32),MmNonCached);
*APIC=ORIGINAL_APIC_VALUE;
MmUnmapIoSpace(APIC,sizeof(APIC));
#endif
/* set ds area register */
Old_DS=__readmsr(MSR_IA32_DS_AREA);
__writemsr(MSR_DS_AREA,(UINT_PTR)DS_BASE);
//wrmsrl(MSR_IA32_DS_AREA, (unsigned long)__this_cpu_read(cpu_ds));
return ;
}
void clean_PEBDS( )
{
#ifndef _PMI_
LARGE_INTEGER pa;
UINT32* APIC;
#endif
#ifndef _PMI_
/* change APIC */
pa.QuadPart=PERF_COUNTER_APIC;
APIC=(UINT32*)MmMapIoSpace(pa,sizeof(UINT32),MmNonCached);
*APIC=ORIGINAL_APIC_VALUE;
MmUnmapIoSpace(APIC,sizeof(APIC));
#endif
__writemsr(MSR_DS_AREA,(UINT_PTR)Old_DS);
ExFreePool(PEBS_BUFFER);
ExFreePool(DS_BASE);
}