arch-arm,cpu: Introduce a getEMI virtual method on StaticInst.
[gem5.git] / src / sim / mem_state.hh
1 /*
2 * Copyright (c) 2017-2020 Advanced Micro Devices, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifndef SRC_SIM_MEM_STATE_HH
30 #define SRC_SIM_MEM_STATE_HH
31
32 #include <list>
33 #include <memory>
34 #include <string>
35 #include <vector>
36
37 #include "config/the_isa.hh"
38 #include "debug/Vma.hh"
39 #include "mem/page_table.hh"
40 #include "mem/se_translating_port_proxy.hh"
41 #include "sim/serialize.hh"
42 #include "sim/vma.hh"
43
44 class Process;
45 class ProcessParams;
46 class System;
47
48 /**
49 * This class holds the memory state for the Process class and all of its
50 * derived, architecture-specific children.
51 *
52 * The class represents the Process' address space which may change
53 * dynamically while the simulation is running. They are updated by system
54 * calls and faults. Each change represents a modification to the process
55 * address space.
56 *
57 * The class is meant to be allocated dynamically and shared through a
58 * pointer interface. Multiple process can potentially share portions of their
59 * virtual address space if specific options are passed into the clone(2)
60 * system call.
61 */
62 class MemState : public Serializable
63 {
64 public:
65 MemState(Process *owner, Addr brk_point, Addr stack_base,
66 Addr max_stack_size, Addr next_thread_stack_base,
67 Addr mmap_end);
68
69 MemState& operator=(const MemState &in);
70
71 /**
72 * Change the Process owner in case this MemState is copied.
73 */
74 void resetOwner(Process *owner);
75
76 /**
77 * Get/set base addresses and sizes for the stack and data segments of
78 * the process' memory.
79 */
80 Addr getBrkPoint() const { return _brkPoint; }
81 Addr getStackBase() const { return _stackBase; }
82 Addr getStackSize() const { return _stackSize; }
83 Addr getMaxStackSize() const { return _maxStackSize; }
84 Addr getStackMin() const { return _stackMin; }
85 Addr getNextThreadStackBase() const { return _nextThreadStackBase; }
86 Addr getMmapEnd() const { return _mmapEnd; }
87 void setBrkPoint(Addr brk_point) { _brkPoint = brk_point; }
88 void setStackBase(Addr stack_base) { _stackBase = stack_base; }
89 void setStackSize(Addr stack_size) { _stackSize = stack_size; }
90 void setMaxStackSize(Addr max_stack) { _maxStackSize = max_stack; }
91 void setStackMin(Addr stack_min) { _stackMin = stack_min; }
92 void setNextThreadStackBase(Addr ntsb) { _nextThreadStackBase = ntsb; }
93 void setMmapEnd(Addr mmap_end) { _mmapEnd = mmap_end; }
94
95 /*
96 * Extend the end of the mmap region by length bytes. Once a contiguous
97 * region of free virtual memory is found the start of that region is
98 * returned.
99 */
100 Addr extendMmap(Addr length);
101
102 /**
103 * Check if any page in the virtual address range from start_addr to
104 * start_addr + length is already mapped in the page table.
105 *
106 * @param start_addr Starting address of region to check.
107 * @param length Length of the range to check.
108 *
109 * @return true if all pages in the range are unmapped in page table
110 */
111 bool isUnmapped(Addr start_addr, Addr length);
112
113 /**
114 * Add a new memory region. The region represents a contiguous virtual
115 * address range which can map to physical memory or a host-backed file.
116 * Regions which are not file-backed should use -1 for sim_fd and 0 for
117 * offset.
118 *
119 * @param start_addr Starting address of the region.
120 * @param length Size of the region.
121 * @param name Name of region. Optional.
122 * @param sim_fd File descriptor for file-backed regions or -1.
123 * @param offset Offset in file in which region starts.
124 */
125 void mapRegion(Addr start_addr, Addr length,
126 const std::string& name="anon", int sim_fd=-1,
127 Addr offset=0);
128
129 /**
130 * Unmap a pre-existing region. Depending on the range being unmapped
131 * the resulting new regions will either be split, resized, or
132 * removed completely.
133 *
134 * @param start_addr Starting address of region to unmap.
135 * @param length Size of region to unmap.
136 */
137 void unmapRegion(Addr start_addr, Addr length);
138
139 /**
140 * Remap a pre-existing region. This changes the virtual address
141 * range of the region. This will result in regions being expanded
142 * if there is overlap with another region or simply moving the range
143 * otherwise.
144 *
145 * @param start_addr Start address of region being remapped.
146 * @param new_start_addr New start address of the region.
147 * @param length Length of the newly remapped region.
148 */
149 void remapRegion(Addr start_addr, Addr new_start_addr, Addr length);
150
151 /**
152 * Change the end of a process' program break. This represents the end
153 * of the heap segment of a process.
154 *
155 * @param old_brk Old program break address
156 * @param new_brk New program break address
157 */
158 void updateBrkRegion(Addr old_brk, Addr new_brk);
159
160 /**
161 * Attempt to fix up a fault at vaddr by allocating a page. The fault
162 * likely occurred because a virtual page which does not have physical
163 * page assignment is being accessed.
164 *
165 * @param vaddr The virtual address which is causing the fault.
166 * @return Whether the fault has been fixed.
167 */
168 bool fixupFault(Addr vaddr);
169
170 /**
171 * Given the vaddr and size, this method will chunk the allocation into
172 * page granularity and then request physical pages (frames) from the
173 * system object. After retrieving a frame, the method updates the page
174 * table mappings.
175 *
176 * @param vaddr The virtual address in need of a frame allocation.
177 * @param size The size in bytes of the requested mapping.
178 * @param clobber This flag specifies whether mappings in the page tables
179 * can be overwritten and replaced with the new mapping.
180 */
181 void allocateMem(Addr vaddr, int64_t size, bool clobber = false);
182
183 void
184 serialize(CheckpointOut &cp) const override
185 {
186 paramOut(cp, "brkPoint", _brkPoint);
187 paramOut(cp, "stackBase", _stackBase);
188 paramOut(cp, "stackSize", _stackSize);
189 paramOut(cp, "maxStackSize", _maxStackSize);
190 paramOut(cp, "stackMin", _stackMin);
191 paramOut(cp, "nextThreadStackBase", _nextThreadStackBase);
192 paramOut(cp, "mmapEnd", _mmapEnd);
193
194 ScopedCheckpointSection sec(cp, "vmalist");
195 paramOut(cp, "size", _vmaList.size());
196 int count = 0;
197 for (auto vma : _vmaList) {
198 ScopedCheckpointSection sec(cp, csprintf("Vma%d", count++));
199 paramOut(cp, "name", vma.getName());
200 paramOut(cp, "addrRangeStart", vma.start());
201 paramOut(cp, "addrRangeEnd", vma.end());
202 }
203 }
204
205 void
206 unserialize(CheckpointIn &cp) override
207 {
208 paramIn(cp, "brkPoint", _brkPoint);
209 paramIn(cp, "stackBase", _stackBase);
210 paramIn(cp, "stackSize", _stackSize);
211 paramIn(cp, "maxStackSize", _maxStackSize);
212 paramIn(cp, "stackMin", _stackMin);
213 paramIn(cp, "nextThreadStackBase", _nextThreadStackBase);
214 paramIn(cp, "mmapEnd", _mmapEnd);
215
216 int count;
217 ScopedCheckpointSection sec(cp, "vmalist");
218 paramIn(cp, "size", count);
219 for (int i = 0; i < count; ++i) {
220 ScopedCheckpointSection sec(cp, csprintf("Vma%d", i));
221 std::string name;
222 Addr start;
223 Addr end;
224 paramIn(cp, "name", name);
225 paramIn(cp, "addrRangeStart", start);
226 paramIn(cp, "addrRangeEnd", end);
227 _vmaList.emplace_back(AddrRange(start, end), _pageBytes, name);
228 }
229 }
230
231 /**
232 * Print the list of VMAs in a format similar to /proc/self/maps
233 */
234 std::string printVmaList();
235
236 private:
237 /**
238 * Owner process of MemState. Used to manipulate page tables.
239 */
240 Process * _ownerProcess;
241
242 Addr _pageBytes;
243 Addr _brkPoint;
244 Addr _stackBase;
245 Addr _stackSize;
246 Addr _maxStackSize;
247 Addr _stackMin;
248 Addr _nextThreadStackBase;
249 Addr _mmapEnd;
250
251 /**
252 * Keeps record of the furthest mapped heap location.
253 */
254 Addr _endBrkPoint;
255
256 /**
257 * The _vmaList member is a list of virtual memory areas in the target
258 * application space that have been allocated by the target. In most
259 * operating systems, lazy allocation is used and these structures (or
260 * equivalent ones) are used to track the valid address ranges.
261 *
262 * This could use a more efficient data structure like an interval
263 * tree, but it is unclear whether the vmas will be modified often enough
264 * for the improvement in lookup time to matter. Unmapping VMAs currently
265 * modifies the list while iterating so the STL container must either
266 * support this or the unmapping method must be changed.
267 */
268 std::list<VMA> _vmaList;
269 };
270
271 #endif