📄 trace_processor.h
字号:
#ifndef __TRACE_PROCESSOR_H#define __TRACE_PROCESSOR_H/* This file (trace_processor.h) was created by Ron Rechenmacher <ron@fnal.gov> on Dec 20, 1999. "TERMS AND CONDITIONS" governing this file are in the README or COPYING file. If you do not have such a file, one can be obtained by contacting Ron or Fermi Lab in Batavia IL, 60510, phone: 630-840-3000.*/#define __TRACE_PROCESSOR_H_REV "\$RCSfile: trace_processor.h,v $(i386)\$Revision: 1.17 $\$Date: 2002/03/14 23:05:56 $"#define TIME_WIDTH 20#if CPU == 486 /*---------------------------------------------------*/# define TRACE_INIT_SPECIFIC# define TRACE_CONTROL_SPECIFIC_WRITE(ss)# define TRACE_CONTROL_SPECIFIC_READ(ss)# define TRACE_PRINT_HEADING# define TRACE_ENTRY_MEMBERS# define TRACE_ENTRY_SPECIFIC(ep)# define TRACE_RDPMC(dst1,cntr)/* general useful macros */# define TRACE_CLOCK_READ# define TRACE_CLOCK_DIFF(t1)#else /* p5,p6,etc ----------------------------------------*/# ifdef __KERNEL__# include <linux/kernel.h> /* simple_strtoul */# include <asm/smp.h> /* smp_processor_id */# include <asm/current.h> /* current needed by smp_processor_id macro */# include <linux/sched.h> /* struct task (to dereference current) */ /* pick regs that will show something for both P5 and p6 */static const int trace_P4ESCR[18][8] = {{0x3b2,0x3b4,0x3aa,0x3b6,0x3ac,0x3c8,0x3a2,0x3a0}, /* 0 */ {0x3b2,0x3b4,0x3aa,0x3b6,0x3ac,0x3c8,0x3a2,0x3a0}, /* 1 */ {0x3b3,0x3b5,0x3ab,0x3b7,0x3ad,0x3c9,0x3a3,0x3a1}, /* 2 */ {0x3b3,0x3b5,0x3ab,0x3b7,0x3ad,0x3c9,0x3a3,0x3a1}, /* 3 */ {0x3c0,0x3c4,0x3c2 }, /* 4 */ {0x3c0,0x3c4,0x3c2 }, /* 5 */ {0x3c1,0x3c5,0x3c3 }, /* 6 */ {0x3c1,0x3c5,0x3c3 }, /* 7 */ {0x3a6,0x3a4,0x3ae,0x3b0,0x0 ,0x3a8 }, /* 8 */ {0x3a6,0x3a4,0x3ae,0x3b0,0x0 ,0x3a8 }, /* 9 */ {0x3a7,0x3a5,0x3af,0x3b1,0x0 ,0x3a9 }, /* 10 */ {0x3a7,0x3a5,0x3af,0x3b1,0x0 ,0x3a9 }, /* 11 */ {0x3ba,0x3ca,0x3be,0x3bc,0x3b8,0x3cc,0x3e0 }, /* 12 */ {0x3ba,0x3ca,0x3be,0x3bc,0x3b8,0x3cc,0x3e0 }, /* 13 */ {0x3bb,0x3cb,0x3bd,0x0 ,0x3b9,0x3cd,0x3e1 }, /* 14 */ {0x3bb,0x3cb,0x3bd,0x0 ,0x3b9,0x3cd,0x3e1 }, /* 15 */ {0x3ba,0x3ca,0x3be,0x3bc,0x3b8,0x3cc,0x3e0 }, /* 16 */ {0x3bb,0x3cb,0x3bd,0x0 ,0x3b9,0x3cd,0x3e1 }, /* 17 */};# endif /* __KERNEL__ */# define TRACE_INIT_SPECIFIC TRC_SETPMC( 0, 3, 0 ); TRC_SETPMC( 1, 4, 0 );# define TRACE_CONTROL_SPECIFIC_READ(ss) do\ {\ int pmc[2]={0,0}; /*quiet compiler*/\ int esr[2]={0,0}; /*quiet compiler*/\ register int pmcx=0;\ register int hi;\ register int a,b,c,d;\ a = 0; /* gets id info */\ /* ref. AP-485 (Intel Prec. Id. w/ CPUID inst.) */\ TRC_CPUID(a,b,c,d);\ if (c == ('c'|('A'<<8)|('M'<<16)|('D'<<24))) /* part of AuthenticAMD */\ { /* AMD */\ a = 1; /* get Processor signature */\ TRC_CPUID(a,b,c,d);\ if (d & 0x20) /* check for {RD,WR}MSR available */\ { TRC_RDMSR( 0xc0010000,hi,pmcx ); pmc[0] = pmcx;\ TRC_RDMSR( 0xc0010001,hi,pmcx ); pmc[1] = pmcx;\ }\ }\ else\ { /* Assume INTEL */\ a = 1; /* get Processor signature */\ TRC_CPUID(a,b,c,d);\ if (d & 0x20) /* check for {RD,WR}MSR available */\ {\ if ((a&0xf00) == 0x600) /* ref. p. 11-74 of Vol. 2 */\ { /* pentium pro/II/III */\ TRC_RDMSR( 0x186,hi,pmcx ); pmc[0] = pmcx;\ TRC_RDMSR( 0x187,hi,pmcx ); pmc[1] = pmcx;\ }\ else if ((a&0xf00) == 0xf00) /* ref. p. 11-74 of Vol. 2 */\ { /* pentium IV */\ /* ref. p. B-11 (Appendix B) of IA-32 Intel Architecture Software\ Developer s Manual Volume 3: System Programming Guide\ (Order Number 245472) */\ /* _reg=0 selects MSR_BPU_ESCR0 (ESCR No. 0) at MSR Addr 3B2H)\ Ref. p. 14-24 in manual mentioned above.\ _reg=1 selects MSR_IS_ESCR0 (ESCR No. 1) at MSR Addr 3B4H) */\ int _reg;\ for (_reg=2;_reg--; )\ { TRC_RDMSR( 0x360+tracePMC[_reg],hi,pmcx );\ pmc[_reg] = pmcx;\ esr[_reg] = (pmcx>>13)&7; /* which escr No. */\ esr[_reg] = trace_P4ESCR[tracePMC[_reg]][esr[_reg]]; /* convert to address */\ TRC_RDMSR( esr[_reg], hi, pmcx ); /* get the value */\ esr[_reg] = pmcx;\ }\ *(ss) += sprintf( *(ss), \"cpu%d: PMC0=%02d,0x%08x,0x%08x\n PMC1=%02d,0x%08x,0x%08x\n"\ , smp_processor_id(),tracePMC[0],pmc[0],esr[0],tracePMC[1],pmc[1],esr[1] );\ break;\ }\ else\ { /* pentium */\ TRC_RDMSR( 0x11,hi,pmcx );\ pmc[1] = pmcx >> 16;\ pmc[0] = pmcx & 0x0000ffff;\ }\ }\ }\ *(ss) += sprintf( *(ss), \"cpu%d: PMC0=0x%08x\n PMC1=0x%08x\n"\ , smp_processor_id(), pmc[0], pmc[1] );\ } while (0)# define TRACE_CONTROL_SPECIFIC_WRITE(ss) do\{ /* setup the pmc register */\ int reg=0,val=0;\ char *sss;\ register int a,b,c,d;\ a = 0; /* gets id info */\ /* ref. AP-485 (Intel Prec. Id. w/ CPUID inst.) */\ TRC_CPUID(a,b,c,d);\ if (c != ('c'|('A'<<8)|('M'<<16)|('D'<<24))) /* part of AuthenticAMD */\ { /* Intel */\ a = 1; /* gets Proc. sig. in a; Feature flags in d */\ TRC_CPUID(a,b,c,d);\ if ((d&0x20)) /* check for {RD,WR}MSR available */\ {\ if ((a&0xf00) == 0xf00) /* ref. p. 11-74 of Vol. 2 */\ { /* pentium IV */\ /* ref. p. B-11 (Appendix B) of IA-32 Intel Architecture Software\ Developer s Manual Volume 3: System Programming Guide\ (Order Number 245472) \ User passes: pmcx=pmcCtr,ccrVal,essVal */\ for (sss=ss; *sss; sss++)\ {\ int pmcCtr=0, ccrVal=0, esrVal=0;\ if ( (strncmp("pmc0=",sss,sizeof("pmc0=")-1)==0)\ ||(strncmp("PMC0=",sss,sizeof("PMC0=")-1)==0))\ { sss+=sizeof("pmc0=")-1;\ pmcCtr=simple_strtoul(sss,&sss,0);\ tracePMC[0] = pmcCtr;\ sss++;\ ccrVal=simple_strtoul(sss,&sss,0);\ sss++;\ esrVal=simple_strtoul(sss,&sss,0);\ TRC_SETPMC( pmcCtr, ccrVal, esrVal );\ } \ else if ( (strncmp("pmc1=",sss,sizeof("pmc1=")-1)==0)\ ||(strncmp("PMC1=",sss,sizeof("PMC1=")-1)==0))\ { sss+=sizeof("pmc0=")-1;\ pmcCtr=simple_strtoul(sss,&sss,0);\ tracePMC[1] = pmcCtr;\ sss++;\ ccrVal=simple_strtoul(sss,&sss,0);\ sss++;\ esrVal=simple_strtoul(sss,&sss,0);\ TRC_SETPMC( pmcCtr, ccrVal, esrVal );\ } \ }\ break;\ }\ }\ }\ for (sss=ss; *sss; sss++)\ {\ if ( (strncmp("pmc0=",sss,sizeof("pmc0=")-1)==0)\ ||(strncmp("PMC0=",sss,sizeof("PMC0=")-1)==0))\ { sss+=sizeof("pmc0=")-1;\ reg=0;\ val=simple_strtoul(sss,&sss,0);\ TRC_SETPMC( reg, val, 0 );\ }\ else if ( (strncmp("pmc1=",sss,sizeof("pmc1=")-1)==0)\ ||(strncmp("PMC1=",sss,sizeof("PMC1=")-1)==0))\ { sss+=sizeof("pmc1=")-1;\ reg=1;\ val=simple_strtoul(sss,&sss,0);\ TRC_SETPMC( reg, val, 0 );\ }\ }\} while (0)# define TRACE_PRINT_HEADING {"cycle",20,'L',TRACE_OFFSET(cycle)},\ {"PMC0", 20,'L',TRACE_OFFSET(pmc0)},\ {"PMC1", 20,'L',TRACE_OFFSET(pmc1)},# define TRACE_CLOCK_READ ({register unsigned long long _r_;\ __asm__( ".byte 0x0f,0x31":"=A"(_r_) );_r_;})# define TRACE_CLOCK_DIFF(t1) ({register unsigned long long _r_;\ __asm__( ".byte 0x0f,0x31":"=A"(_r_) );\ _r_-(unsigned long long)t1;})# define TRACE_ENTRY_MEMBERS unsigned long long pmc0,pmc1,cycle# define TRACE_ENTRY_SPECIFIC(ep) do\ { TRACE_RDPMC( &ep->pmc0, tracePMC[0] );\ TRACE_RDPMC( &ep->pmc1, tracePMC[1] );\ ep->cycle = TRACE_CLOCK_READ;\ } while (0)# define TRC_CPUID( a,b,c,d ) __asm__(".byte 0x0f,0xa2":\ "=a"(a),"=b"(b),"=c"(c),"=d"(d):"a"(a))# define TRC_SETPMC( pmcCtr, val, esrVal) do \ { register int lo=0;\ register int hi;\ register int a,b,c,d;\ int _val=val;\ int _pmcCtr=pmcCtr;\ int _ccrVal=val;\ int _esrVal=esrVal;\ a = 0; /* gets id info */\ /* ref. AP-485 (Intel Prec. Id. w/ CPUID inst.) */\ TRC_CPUID(a,b,c,d);\ if (c == ('c'|('A'<<8)|('M'<<16)|('D'<<24))) /* part of AuthenticAMD */\ { /* AMD */\ if (_pmcCtr > 1) _pmcCtr = 1;\ _val |= 0x400000; /* make sure it is enabled */\ TRC_RDMSR( 0xc0010000+_pmcCtr,hi,lo ); /* read to preserve hi part */\ TRC_WRMSR( 0xc0010000+_pmcCtr,hi,_val );\ TRC_WRMSR( 0xc0010004+_pmcCtr,0,0 ); /* clear the counter */\ printk( "trace: cpu%d just set AMD PMC%d to 0x%x\n"\ ,smp_processor_id(),_pmcCtr,_val);\ }\ else\ { /* Intel */\ a = 1; /* gets Proc. sig. in a; Feature flags in d */\ TRC_CPUID(a,b,c,d);\ if ((d&0x20)) /* check for {RD,WR}MSR available */\ {\ if ((a&0xf00) == 0x600) /* ref. p. 11-74 of Vol. 2 */\ { /* pentium pro/II/III */\ /* ref. p. C-3,4 (Appendix C) of Vol. 3 */\ if (_pmcCtr > 1) _pmcCtr = 1;\ if (!(_val&0x70000)) _val|=0x70000;/*default type of counting*/\ _val |= 0x400000; /* make sure it is enabled */\ TRC_RDMSR( 0x186+_pmcCtr,hi,lo ); /* read to preserve hi part */\ TRC_WRMSR( 0x186+_pmcCtr,hi,_val );\ TRC_WRMSR( 0x0c1+_pmcCtr,0,0 ); /* clear the counter */\ printk( "trace: cpu%d just set PPRO PMC%d to 0x%x\n"\ ,smp_processor_id(),_pmcCtr,_val);\ }\ else if ((a&0xf00) == 0xf00) /* ref. p. 11-74 of Vol. 2 */\ { /* pentium IV */\ /* ref. p. B-11 (Appendix B) of IA-32 Intel Architecture Software\ Developer s Manual Volume 3: System Programming Guide\ (Order Number 245472) */\ /* from the passed in cccr val, get which esr */\ int escr=(_ccrVal>>13)&7;\ /* convert to address from table */\ escr = trace_P4ESCR[_pmcCtr][escr];\ /* load the passed in ESCR val */\ TRC_WRMSR( escr, 0,_esrVal ); /* Event Selection Control Reg */\ /* load the passed in CCCR val */\ TRC_WRMSR( 0x360+_pmcCtr,0,_ccrVal ); /* Counter Configuration Control Reg */\ /* clear the counter */\ TRC_WRMSR( 0x300+_pmcCtr,0,0 );\ printk( "trace: cpu%d just set P4 PMC%d to 0x%x/0x%x\n"\ ,smp_processor_id(),_pmcCtr,_val,_esrVal);\ }\ else\ { /* pentium (i.e. 80586) */\ /* ref. Ch.16 of Pentium Processor Manual Vol. ??? */\ if (_pmcCtr > 1) _pmcCtr = 1;\ _val &= 0xffff;\ if (!(_val&0x1c0)) _val |= 0xc0;/*deflt-type-cnting/ENABLE*/\ if (_pmcCtr==1) _val<<=16;\ TRC_RDMSR( 0x11,hi,lo ); /* preserve other PMC selection */\ if (_pmcCtr==0) lo&=0xffff0000; /* clear reg0 area */\ else lo&= 0xffff; /* clear reg1 area */\ _val = _val | lo;\ TRC_WRMSR( 0x11,hi,_val );\ TRC_WRMSR( 0x12+_pmcCtr,0,0 );/* clear the counter */\ printk("trace: just set PENT PMC%d to 0x%x\n",_pmcCtr,_val);\ }\ }\ }\ } while (0)# define TRC_RDMSR( reg,hi,lo ) __asm__(".byte 0x0f,0x32":"=d"(hi),"=a"(lo):\ "c"(reg))# define TRC_WRMSR( reg,hi,lo ) __asm__(".byte 0x0f,0x30"::\ "c"(reg),"d"(hi),"a"(lo))# define TRACE_RDPMC(dst1,cntr) __asm__( ".byte 0x0f,0x33;andl $0x000000ff,%%edx":"=a"(*(int *)dst1)\ ,"=d"(*((int *)dst1+1)):"c"(cntr) )#endif /* CPU ---------------------------------------------------------------*/#endif /* __TRACE_PROCESSOR_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -