Phoenix
Object-oriented orthogonally persistent operating system
vm.h
Go to the documentation of this file.
00001 /*
00002  * /phoenix/kernel/sys/vm.h
00003  *
00004  * This file is a part of Phoenix operating system.
00005  * Copyright (c) 2011-2012, Artyom Lebedev <artyom.lebedev@gmail.com>
00006  * All rights reserved.
00007  * See COPYING file for copyright details.
00008  */
00009 
00010 #ifndef VM_H_
00011 #define VM_H_
00012 
00017 #ifdef AUTONOMOUS_LINKING
00018 namespace {
00019 #endif /* AUTONOMOUS_LINKING */
00020 
00022 namespace vm {
00023 
00029 enum LatEntryFlags {
00034     LAT_EF_PRESENT =        0x1,
00038     LAT_EF_WRITE =          0x2,
00042     LAT_EF_USER =           0x4,
00046     LAT_EF_WRITE_THROUGH =  0x8,
00050     LAT_EF_CACHE_DISABLE =  0x10,
00052     LAT_EF_EXECUTE =        0x20,
00057     LAT_EF_GLOBAL =         0x40,
00058 };
00059 
00063 #ifndef AUTONOMOUS_LINKING
00064 extern
00065 #endif /* AUTONOMOUS_LINKING */
00066 struct VmCaps {
00067     bool    valid:1,    
00068             pge:1,      
00069             pat:1,      
00070             pcid:1,     
00071             smep:1,     
00072             nx:1,       
00073             oneGb:1;    
00074     short   width_phys; 
00075     short   width_lin;  
00081     inline bool IsValid() {
00082         if (!valid) {
00083             Initialize();
00084         }
00085         return true;
00086     }
00087 
00088     void Initialize() {
00089         cpu::CpuCaps caps;
00090 
00091         pge = caps.GetCapability(cpu::CPU_CAP_PG_PGE) ? true : false;
00092         pat = caps.GetCapability(cpu::CPU_CAP_PG_PAT) ? true : false;
00093         pcid = caps.GetCapability(cpu::CPU_CAP_PG_PCID) ? true : false;
00094         smep = caps.GetCapability(cpu::CPU_CAP_PG_SMEP) ? true : false;
00095         nx = caps.GetCapability(cpu::CPU_CAP_PG_NX) ? true : false;
00096         oneGb = caps.GetCapability(cpu::CPU_CAP_PG_1GB) ? true : false;
00097         width_phys = caps.GetCapability(cpu::CPU_CAP_PG_WIDTH_PHYS);
00098         width_lin = caps.GetCapability(cpu::CPU_CAP_PG_WIDTH_LIN);
00099 
00100         valid = true;
00101     }
00102 
00103 } vmCaps;
00104 
00105 } /* namespace vm */
00106 
00107 #include <md_vm.h>
00108 
00109 namespace vm {
00110 
00111 enum {
00113     PAGE_SIZE =             (1 << PAGE_SHIFT),
00115     NUM_QUICK_MAP =         4,
00116 
00118     SYS_DATA_SIZE =         static_cast<vaddr_t>(4) * 1024 * 1024 * 1024,
00122     GATE_AREA_SIZE =        64 * 1024,
00123 
00125     VMA_CNTR_TEXT =         PAGE_SIZE,
00127     VMA_KERNEL_TEXT =       KERNEL_ADDRESS,
00129     VMA_SYS_DATA =          static_cast<vaddr_t>(2) * 1024 * 1024 * 1024,
00131     VMA_KERNEL_PUBLIC =     VMA_SYS_DATA - GATE_AREA_SIZE,
00133     VMA_GLOBAL_DATA =       VMA_SYS_DATA + SYS_DATA_SIZE
00134 };
00135 
00137 template <typename AddrType>
00138 class Addr {
00139 public:
00141     inline Addr(AddrType addr = 0) { _addr.addr = addr; }
00143     template <typename T>
00144     inline Addr(T addr) { _addr.addr = addr; }
00146     template <typename T>
00147     inline Addr(T *ptr) { _addr.ptr = ptr; }
00148 
00150     inline Addr &operator=(AddrType addr) { _addr.addr = addr; return *this; }
00152     inline Addr &operator=(void *ptr) { _addr.ptr = ptr; return *this; }
00153 
00155     inline Addr &operator+=(const Addr &addr) { _addr.addr += addr._addr.addr; return *this; }
00157     inline Addr &operator+=(const AddrType addr) { _addr.addr += addr; return *this; }
00158 
00160     inline Addr &operator-=(const Addr &addr) { _addr.addr -= addr._addr.addr; return *this; }
00162     inline Addr &operator-=(const AddrType addr) { _addr.addr -= addr; return *this; }
00163 
00165     inline bool operator==(const Addr &addr) { return _addr.addr == addr._addr.addr; }
00167     inline bool operator==(void *ptr) { return _addr.ptr == ptr; }
00169     inline bool operator==(AddrType addr) { return _addr.addr == addr; }
00171     inline bool operator==(int addr) { return _addr.addr == static_cast<AddrType>(addr); }
00172 
00174     inline bool operator!=(const Addr &addr) { return _addr.addr != addr._addr.addr; }
00176     inline bool operator!=(void *ptr) { return _addr.ptr != ptr; }
00178     inline bool operator!=(AddrType addr) { return _addr.addr != addr; }
00180     inline bool operator!=(int addr) { return _addr.addr != static_cast<AddrType>(addr); }
00181 
00183     inline bool operator <(Addr &addr) { return _addr.addr < addr._addr.addr; }
00185     template <typename T>
00186     inline bool operator <(T addr) { return _addr.addr < addr; }
00188     inline bool operator <=(Addr &addr) { return _addr.addr <= addr._addr.addr; }
00190     template <typename T>
00191     inline bool operator <=(T addr) { return _addr.addr <= addr; }
00193     inline bool operator >(Addr &addr) { return _addr.addr > addr._addr.addr; }
00195     template <typename T>
00196     inline bool operator >(T addr) { return _addr.addr > addr; }
00198     inline bool operator >=(Addr &addr) { return _addr.addr >= addr._addr.addr; }
00200     template <typename T>
00201     inline bool operator >=(T addr) { return _addr.addr >= addr; }
00202 
00204     inline Addr operator +(Addr &addr) {
00205         return Addr(_addr.addr + addr._addr.addr);
00206     }
00208     template <typename T>
00209     inline Addr operator +(T addr) {
00210         return Addr(_addr.addr + addr);
00211     }
00213     inline Addr operator -(Addr &addr) {
00214         return Addr(_addr.addr - addr._addr.addr);
00215     }
00217     template <typename T>
00218     inline Addr operator -(T addr) {
00219         return Addr(_addr.addr - addr);
00220     }
00221 
00223     inline operator AddrType() { return _addr.addr; }
00225     inline AddrType BaseAddr() { return _addr.addr; }
00227     inline operator void *() { return _addr.ptr; }
00229     template<typename T>
00230     inline operator T *() { return static_cast<T *>(_addr.ptr); }
00231 
00238     inline Addr &RoundUp(AddrType alignment = PAGE_SIZE) {
00239         _addr.addr = ::RoundUp2(_addr.addr, alignment);
00240         return *this;
00241     }
00242 
00249     inline Addr &RoundDown(AddrType alignment = PAGE_SIZE) {
00250         _addr.addr = ::RoundDown2(_addr.addr, alignment);
00251         return *this;
00252     }
00253 
00259     inline bool IsAligned(AddrType alignment = PAGE_SIZE) {
00260         ASSERT(IsPowerOf2(alignment));
00261         return !(_addr.addr & (alignment - 1));
00262     }
00263 
00265     inline PageIdx GetPageIdx() { return _addr.addr >> PAGE_SHIFT; }
00266 
00268     inline vaddr_t GetPageOffset() {
00269         VaddrDecoder dec(_addr.addr);
00270         return dec.GetPageOffset();
00271     }
00272 
00274     inline bool CheckFmtChar(char fmtChar) {
00275         return !fmtChar || fmtChar == 'd' ||  fmtChar == 'u' || fmtChar == 'p' ||
00276                fmtChar == 'x' || fmtChar == 'X' || fmtChar == 'o';
00277     }
00278 
00280     inline bool ToString(text_stream::OTextStreamBase &stream,
00281                          text_stream::OTextStreamBase::Context &ctx,
00282                          char fmtChar = 0) {
00283 
00284         if (fmtChar == 'p') {
00285             return stream.FormatValue(ctx,  _addr.ptr, fmtChar);
00286         } else if (!fmtChar) {
00287             fmtChar = 'x';
00288         }
00289         return stream.FormatValue(ctx, _addr.addr, fmtChar);
00290     }
00291 
00292 protected:
00293     union {
00294         AddrType addr;
00295         void *ptr;
00296     } _addr;
00297 };
00298 
00300 class Vaddr : public Addr<vaddr_t> {
00301 public:
00303     inline Vaddr(vaddr_t addr = 0) : Addr(addr) { }
00305     template <typename T>
00306     inline Vaddr(T addr) : Addr(addr) { }
00308     template <typename T>
00309     inline Vaddr(T *ptr) : Addr(ptr) { }
00311     inline Vaddr(Addr<vaddr_t> addr) : Addr(addr) { }
00312 
00314     inline paddr_t IdentityPaddr() { return static_cast<paddr_t>(_addr.addr); }
00315 };
00316 
00318 class Paddr : public Addr<paddr_t> {
00319 public:
00321     inline Paddr(paddr_t addr = 0) : Addr(addr) { }
00323     template <typename T>
00324     inline Paddr(T addr) : Addr(addr) { }
00326     template <typename T>
00327     inline Paddr(T *ptr) : Addr(ptr) { }
00329     inline Paddr(Addr<paddr_t> addr) : Addr(addr) { }
00330 
00332     inline vaddr_t IdentityVaddr() { return static_cast<vaddr_t>(_addr.addr); }
00333 };
00334 
00335 } /* namespace vm */
00336 
00337 #include <vm_mm.h>
00338 
00339 #ifdef AUTONOMOUS_LINKING
00340 }
00341 #endif /* AUTONOMOUS_LINKING */
00342 
00343 #endif /* VM_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines