2 * Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
4 * Distributed under the terms of the MIT License.
6 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
7 * Distributed under the terms of the NewOS License.
9 #ifndef _KERNEL_VM_VM_AREA_H
10 #define _KERNEL_VM_VM_AREA_H
16 #include <util/DoublyLinkedList.h>
17 #include <util/SinglyLinkedList.h>
18 #include <util/OpenHashTable.h>
19 #include <vm/vm_types.h>
22 struct VMAddressSpace
;
24 struct VMKernelAddressSpace
;
25 struct VMUserAddressSpace
;
28 struct VMAreaUnwiredWaiter
29 : public DoublyLinkedListLinkImpl
<VMAreaUnwiredWaiter
> {
33 ConditionVariable condition
;
34 ConditionVariableEntry waitEntry
;
37 typedef DoublyLinkedList
<VMAreaUnwiredWaiter
> VMAreaUnwiredWaiterList
;
40 struct VMAreaWiredRange
: SinglyLinkedListLinkImpl
<VMAreaWiredRange
> {
45 bool implicit
; // range created automatically
46 VMAreaUnwiredWaiterList waiters
;
52 VMAreaWiredRange(addr_t base
, size_t size
, bool writable
, bool implicit
)
62 void SetTo(addr_t base
, size_t size
, bool writable
, bool implicit
)
67 this->writable
= writable
;
68 this->implicit
= implicit
;
71 bool IntersectsWith(addr_t base
, size_t size
) const
73 return this->base
+ this->size
- 1 >= base
74 && base
+ size
- 1 >= this->base
;
78 typedef SinglyLinkedList
<VMAreaWiredRange
> VMAreaWiredRangeList
;
81 struct VMPageWiringInfo
{
82 VMAreaWiredRange range
;
83 phys_addr_t physicalAddress
;
84 // the actual physical address corresponding to
85 // the virtual address passed to vm_wire_page()
86 // (i.e. with in-page offset)
94 // AddWaiterIfWired() flags
95 IGNORE_WRITE_WIRED_RANGES
= 0x01, // ignore existing ranges that
106 uint16 memory_type
; // >> shifted by MEMORY_TYPE_SHIFT
110 vint32 no_cache_change
;
113 VMAreaMappings mappings
;
114 uint8
* page_protections
;
116 struct VMAddressSpace
* address_space
;
117 struct VMArea
* cache_next
;
118 struct VMArea
* cache_prev
;
119 struct VMArea
* hash_next
;
121 addr_t
Base() const { return fBase
; }
122 size_t Size() const { return fSize
; }
124 inline uint32
MemoryType() const;
125 inline void SetMemoryType(uint32 memoryType
);
127 bool ContainsAddress(addr_t address
) const
128 { return address
>= fBase
129 && address
<= fBase
+ (fSize
- 1); }
132 { return !fWiredRanges
.IsEmpty(); }
133 bool IsWired(addr_t base
, size_t size
) const;
135 void Wire(VMAreaWiredRange
* range
);
136 void Unwire(VMAreaWiredRange
* range
);
137 VMAreaWiredRange
* Unwire(addr_t base
, size_t size
, bool writable
);
139 bool AddWaiterIfWired(VMAreaUnwiredWaiter
* waiter
);
140 bool AddWaiterIfWired(VMAreaUnwiredWaiter
* waiter
,
141 addr_t base
, size_t size
, uint32 flags
= 0);
144 VMArea(VMAddressSpace
* addressSpace
,
145 uint32 wiring
, uint32 protection
);
148 status_t
Init(const char* name
, uint32 allocationFlags
);
151 friend struct VMAddressSpace
;
152 friend struct VMKernelAddressSpace
;
153 friend struct VMUserAddressSpace
;
156 void SetBase(addr_t base
) { fBase
= base
; }
157 void SetSize(size_t size
) { fSize
= size
; }
162 VMAreaWiredRangeList fWiredRanges
;
166 struct VMAreaHashDefinition
{
167 typedef area_id KeyType
;
168 typedef VMArea ValueType
;
170 size_t HashKey(area_id key
) const
175 size_t Hash(const VMArea
* value
) const
177 return HashKey(value
->id
);
180 bool Compare(area_id key
, const VMArea
* value
) const
182 return value
->id
== key
;
185 VMArea
*& GetLink(VMArea
* value
) const
187 return value
->hash_next
;
191 typedef BOpenHashTable
<VMAreaHashDefinition
> VMAreaHashTable
;
195 static status_t
Init();
197 static status_t
ReadLock()
198 { return rw_lock_read_lock(&sLock
); }
199 static void ReadUnlock()
200 { rw_lock_read_unlock(&sLock
); }
201 static status_t
WriteLock()
202 { return rw_lock_write_lock(&sLock
); }
203 static void WriteUnlock()
204 { rw_lock_write_unlock(&sLock
); }
206 static VMArea
* LookupLocked(area_id id
)
207 { return sTable
.Lookup(id
); }
208 static VMArea
* Lookup(area_id id
);
209 static area_id
Find(const char* name
);
210 static void Insert(VMArea
* area
);
211 static void Remove(VMArea
* area
);
213 static VMAreaHashTable::Iterator
GetIterator()
214 { return sTable
.GetIterator(); }
217 static rw_lock sLock
;
218 static VMAreaHashTable sTable
;
223 VMArea::MemoryType() const
225 return (uint32
)memory_type
<< MEMORY_TYPE_SHIFT
;
230 VMArea::SetMemoryType(uint32 memoryType
)
232 memory_type
= memoryType
>> MEMORY_TYPE_SHIFT
;
236 #endif // _KERNEL_VM_VM_AREA_H