1 /* 2 * Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 * 6 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. 7 * Distributed under the terms of the NewOS License. 8 */ 9 #ifndef _KERNEL_VM_VM_ADDRESS_SPACE_H 10 #define _KERNEL_VM_VM_ADDRESS_SPACE_H 11 12 13 #include <OS.h> 14 15 #include <vm/vm_priv.h> 16 #include <vm/VMArea.h> 17 #include <vm/VMTranslationMap.h> 18 19 20 struct virtual_address_restrictions; 21 22 23 struct VMAddressSpace { 24 public: 25 class AreaIterator; 26 27 public: 28 VMAddressSpace(team_id id, addr_t base, 29 size_t size, const char* name); 30 virtual ~VMAddressSpace(); 31 32 static status_t Init(); 33 34 team_id ID() const { return fID; } 35 addr_t Base() const { return fBase; } 36 addr_t EndAddress() const { return fEndAddress; } 37 size_t Size() const { return fEndAddress - fBase + 1; } 38 size_t FreeSpace() const { return fFreeSpace; } 39 bool IsBeingDeleted() const { return fDeleting; } 40 41 VMTranslationMap* TranslationMap() { return fTranslationMap; } 42 43 status_t ReadLock() 44 { return rw_lock_read_lock(&fLock); } 45 void ReadUnlock() 46 { rw_lock_read_unlock(&fLock); } 47 status_t WriteLock() 48 { return rw_lock_write_lock(&fLock); } 49 void WriteUnlock() 50 { rw_lock_write_unlock(&fLock); } 51 52 int32 RefCount() const 53 { return fRefCount; } 54 55 inline void Get() { atomic_add(&fRefCount, 1); } 56 inline void Put(); 57 void RemoveAndPut(); 58 59 void IncrementFaultCount() 60 { atomic_add(&fFaultCount, 1); } 61 void IncrementChangeCount() 62 { fChangeCount++; } 63 64 inline bool IsRandomizingEnabled() const 65 { return fRandomizingEnabled; } 66 inline void SetRandomizingEnabled(bool enabled) 67 { fRandomizingEnabled = enabled; } 68 69 inline AreaIterator GetAreaIterator(); 70 71 VMAddressSpace*& HashTableLink() { return fHashTableLink; } 72 73 virtual status_t InitObject(); 74 75 virtual VMArea* FirstArea() const = 0; 76 virtual VMArea* NextArea(VMArea* area) const = 0; 77 78 virtual VMArea* LookupArea(addr_t address) const = 0; 79 virtual VMArea* CreateArea(const char* name, uint32 wiring, 80 uint32 protection, 81 uint32 allocationFlags) = 0; 82 virtual void DeleteArea(VMArea* area, 83 uint32 allocationFlags) = 0; 84 virtual status_t InsertArea(VMArea* area, size_t size, 85 const virtual_address_restrictions* 86 addressRestrictions, 87 uint32 allocationFlags, void** _address) 88 = 0; 89 virtual void RemoveArea(VMArea* area, 90 uint32 allocationFlags) = 0; 91 92 virtual bool CanResizeArea(VMArea* area, size_t newSize) = 0; 93 virtual status_t ResizeArea(VMArea* area, size_t newSize, 94 uint32 allocationFlags) = 0; 95 virtual status_t ShrinkAreaHead(VMArea* area, size_t newSize, 96 uint32 allocationFlags) = 0; 97 virtual status_t ShrinkAreaTail(VMArea* area, size_t newSize, 98 uint32 allocationFlags) = 0; 99 100 virtual status_t ReserveAddressRange(size_t size, 101 const virtual_address_restrictions* 102 addressRestrictions, 103 uint32 flags, uint32 allocationFlags, 104 void** _address) = 0; 105 virtual status_t UnreserveAddressRange(addr_t address, 106 size_t size, uint32 allocationFlags) = 0; 107 virtual void UnreserveAllAddressRanges( 108 uint32 allocationFlags) = 0; 109 110 virtual void Dump() const; 111 112 static status_t Create(team_id teamID, addr_t base, size_t size, 113 bool kernel, 114 VMAddressSpace** _addressSpace); 115 116 static team_id KernelID() 117 { return sKernelAddressSpace->ID(); } 118 static VMAddressSpace* Kernel() 119 { return sKernelAddressSpace; } 120 static VMAddressSpace* GetKernel(); 121 122 static team_id CurrentID(); 123 static VMAddressSpace* GetCurrent(); 124 125 static VMAddressSpace* Get(team_id teamID); 126 127 static VMAddressSpace* DebugFirst(); 128 static VMAddressSpace* DebugNext(VMAddressSpace* addressSpace); 129 static VMAddressSpace* DebugGet(team_id teamID); 130 131 protected: 132 static void _DeleteIfUnreferenced(team_id id); 133 134 static int _DumpCommand(int argc, char** argv); 135 static int _DumpListCommand(int argc, char** argv); 136 137 protected: 138 struct HashDefinition; 139 140 protected: 141 VMAddressSpace* fHashTableLink; 142 addr_t fBase; 143 addr_t fEndAddress; // base + (size - 1) 144 size_t fFreeSpace; 145 rw_lock fLock; 146 team_id fID; 147 int32 fRefCount; 148 int32 fFaultCount; 149 int32 fChangeCount; 150 VMTranslationMap* fTranslationMap; 151 bool fRandomizingEnabled; 152 bool fDeleting; 153 static VMAddressSpace* sKernelAddressSpace; 154 }; 155 156 157 void 158 VMAddressSpace::Put() 159 { 160 team_id id = fID; 161 if (atomic_add(&fRefCount, -1) == 1) 162 _DeleteIfUnreferenced(id); 163 } 164 165 166 class VMAddressSpace::AreaIterator { 167 public: 168 AreaIterator() 169 { 170 } 171 172 AreaIterator(VMAddressSpace* addressSpace) 173 : 174 fAddressSpace(addressSpace), 175 fNext(addressSpace->FirstArea()) 176 { 177 } 178 179 bool HasNext() const 180 { 181 return fNext != NULL; 182 } 183 184 VMArea* Next() 185 { 186 VMArea* result = fNext; 187 if (fNext != NULL) 188 fNext = fAddressSpace->NextArea(fNext); 189 return result; 190 } 191 192 void Rewind() 193 { 194 fNext = fAddressSpace->FirstArea(); 195 } 196 197 private: 198 VMAddressSpace* fAddressSpace; 199 VMArea* fNext; 200 }; 201 202 203 inline VMAddressSpace::AreaIterator 204 VMAddressSpace::GetAreaIterator() 205 { 206 return AreaIterator(this); 207 } 208 209 210 #ifdef __cplusplus 211 extern "C" { 212 #endif 213 214 void vm_delete_areas(struct VMAddressSpace *aspace, bool deletingAddressSpace); 215 #define vm_swap_address_space(from, to) arch_vm_aspace_swap(from, to) 216 217 #ifdef __cplusplus 218 } 219 #endif 220 221 222 #endif /* _KERNEL_VM_VM_ADDRESS_SPACE_H */ 223