Phoenix
Object-oriented orthogonally persistent operating system
|
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_ */