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