gem5 v24.1.0.1
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 "cpu/thread_context.hh"
48#include "debug/Stack.hh"
49#include "mem/page_table.hh"
50#include "params/Process.hh"
51#include "sim/aux_vector.hh"
52#include "sim/process.hh"
53#include "sim/process_impl.hh"
54#include "sim/syscall_return.hh"
55#include "sim/system.hh"
56
57namespace gem5
58{
59
60using namespace RiscvISA;
61
62RiscvProcess::RiscvProcess(const ProcessParams &params,
63 loader::ObjectFile *objFile) :
64 Process(params,
65 new EmulationPageTable(params.name, params.pid, PageBytes),
66 objFile)
67{
68 fatal_if(params.useArchPT, "Arch page tables not implemented.");
69}
70
71RiscvProcess64::RiscvProcess64(const ProcessParams &params,
72 loader::ObjectFile *objFile) :
73 RiscvProcess(params, objFile)
74{
75 const Addr stack_base = 0x7FFFFFFFFFFFFFFFL;
76 const Addr max_stack_size = 8 * 1024 * 1024;
77 const Addr next_thread_stack_base = stack_base - max_stack_size;
78 const Addr brk_point = roundUp(image.maxAddr(), PageBytes);
79 const Addr mmap_end = 0x4000000000000000L;
80 memState = std::make_shared<MemState>(this, brk_point, stack_base,
81 max_stack_size, next_thread_stack_base, mmap_end);
82}
83
84RiscvProcess32::RiscvProcess32(const ProcessParams &params,
85 loader::ObjectFile *objFile) :
86 RiscvProcess(params, objFile)
87{
88 const Addr stack_base = 0x7FFFFFFF;
89 const Addr max_stack_size = 8 * 1024 * 1024;
90 const Addr next_thread_stack_base = stack_base - max_stack_size;
91 const Addr brk_point = roundUp(image.maxAddr(), PageBytes);
92 const Addr mmap_end = 0x40000000L;
93 memState = std::make_shared<MemState>(this, brk_point, stack_base,
94 max_stack_size, next_thread_stack_base, mmap_end);
95}
96
97void
99{
101
102 argsInit<uint64_t>(PageBytes);
103 for (ContextID ctx: contextIds) {
104 auto *tc = system->threads[ctx];
105 tc->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
106 auto *isa = dynamic_cast<ISA*>(tc->getIsaPtr());
107 fatal_if(isa->rvType() != RV64, "RISC V CPU should run in 64 bits mode");
108 MISA misa = tc->readMiscRegNoEffect(MISCREG_ISA);
109 fatal_if(!(misa.rvu && misa.rvs),
110 "RISC V SE mode can't run without supervisor and user "
111 "privilege modes.");
112 }
113}
114
115void
117{
119
120 argsInit<uint32_t>(PageBytes);
121 for (ContextID ctx: contextIds) {
122 auto *tc = system->threads[ctx];
123 tc->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
124 auto *isa = dynamic_cast<ISA*>(tc->getIsaPtr());
125 fatal_if(isa->rvType() != RV32, "RISC V CPU should run in 32 bits mode");
126 MISA misa = tc->readMiscRegNoEffect(MISCREG_ISA);
127 fatal_if(!(misa.rvu && misa.rvs),
128 "RISC V SE mode can't run without supervisor and user "
129 "privilege modes.");
130 }
131}
132
133template<class IntType> void
135{
136 const int RandomBytes = 16;
137 const int addrSize = sizeof(IntType);
138
139 auto *elfObject = dynamic_cast<loader::ElfObject*>(objFile);
140 memState->setStackMin(memState->getStackBase());
141
142 // Determine stack size and populate auxv
143 Addr stack_top = memState->getStackMin();
144 stack_top -= RandomBytes;
145 for (const std::string& arg: argv)
146 stack_top -= arg.size() + 1;
147 for (const std::string& env: envp)
148 stack_top -= env.size() + 1;
149 stack_top &= -addrSize;
150
152 if (elfObject != nullptr) {
153 auxv.emplace_back(gem5::auxv::Entry, objFile->entryPoint());
154 auxv.emplace_back(gem5::auxv::Phnum, elfObject->programHeaderCount());
155 auxv.emplace_back(gem5::auxv::Phent, elfObject->programHeaderSize());
156 auxv.emplace_back(gem5::auxv::Phdr, elfObject->programHeaderTable());
157 auxv.emplace_back(gem5::auxv::Pagesz, PageBytes);
158 auxv.emplace_back(gem5::auxv::Secure, 0);
159 auxv.emplace_back(gem5::auxv::Random, stack_top);
160 auxv.emplace_back(gem5::auxv::Null, 0);
161 }
162 stack_top -= (1 + argv.size()) * addrSize +
163 (1 + envp.size()) * addrSize +
164 addrSize + 2 * sizeof(IntType) * auxv.size();
165 stack_top &= -2*addrSize;
166 memState->setStackSize(memState->getStackBase() - stack_top);
167 memState->mapRegion(roundDown(stack_top, pageSize),
168 roundUp(memState->getStackSize(), pageSize), "stack");
169
170 // Copy random bytes (for AT_RANDOM) to stack
171 memState->setStackMin(memState->getStackMin() - RandomBytes);
172 uint8_t at_random[RandomBytes];
173 std::generate(std::begin(at_random), std::end(at_random),
174 [&]{ return rng->random(0, 0xFF); });
175 initVirtMem->writeBlob(memState->getStackMin(), at_random, RandomBytes);
176
177 // Copy argv to stack
178 std::vector<Addr> argPointers;
179 for (const std::string& arg: argv) {
180 memState->setStackMin(memState->getStackMin() - (arg.size() + 1));
181 initVirtMem->writeString(memState->getStackMin(), arg.c_str());
182 argPointers.push_back(memState->getStackMin());
183 if (debug::Stack) {
184 std::string wrote;
185 initVirtMem->readString(wrote, argPointers.back());
186 DPRINTFN("Wrote arg \"%s\" to address %p\n",
187 wrote, (void*)memState->getStackMin());
188 }
189 }
190 argPointers.push_back(0);
191
192 // Copy envp to stack
193 std::vector<Addr> envPointers;
194 for (const std::string& env: envp) {
195 memState->setStackMin(memState->getStackMin() - (env.size() + 1));
196 initVirtMem->writeString(memState->getStackMin(), env.c_str());
197 envPointers.push_back(memState->getStackMin());
198 DPRINTF(Stack, "Wrote env \"%s\" to address %p\n",
199 env, (void*)memState->getStackMin());
200 }
201 envPointers.push_back(0);
202
203 // Align stack
204 memState->setStackMin(memState->getStackMin() & -addrSize);
205
206 // Calculate bottom of stack
207 memState->setStackMin(memState->getStackMin() -
208 ((1 + argv.size()) * addrSize +
209 (1 + envp.size()) * addrSize +
210 addrSize + 2 * sizeof(IntType) * auxv.size()));
211 memState->setStackMin(memState->getStackMin() & (-2 * addrSize));
212 Addr sp = memState->getStackMin();
213 const auto pushOntoStack =
214 [this, &sp](IntType data) {
215 initVirtMem->write(sp, data, ByteOrder::little);
216 sp += sizeof(data);
217 };
218
219 // Push argc and argv pointers onto stack
220 IntType argc = argv.size();
221 DPRINTF(Stack, "Wrote argc %d to address %#x\n", argc, sp);
222 pushOntoStack(argc);
223
224 for (const Addr& argPointer: argPointers) {
225 DPRINTF(Stack, "Wrote argv pointer %#x to address %#x\n",
226 argPointer, sp);
227 pushOntoStack(argPointer);
228 }
229
230 // Push env pointers onto stack
231 for (const Addr& envPointer: envPointers) {
232 DPRINTF(Stack, "Wrote envp pointer %#x to address %#x\n",
233 envPointer, sp);
234 pushOntoStack(envPointer);
235 }
236
237 // Push aux vector onto stack
238 std::map<IntType, std::string> aux_keys = {
239 {gem5::auxv::Entry, "gem5::auxv::Entry"},
240 {gem5::auxv::Phnum, "gem5::auxv::Phnum"},
241 {gem5::auxv::Phent, "gem5::auxv::Phent"},
242 {gem5::auxv::Phdr, "gem5::auxv::Phdr"},
243 {gem5::auxv::Pagesz, "gem5::auxv::Pagesz"},
244 {gem5::auxv::Secure, "gem5::auxv::Secure"},
245 {gem5::auxv::Random, "gem5::auxv::Random"},
246 {gem5::auxv::Null, "gem5::auxv::Null"}
247 };
248 for (const auto &aux: auxv) {
249 DPRINTF(Stack, "Wrote aux key %s to address %#x\n",
250 aux_keys[aux.type], sp);
251 pushOntoStack(aux.type);
252 DPRINTF(Stack, "Wrote aux value %x to address %#x\n", aux.val, sp);
253 pushOntoStack(aux.val);
254 }
255
257 tc->setReg(StackPointerReg, memState->getStackMin());
258 tc->pcState(getStartPC());
259
260 memState->setStackMin(roundDown(memState->getStackMin(), pageSize));
261}
262
263} // namespace gem5
#define DPRINTFN(...)
Definition trace.hh:237
#define DPRINTF(x,...)
Definition trace.hh:209
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:116
RiscvProcess32(const ProcessParams &params, loader::ObjectFile *objFile)
Definition process.cc:84
RiscvProcess64(const ProcessParams &params, loader::ObjectFile *objFile)
Definition process.cc:71
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition process.cc:98
RiscvProcess(const ProcessParams &params, loader::ObjectFile *objFile)
Definition process.cc:62
void argsInit(int pageSize)
Definition process.cc:134
Random::RandomPtr rng
Definition process.hh:62
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
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
Definition intmath.hh:279
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 Arm Limited 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 Mon Jan 13 2025 04:28:42 for gem5 by doxygen 1.9.8