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 AreaIterator GetAreaIterator(); 65 66 VMAddressSpace*& HashTableLink() { return fHashTableLink; } 67 68 virtual status_t InitObject(); 69 70 virtual VMArea* FirstArea() const = 0; 71 virtual VMArea* NextArea(VMArea* area) const = 0; 72 73 virtual VMArea* LookupArea(addr_t address) const = 0; 74 virtual VMArea* CreateArea(const char* name, uint32 wiring, 75 uint32 protection, 76 uint32 allocationFlags) = 0; 77 virtual void DeleteArea(VMArea* area, 78 uint32 allocationFlags) = 0; 79 virtual status_t InsertArea(VMArea* area, size_t size, 80 const virtual_address_restrictions* 81 addressRestrictions, 82 uint32 allocationFlags, void** _address) 83 = 0; 84 virtual void RemoveArea(VMArea* area, 85 uint32 allocationFlags) = 0; 86 87 virtual bool CanResizeArea(VMArea* area, size_t newSize) = 0; 88 virtual status_t ResizeArea(VMArea* area, size_t newSize, 89 uint32 allocationFlags) = 0; 90 virtual status_t ShrinkAreaHead(VMArea* area, size_t newSize, 91 uint32 allocationFlags) = 0; 92 virtual status_t ShrinkAreaTail(VMArea* area, size_t newSize, 93 uint32 allocationFlags) = 0; 94 95 virtual status_t ReserveAddressRange(size_t size, 96 const virtual_address_restrictions* 97 addressRestrictions, 98 uint32 flags, uint32 allocationFlags, 99 void** _address) = 0; 100 virtual status_t UnreserveAddressRange(addr_t address, 101 size_t size, uint32 allocationFlags) = 0; 102 virtual void UnreserveAllAddressRanges( 103 uint32 allocationFlags) = 0; 104 105 virtual void Dump() const; 106 107 static status_t Create(team_id teamID, addr_t base, size_t size, 108 bool kernel, 109 VMAddressSpace** _addressSpace); 110 111 static team_id KernelID() 112 { return sKernelAddressSpace->ID(); } 113 static VMAddressSpace* Kernel() 114 { return sKernelAddressSpace; } 115 static VMAddressSpace* GetKernel(); 116 117 static team_id CurrentID(); 118 static VMAddressSpace* GetCurrent(); 119 120 static VMAddressSpace* Get(team_id teamID); 121 122 static VMAddressSpace* DebugFirst(); 123 static VMAddressSpace* DebugNext(VMAddressSpace* addressSpace); 124 static VMAddressSpace* DebugGet(team_id teamID); 125 126 protected: 127 static void _DeleteIfUnreferenced(team_id id); 128 129 static int _DumpCommand(int argc, char** argv); 130 static int _DumpListCommand(int argc, char** argv); 131 132 protected: 133 struct HashDefinition; 134 135 protected: 136 VMAddressSpace* fHashTableLink; 137 addr_t fBase; 138 addr_t fEndAddress; // base + (size - 1) 139 size_t fFreeSpace; 140 rw_lock fLock; 141 team_id fID; 142 int32 fRefCount; 143 int32 fFaultCount; 144 int32 fChangeCount; 145 VMTranslationMap* fTranslationMap; 146 bool fDeleting; 147 static VMAddressSpace* sKernelAddressSpace; 148 }; 149 150 151 void 152 VMAddressSpace::Put() 153 { 154 team_id id = fID; 155 if (atomic_add(&fRefCount, -1) == 1) 156 _DeleteIfUnreferenced(id); 157 } 158 159 160 class VMAddressSpace::AreaIterator { 161 public: 162 AreaIterator() 163 { 164 } 165 166 AreaIterator(VMAddressSpace* addressSpace) 167 : 168 fAddressSpace(addressSpace), 169 fNext(addressSpace->FirstArea()) 170 { 171 } 172 173 bool HasNext() const 174 { 175 return fNext != NULL; 176 } 177 178 VMArea* Next() 179 { 180 VMArea* result = fNext; 181 if (fNext != NULL) 182 fNext = fAddressSpace->NextArea(fNext); 183 return result; 184 } 185 186 void Rewind() 187 { 188 fNext = fAddressSpace->FirstArea(); 189 } 190 191 private: 192 VMAddressSpace* fAddressSpace; 193 VMArea* fNext; 194 }; 195 196 197 inline VMAddressSpace::AreaIterator 198 VMAddressSpace::GetAreaIterator() 199 { 200 return AreaIterator(this); 201 } 202 203 204 #ifdef __cplusplus 205 extern "C" { 206 #endif 207 208 void vm_delete_areas(struct VMAddressSpace *aspace, bool deletingAddressSpace); 209 #define vm_swap_address_space(from, to) arch_vm_aspace_swap(from, to) 210 211 #ifdef __cplusplus 212 } 213 #endif 214 215 216 #endif /* _KERNEL_VM_VM_ADDRESS_SPACE_H */ 217