gem5 v24.0.0.0
Loading...
Searching...
No Matches
process.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * Copyright (c) 2016 The University of Virginia
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "arch/riscv/process.hh"
31
32#include <algorithm>
33#include <cstddef>
34#include <iostream>
35#include <iterator>
36#include <map>
37#include <string>
38#include <vector>
39
40#include "arch/riscv/isa.hh"
46#include "base/logging.hh"
47#include "base/random.hh"
48#include "cpu/thread_context.hh"
49#include "debug/Stack.hh"
50#include "mem/page_table.hh"
51#include "params/Process.hh"
52#include "sim/aux_vector.hh"
53#include "sim/process.hh"
54#include "sim/process_impl.hh"
55#include "sim/syscall_return.hh"
56#include "sim/system.hh"
57
58namespace gem5
59{
60
61using namespace RiscvISA;
62
63RiscvProcess::RiscvProcess(const ProcessParams &params,
64 loader::ObjectFile *objFile) :
65 Process(params,
66 new EmulationPageTable(params.name, params.pid, PageBytes),
67 objFile)
68{
69 fatal_if(params.useArchPT, "Arch page tables not implemented.");
70}
71
72RiscvProcess64::RiscvProcess64(const ProcessParams &params,
73 loader::ObjectFile *objFile) :
74 RiscvProcess(params, objFile)
75{
76 const Addr stack_base = 0x7FFFFFFFFFFFFFFFL;
77 const Addr max_stack_size = 8 * 1024 * 1024;
78 const Addr next_thread_stack_base = stack_base - max_stack_size;
79 const Addr brk_point = roundUp(image.maxAddr(), PageBytes);
80 const Addr mmap_end = 0x4000000000000000L;
81 memState = std::make_shared<MemState>(this, brk_point, stack_base,
82 max_stack_size, next_thread_stack_base, mmap_end);
83}
84
85RiscvProcess32::RiscvProcess32(const ProcessParams &params,
86 loader::ObjectFile *objFile) :
87 RiscvProcess(params, objFile)
88{
89 const Addr stack_base = 0x7FFFFFFF;
90 const Addr max_stack_size = 8 * 1024 * 1024;
91 const Addr next_thread_stack_base = stack_base - max_stack_size;
92 const Addr brk_point = roundUp(image.maxAddr(), PageBytes);
93 const Addr mmap_end = 0x40000000L;
94 memState = std::make_shared<MemState>(this, brk_point, stack_base,
95 max_stack_size, next_thread_stack_base, mmap_end);
96}
97
98void
100{
102
104 for (ContextID ctx: contextIds) {
105 auto *tc = system->threads[ctx];
106 tc->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
107 auto *isa = dynamic_cast<ISA*>(tc->getIsaPtr());
108 fatal_if(isa->rvType() != RV64, "RISC V CPU should run in 64 bits mode");
109 MISA misa = tc->readMiscRegNoEffect(MISCREG_ISA);
110 fatal_if(!(misa.rvu && misa.rvs),
111 "RISC V SE mode can't run without supervisor and user "
112 "privilege modes.");
113 }
114}
115
116void
118{
120
122 for (ContextID ctx: contextIds) {
123 auto *tc = system->threads[ctx];
124 tc->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
125 auto *isa = dynamic_cast<ISA*>(tc->getIsaPtr());
126 fatal_if(isa->rvType() != RV32, "RISC V CPU should run in 32 bits mode");
127 MISA misa = tc->readMiscRegNoEffect(MISCREG_ISA);
128 fatal_if(!(misa.rvu && misa.rvs),
129 "RISC V SE mode can't run without supervisor and user "
130 "privilege modes.");
131 }
132}
133
134template<class IntType> void
136{
137 const int RandomBytes = 16;
138 const int addrSize = sizeof(IntType);
139
140 auto *elfObject = dynamic_cast<loader::ElfObject*>(objFile);
141 memState->setStackMin(memState->getStackBase());
142
143 // Determine stack size and populate auxv
144 Addr stack_top = memState->getStackMin();
145 stack_top -= RandomBytes;
146 for (const std::string& arg: argv)
147 stack_top -= arg.size() + 1;
148 for (const std::string& env: envp)
149 stack_top -= env.size() + 1;
150 stack_top &= -addrSize;
151
153 if (elfObject != nullptr) {
154 auxv.emplace_back(gem5::auxv::Entry, objFile->entryPoint());
155 auxv.emplace_back(gem5::auxv::Phnum, elfObject->programHeaderCount());
156 auxv.emplace_back(gem5::auxv::Phent, elfObject->programHeaderSize());
157 auxv.emplace_back(gem5::auxv::Phdr, elfObject->programHeaderTable());
158 auxv.emplace_back(gem5::auxv::Pagesz, PageBytes);
159 auxv.emplace_back(gem5::auxv::Secure, 0);
160 auxv.emplace_back(gem5::auxv::Random, stack_top);
161 auxv.emplace_back(gem5::auxv::Null, 0);
162 }
163 stack_top -= (1 + argv.size()) * addrSize +
164 (1 + envp.size()) * addrSize +
165 addrSize + 2 * sizeof(IntType) * auxv.size();
166 stack_top &= -2*addrSize;
167 memState->setStackSize(memState->getStackBase() - stack_top);
168 memState->mapRegion(roundDown(stack_top, pageSize),
169 roundUp(memState->getStackSize(), pageSize), "stack");
170
171 // Copy random bytes (for AT_RANDOM) to stack
172 memState->setStackMin(memState->getStackMin() - RandomBytes);
173 uint8_t at_random[RandomBytes];
174 std::generate(std::begin(at_random), std::end(at_random),
175 [&]{ return random_mt.random(0, 0xFF); });
176 initVirtMem->writeBlob(memState->getStackMin(), at_random, RandomBytes);
177
178 // Copy argv to stack
179 std::vector<Addr> argPointers;
180 for (const std::string& arg: argv) {
181 memState->setStackMin(memState->getStackMin() - (arg.size() + 1));
182 initVirtMem->writeString(memState->getStackMin(), arg.c_str());
183 argPointers.push_back(memState->getStackMin());
184 if (debug::Stack) {
185 std::string wrote;
186 initVirtMem->readString(wrote, argPointers.back());
187 DPRINTFN("Wrote arg \"%s\" to address %p\n",
188 wrote, (void*)memState->getStackMin());
189 }
190 }
191 argPointers.push_back(0);
192
193 // Copy envp to stack
194 std::vector<Addr> envPointers;
195 for (const std::string& env: envp) {
196 memState->setStackMin(memState->getStackMin() - (env.size() + 1));
197 initVirtMem->writeString(memState->getStackMin(), env.c_str());
198 envPointers.push_back(memState->getStackMin());
199 DPRINTF(Stack, "Wrote env \"%s\" to address %p\n",
200 env, (void*)memState->getStackMin());
201 }
202 envPointers.push_back(0);
203
204 // Align stack
205 memState->setStackMin(memState->getStackMin() & -addrSize);
206
207 // Calculate bottom of stack
208 memState->setStackMin(memState->getStackMin() -
209 ((1 + argv.size()) * addrSize +
210 (1 + envp.size()) * addrSize +
211 addrSize + 2 * sizeof(IntType) * auxv.size()));
212 memState->setStackMin(memState->getStackMin() & (-2 * addrSize));
213 Addr sp = memState->getStackMin();
214 const auto pushOntoStack =
215 [this, &sp](IntType data) {
216 initVirtMem->write(sp, data, ByteOrder::little);
217 sp += sizeof(data);
218 };
219
220 // Push argc and argv pointers onto stack
221 IntType argc = argv.size();
222 DPRINTF(Stack, "Wrote argc %d to address %#x\n", argc, sp);
223 pushOntoStack(argc);
224
225 for (const Addr& argPointer: argPointers) {
226 DPRINTF(Stack, "Wrote argv pointer %#x to address %#x\n",
227 argPointer, sp);
228 pushOntoStack(argPointer);
229 }
230
231 // Push env pointers onto stack
232 for (const Addr& envPointer: envPointers) {
233 DPRINTF(Stack, "Wrote envp pointer %#x to address %#x\n",
234 envPointer, sp);
235 pushOntoStack(envPointer);
236 }
237
238 // Push aux vector onto stack
239 std::map<IntType, std::string> aux_keys = {
240 {gem5::auxv::Entry, "gem5::auxv::Entry"},
241 {gem5::auxv::Phnum, "gem5::auxv::Phnum"},
242 {gem5::auxv::Phent, "gem5::auxv::Phent"},
243 {gem5::auxv::Phdr, "gem5::auxv::Phdr"},
244 {gem5::auxv::Pagesz, "gem5::auxv::Pagesz"},
245 {gem5::auxv::Secure, "gem5::auxv::Secure"},
246 {gem5::auxv::Random, "gem5::auxv::Random"},
247 {gem5::auxv::Null, "gem5::auxv::Null"}
248 };
249 for (const auto &aux: auxv) {
250 DPRINTF(Stack, "Wrote aux key %s to address %#x\n",
251 aux_keys[aux.type], sp);
252 pushOntoStack(aux.type);
253 DPRINTF(Stack, "Wrote aux value %x to address %#x\n", aux.val, sp);
254 pushOntoStack(aux.val);
255 }
256
258 tc->setReg(StackPointerReg, memState->getStackMin());
259 tc->pcState(getStartPC());
260
261 memState->setStackMin(roundDown(memState->getStackMin(), pageSize));
262}
263
264} // namespace gem5
#define DPRINTFN(...)
Definition trace.hh:238
#define DPRINTF(x,...)
Definition trace.hh:210
const char data[]
loader::MemoryImage image
Definition process.hh:224
std::unique_ptr< SETranslatingPortProxy > initVirtMem
Definition process.hh:187
std::shared_ptr< MemState > memState
Definition process.hh:289
std::vector< std::string > argv
Definition process.hh:226
std::vector< ContextID > contextIds
Definition process.hh:170
System * system
Definition process.hh:173
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition process.cc:288
std::vector< std::string > envp
Definition process.hh:227
Addr getStartPC()
Definition process.cc:497
loader::ObjectFile * objFile
Definition process.hh:223
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition process.cc:117
RiscvProcess32(const ProcessParams &params, loader::ObjectFile *objFile)
Definition process.cc:85
RiscvProcess64(const ProcessParams &params, loader::ObjectFile *objFile)
Definition process.cc:72
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition process.cc:99
RiscvProcess(const ProcessParams &params, loader::ObjectFile *objFile)
Definition process.cc:63
void argsInit(int pageSize)
Definition process.cc:135
Threads threads
Definition system.hh:310
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual void setReg(const RegId &reg, RegVal val)
virtual const PCStateBase & pcState() const =0
STL vector class.
Definition stl.hh:37
Random random_mt
Definition random.cc:99
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
Definition intmath.hh:279
std::enable_if_t< std::is_integral_v< T >, T > random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
Definition random.hh:90
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
Definition intmath.hh:260
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
const Params & params() const
constexpr auto & StackPointerReg
Definition int.hh:654
Bitfield< 0 > sp
Definition misc_types.hh:75
const Addr PageBytes
Definition page_size.hh:53
constexpr enums::RiscvType RV32
Definition pcstate.hh:56
constexpr enums::RiscvType RV64
Definition pcstate.hh:57
Bitfield< 15 > system
Definition misc.hh:1032
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
int ContextID
Globally unique thread context ID.
Definition types.hh:239
Declarations of a non-full system Page Table.
const std::string & name()
Definition trace.cc:48

Generated on Tue Jun 18 2024 16:24:06 for gem5 by doxygen 1.11.0