The Pedigree Project 0.1
kernel/core/processor/hosted/VirtualAddressSpace.h
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#ifndef KERNEL_PROCESSOR_HOSTED_VIRTUALADDRESSSPACE_H
21#define KERNEL_PROCESSOR_HOSTED_VIRTUALADDRESSSPACE_H
22#include "pedigree/kernel/Spinlock.h"
23#include "pedigree/kernel/processor/VirtualAddressSpace.h"
24#include "pedigree/kernel/processor/types.h"
25#include "pedigree/kernel/utilities/Vector.h"
26
27#include <config.h>
28
29#include "MappingIndex.h"
30
31//
32// Virtual address space layout
33//
34#define KERNEL_SPACE_START reinterpret_cast<void*>(0x0000700000000000)
35
36#define USERSPACE_DYNAMIC_LINKER_LOCATION reinterpret_cast<void*>(0x4FA00000)
37
38#define USERSPACE_VIRTUAL_START reinterpret_cast<void*>(0x20000000)
39#define USERSPACE_VIRTUAL_HEAP reinterpret_cast<void*>(0x50000000)
40#define USERSPACE_RESERVED_START USERSPACE_DYNAMIC_LINKER_LOCATION
41#define USERSPACE_VIRTUAL_STACK_SIZE 0x100000
42#define USERSPACE_VIRTUAL_MAX_STACK_SIZE 0x100000
43#define USERSPACE_DYNAMIC_START reinterpret_cast<void*>(0x0000400000000000)
44#define USERSPACE_DYNAMIC_END reinterpret_cast<void*>(0x0000500000000000)
45#define USERSPACE_VIRTUAL_LOWEST_STACK \
46 reinterpret_cast<void*>(USERSPACE_DYNAMIC_END + USERSPACE_VIRTUAL_MAX_STACK_SIZE)
47#define USERSPACE_VIRTUAL_STACK \
48 reinterpret_cast<void*>(0x0000700000000000ULL - PEDIGREE_TARGET_PAGE_SIZE)
49#define KERNEL_VIRTUAL_MODULE_BASE reinterpret_cast<void*>(0x70000000)
50#define KERNEL_VIRTUAL_MODULE_SIZE 0x10000000
51#define KERNEL_VIRTUAL_EVENT_BASE reinterpret_cast<void*>(0x300000000000)
52#define KERNEL_VIRTUAL_HEAP reinterpret_cast<void*>(0x0000700000000000)
53#define KERNEL_VIRTUAL_HEAP_SIZE 0x40000000
54#define KERNEL_VIRTUAL_ADDRESS reinterpret_cast<void*>(0x400000)
55#define KERNEL_VIRTUAL_CACHE reinterpret_cast<void*>(0x200000000000)
56#define KERNEL_VIRTUAL_CACHE_SIZE 0x10000000
57#define KERNEL_VIRTUAL_MEMORYREGION_ADDRESS reinterpret_cast<void*>(0x0000700040000000)
58#define KERNEL_VIRTUAL_MEMORYREGION_SIZE 0x40000000
59#define KERNEL_VIRTUAL_PAGESTACK_4GB reinterpret_cast<void*>(0x0000700080000000)
60#define KERNEL_VIRTUAL_STACK \
61 reinterpret_cast<void*>(0x0000701000000000ULL - PEDIGREE_TARGET_PAGE_SIZE)
62#define KERNEL_STACK_SIZE 0x10000
63
72 friend class HostedProcessor;
73 friend class ProcessorBase;
75 friend class Multiprocessor;
81
82 public:
83 //
84 // VirtualAddressSpace Interface
85 //
86 virtual bool isAddressValid(void* virtualAddress);
87 virtual bool isMapped(void* virtualAddress);
88
89 virtual bool map(physical_uintptr_t physAddress, void* virtualAddress, size_t flags);
90 bool tryMapUserPage(physical_uintptr_t physical, void* address, size_t flags,
91 size_t* committedTablePages = nullptr) override;
92 bool tryDetachUserPage(void* address, physical_uintptr_t expected) override;
93 virtual bool getMapping(void* virtualAddress, physical_uintptr_t& physAddress, size_t& flags);
94 virtual bool handleCopyOnWriteFault(void* virtualAddress, bool userMode);
95 virtual bool tryWriteUser32(uintptr_t address, uint32_t value);
96 virtual bool tryReadUser32(uintptr_t address, uint32_t& value);
97 virtual bool tryReadUserPointer(uintptr_t address, uintptr_t& value);
98 virtual bool tryCompareExchangeUser32(uintptr_t address, uint32_t& expected, uint32_t desired,
99 bool& exchanged);
100 virtual void setFlags(void* virtualAddress, size_t newFlags);
101 MUST_USE_RESULT bool trySetFlags(void* virtualAddress, size_t newFlags) override;
102 virtual void unmap(void* virtualAddress);
103 virtual bool detachMapping(void* virtualAddress, physical_uintptr_t& physical, size_t& flags,
104 size_t requiredFlags = 0);
105 virtual Stack* allocateStack();
106 virtual Stack* allocateStack(size_t stackSz);
107 virtual void freeStack(Stack* pStack);
108
109 virtual bool memIsInHeap(void* pMem);
110 virtual void* getEndOfHeap();
111
112 virtual bool memIsInKernelHeap(void* pMem);
113
114 virtual VirtualAddressSpace* clone(bool copyOnWrite = true);
115 virtual void revertToKernelAddressSpace();
116
119
121 virtual uintptr_t getKernelStart() const {
122 return reinterpret_cast<uintptr_t>(KERNEL_SPACE_START);
123 }
124
126 virtual uintptr_t getUserStart() const {
127 return reinterpret_cast<uintptr_t>(USERSPACE_VIRTUAL_START);
128 }
129
131 virtual uintptr_t getUserReservedStart() const {
132 return reinterpret_cast<uintptr_t>(USERSPACE_RESERVED_START);
133 }
134
136 virtual uintptr_t getDynamicLinkerAddress() const {
137 return reinterpret_cast<uintptr_t>(USERSPACE_DYNAMIC_LINKER_LOCATION);
138 }
139
141 virtual uintptr_t getKernelHeapStart() const {
142 return reinterpret_cast<uintptr_t>(KERNEL_VIRTUAL_HEAP);
143 }
144
146 virtual uintptr_t getKernelHeapEnd() const {
147 return reinterpret_cast<uintptr_t>(KERNEL_VIRTUAL_HEAP) + KERNEL_VIRTUAL_HEAP_SIZE;
148 }
149
151 virtual uintptr_t getDynamicStart() const {
152 return reinterpret_cast<uintptr_t>(USERSPACE_DYNAMIC_START);
153 }
154
156 virtual uintptr_t getDynamicEnd() const {
157 return reinterpret_cast<uintptr_t>(USERSPACE_DYNAMIC_END);
158 }
159
161 virtual uintptr_t getKernelCacheStart() const {
162 return reinterpret_cast<uintptr_t>(KERNEL_VIRTUAL_CACHE);
163 }
164
166 virtual uintptr_t getKernelCacheEnd() const {
167 return reinterpret_cast<uintptr_t>(KERNEL_VIRTUAL_CACHE) + KERNEL_VIRTUAL_CACHE_SIZE;
168 }
169
171 virtual uintptr_t getKernelEventBlockStart() const {
172 return reinterpret_cast<uintptr_t>(KERNEL_VIRTUAL_EVENT_BASE);
173 }
174
176 virtual uintptr_t getKernelModulesStart() const {
177 return reinterpret_cast<uintptr_t>(KERNEL_VIRTUAL_MODULE_BASE);
178 }
179
181 virtual uintptr_t getKernelModulesEnd() const {
182 return reinterpret_cast<uintptr_t>(KERNEL_VIRTUAL_MODULE_BASE) + KERNEL_VIRTUAL_MODULE_SIZE;
183 }
184
186 virtual uintptr_t getKernelVirtualPagestack() const {
187 return reinterpret_cast<uintptr_t>(KERNEL_VIRTUAL_PAGESTACK_4GB);
188 }
189
190 private:
191 bool tryAccessUserWord(uintptr_t address, size_t width, uintptr_t& value,
192 const uintptr_t* replacement);
201 HostedVirtualAddressSpace(void* Heap, void* VirtualStack);
202
209
211 static void switchAddressSpace(VirtualAddressSpace& oldSpace, VirtualAddressSpace& newSpace);
212
218 uint64_t toFlags(size_t flags, bool bFinal = false);
224 size_t fromFlags(uint64_t Flags, bool bFinal = false);
225
227 Stack* doAllocateStack(size_t sSize);
228
229 typedef struct {
230 bool active;
231 void* vaddr;
232 physical_uintptr_t paddr;
233 size_t flags; // Real flags, not the mmap-specific ones.
234 } mapping_t;
235
236 // Mapping records can move during growth; the index stores array slots.
237 mapping_t* findMapping(void* address);
238
251 HostedMappingIndex m_MappingIndex;
258
259 static HostedVirtualAddressSpace m_KernelSpace;
260};
261
264#endif
HostedVirtualAddressSpace(const HostedVirtualAddressSpace &)
virtual bool map(physical_uintptr_t physAddress, void *virtualAddress, size_t flags)
MUST_USE_RESULT bool trySetFlags(void *virtualAddress, size_t newFlags) override
virtual void setFlags(void *virtualAddress, size_t newFlags)
virtual bool detachMapping(void *virtualAddress, physical_uintptr_t &physical, size_t &flags, size_t requiredFlags=0)
static void switchAddressSpace(VirtualAddressSpace &oldSpace, VirtualAddressSpace &newSpace)
virtual bool tryReadUser32(uintptr_t address, uint32_t &value)
virtual bool tryWriteUser32(uintptr_t address, uint32_t value)
virtual bool isMapped(void *virtualAddress)
uint64_t toFlags(size_t flags, bool bFinal=false)
HostedVirtualAddressSpace & operator=(const HostedVirtualAddressSpace &)
virtual bool memIsInHeap(void *pMem)
size_t fromFlags(uint64_t Flags, bool bFinal=false)
virtual bool isAddressValid(void *virtualAddress)
virtual VirtualAddressSpace * clone(bool copyOnWrite=true)
virtual bool memIsInKernelHeap(void *pMem)
virtual bool tryCompareExchangeUser32(uintptr_t address, uint32_t &expected, uint32_t desired, bool &exchanged)
virtual void freeStack(Stack *pStack)
virtual bool getMapping(void *virtualAddress, physical_uintptr_t &physAddress, size_t &flags)
virtual void unmap(void *virtualAddress)
virtual bool handleCopyOnWriteFault(void *virtualAddress, bool userMode)
A vector / dynamic array.
Definition Vector.h:33
static VirtualAddressSpace * create()
static EXPORTED_PUBLIC VirtualAddressSpace & getKernelAddressSpace()