Main Page | Modules | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

perf_cnt.h

Go to the documentation of this file.
00001 // AUTOMATICALLY GENERATED -- DO NOT EDIT!         -*- c++ -*-
00002 
00003 #ifndef perf_cnt_h
00004 #define perf_cnt_h
00005 
00006 #include "types.h"
00007 
00008 #include "cpu.h"
00009 #include "types.h"
00010 
00011 //
00012 // INTERFACE definition follows 
00013 //
00014 
00015 
00016 class Perf_cnt_arch;
00017 
00018 class Perf_cnt
00019 {
00020 public:
00021   enum {
00022     Max_slot = 2,
00023     Max_pmc  = 4,
00024   };
00025 
00026   enum Unit_mask_type
00027     { None, Fixed, Exclusive, Bitmask, };
00028 
00029   typedef Mword (*Perf_read_fn)();
00030 private:
00031 
00032 public:
00033   enum Perf_event_type
00034     { P5, P6, P4, };
00035 
00036   static Perf_read_fn read_pmc[Max_slot];
00037 
00038 private:
00039   static Perf_read_fn *read_pmc_fns;
00040   static Perf_read_fn read_pmc_fn[Max_slot];
00041   static Perf_cnt_arch *pcnt;
00042   static char const *perf_type_str;
00043   static Perf_event_type perf_event_type;
00044 
00045 public:  
00046   // basic perfcounter detection
00047   static FIASCO_INIT void init();
00048   
00049   static inline void set_pmc_fn(Mword slot, Mword nr);
00050   
00051   // watchdog supported by performance counter architecture?
00052   static inline int have_watchdog();
00053   
00054   // setup watchdog function with timeout in seconds
00055   static inline void setup_watchdog(Mword timeout);
00056   
00057   static inline void setup_loadcnt();
00058   
00059   static inline void start_watchdog();
00060   
00061   static inline void stop_watchdog();
00062   
00063   static inline void touch_watchdog();
00064   
00065   // return human-readable type of performance counters
00066   static inline char const * perf_type();
00067   
00068   // set performance counter counting the selected event in slot #slot
00069   static int setup_pmc(Mword slot, Mword event, Mword user, Mword kern, Mword edge);
00070   
00071   // return current selected event for a slot #slot
00072   static int mode(Mword slot, const char **mode, const char **name, Mword *event, Mword *user, Mword *kern, Mword *edge);
00073   
00074   static Mword get_max_perf_event();
00075   
00076   static void get_perf_event(Mword nr, unsigned *evntsel, const char **name, const char **desc);
00077   
00078   static Mword lookup_event(unsigned evntsel);
00079   
00080   static void get_unit_mask(Mword nr, Unit_mask_type *type, Mword *default_value, Mword *nvalues);
00081   
00082   static void get_unit_mask_entry(Mword nr, Mword idx, Mword *value, const char **desc);
00083   
00085   static void split_event(Mword event, unsigned *evntsel, Mword *unit_mask);
00086   
00088   static void combine_event(Mword evntsel, Mword unit_mask, Mword *event);
00089 };
00090 
00091 class Perf_cnt_arch
00092 {
00093 public:
00094   // basic initialization
00095   virtual int  init() = 0;
00096 
00097   // set event the counter should count
00098   virtual void set_pmc_event(Mword slot) = 0;
00099 
00100   inline void touch_watchdog()
00101     { Cpu::wrmsr(hold_watchdog, _ctr_reg0+pmc_watchdog); }
00102 
00103 protected:
00104   Mword _nr_regs;
00105   Mword _sel_reg0;
00106   Mword _ctr_reg0;
00107   Mword _watchdog;
00108 
00109   typedef struct 
00110   {
00111     char  user;         // 1=count in user mode
00112     char  kern;         // 1=count in kernel mode
00113     char  edge;         // 1=count edge / 0=count duration
00114     Mword pmc;          // # of performance counter
00115     Mword bitmask;      // counter bitmask
00116     Mword evnt;         // event selector
00117   } Event;
00118 
00119   static Mword    pmc_watchdog;                   // # perfcounter of watchdog
00120   static Mword    pmc_loadcnt;                    // # perfcounter of loadcnt
00121   static Signed64 hold_watchdog;
00122   static Event    pmc_event[Perf_cnt::Max_slot];  // index is slot number
00123   static char     pmc_alloc[Perf_cnt::Max_pmc];   // index is # of perfcounter
00124 
00125 public:  
00126   inline Mword watchdog_allocated();
00127   
00128   inline Mword loadcnt_allocated();
00129   
00130   virtual void clear_pmc(Mword reg_nr);
00131   
00132   void mode(Mword slot, const char **mode, Mword *event, Mword *user, Mword *kern, Mword *edge);
00133   
00134   void setup_pmc(Mword slot, Mword bitmask, Mword event, Mword user, Mword kern, Mword edge);
00135   
00136   virtual void start_pmc(Mword /*reg_nr*/);
00137   
00138   // watchdog supported by performance counter architecture?
00139   inline int have_watchdog();
00140   
00141   void setup_watchdog(Mword timeout);
00142   
00143   void setup_loadcnt();
00144   
00145   virtual void init_watchdog();
00146   
00147   virtual void init_loadcnt();
00148   
00149   // start watchdog (enable generation of overflow interrupt)
00150   virtual void start_watchdog();
00151   
00152   // stop watchdog (disable generation of overflow interrupt)
00153   virtual void stop_watchdog();
00154 
00155 protected:  
00156   //--------------------------------------------------------------------
00157   inline Perf_cnt_arch(Mword sel_reg0, Mword ctr_reg0, Mword nr_regs, Mword watchdog);
00158 
00159 private:  
00160   void alloc_watchdog();
00161   
00162   void alloc_loadcnt();
00163   
00164   // allocate a performance counter according to bitmask (some events depend
00165   // on specific counters)
00166   int alloc_pmc(Mword slot, Mword bitmask);
00167 };
00168 
00169 class Perf_cnt_p5 : public Perf_cnt_arch {
00170 public:  
00171   //--------------------------------------------------------------------
00172   // Intel P5 (Pentium/Pentium MMX) has 2 performance counters. No overflow
00173   // interrupt available. Some events are not symmtetric.
00174   inline Perf_cnt_p5();
00175 
00176 private:  
00177   FIASCO_INIT int init();
00178   
00179   void set_pmc_event(Mword slot);
00180 };
00181 class Perf_cnt_p6 : public Perf_cnt_arch {
00182 public:  
00183   //--------------------------------------------------------------------
00184   // Intel P6 (PPro/PII/PIII) has 2 performance counters. Overflow interrupt
00185   // is available. Some events are not symmtetric.
00186   inline Perf_cnt_p6();
00187 
00188 protected:  
00189   Perf_cnt_p6(Mword sel_reg0, Mword ctr_reg0, Mword nr_regs, Mword watchdog);
00190 
00191 private:  
00192   FIASCO_INIT int init();
00193   
00194   void set_pmc_event(Mword slot);
00195   
00196   void start_pmc(Mword /*reg_nr*/);
00197   
00198   void init_watchdog();
00199   
00200   void init_loadcnt();
00201   
00202   void start_watchdog();
00203   
00204   void stop_watchdog();
00205 };
00206 class Perf_cnt_k7 : public Perf_cnt_p6   {
00207 public:  
00208   //--------------------------------------------------------------------
00209   // AMD K7 (Athlon, K8=Athlon64) has 4 performance counters. All events
00210   // seem to be symmtetric. Overflow interrupts available.
00211   inline Perf_cnt_k7();
00212 
00213 private:  
00214   void start_pmc(Mword reg_nr);
00215   
00216   void init_watchdog();
00217   
00218   void init_loadcnt();
00219 };
00220 class Perf_cnt_p4 : public Perf_cnt_arch {
00221 public:  
00222   //--------------------------------------------------------------------
00223   // Intel P4
00224   inline Perf_cnt_p4();
00225 
00226 private:  
00227   static inline Mword escr_event_select(Mword n);
00228   
00229   static inline Mword escr_event_mask(Mword n);
00230   
00231   static inline Mword cccr_threshold(Mword n);
00232   
00233   static inline Mword cccr_escr_select(Mword n);
00234   
00235   FIASCO_INIT int init();
00236   
00237   void set_pmc_event(Mword /*slot*/);
00238   
00239   void start_pmc(Mword reg_nr);
00240   
00241   void init_watchdog();
00242   
00243   void init_loadcnt();
00244   
00245   void start_watchdog();
00246   
00247   void stop_watchdog();
00248 };
00249 
00250 //
00251 // IMPLEMENTATION of inline functions (and needed classes)
00252 //
00253 
00254 
00255 
00256 // watchdog supported by performance counter architecture?
00257 
00258 inline int
00259 Perf_cnt::have_watchdog()
00260 { return (pcnt && pcnt->have_watchdog()); }
00261 
00262 
00263 // setup watchdog function with timeout in seconds
00264 
00265 inline void
00266 Perf_cnt::setup_watchdog(Mword timeout)
00267 {
00268   if (pcnt)
00269     pcnt->setup_watchdog(timeout);
00270 }
00271 
00272 
00273 
00274 inline void
00275 Perf_cnt::setup_loadcnt()
00276 {
00277   if (pcnt)
00278     pcnt->setup_loadcnt();
00279 }
00280 
00281 
00282 
00283 inline void
00284 Perf_cnt::start_watchdog()
00285 {
00286   if (pcnt && pcnt->watchdog_allocated())
00287     {
00288       pcnt->touch_watchdog();
00289       pcnt->start_watchdog();
00290     }
00291 }
00292 
00293 
00294 
00295 inline void
00296 Perf_cnt::stop_watchdog()
00297 {
00298   if (pcnt && pcnt->watchdog_allocated())
00299     pcnt->stop_watchdog();
00300 }
00301 
00302 
00303 
00304 inline void
00305 Perf_cnt::touch_watchdog()
00306 {
00307   if (pcnt && pcnt->watchdog_allocated())
00308     pcnt->touch_watchdog();
00309 }
00310 
00311 
00312 // return human-readable type of performance counters
00313 
00314 inline char const *
00315 Perf_cnt::perf_type()
00316 { return perf_type_str; }
00317 
00318 
00319 
00320 inline Mword
00321 Perf_cnt_arch::watchdog_allocated()
00322 { return (pmc_watchdog != (Mword)-1); }
00323 
00324 
00325 
00326 inline Mword
00327 Perf_cnt_arch::loadcnt_allocated()
00328 { return (pmc_loadcnt != (Mword)-1); }
00329 
00330 
00331 // watchdog supported by performance counter architecture?
00332 
00333 inline int
00334 Perf_cnt_arch::have_watchdog()
00335 { return _watchdog; }
00336 
00337 
00338 
00339 //--------------------------------------------------------------------
00340 
00341 inline Perf_cnt_arch::Perf_cnt_arch(Mword sel_reg0, Mword ctr_reg0, 
00342                              Mword nr_regs, Mword watchdog)
00343 {
00344   _sel_reg0 = sel_reg0;
00345   _ctr_reg0 = ctr_reg0;
00346   _nr_regs  = nr_regs;
00347   _watchdog = watchdog;
00348 
00349   for (Mword slot=0; slot<Perf_cnt::Max_slot; slot++)
00350     {
00351       pmc_event[slot].pmc  = (Mword)-1;
00352       pmc_event[slot].edge = 0;
00353     }
00354 }
00355 
00356 #endif // perf_cnt_h

Generated on Mon Sep 26 14:20:11 2005 for Fiasco by  doxygen 1.4.2