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

apic.h

Go to the documentation of this file.
00001 // AUTOMATICALLY GENERATED -- DO NOT EDIT!         -*- c++ -*-
00002 
00003 #ifndef apic_h
00004 #define apic_h
00005 
00006 #include "types.h"
00007 #include "initcalls.h"
00008 
00009 //
00010 // INTERFACE definition follows 
00011 //
00012 
00013 
00014 class Return_frame;
00015 
00016 class Apic
00017 {
00018 public:
00019   static void init() FIASCO_INIT;
00020 
00021   typedef enum
00022     {
00023       APIC_NONE,
00024       APIC_P6,                  // Intel PPro, PIII
00025       APIC_P4,                  // Intel PIV
00026       APIC_K7                   // AMD Athlon Model 2
00027     } Apic_type;
00028 
00029 private:
00030   Apic();                       // default constructors are undefined
00031   Apic(const Apic&);
00032   static void                   error_interrupt(Return_frame *regs)
00033                                 asm ("apic_error_interrupt") FIASCO_FASTCALL;
00034 
00035   static int                    present;
00036   static int                    good_cpu;
00037   static const                  Address io_base;
00038   static Address                phys_base;
00039   static unsigned               timer_divisor;
00040   static Apic_type              type;
00041   static unsigned               frequency_khz;
00042   static unsigned               max_lvt;
00043   static Unsigned32             scaler_ns_to_apic;
00044 
00045   enum
00046     {
00047       APIC_ID                   = 0x20,
00048       APIC_LVR                  = 0x30,
00049       APIC_TASKPRI              = 0x80,
00050       APIC_TPRI_MASK            = 0xFF,
00051       APIC_EOI                  = 0xB0,
00052       APIC_LDR                  = 0xD0,
00053       APIC_LDR_MASK             = (0xFF<<24),
00054       APIC_DFR                  = 0xE0,
00055       APIC_SPIV                 = 0xF0,
00056       APIC_ISR                  = 0x100,
00057       APIC_TMR                  = 0x180,
00058       APIC_IRR                  = 0x200,
00059       APIC_ESR                  = 0x280,
00060       APIC_LVTT                 = 0x320,
00061       APIC_LVTTHMR              = 0x330,
00062       APIC_LVTPC                = 0x340,
00063       APIC_LVT0                 = 0x350,
00064       APIC_TIMER_BASE_DIV       = 0x2,
00065       APIC_LVT1                 = 0x360,
00066       APIC_LVTERR               = 0x370,
00067       APIC_TMICT                = 0x380,
00068       APIC_TMCCT                = 0x390,
00069       APIC_TDCR                 = 0x3E0,
00070 
00071       APIC_SND_PENDING          = (1<<12),
00072       APIC_INPUT_POLARITY       = (1<<13),
00073       APIC_LVT_REMOTE_IRR       = (1<<14),
00074       APIC_LVT_LEVEL_TRIGGER    = (1<<15),
00075       APIC_LVT_MASKED           = (1<<16),
00076       APIC_LVT_TIMER_PERIODIC   = (1<<17),
00077       APIC_TDR_DIV_1            = 0xB,
00078       APIC_TDR_DIV_2            = 0x0,
00079       APIC_TDR_DIV_4            = 0x1,
00080       APIC_TDR_DIV_8            = 0x2,
00081       APIC_TDR_DIV_16           = 0x3,
00082       APIC_TDR_DIV_32           = 0x8,
00083       APIC_TDR_DIV_64           = 0x9,
00084       APIC_TDR_DIV_128          = 0xA,
00085     };
00086 
00087   enum
00088     {
00089       MASK                      =  1,
00090       TRIGGER_MODE              =  2,
00091       REMOTE_IRR                =  4,
00092       PIN_POLARITY              =  8,
00093       DELIVERY_STATE            = 16,
00094       DELIVERY_MODE             = 32,
00095     };
00096 
00097   enum
00098     {
00099       APIC_BASE_MSR             = 0x1b,
00100     };
00101 
00102 public:  
00103   static inline unsigned get_frequency_khz();
00104   
00105   static inline Unsigned32 reg_read(unsigned reg);
00106   
00107   static inline void reg_write(unsigned reg, Unsigned32 val);
00108   
00109   static inline int reg_delivery_mode(Unsigned32 val);
00110   
00111   static inline int reg_lvt_vector(Unsigned32 val);
00112   
00113   static inline Unsigned32 timer_reg_read();
00114   
00115   static inline Unsigned32 timer_reg_read_initial();
00116   
00117   static inline void timer_reg_write(Unsigned32 val);
00118   
00119   static inline Unsigned32 ns_to_apic(Unsigned64 ns);
00120   
00121   static inline void timer_enable_irq();
00122   
00123   static inline void timer_disable_irq();
00124   
00125   static inline int timer_is_irq_enabled();
00126   
00127   static inline void timer_set_periodic();
00128   
00129   static inline void timer_set_one_shot();
00130   
00131   static inline void timer_assign_irq_vector(unsigned vector);
00132   
00133   static inline void irq_ack();
00134   
00135   static inline int have_pcint();
00136   
00137   static inline int have_tsint();
00138   
00139   // give us a hint if we have an APIC but it is disabled
00140   static int test_present_but_disabled();
00141   
00142   // check if we still receive interrupts after we changed the IRQ routing
00143   static FIASCO_INIT int check_still_getting_interrupts();
00144   
00145   static inline int is_present();
00146   
00147   static inline int cpu_type();
00148   
00149   static void set_perf_nmi();
00150   
00151   // deactivate APIC by writing to appropriate MSR
00152   static void done();
00153   
00154   static void reg_show(unsigned reg);
00155   
00156   static void regs_show(void);
00157   
00158   static void timer_show(void);
00159   
00160   static void id_show(void);
00161   
00162   static void irr_show();
00163   
00164   static void isr_show();
00165 
00166 private:  
00167   static inline Unsigned32 get_id();
00168   
00169   static inline Unsigned32 get_version();
00170   
00171   static inline int is_integrated();
00172   
00173   static inline Unsigned32 get_max_lvt();
00174   
00175   static inline Unsigned32 get_num_errors();
00176   
00177   static inline void clear_num_errors();
00178   
00179   // set the global pagetable entry for the Local APIC device registers
00180   static FIASCO_INIT void map_apic_page();
00181   
00182   // check CPU type if APIC could be present
00183   static FIASCO_INIT int test_cpu();
00184   
00185   // test if APIC present
00186   static inline int test_present();
00187   
00188   static void timer_set_divisor(unsigned newdiv);
00189   
00190   static FIASCO_INIT int get_maxlvt();
00191   
00192   // check if APIC is working (check timer functionality)
00193   static FIASCO_INIT int check_working();
00194   
00195   static FIASCO_INIT void init_spiv();
00196   
00197   // activate APIC error interrupt
00198   static FIASCO_INIT void enable_errors();
00199   
00200   // activate APIC after activating by MSR was successful
00201   // see "Intel Architecture Software Developer's Manual,
00202   //      Volume 3: System Programming Guide, Appendix E"
00203   static FIASCO_INIT void route_pic_through_apic();
00204   
00205   static FIASCO_INIT void init_lvt();
00206   
00207   // activate APIC by writing to appropriate MSR
00208   static FIASCO_INIT void activate_by_msr();
00209   
00210   static FIASCO_INIT void calibrate_timer();
00211   
00212   static const char* reg_lvt_bit_str(unsigned reg, Unsigned32 val, int bit);
00213   
00214   static void bitfield_show(unsigned reg, const char *name, char flag);
00215 };
00216 
00217 extern unsigned apic_spurious_interrupt_bug_cnt;
00218 extern unsigned apic_spurious_interrupt_cnt;
00219 extern unsigned apic_error_cnt;
00220 
00221 //
00222 // IMPLEMENTATION of inline functions (and needed classes)
00223 //
00224 
00225 
00226 
00227 
00228 inline unsigned
00229 Apic::get_frequency_khz()
00230 {
00231   return frequency_khz;
00232 }
00233 
00234 
00235 
00236 inline Unsigned32
00237 Apic::reg_read(unsigned reg)
00238 {
00239   return *((volatile unsigned*)(io_base + reg));
00240 }
00241 
00242 
00243 
00244 inline void
00245 Apic::reg_write(unsigned reg, Unsigned32 val)
00246 {
00247   *((volatile Unsigned32*)(io_base + reg)) = val;
00248 }
00249 
00250 
00251 
00252 inline int
00253 Apic::reg_delivery_mode(Unsigned32 val)
00254 {
00255   return (val >> 8) & 7;
00256 }
00257 
00258 
00259 
00260 inline int
00261 Apic::reg_lvt_vector(Unsigned32 val)
00262 {
00263   return val & 0xff;
00264 }
00265 
00266 
00267 
00268 inline Unsigned32
00269 Apic::timer_reg_read()
00270 {
00271   return reg_read(APIC_TMCCT);
00272 }
00273 
00274 
00275 
00276 inline Unsigned32
00277 Apic::timer_reg_read_initial()
00278 {
00279   return reg_read(APIC_TMICT);
00280 }
00281 
00282 
00283 
00284 inline void
00285 Apic::timer_reg_write(Unsigned32 val)
00286 {
00287   reg_read(APIC_TMICT);
00288   reg_write(APIC_TMICT, val);
00289 }
00290 
00291 
00292 
00293 inline Unsigned32
00294 Apic::ns_to_apic(Unsigned64 ns)
00295 {
00296   Unsigned32 apic, dummy1, dummy2;
00297   asm ("movl  %%edx, %%ecx              \n\t"
00298        "mull  %4                        \n\t"
00299        "movl  %%ecx, %%eax              \n\t"
00300        "movl  %%edx, %%ecx              \n\t"
00301        "mull  %4                        \n\t"
00302        "addl  %%ecx, %%eax              \n\t"
00303       :"=a" (apic), "=d" (dummy1), "=&c" (dummy2)
00304       : "A" (ns),   "g" (scaler_ns_to_apic)
00305        );
00306   return apic;
00307 }
00308 
00309 
00310 
00311 inline void
00312 Apic::timer_enable_irq()
00313 {
00314   Unsigned32 tmp_val;
00315 
00316   tmp_val = reg_read(APIC_LVTT);
00317   tmp_val &= ~(APIC_LVT_MASKED);
00318   reg_write(APIC_LVTT, tmp_val);
00319 }
00320 
00321 
00322 
00323 inline void
00324 Apic::timer_disable_irq()
00325 {
00326   Unsigned32 tmp_val;
00327 
00328   tmp_val = reg_read(APIC_LVTT);
00329   tmp_val |= APIC_LVT_MASKED;
00330   reg_write(APIC_LVTT, tmp_val);
00331 }
00332 
00333 
00334 
00335 inline int
00336 Apic::timer_is_irq_enabled()
00337 {
00338   return ~reg_read(APIC_LVTT) & APIC_LVT_MASKED;
00339 }
00340 
00341 
00342 
00343 inline void
00344 Apic::timer_set_periodic()
00345 {
00346   Unsigned32 tmp_val = reg_read(APIC_LVTT);
00347   tmp_val |= APIC_LVT_TIMER_PERIODIC;
00348   reg_write(APIC_LVTT, tmp_val);
00349 }
00350 
00351 
00352 
00353 inline void
00354 Apic::timer_set_one_shot()
00355 {
00356   Unsigned32 tmp_val = reg_read(APIC_LVTT);
00357   tmp_val &= ~APIC_LVT_TIMER_PERIODIC;
00358   reg_write(APIC_LVTT, tmp_val);
00359 }
00360 
00361 
00362 
00363 inline void
00364 Apic::timer_assign_irq_vector(unsigned vector)
00365 {
00366   Unsigned32 tmp_val = reg_read(APIC_LVTT);
00367   tmp_val &= 0xffffff00;
00368   tmp_val |= vector;
00369   reg_write(APIC_LVTT, tmp_val);
00370 }
00371 
00372 
00373 
00374 inline void
00375 Apic::irq_ack()
00376 {
00377   reg_read(APIC_SPIV);
00378   reg_write(APIC_EOI, 0);
00379 }
00380 
00381 
00382 
00383 inline int
00384 Apic::have_pcint()
00385 {
00386   return (present && (max_lvt >= 4));
00387 }
00388 
00389 
00390 
00391 inline int
00392 Apic::have_tsint()
00393 {
00394   return (present && (max_lvt >= 5));
00395 }
00396 
00397 
00398 
00399 inline int
00400 Apic::is_present()
00401 {
00402   return present;
00403 }
00404 
00405 
00406 
00407 inline int
00408 Apic::cpu_type()
00409 {
00410   return type;
00411 }
00412 
00413 #endif // apic_h

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