FreeNOS
MemoryContext.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#ifdef __clang__
19#pragma clang optimize off
20#endif
21
22#ifdef __GNUC__
23#pragma GCC push_options
24#pragma GCC optimize ("O0")
25#endif
26
27#include <FreeNOS/System.h>
28#include <SplitAllocator.h>
29#include "MemoryContext.h"
30
32
34 : m_alloc(alloc)
35 , m_map(map)
36 , m_mapRangeSparseCallback(this, &MemoryContext::mapRangeSparseCallback)
37 , m_savedRange(ZERO)
38 , m_numSparsePages(ZERO)
39{
40}
41
45
50
52{
53 Result r = Success;
54
55 // Allocate a block of contiguous physical pages, if needed.
56 if (!range->phys)
57 {
58 Allocator::Range alloc_args;
59 alloc_args.address = 0;
60 alloc_args.size = range->size;
61 alloc_args.alignment = PAGESIZE;
62
63 if (m_alloc->allocate(alloc_args) != Allocator::Success)
64 return OutOfMemory;
65
66 range->phys = alloc_args.address;
67 }
68
69 // Insert virtual page(s)
70 for (Size i = 0; i < range->size; i += PAGESIZE)
71 {
72 if ((r = map(range->virt + i,
73 range->phys + i,
74 range->access)) != Success)
75 break;
76 }
77
78 return r;
79}
80
82{
83 Allocator::Range alloc_args;
84
85 // Allocate a set of physical pages (non-contiguous)
86 m_savedRange = range;
88
89 alloc_args.address = 0;
90 alloc_args.size = range->size;
91 alloc_args.alignment = 0;
92
93 // This invokes our callback for each new page that is allocated
95 return OutOfMemory;
96
97 return Success;
98}
99
101{
102 Result r = Success;
103
104 for (Size i = 0; i < range->size; i += PAGESIZE)
105 if ((r = unmap(range->virt + i)) != Success)
106 break;
107
108 return r;
109}
110
112{
113 Address phys;
114 Result result = lookup(virt, &phys);
115
116 if (result == Success)
117 m_alloc->release(phys);
118
119 return result;
120}
121
123{
124 Memory::Range r = m_map->range(region);
125 Size currentSize = 0;
126 Address addr = r.virt, currentAddr = r.virt, tmp;
127
128 while (addr < r.virt+r.size && currentSize < size)
129 {
130 if (lookup(addr, &tmp) == InvalidAddress)
131 {
132 currentSize += PAGESIZE;
133 }
134 else
135 {
136 currentSize = 0;
137 currentAddr = addr + PAGESIZE;
138 }
139 addr += PAGESIZE;
140 }
141
142 if (currentSize >= size)
143 {
144 *virt = currentAddr;
145 return Success;
146 }
147 else
148 return OutOfMemory;
149}
150
152{
153 Result r = Success;
154
155 for (Size i = 0; i < 8U * PAGESIZE; i += PAGESIZE)
156 {
158 if (r != Success)
159 break;
160
162 }
163
164 assert(r == Success);
165}
Virtual memory abstract interface.
Result
Result codes.
virtual Result unmap(Address virt)=0
Unmap a virtual address.
virtual Result mapRangeSparse(Memory::Range *range)
Map and allocate a range of sparse (non-contiguous) physical pages to virtual addresses.
MemoryMap * m_map
Virtual memory layout.
virtual void mapRangeSparseCallback(Address *phys)
Callback to provide intermediate Range object during mapRangeSparse()
Size m_numSparsePages
Number of pages allocated via mapRangeSparse Callback.
MemoryContext(MemoryMap *map, SplitAllocator *alloc)
Constructor.
SplitAllocator * m_alloc
Physical memory allocator.
virtual Result findFree(Size size, MemoryMap::Region region, Address *virt) const
Find unused memory.
virtual Result map(Address virt, Address phys, Memory::Access access)=0
Map a physical page to a virtual address.
virtual Result unmapRange(Memory::Range *range)
Unmaps a range of virtual memory.
virtual ~MemoryContext()
Destructor.
virtual Result release(Address virt)
Release a memory page mapping.
static MemoryContext * getCurrent()
Get currently active MemoryContext.
Callback< MemoryContext, Address > m_mapRangeSparseCallback
Callback object for mapRangeSparseCallback function.
static MemoryContext * m_current
The currently active MemoryContext.
Memory::Range * m_savedRange
Saved range input for use in the mapRangeSparse Callback.
virtual Result mapRangeContiguous(Memory::Range *range)
Map a range of contiguous physical pages to virtual addresses.
virtual Result lookup(Address virt, Address *phys) const =0
Translate virtual address to physical address.
Describes virtual memory map layout.
Definition MemoryMap.h:39
Region
Memory regions.
Definition MemoryMap.h:53
Memory::Range range(Region region) const
Get memory range for the given region.
Definition MemoryMap.cpp:36
Allocator which separates kernel mapped memory at virtual and physical addresses.
virtual Result allocate(Range &args)
Allocate physical memory.
Result allocateSparse(const Range &range, CallbackFunction *function)
Allocate sparse (non-contiguous) physical memory.
virtual Result release(const Address addr)
Release memory page.
#define PAGESIZE
ARM uses 4K pages.
Definition ARMConstant.h:97
#define assert(exp)
Insert program diagnostics.
Definition assert.h:60
unsigned long Address
A memory address.
Definition Types.h:131
unsigned int Size
Any sane size indicator cannot go negative.
Definition Types.h:128
#define ZERO
Zero value.
Definition Macros.h:43
Describes a range of memory.
Definition Allocator.h:66
Size alignment
Alignment in bytes or ZERO for default alignment.
Definition Allocator.h:69
Address address
Starting address of the memory range.
Definition Allocator.h:67
Size size
Amount of memory in bytes.
Definition Allocator.h:68
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