gem5 v23.0.0.0
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 "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
103 argsInit<uint64_t>(PageBytes);
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 }
110}
111
112void
114{
116
117 argsInit<uint32_t>(PageBytes);
118 for (ContextID ctx: contextIds) {
119 auto *tc = system->threads[ctx];
120 tc->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
121 auto *isa = dynamic_cast<ISA*>(tc->getIsaPtr());
122 fatal_if(isa->rvType() != RV32, "RISC V CPU should run in 32 bits mode");
123 }
124}
125
126template<class IntType> void
128{
129 const int RandomBytes = 16;
130 const int addrSize = sizeof(IntType);
131
132 auto *elfObject = dynamic_cast<loader::ElfObject*>(objFile);
133 memState->setStackMin(memState->getStackBase());
134
135 // Determine stack size and populate auxv
136 Addr stack_top = memState->getStackMin();
137 stack_top -= RandomBytes;
138 for (const std::string& arg: argv)
139 stack_top -= arg.size() + 1;
140 for (const std::string& env: envp)
141 stack_top -= env.size() + 1;
142 stack_top &= -addrSize;
143
145 if (elfObject != nullptr) {
146 auxv.emplace_back(gem5::auxv::Entry, objFile->entryPoint());
147 auxv.emplace_back(gem5::auxv::Phnum, elfObject->programHeaderCount());
148 auxv.emplace_back(gem5::auxv::Phent, elfObject->programHeaderSize());
149 auxv.emplace_back(gem5::auxv::Phdr, elfObject->programHeaderTable());
150 auxv.emplace_back(gem5::auxv::Pagesz, PageBytes);
151 auxv.emplace_back(gem5::auxv::Secure, 0);
152 auxv.emplace_back(gem5::auxv::Random, stack_top);
153 auxv.emplace_back(gem5::auxv::Null, 0);
154 }
155 stack_top -= (1 + argv.size()) * addrSize +
156 (1 + envp.size()) * addrSize +
157 addrSize + 2 * sizeof(IntType) * auxv.size();
158 stack_top &= -2*addrSize;
159 memState->setStackSize(memState->getStackBase() - stack_top);
160 memState->mapRegion(roundDown(stack_top, pageSize),
161 roundUp(memState->getStackSize(), pageSize), "stack");
162
163 // Copy random bytes (for AT_RANDOM) to stack
164 memState->setStackMin(memState->getStackMin() - RandomBytes);
165 uint8_t at_random[RandomBytes];
166 std::generate(std::begin(at_random), std::end(at_random),
167 [&]{ return random_mt.random(0, 0xFF); });
168 initVirtMem->writeBlob(memState->getStackMin(), at_random, RandomBytes);
169
170 // Copy argv to stack
171 std::vector<Addr> argPointers;
172 for (const std::string& arg: argv) {
173 memState->setStackMin(memState->getStackMin() - (arg.size() + 1));
174 initVirtMem->writeString(memState->getStackMin(), arg.c_str());
175 argPointers.push_back(memState->getStackMin());
176 if (debug::Stack) {
177 std::string wrote;
178 initVirtMem->readString(wrote, argPointers.back());
179 DPRINTFN("Wrote arg \"%s\" to address %p\n",
180 wrote, (void*)memState->getStackMin());
181 }
182 }
183 argPointers.push_back(0);
184
185 // Copy envp to stack
186 std::vector<Addr> envPointers;
187 for (const std::string& env: envp) {
188 memState->setStackMin(memState->getStackMin() - (env.size() + 1));
189 initVirtMem->writeString(memState->getStackMin(), env.c_str());
190 envPointers.push_back(memState->getStackMin());
191 DPRINTF(Stack, "Wrote env \"%s\" to address %p\n",
192 env, (void*)memState->getStackMin());
193 }
194 envPointers.push_back(0);
195
196 // Align stack
197 memState->setStackMin(memState->getStackMin() & -addrSize);
198
199 // Calculate bottom of stack
200 memState->setStackMin(memState->getStackMin() -
201 ((1 + argv.size()) * addrSize +
202 (1 + envp.size()) * addrSize +
203 addrSize + 2 * sizeof(IntType) * auxv.size()));
204 memState->setStackMin(memState->getStackMin() & (-2 * addrSize));
205 Addr sp = memState->getStackMin();
206 const auto pushOntoStack =
207 [this, &sp](IntType data) {
208 initVirtMem->write(sp, data, ByteOrder::little);
209 sp += sizeof(data);
210 };
211
212 // Push argc and argv pointers onto stack
213 IntType argc = argv.size();
214 DPRINTF(Stack, "Wrote argc %d to address %#x\n", argc, sp);
215 pushOntoStack(argc);
216
217 for (const Addr& argPointer: argPointers) {
218 DPRINTF(Stack, "Wrote argv pointer %#x to address %#x\n",
219 argPointer, sp);
220 pushOntoStack(argPointer);
221 }
222
223 // Push env pointers onto stack
224 for (const Addr& envPointer: envPointers) {
225 DPRINTF(Stack, "Wrote envp pointer %#x to address %#x\n",
226 envPointer, sp);
227 pushOntoStack(envPointer);
228 }
229
230 // Push aux vector onto stack
231 std::map<IntType, std::string> aux_keys = {
232 {gem5::auxv::Entry, "gem5::auxv::Entry"},
233 {gem5::auxv::Phnum, "gem5::auxv::Phnum"},
234 {gem5::auxv::Phent, "gem5::auxv::Phent"},
235 {gem5::auxv::Phdr, "gem5::auxv::Phdr"},
236 {gem5::auxv::Pagesz, "gem5::auxv::Pagesz"},
237 {gem5::auxv::Secure, "gem5::auxv::Secure"},
238 {gem5::auxv::Random, "gem5::auxv::Random"},
239 {gem5::auxv::Null, "gem5::auxv::Null"}
240 };
241 for (const auto &aux: auxv) {
242 DPRINTF(Stack, "Wrote aux key %s to address %#x\n",
243 aux_keys[aux.type], sp);
244 pushOntoStack(aux.type);
245 DPRINTF(Stack, "Wrote aux value %x to address %#x\n", aux.val, sp);
246 pushOntoStack(aux.val);
247 }
248
250 tc->setReg(StackPointerReg, memState->getStackMin());
251 tc->pcState(getStartPC());
252
253 memState->setStackMin(roundDown(memState->getStackMin(), pageSize));
254}
255
256} // 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:113
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:127
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:54
constexpr enums::RiscvType RV64
Definition pcstate.hh:55
Bitfield< 15 > system
Definition misc.hh:1004
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
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 Jul 10 2023 14:24:33 for gem5 by doxygen 1.9.7