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
20struct virtual_address_restrictions;
21
22
23struct VMAddressSpace {
24public:
25			class AreaIterator;
26
27public:
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
126protected:
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
132protected:
133			struct HashDefinition;
134
135protected:
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
151void
152VMAddressSpace::Put()
153{
154	team_id id = fID;
155	if (atomic_add(&fRefCount, -1) == 1)
156		_DeleteIfUnreferenced(id);
157}
158
159
160class VMAddressSpace::AreaIterator {
161public:
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
191private:
192	VMAddressSpace*	fAddressSpace;
193	VMArea*			fNext;
194};
195
196
197inline VMAddressSpace::AreaIterator
198VMAddressSpace::GetAreaIterator()
199{
200	return AreaIterator(this);
201}
202
203
204#ifdef __cplusplus
205extern "C" {
206#endif
207
208void 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