00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef __L4UTIL_PERFORM_H
00011 #define __L4UTIL_PERFORM_H
00012
00013 #include <l4/sys/types.h>
00014 #include <l4/sys/compiler.h>
00015
00016 EXTERN_C_BEGIN
00017
00018 extern const char*strp6pmc_event(l4_uint32_t event);
00019
00020 #ifndef CONFIG_PERFORM_ONLY_PROTOTYPES
00021
00022 #if ! (defined CPU_PENTIUM ^ defined CPU_P6 ^ defined CPU_K7)
00023
00024 #error You must define your target architecture.
00025 #error Define EITHER CPU_PENTIUM for Intel Pentium or CPU_P6 for Intel PPro/PII/PIII.
00026
00027 #else
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 static inline void l4_i586_wrmsr(unsigned reg,unsigned long long*val){
00038 unsigned long dummyeax, dummyecx, dummyedx;
00039
00040 asm volatile(
00041 ".byte 0xf; .byte 0x30\n"
00042 : "=a" (dummyeax), "=d" (dummyedx), "=c" (dummyecx)
00043 : "2" (reg), "0" (*(unsigned *)val), "1" (*((unsigned *)val+1))
00044 );
00045 }
00046
00047
00048
00049
00050
00051
00052 static inline void l4_i586_rdmsr(unsigned reg,unsigned long long*val){
00053 unsigned dummy;
00054
00055 asm volatile(
00056 ".byte 0xf; .byte 0x32\n"
00057 : "=a" (*(unsigned *)val), "=d" (*((unsigned *)val+1)), "=c" (dummy)
00058 : "2" (reg)
00059 );
00060 }
00061
00062
00063 #ifdef CPU_PENTIUM
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 static inline void
00074 l4_i586_reset_event_counter(void){
00075 asm volatile("xor %%eax, %%eax\n"
00076 "xor %%edx, %%edx\n"
00077 "movl $0x12, %%ecx\n"
00078 ".byte 0x0f, 0x30\n"
00079 "movl $0x13, %%ecx\n"
00080 ".byte 0x0f, 0x30\n"
00081 : : : "cx", "ax", "dx"
00082 );
00083 };
00084
00085 static inline void
00086 l4_i586_read_event_counter_long(long long *counter0, long long *counter1)
00087 {
00088 asm volatile(
00089
00090
00091
00092 "movl $0x12, %%ecx\n"
00093 ".byte 0x0f, 0x32\n"
00094 "movl %%eax, (%%ebx)\n"
00095 "movl %%edx, 4(%%ebx)\n"
00096 "movl $0x13, %%ecx\n"
00097 ".byte 0x0f, 0x32\n"
00098 "movl %%eax, (%%esi)\n"
00099 "movl %%edx, 4(%%esi)\n"
00100 :
00101 : "b" (counter0), "S" (counter1)
00102 : "ax", "cx", "dx"
00103 );
00104 }
00105
00106 static inline void
00107 l4_i586_read_event_counter(int *counter0, int *counter1)
00108 {
00109 asm volatile("pushl %%edx\n"
00110 ".byte 0x0f, 0x30\n"
00111 "movl $0x12, %%ecx\n"
00112 ".byte 0x0f, 0x32\n"
00113 "movl %%eax, %%ebx\n"
00114 "movl $0x13, %%ecx\n"
00115 ".byte 0x0f, 0x32\n"
00116 "popl %%edx\n"
00117 : "=b" (*counter0), "=a" (*counter1)
00118 : "1" (0), "c" (0x11)
00119 );
00120 }
00121
00122 static inline void
00123 l4_i586_select_event(int event0, int event1)
00124 {
00125 asm volatile(".byte 0x0f, 0x30\n"
00126 :
00127 :
00128 "a" (event0 + (event1 << 16)),
00129 "d" (0),
00130 "c" (0x11)
00131 );
00132 };
00133
00134 #define P5_RD_MISS 0x003
00135 #define P5_WR_MISS 0x008
00136 #define P5_RW_MISS 0x029
00137 #define P5_EX_MISS 0x00e
00138
00139 #define P5_D_WBACK 0x006
00140
00141 #define P5_RW_TLB 0x002
00142 #define P5_EX_TLB 0x00d
00143
00144 #define P5_A_STALL 0x01f
00145 #define P5_W_STALL 0x019
00146 #define P5_R_STALL 0x01a
00147 #define P5_X_STALL 0x01b
00148
00149 #define P5_AGI_STALL 0x01f
00150
00151 #define P5_PIPLINE_FLUSH 0x015
00152
00153 #define P5_NON_CACHE_RD 0x01e
00154 #define P5_NCACHE_REFS 0x01e
00155 #define P5_LOCKED_BUS 0x01c
00156
00157 #define P5_MEM2PIPE 0x009
00158 #define P5_BANK_CONF 0x00a
00159
00160
00161 #define P5_INSTRS_EX 0x016
00162 #define P5_INSTRS_EX_V 0x017
00163
00164
00165 #define P5_CNT_NOTHING (0x00 << 6)
00166 #define P5_CNT_EVENT_PL0 (0x01 << 6)
00167 #define P5_CNT_EVENT_PL3 (0x02 << 6)
00168 #define P5_CNT_EVENT (0x03 << 6)
00169 #define P5_CNT_CLOCKS_PL0 (0x05 << 6)
00170 #define P5_CNT_CLOCKS_PL3 (0x06 << 6)
00171 #define P5_CNT_CLOCKS (0x07 << 6)
00172
00173
00174 #else
00175 #if defined CPU_P6
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 #define P6_DATA_MEM_REFS 0x43
00227 #define P6_DCU_LINES_IN 0x45
00228 #define P6_DCU_M_LINES_IN 0x46
00229 #define P6_DCU_M_LINES_OUT 0x47
00230 #define P6_DCU_MISS_OUTSTANDING 0x48
00231
00232
00233 #define P6_IFU_IFETCH 0x80
00234 #define P6_IFU_IFETCH_MISS 0x81
00235 #define P6_ITLB_MISS 0x85
00236 #define P6_IFU_MEM_STALL 0x86
00237 #define P6_ILD_STALL 0x87
00238
00239
00240 #define P6_L2_IFETCH 0x28
00241 #define P6_L2_LD 0x29
00242 #define P6_L2_ST 0x2a
00243 #define P6_L2_LINES_IN 0x24
00244 #define P6_L2_LINES_OUT 0x26
00245 #define P6_L2_M_LINES_INM 0x25
00246 #define P6_L2_M_LINES_OUTM 0x27
00247 #define P6_L2_RQSTS 0x2e
00248 #define P6_L2_ADS 0x21
00249 #define P6_L2_DBUS_BUSY 0x22
00250 #define P6_L2_DBUS_BUSY_RD 0x23
00251
00252
00253 #define P6_BUS_DRDY_CLOCKS 0x62
00254 #define P6_BUS_LOCK_CLOCKS 0x63
00255 #define P6_BUS_REQ_OUTSTANDING 0x60
00256 #define P6_BUS_TRAN_BRD 0x65
00257 #define P6_BUS_TRAN_RFO 0x66
00258 #define P6_BUS_TRAN_WB 0x67
00259 #define P6_BUS_TRAN_IFETCH 0x68
00260 #define P6_BUS_TRAN_INVAL 0x69
00261 #define P6_BUS_TRAN_PWR 0x6a
00262 #define P6_BUS_TRANS_P 0x6b
00263 #define P6_BUS_TRANS_IO 0x6c
00264 #define P6_BUS_TRAN_DEF 0x6d
00265 #define P6_BUS_TRAN_BURST 0x6e
00266 #define P6_BUS_TRAN_ANY 0x70
00267 #define P6_BUS_TRAN_MEM 0x6f
00268 #define P6_BUS_DATA_RCV 0x64
00269 #define P6_BUS_BNR_DRV 0x61
00270 #define P6_BUS_HIT_DRV 0x7a
00271 #define P6_BUS_HITM_DRV 0x7b
00272 #define P6_BUS_SNOOP_STALL 0x7e
00273
00274
00275 #define P6_FLOPS 0xc1
00276 #define P6_FP_COMP_OPS 0x10
00277 #define P6_FP_ASSIST 0x11
00278 #define P6_MUL 0x12
00279 #define P6_DIV 0x13
00280 #define P6_CYCLES_DIV_BUSY 0x14
00281
00282
00283 #define P6_LD_BLOCKS 0x03
00284 #define P6_SB_DRAINS 0x04
00285 #define P6_MISALING_MEM_REF 0x05
00286
00287
00288 #define P6_INST_RETIRED 0xc0
00289 #define P6_UOPS_RETIRED 0xc2
00290 #define P6_INST_DECODER 0xd0
00291
00292
00293 #define P6_HW_INT_RX 0xc8
00294 #define P6_CYCLES_INT_MASKED 0xc6
00295 #define P6_CYCLES_INT_PENDING_AND_MASKED 0xc7
00296
00297
00298 #define P6_BR_INST_RETIRED 0xc4
00299 #define P6_BR_MISS_PRED_RETIRED 0xc5
00300 #define P6_BR_TAKEN_RETIRED 0xc9
00301 #define P6_BR_MISS_PRED_TAKEN_RET 0xca
00302 #define P6_BR_INST_DECODED 0xe0
00303 #define P6_BTB_MISSES 0xe2
00304 #define P6_BR_BOGUS 0xe4
00305 #define P6_BACLEARS 0xe6
00306
00307
00308 #define P6_RESOURCE_STALLS 0xa2
00309 #define P6_PARTIAL_RAT_STALLS 0xd2
00310
00311
00312 #define P6_SEGMENT_REG_LOADS 0x06
00313
00314
00315 #define P6_CPU_CLK_UNHALTED 0x79
00316
00317
00318 #define P6_UNIT_M 0x0800
00319 #define P6_UNIT_E 0x0400
00320 #define P6_UNIT_S 0x0200
00321 #define P6_UNIT_I 0x0100
00322 #define P6_UNIT_MESI 0x0f00
00323
00324 #define P6_UNIT_SELF 0x0000
00325 #define P6_UNIT_ANY 0x2000
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 #define P6CNT_U 0x010000
00337 #define P6CNT_K 0x020000
00338 #define P6CNT_E 0x040000
00339 #define P6CNT_PC 0x080000
00340 #define P6CNT_IE 0x100000
00341 #define P6CNT_F 0x200000
00342 #define P6CNT_EN 0x400000
00343 #define P6CNT_IV 0x800000
00344
00345
00346
00347
00348
00349
00350
00351 #define NUM_P6HWC 2
00352
00353
00354
00355
00356
00357
00358
00359
00360 #define MSR_P6_EVNTSEL0 0x186
00361 #define MSR_P6_EVNTSEL1 0x187
00362 #define MSR_P6_PERFCTR0 0xc1
00363 #define MSR_P6_PERFCTR1 0xc2
00364
00365
00366
00367
00368
00369
00370
00371 #define l4_i686_rdpmc(cntr, res_p) \
00372 __asm __volatile( \
00373 "movl %2, %%ecx # put counter number in \n\
00374 .byte 0xf; .byte 0x33 # RDPMC instruction \n\
00375 movl %%edx, %1 # High order 32 bits \n\
00376 movl %%eax, %0 # Low order 32 bits" \
00377 : "=g" (*(int *)(res_p)), "=g" (*(((int *)res_p)+1)) \
00378 : "g" (cntr) \
00379 : "ecx", "eax", "edx")
00380
00381 static inline l4_uint32_t l4_i686_rdpmc_32(int cntr){
00382 l4_uint32_t x;
00383
00384 __asm__ __volatile__(
00385 ".byte 0xf; .byte 0x33 # RDPMC instruction"
00386 : "=a" (x)
00387 : "c" (cntr)
00388 : "ecx", "eax", "edx");
00389 return x;
00390 }
00391
00392 static inline void l4_i686_select_perfctr_event(int counter,
00393 unsigned long long val){
00394 l4_i586_wrmsr(MSR_P6_EVNTSEL0+counter, &val);
00395 }
00396
00397 static inline void l4_i686_select_perfctr0_event(long long *val){
00398 asm volatile(
00399 "movl $MSR_P6_EVNTSEL0, %%ecx\n"
00400 "movl (%%ebx), %%eax\n"
00401 "movl 4(%%ebx), %%edx\n"
00402
00403 ".byte 0x0f, 0x30\n"
00404
00405 :
00406 : "b" (val)
00407 : "ax", "cx", "dx", "bx"
00408 );
00409
00410 }
00411
00412
00413 #else
00414
00415 #define K7CNT_U 0x010000
00416 #define K7CNT_K 0x020000
00417 #define K7CNT_E 0x040000
00418 #define K7CNT_PC 0x080000
00419 #define K7CNT_IE 0x100000
00420 #define K7CNT_F 0x200000
00421 #define K7CNT_EN 0x400000
00422 #define K7CNT_IV 0x800000
00423
00424 #define MSR_K7_EVNTSEL0 0xC0010000
00425 #define MSR_K7_EVNTSEL1 0xC0010001
00426 #define MSR_K7_EVNTSEL2 0xC0010002
00427 #define MSR_K7_EVNTSEL3 0xC0010003
00428 #define MSR_K7_PERFCTR0 0xC0010004
00429 #define MSR_K7_PERFCTR1 0xC0010005
00430 #define MSR_K7_PERFCTR2 0xC0010006
00431 #define MSR_K7_PERFCTR3 0xC0010007
00432
00433 #endif
00434
00435 #endif
00436
00437
00438 #endif
00439
00440
00441 #endif
00442
00443 EXTERN_C_END
00444
00445 #endif