FreeNOS
VMCtl.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015 Niek Linnenbank
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <FreeNOS/System.h>
19#include <FreeNOS/ProcessManager.h>
20#include <SplitAllocator.h>
21#include "VMCtl.h"
22#include "ProcessID.h"
23
25 const MemoryOperation op,
26 Memory::Range *range)
27{
31 Process *proc = ZERO;
32
33 DEBUG("");
34
35 // Find the given process
36 if (procID == SELF)
37 proc = procs->current();
38 else if (!(proc = procs->get(procID)))
39 {
40 return API::NotFound;
41 }
42
43 // Retrieve memory context
44 MemoryContext *mem = proc->getMemoryContext();
45
46 // Perform operation
47 switch (op)
48 {
49 case LookupVirtual:
50 // Translate virtual address to physical address (page boundary)
51 memResult = mem->lookup(range->virt, &range->phys);
52 if (memResult != MemoryContext::Success)
53 {
54 ERROR("failed to lookup virtual address " << (void *) range->virt <<
55 ": " << (int) memResult);
57 }
58 assert(!(range->phys & ~PAGEMASK));
59
60 // Add offset within the page
61 range->phys += range->virt & ~PAGEMASK;
62 break;
63
64 case MapContiguous:
65 case MapSparse:
66 if (!range->virt)
67 {
68 memResult = mem->findFree(range->size, MemoryMap::UserPrivate, &range->virt);
69 if (memResult != MemoryContext::Success)
70 {
71 ERROR("failed to find free virtual address in UserPrivate: " <<
72 (int) memResult);
73 return API::IOError;
74 }
75 range->virt += range->phys & ~PAGEMASK;
76 }
77 if (op == MapContiguous)
78 memResult = mem->mapRangeContiguous(range);
79 else
80 memResult = mem->mapRangeSparse(range);
81
82 if (memResult != MemoryContext::Success)
83 {
84 ERROR("failed to map memory range " << (void *)range->virt << "->" <<
85 (void *) range->phys << ": " << (int) memResult);
86 return API::IOError;
87 }
88 break;
89
90 case UnMap:
91 memResult = mem->unmapRange(range);
92 if (memResult != MemoryContext::Success)
93 {
94 ERROR("failed to unmap range at virtual address " << (void *)range->virt <<
95 ": " << (int) memResult);
96 return API::IOError;
97 }
98 break;
99
100 case Release:
101 memResult = mem->releaseRange(range);
102 if (memResult != MemoryContext::Success)
103 {
104 ERROR("failed to release range at virtual address " << (void *)range->virt <<
105 ": " << (int) memResult);
106 return API::IOError;
107 }
108 break;
109
110 case ReleaseSections:
111 memResult = mem->releaseSection(*range);
112 if (memResult != MemoryContext::Success)
113 {
114 ERROR("failed to release sections at virtual address " << (void *)range->virt <<
115 ": " << (int) memResult);
116 return API::IOError;
117 }
118 break;
119
120 case CacheClean: {
121 Arch::Cache cache;
122 cache.cleanData(range->virt);
123 break;
124 }
125
126 case CacheInvalidate: {
127 Arch::Cache cache;
128 const Cache::Result r = cache.invalidateAddress(Cache::Data, range->virt);
129 if (r != Cache::Success)
130 {
131 ERROR("failed to invalidate cache at address " << (void *) range->virt <<
132 ": result = " << (int) r);
133 return API::IOError;
134 }
135 break;
136 }
137
139 Arch::Cache cache;
141 break;
142 }
143
144 case Access: {
145 const MemoryContext::Result mr = mem->access(range->virt, &range->access);
146 if (mr == MemoryContext::Success)
147 ret = API::Success;
148 else
150 break;
151 }
152
153 case ReserveMem:
154 {
157
158 for (Size i = 0; i < range->size; i += PAGESIZE)
159 {
160 const Address addr = range->phys + i;
161
162 if (alloc->isAllocated(addr))
163 {
164 ERROR("address " << (void *)addr << " is already allocated");
166 }
167 else if ((allocResult = alloc->allocate(addr)) != Allocator::Success)
168 {
169 ERROR("failed to allocate " << (void *)addr << ", result = " << (int)allocResult);
170 return API::IOError;
171 }
172 }
173 break;
174 }
175
176 default:
178 break;
179 }
180
181 // Done
182 return ret;
183}
Result
Enumeration of generic kernel API result codes.
Definition API.h:69
@ NotFound
Definition API.h:73
@ IOError
Definition API.h:76
@ Success
Definition API.h:70
@ InvalidArgument
Definition API.h:74
@ AccessViolation
Definition API.h:71
ARMv6 cache management implementation.
Definition ARMCacheV6.h:43
virtual Result invalidateAddress(Type type, Address addr)
Invalidate one memory page.
virtual Result cleanInvalidate(Type type)
Clean and invalidate entire cache.
Result
Allocation results.
Definition Allocator.h:54
virtual Result cleanData(Address addr)
Clean one data page.
Definition Cache.cpp:20
Result
Result codes.
Definition Cache.h:43
@ Success
Definition Cache.h:44
@ Data
Definition Cache.h:56
SplitAllocator * getAllocator()
Get physical memory allocator.
Definition Kernel.cpp:138
ProcessManager * getProcessManager()
Get process manager.
Definition Kernel.cpp:143
Virtual memory abstract interface.
Result
Result codes.
virtual Result mapRangeSparse(Memory::Range *range)
Map and allocate a range of sparse (non-contiguous) physical pages to virtual addresses.
virtual Result releaseSection(const Memory::Range &range, const bool tablesOnly=false)=0
Release memory sections.
virtual Result findFree(Size size, MemoryMap::Region region, Address *virt) const
Find unused memory.
virtual Result unmapRange(Memory::Range *range)
Unmaps a range of virtual memory.
virtual Result releaseRange(Memory::Range *range)=0
Release a range of physical memory by its virtual memory pages.
virtual Result mapRangeContiguous(Memory::Range *range)
Map a range of contiguous physical pages to virtual addresses.
virtual Result access(Address virt, Memory::Access *access) const =0
Get Access flags for a virtual address.
virtual Result lookup(Address virt, Address *phys) const =0
Translate virtual address to physical address.
@ UserPrivate
< User private dynamic memory mappings
Definition MemoryMap.h:59
Represents a process which may run on the host.
Process * get(const ProcessID id)
Retrieve a Process by it's ID.
Process * current()
Current process running.
Represents a process which may run on the host.
Definition Process.h:45
MemoryContext * getMemoryContext()
Get MMU memory context.
Definition Process.cpp:95
Allocator which separates kernel mapped memory at virtual and physical addresses.
virtual Result allocate(Range &args)
Allocate physical memory.
bool isAllocated(const Address page) const
Check if a physical page is allocated.
static Kernel * instance()
Retrieve the instance.
Definition Singleton.h:86
API::Result VMCtlHandler(const ProcessID procID, const MemoryOperation op, Memory::Range *range)
Kernel handler prototype.
Definition VMCtl.cpp:24
MemoryOperation
Memory operations which may be used as an argument to VMCtl().
Definition VMCtl.h:36
#define SELF
Definition ProcessID.h:35
@ ReleaseSections
Definition VMCtl.h:41
@ Release
Definition VMCtl.h:40
@ CacheClean
Definition VMCtl.h:46
@ MapSparse
Definition VMCtl.h:38
@ Access
Definition VMCtl.h:43
@ CacheInvalidate
Definition VMCtl.h:47
@ ReserveMem
Definition VMCtl.h:44
@ LookupVirtual
Definition VMCtl.h:42
@ UnMap
Definition VMCtl.h:39
@ MapContiguous
Definition VMCtl.h:37
@ CacheCleanInvalidate
Definition VMCtl.h:48
#define PAGESIZE
ARM uses 4K pages.
Definition ARMConstant.h:97
#define PAGEMASK
Mask to find the page.
#define assert(exp)
Insert program diagnostics.
Definition assert.h:60
u32 ProcessID
Process Identification Number.
Definition Types.h:140
unsigned long Address
A memory address.
Definition Types.h:131
#define ERROR(msg)
Output an error message.
Definition Log.h:61
unsigned int Size
Any sane size indicator cannot go negative.
Definition Types.h:128
#define ZERO
Zero value.
Definition Macros.h:43
#define DEBUG(msg)
Output a debug message to standard output.
Definition Log.h:89
Memory range.
Definition Memory.h:56
Size size
Size in number of bytes.
Definition Memory.h:59
Address phys
Physical address.
Definition Memory.h:58
Address virt
Virtual address.
Definition Memory.h:57
Access access
Page access flags.
Definition Memory.h:60