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

cpu.h

Go to the documentation of this file.
00001 // AUTOMATICALLY GENERATED -- DO NOT EDIT!         -*- c++ -*-
00002 
00003 #ifndef cpu_h
00004 #define cpu_h
00005 
00006 #include "types.h"
00007 #include "initcalls.h"
00008 
00009 #include "l4_types.h"
00010 #include "initcalls.h"
00011 
00012 //
00013 // INTERFACE definition follows 
00014 //
00015 
00016 
00017 class Gdt;
00018 class Tss;
00019 
00020 class Cpu
00021 {
00022 public:
00023 
00024   enum Vendor
00025   {
00026     Vendor_unknown = 0,
00027     Vendor_intel,
00028     Vendor_amd,
00029     Vendor_cyrix,
00030     Vendor_via,
00031     Vendor_umc,
00032     Vendor_nexgen,
00033     Vendor_rise,
00034     Vendor_transmeta,
00035     Vendor_sis,
00036     Vensor_nsc
00037   };
00038 
00039   enum CacheTLB
00040   {
00041     Cache_unknown = 0,
00042     Cache_l1_data,
00043     Cache_l1_inst,
00044     Cache_l1_trace,
00045     Cache_l2,
00046     Cache_l3,
00047     Tlb_data_4k,
00048     Tlb_inst_4k,
00049     Tlb_data_4M,
00050     Tlb_inst_4M,
00051     Tlb_data_4k_4M,
00052     Tlb_inst_4k_4M,
00053   };
00054 
00055   enum
00056   {
00057     Ldt_entry_size = 8,
00058   };
00059 
00060   enum Local_features
00061   {
00062     Lf_rdpmc            = 0x00000001,
00063     Lf_rdpmc32          = 0x00000002,
00064   };
00065 
00066   static void                   init();
00067   static Unsigned64             time_us();
00068   static int                    can_wrmsr();
00069 
00070 private:
00071 
00072   struct Vendor_table {
00073     Unsigned32                  vendor_mask;
00074     Unsigned32                  vendor_code;
00075     Unsigned16                  l2_cache;
00076     char                        vendor_string[32];
00077   } __attribute__((packed));
00078 
00079   struct Cache_table {
00080     Unsigned8                   desc;
00081     Unsigned8                   level;
00082     Unsigned16                  size;
00083     Unsigned8                   asso;
00084     Unsigned8                   line_size;
00085   };
00086 
00087   static Unsigned64             _frequency;
00088   static Unsigned32             _version;
00089   static Unsigned32             _brand;
00090   static Unsigned32             _features;
00091   static Unsigned32             _ext_features;
00092   static Unsigned32             _ext_amd_features;
00093   static Unsigned32             _local_features;
00094 
00095   static Unsigned16             _inst_tlb_4k_entries;
00096   static Unsigned16             _data_tlb_4k_entries;
00097   static Unsigned16             _inst_tlb_4m_entries;
00098   static Unsigned16             _data_tlb_4m_entries;
00099   static Unsigned16             _inst_tlb_4k_4m_entries;
00100   static Unsigned16             _data_tlb_4k_4m_entries;
00101   static Unsigned16             _l2_inst_tlb_4k_entries;
00102   static Unsigned16             _l2_data_tlb_4k_entries;
00103   static Unsigned16             _l2_inst_tlb_4m_entries;
00104   static Unsigned16             _l2_data_tlb_4m_entries;
00105 
00106   static Unsigned16             _l1_trace_cache_size;
00107   static Unsigned16             _l1_trace_cache_asso;
00108 
00109   static Unsigned16             _l1_data_cache_size;
00110   static Unsigned16             _l1_data_cache_asso;
00111   static Unsigned16             _l1_data_cache_line_size;
00112 
00113   static Unsigned16             _l1_inst_cache_size;
00114   static Unsigned16             _l1_inst_cache_asso;
00115   static Unsigned16             _l1_inst_cache_line_size;
00116 
00117   static Unsigned16             _l2_cache_size;
00118   static Unsigned16             _l2_cache_asso;
00119   static Unsigned16             _l2_cache_line_size;
00120 
00121   static Vendor                 _vendor;
00122   static char                   _model_str[32];
00123 
00124   static Vendor_table const     intel_table[];
00125   static Vendor_table const     amd_table[];
00126   static Vendor_table const     cyrix_table[];
00127   static Vendor_table const     via_table[];
00128   static Vendor_table const     umc_table[];
00129   static Vendor_table const     nexgen_table[];
00130   static Vendor_table const     rise_table[];
00131   static Vendor_table const     transmeta_table[];
00132   static Vendor_table const     sis_table[];
00133   static Vendor_table const     nsc_table[];
00134 
00135   static Cache_table const      intel_cache_table[];
00136 
00137   static char * const                   vendor_ident[];
00138   static Vendor_table const * const     vendor_table[];
00139 
00140   static Unsigned32             scaler_tsc_to_ns;
00141   static Unsigned32             scaler_tsc_to_us;
00142   static Unsigned32             scaler_ns_to_tsc;
00143 private:
00144 
00145 public:
00146   enum Lbr
00147     {
00148       LBR_UNINITIALIZED = 0,
00149       LBR_NONE,
00150       LBR_P6,
00151       LBR_P4,
00152     };
00153 
00154 private:
00155   static Lbr            lbr                     asm ("CPU_LBR");
00156   typedef void          (Sysenter)(void);
00157   static Sysenter       *current_sysenter       asm ("CURRENT_SYSENTER");
00158   static Gdt            *gdt                    asm ("CPU_GDT");
00159   static Tss            *tss                    asm ("CPU_TSS");
00160   static Tss            *tss_dbf;
00161 
00162 public:  
00163   static inline char const * vendor_str();
00164   
00165   static inline char const* model_str();
00166   
00167   static inline Cpu::Vendor const vendor();
00168   
00169   static inline unsigned int const family();
00170   
00171   static inline unsigned int const model();
00172   
00173   static inline unsigned int const stepping();
00174   
00175   static inline unsigned int const type();
00176   
00177   static inline Unsigned64 frequency();
00178   
00179   static inline unsigned int const brand();
00180   
00181   static inline unsigned int const features();
00182   
00183   static inline unsigned int const ext_features();
00184   
00185   static inline unsigned int const ext_amd_features();
00186   
00187   static inline unsigned int const local_features();
00188   
00189   static inline bool have_superpages();
00190   
00191   static inline bool have_tsc();
00192   
00193   static inline bool have_sysenter();
00194   
00201   static FIASCO_INIT void identify();
00202   
00203   static inline Unsigned32 muldiv(Unsigned32 val, Unsigned32 mul, Unsigned32 div);
00204   
00205   static inline Unsigned64 ns_to_tsc(Unsigned64 ns);
00206   
00207   static inline Unsigned64 tsc_to_ns(Unsigned64 tsc);
00208   
00209   static inline Unsigned64 tsc_to_us(Unsigned64 tsc);
00210   
00211   static inline void tsc_to_s_and_ns(Unsigned64 tsc, Unsigned32 *s, Unsigned32 *ns);
00212   
00213   static inline void busy_wait_ns(Unsigned64 ns);
00214   
00215   static inline Unsigned64 rdtsc(void);
00216   
00217   static inline Unsigned32 get_scaler_tsc_to_ns();
00218   
00219   static inline Unsigned32 get_scaler_tsc_to_us();
00220   
00221   static inline Unsigned32 get_scaler_ns_to_tsc();
00222   
00223   static inline Unsigned32 get_flags();
00224   
00225   static inline void set_flags(Unsigned32 efl);
00226   
00227   static inline Unsigned32 get_es();
00228   
00229   static inline Unsigned32 get_ss();
00230   
00231   static inline Unsigned32 get_fs();
00232   
00233   static inline Unsigned32 get_gs();
00234   
00235   static inline void set_ds(Unsigned32 val);
00236   
00237   static inline void set_es(Unsigned32 val);
00238   
00239   static inline void set_fs(Unsigned32 val);
00240   
00241   static inline void set_gs(Unsigned32 val);
00242   
00243   static void show_cache_tlb_info(const char *indent);
00244   
00245   static inline void memcpy_bytes(void *dst, void const *src, size_t n);
00246   
00247   static inline void memcpy_mwords(void *dst, void const *src, size_t n);
00248   
00249   static inline void memcpy_bytes_fs(void *dst, void const *src, size_t n);
00250   
00251   static inline void memcpy_mwords_fs(void *dst, void const *src, size_t n);
00252   
00253   static inline void set_cr0(Unsigned32 val);
00254   
00255   static inline void set_pdbr(Address addr);
00256   
00257   static inline void set_cr4(Unsigned32 val);
00258   
00259   static inline void set_ldt(Unsigned16 val);
00260   
00261   static inline void set_cs();
00262   
00263   static inline void set_ss(Unsigned32 val);
00264   
00265   static inline void set_tr(Unsigned16 val);
00266   
00267   static inline Mword get_cr0();
00268   
00269   static inline Address get_pdbr();
00270   
00271   static inline Mword get_cr4();
00272   
00273   static inline Unsigned16 get_ldt();
00274   
00275   static inline Unsigned16 get_tr();
00276   
00277   static inline Unsigned64 rdmsr(Unsigned32 reg);
00278   
00279   static inline Unsigned64 rdpmc(Unsigned32 idx, Unsigned32);
00280   
00281   static inline void wrmsr(Unsigned32 low, Unsigned32 high, Unsigned32 reg);
00282   
00283   static inline void wrmsr(Unsigned64 msr, Unsigned32 reg);
00284   
00285   static inline void enable_rdpmc();
00286   
00287   static Cpu::Lbr const lbr_type();
00288   
00289   static inline void enable_lbr(void);
00290   
00291   static inline void disable_lbr(void);
00292   
00293   static FIASCO_INIT void init_sysenter(Address kernel_esp);
00294   
00295   static void set_sysenter(void (*func)(void));
00296   
00297   static void get_sysenter(void (**func)(void));
00298   
00299   static FIASCO_INIT void init_gdt(Address gdt_mem, Address user_max);
00300   
00301   static FIASCO_INIT void init_tss(Address tss_mem, size_t tss_size);
00302   
00303   static FIASCO_INIT void init_tss_dbf(Address tss_dbf_mem, Address kdir);
00304   
00305   static inline void set_gdt();
00306   
00307   static inline void set_tss();
00308   
00309   static inline Gdt* get_gdt();
00310   
00311   static inline Tss* get_tss();
00312   
00313   static inline void enable_ldt(Address addr, int size);
00314 
00315 private:  
00316   static inline FIASCO_INIT void cpuid(Unsigned32 const mode, Unsigned32 *const eax, Unsigned32 *const ebx, Unsigned32 *const ecx, Unsigned32 *const edx);
00317   
00318   static FIASCO_INIT void cache_tlb_intel();
00319   
00320   static FIASCO_INIT void cache_tlb_l1();
00321   
00322   static FIASCO_INIT void cache_tlb_l2(Cpu::Vendor vendor);
00323   
00324   static FIASCO_INIT void set_model_str(Cpu::Vendor const vendor, unsigned const version, Unsigned16 const l2_cache);
00325   
00326   // Return 2^32 / (tsc clocks per usec)
00327   static FIASCO_INIT void calibrate_tsc();
00328 };
00329 /*
00330  * Fiasco ia32-native
00331  * Architecture specific cpu init code
00332  */
00333 
00334 
00335 //
00336 // IMPLEMENTATION includes follow (for use by inline functions)
00337 //
00338 
00339 #include "gdt.h"
00340 #include "processor.h"
00341 #include "regdefs.h"
00342 
00343 //
00344 // IMPLEMENTATION of inline functions (and needed classes)
00345 //
00346 
00347 
00348 
00349 
00350 inline char const *
00351 Cpu::vendor_str()
00352 {
00353   return _vendor == Vendor_unknown ? "Unknown" : vendor_ident[_vendor];
00354 }
00355 
00356 
00357 
00358 inline char const*
00359 Cpu::model_str()
00360 { return _model_str; }
00361 
00362 
00363 
00364 inline Cpu::Vendor const
00365 Cpu::vendor()
00366 { return _vendor; }
00367 
00368 
00369 
00370 inline unsigned int const
00371 Cpu::family()
00372 {
00373   unsigned int val = (_version >> 8) & 0xF;
00374 
00375   return val == 0xF ? val + ((_version >> 16) & 0xF0) : val;
00376 }
00377 
00378 
00379 
00380 inline unsigned int const
00381 Cpu::model()
00382 {
00383   unsigned int val = (_version >> 4) & 0xF;
00384 
00385   return val == 0xF ? val + ((_version >> 12) & 0xF0) : val;
00386 }
00387 
00388 
00389 
00390 inline unsigned int const
00391 Cpu::stepping()
00392 { return _version & 0xF; }
00393 
00394 
00395 
00396 inline unsigned int const
00397 Cpu::type()
00398 { return (_version >> 12) & 0x3; }
00399 
00400 
00401 
00402 inline Unsigned64
00403 Cpu::frequency()
00404 { return _frequency; }
00405 
00406 
00407 
00408 inline unsigned int const
00409 Cpu::brand()
00410 { return _brand & 0xFF; }
00411 
00412 
00413 
00414 inline unsigned int const
00415 Cpu::features()
00416 { return _features; }
00417 
00418 
00419 
00420 inline unsigned int const
00421 Cpu::ext_features()
00422 { return _ext_features; }
00423 
00424 
00425 
00426 inline unsigned int const
00427 Cpu::ext_amd_features()
00428 { return _ext_amd_features; }
00429 
00430 
00431 
00432 inline unsigned int const
00433 Cpu::local_features()
00434 { return _local_features; }
00435 
00436 
00437 
00438 inline bool
00439 Cpu::have_superpages()
00440 { return features() & FEAT_PSE; }
00441 
00442 
00443 
00444 inline bool
00445 Cpu::have_tsc()
00446 { return features() & FEAT_TSC; }
00447 
00448 
00449 
00450 inline bool
00451 Cpu::have_sysenter()
00452 { return features() & FEAT_SEP; }
00453 
00454 
00455 
00456 inline Unsigned32
00457 Cpu::muldiv(Unsigned32 val, Unsigned32 mul, Unsigned32 div)
00458 {
00459   Unsigned32 dummy;
00460 
00461   asm volatile ("mull %3 ; divl %4\n\t"
00462                :"=a" (val), "=d" (dummy)
00463                : "0" (val),  "d" (mul),  "c" (div));
00464   return val;
00465 }
00466 
00467 
00468 
00469 inline Unsigned64
00470 Cpu::ns_to_tsc(Unsigned64 ns)
00471 {
00472   Unsigned32 dummy;
00473   Unsigned64 tsc;
00474   asm volatile
00475         ("movl  %%edx, %%ecx            \n\t"
00476          "mull  %3                      \n\t"
00477          "movl  %%ecx, %%eax            \n\t"
00478          "movl  %%edx, %%ecx            \n\t"
00479          "mull  %3                      \n\t"
00480          "addl  %%ecx, %%eax            \n\t"
00481          "adcl  $0, %%edx               \n\t"
00482          "shld  $5, %%eax, %%edx        \n\t"
00483          "shll  $5, %%eax               \n\t"
00484         :"=A" (tsc), "=c" (dummy)
00485         : "0" (ns),  "b" (scaler_ns_to_tsc)
00486         );
00487   return tsc;
00488 }
00489 
00490 
00491 
00492 inline Unsigned64
00493 Cpu::tsc_to_ns(Unsigned64 tsc)
00494 {
00495   Unsigned32 dummy;
00496   Unsigned64 ns;
00497   asm volatile
00498         ("movl  %%edx, %%ecx            \n\t"
00499          "mull  %3                      \n\t"
00500          "movl  %%ecx, %%eax            \n\t"
00501          "movl  %%edx, %%ecx            \n\t"
00502          "mull  %3                      \n\t"
00503          "addl  %%ecx, %%eax            \n\t"
00504          "adcl  $0, %%edx               \n\t"
00505          "shld  $5, %%eax, %%edx        \n\t"
00506          "shll  $5, %%eax               \n\t"
00507         :"=A" (ns), "=c" (dummy)
00508         : "0" (tsc), "b" (scaler_tsc_to_ns)
00509         );
00510   return ns;
00511 }
00512 
00513 
00514 
00515 inline Unsigned64
00516 Cpu::tsc_to_us(Unsigned64 tsc)
00517 {
00518   Unsigned32 dummy;
00519   Unsigned64 us;
00520   asm volatile
00521         ("movl  %%edx, %%ecx            \n\t"
00522          "mull  %3                      \n\t"
00523          "movl  %%ecx, %%eax            \n\t"
00524          "movl  %%edx, %%ecx            \n\t"
00525          "mull  %3                      \n\t"
00526          "addl  %%ecx, %%eax            \n\t"
00527          "adcl  $0, %%edx               \n\t"
00528         :"=A" (us), "=c" (dummy)
00529         : "0" (tsc), "S" (scaler_tsc_to_us)
00530         );
00531   return us;
00532 }
00533 
00534 
00535 
00536 inline void
00537 Cpu::tsc_to_s_and_ns(Unsigned64 tsc, Unsigned32 *s, Unsigned32 *ns)
00538 {
00539     Unsigned32 dummy;
00540     __asm__
00541         ("                              \n\t"
00542          "movl  %%edx, %%ecx            \n\t"
00543          "mull  %4                      \n\t"
00544          "movl  %%ecx, %%eax            \n\t"
00545          "movl  %%edx, %%ecx            \n\t"
00546          "mull  %4                      \n\t"
00547          "addl  %%ecx, %%eax            \n\t"
00548          "adcl  $0, %%edx               \n\t"
00549          "movl  $1000000000, %%ecx      \n\t"
00550          "shld  $5, %%eax, %%edx        \n\t"
00551          "shll  $5, %%eax               \n\t"
00552          "divl  %%ecx                   \n\t"
00553         :"=a" (*s), "=d" (*ns), "=c" (dummy)
00554         : "A" (tsc), "g" (scaler_tsc_to_ns)
00555         );
00556 }
00557 
00558 
00559 
00560 inline void
00561 Cpu::busy_wait_ns(Unsigned64 ns)
00562 {
00563   Unsigned64 stop = rdtsc () + ns_to_tsc(ns);
00564 
00565   while (rdtsc() < stop)
00566     Proc::pause();
00567 }
00568 
00569 
00570 
00571 inline Unsigned64
00572 Cpu::rdtsc(void)
00573 {
00574   Unsigned64 tsc;
00575   asm volatile ("rdtsc" : "=A" (tsc));
00576   return tsc;
00577 }
00578 
00579 
00580 
00581 inline Unsigned32
00582 Cpu::get_scaler_tsc_to_ns()
00583 { return scaler_tsc_to_ns; }
00584 
00585 
00586 
00587 inline Unsigned32
00588 Cpu::get_scaler_tsc_to_us()
00589 { return scaler_tsc_to_us; }
00590 
00591 
00592 
00593 inline Unsigned32
00594 Cpu::get_scaler_ns_to_tsc()
00595 { return scaler_ns_to_tsc; }
00596 
00597 
00598 
00599 inline Unsigned32
00600 Cpu::get_flags()
00601 { Unsigned32 efl; asm volatile ("pushfl ; popl %0" : "=rm"(efl)); return efl; }
00602 
00603 
00604 
00605 inline void
00606 Cpu::set_flags(Unsigned32 efl)
00607 { asm volatile ("pushl %0 ; popfl" : : "rm" (efl) : "memory"); }
00608 
00609 
00610 
00611 inline Unsigned32
00612 Cpu::get_es()
00613 { Unsigned32 val; asm volatile ("mov %%es, %0" : "=rm" (val)); return val; }
00614 
00615 
00616 
00617 inline Unsigned32
00618 Cpu::get_ss()
00619 { Unsigned32 val; asm volatile ("mov %%ss, %0" : "=rm" (val)); return val; }
00620 
00621 
00622 
00623 inline Unsigned32
00624 Cpu::get_fs()
00625 { Unsigned32 val; asm volatile ("mov %%fs, %0" : "=rm" (val)); return val; }
00626 
00627 
00628 
00629 inline Unsigned32
00630 Cpu::get_gs()
00631 { Unsigned32 val; asm volatile ("mov %%gs, %0" : "=rm" (val)); return val; }
00632 
00633 
00634 
00635 inline void
00636 Cpu::set_ds(Unsigned32 val)
00637 { asm volatile ("mov %0, %%ds" : : "rm" (val)); }
00638 
00639 
00640 
00641 inline void
00642 Cpu::set_es(Unsigned32 val)
00643 { asm volatile ("mov %0, %%es" : : "rm" (val)); }
00644 
00645 
00646 
00647 inline void
00648 Cpu::set_fs(Unsigned32 val)
00649 { asm volatile ("mov %0, %%fs" : : "rm" (val)); }
00650 
00651 
00652 
00653 inline void
00654 Cpu::set_gs(Unsigned32 val)
00655 { asm volatile ("mov %0, %%gs" : : "rm" (val)); }
00656 
00657 
00658 
00659 inline void
00660 Cpu::memcpy_bytes(void *dst, void const *src, size_t n)
00661 {
00662   unsigned dummy1, dummy2, dummy3;
00663 
00664   asm volatile ("cld                                    \n\t"
00665                 "repz movsl %%ds:(%%esi), %%es:(%%edi)  \n\t"
00666                 "mov %%edx, %%ecx                       \n\t"
00667                 "repz movsb %%ds:(%%esi), %%es:(%%edi)  \n\t"
00668                 : "=c" (dummy1), "=S" (dummy2), "=D" (dummy3)
00669                 : "c" (n >> 2), "d" (n & 3), "S" (src), "D" (dst)
00670                 : "memory");
00671 }
00672 
00673 
00674 
00675 inline void
00676 Cpu::memcpy_mwords(void *dst, void const *src, size_t n)
00677 {
00678   unsigned dummy1, dummy2, dummy3;
00679 
00680   asm volatile ("cld                                    \n\t"
00681                 "rep movsl %%ds:(%%esi), %%es:(%%edi)   \n\t"
00682                 : "=c" (dummy1), "=S" (dummy2), "=D" (dummy3)
00683                 : "c" (n), "S" (src), "D" (dst)
00684                 : "memory");
00685 }
00686 
00687 
00688 
00689 inline void
00690 Cpu::memcpy_bytes_fs(void *dst, void const *src, size_t n)
00691 {
00692   unsigned dummy1, dummy2, dummy3;
00693 
00694   asm volatile ("cld                                    \n\t"
00695                 "rep movsl %%fs:(%%esi), %%es:(%%edi)   \n\t"
00696                 "mov %%edx, %%ecx                       \n\t"
00697                 "repz movsb %%fs:(%%esi), %%es:(%%edi)  \n\t"
00698                 : "=c" (dummy1), "=S" (dummy2), "=D" (dummy3)
00699                 : "c" (n >> 2), "d" (n & 3), "S" (src), "D" (dst)
00700                 : "memory");
00701 }
00702 
00703 
00704 
00705 inline void
00706 Cpu::memcpy_mwords_fs(void *dst, void const *src, size_t n)
00707 {
00708   unsigned dummy1, dummy2, dummy3;
00709 
00710   asm volatile ("cld                                    \n\t"
00711                 "rep movsl %%fs:(%%esi), %%es:(%%edi)   \n\t"
00712                 : "=c" (dummy1), "=S" (dummy2), "=D" (dummy3)
00713                 : "c" (n), "S" (src), "D" (dst)
00714                 : "memory");
00715 }
00716 
00717 
00718 
00719 inline void
00720 Cpu::set_cr0(Unsigned32 val)
00721 { asm volatile ("movl %0, %%cr0" : : "r" (val)); }
00722 
00723 
00724 
00725 inline void
00726 Cpu::set_pdbr(Address addr)
00727 { asm volatile ("movl %0, %%cr3" : : "r" (addr)); }
00728 
00729 
00730 
00731 inline void
00732 Cpu::set_cr4(Unsigned32 val)
00733 { asm volatile ("movl %0, %%cr4" : : "r" (val)); }
00734 
00735 
00736 
00737 inline void
00738 Cpu::set_ldt(Unsigned16 val)
00739 { asm volatile ("lldt %0" : : "rm" (val)); }
00740 
00741 
00742 
00743 inline void
00744 Cpu::set_cs()
00745 {
00746   asm volatile ("ljmp %0,$1f ; 1:" 
00747                 : : "i"(Gdt::gdt_code_kernel | Gdt::Selector_kernel));
00748 }
00749 
00750 
00751 
00752 inline void
00753 Cpu::set_ss(Unsigned32 val)
00754 { asm volatile ("movl %0, %%ss" : : "rm" (val)); }
00755 
00756 
00757 
00758 inline void
00759 Cpu::set_tr(Unsigned16 val)
00760 { asm volatile ("ltr %0" : : "rm" (val)); }
00761 
00762 
00763 
00764 inline Mword
00765 Cpu::get_cr0()
00766 { Mword val; asm volatile ("movl %%cr0, %0" : "=r" (val)); return val; }
00767 
00768 
00769 
00770 inline Address
00771 Cpu::get_pdbr()
00772 { Address addr; asm volatile ("movl %%cr3, %0" : "=r" (addr)); return addr; }
00773 
00774 
00775 
00776 inline Mword
00777 Cpu::get_cr4()
00778 { Mword val; asm volatile ("movl %%cr4, %0" : "=r" (val)); return val; }
00779 
00780 
00781 
00782 inline Unsigned16
00783 Cpu::get_ldt()
00784 { Unsigned16 val; asm volatile ("sldt %0" : "=rm" (val)); return val; }
00785 
00786 
00787 
00788 inline Unsigned16
00789 Cpu::get_tr()
00790 { Unsigned16 val; asm volatile ("str %0" : "=rm" (val)); return val; }
00791 
00792 
00793 
00794 inline Unsigned64
00795 Cpu::rdmsr(Unsigned32 reg)
00796 {
00797   Unsigned64 msr;
00798 
00799   asm volatile ("rdmsr" : "=A" (msr) : "c" (reg));
00800   return msr;
00801 }
00802 
00803 
00804 
00805 inline Unsigned64
00806 Cpu::rdpmc(Unsigned32 idx, Unsigned32)
00807 {
00808   Unsigned64 pmc;
00809 
00810   asm volatile ("rdpmc" : "=A" (pmc) : "c" (idx));
00811   return pmc;
00812 }
00813 
00814 
00815 
00816 inline void
00817 Cpu::wrmsr(Unsigned32 low, Unsigned32 high, Unsigned32 reg)
00818 { asm volatile ("wrmsr" : : "a" (low), "d" (high), "c" (reg)); }
00819 
00820 
00821 
00822 inline void
00823 Cpu::wrmsr(Unsigned64 msr, Unsigned32 reg)
00824 { asm volatile ("wrmsr" : : "A" (msr), "c" (reg)); }
00825 
00826 
00827 
00828 inline void
00829 Cpu::enable_rdpmc()
00830 { set_cr4(get_cr4() | CR4_PCE); }
00831 
00832 
00833 
00834 inline void
00835 Cpu::enable_lbr(void)
00836 {
00837   if (lbr_type() != LBR_NONE)
00838     {
00839       Unsigned64 lbr_ctrl = rdmsr (0x1d9);
00840       wrmsr (lbr_ctrl | 1, 0x1d9);
00841     }
00842 }
00843 
00844 
00845 
00846 inline void
00847 Cpu::disable_lbr(void)
00848 {
00849   if (lbr_type() != LBR_NONE)
00850     {
00851       Unsigned64 lbr_ctrl = rdmsr (0x1d9);
00852       wrmsr (lbr_ctrl & ~1, 0x1d9);
00853     }
00854 }
00855 
00856 
00857 
00858 inline void
00859 Cpu::set_gdt()
00860 {
00861   Pseudo_descriptor desc((Address)gdt, Gdt::gdt_max-1);
00862   Gdt::set (&desc);
00863 }
00864 
00865 
00866 
00867 inline void
00868 Cpu::set_tss()
00869 {
00870   set_tr (Gdt::gdt_tss);
00871 }
00872 
00873 
00874 
00875 inline Gdt*
00876 Cpu::get_gdt()
00877 { return gdt; }
00878 
00879 
00880 
00881 inline Tss*
00882 Cpu::get_tss()
00883 { return tss; }
00884 
00885 
00886 
00887 inline void
00888 Cpu::enable_ldt(Address addr, int size)
00889 {
00890   if (!size)
00891     {
00892       get_gdt()->clear_entry (Gdt::gdt_ldt / 8);
00893       set_ldt(0);
00894     }
00895   else
00896     {
00897       get_gdt()->set_entry_byte (Gdt::gdt_ldt / 8, addr, size-1, 2/*=ldt*/, 0);
00898       set_ldt(Gdt::gdt_ldt);
00899     }
00900 }
00901 
00902 
00903 
00904 inline int
00905 Cpu::can_wrmsr()
00906 { return features() & FEAT_MSR; }
00907 
00908 
00909 
00910 inline Unsigned64
00911 Cpu::time_us()
00912 {
00913   return tsc_to_us (rdtsc());
00914 }
00915 
00916 #endif // cpu_h

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