49#include "debug/Stack.hh"
51#include "params/Process.hh"
61using namespace RiscvISA;
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;
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);
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;
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);
105 auto *tc =
system->threads[ctx];
107 auto *isa =
dynamic_cast<ISA*
>(tc->getIsaPtr());
108 fatal_if(isa->rvType() !=
RV64,
"RISC V CPU should run in 64 bits mode");
111 "RISC V SE mode can't run without supervisor and user "
123 auto *tc =
system->threads[ctx];
125 auto *isa =
dynamic_cast<ISA*
>(tc->getIsaPtr());
126 fatal_if(isa->rvType() !=
RV32,
"RISC V CPU should run in 32 bits mode");
129 "RISC V SE mode can't run without supervisor and user "
134template<
class IntType>
void
137 const int RandomBytes = 16;
138 const int addrSize =
sizeof(IntType);
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;
153 if (elfObject !=
nullptr) {
163 stack_top -= (1 +
argv.size()) * addrSize +
164 (1 +
envp.size()) * addrSize +
165 addrSize + 2 *
sizeof(IntType) * auxv.size();
166 stack_top &= -2*addrSize;
173 uint8_t at_random[RandomBytes];
174 std::generate(std::begin(at_random), std::end(at_random),
180 for (
const std::string& arg:
argv) {
183 argPointers.push_back(
memState->getStackMin());
186 initVirtMem->readString(wrote, argPointers.back());
187 DPRINTFN(
"Wrote arg \"%s\" to address %p\n",
188 wrote, (
void*)
memState->getStackMin());
191 argPointers.push_back(0);
195 for (
const std::string& env:
envp) {
198 envPointers.push_back(
memState->getStackMin());
199 DPRINTF(Stack,
"Wrote env \"%s\" to address %p\n",
200 env, (
void*)
memState->getStackMin());
202 envPointers.push_back(0);
209 ((1 +
argv.size()) * addrSize +
210 (1 +
envp.size()) * addrSize +
211 addrSize + 2 *
sizeof(IntType) * auxv.size()));
214 const auto pushOntoStack =
215 [
this, &
sp](IntType
data) {
221 IntType argc =
argv.size();
222 DPRINTF(Stack,
"Wrote argc %d to address %#x\n", argc,
sp);
225 for (
const Addr& argPointer: argPointers) {
226 DPRINTF(Stack,
"Wrote argv pointer %#x to address %#x\n",
228 pushOntoStack(argPointer);
232 for (
const Addr& envPointer: envPointers) {
233 DPRINTF(Stack,
"Wrote envp pointer %#x to address %#x\n",
235 pushOntoStack(envPointer);
239 std::map<IntType, std::string> aux_keys = {
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);
loader::MemoryImage image
std::unique_ptr< SETranslatingPortProxy > initVirtMem
std::shared_ptr< MemState > memState
std::vector< std::string > argv
std::vector< ContextID > contextIds
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
std::vector< std::string > envp
loader::ObjectFile * objFile
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
RiscvProcess32(const ProcessParams ¶ms, loader::ObjectFile *objFile)
RiscvProcess64(const ProcessParams ¶ms, loader::ObjectFile *objFile)
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
RiscvProcess(const ProcessParams ¶ms, loader::ObjectFile *objFile)
void argsInit(int pageSize)
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual void setReg(const RegId ®, RegVal val)
virtual const PCStateBase & pcState() const =0
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
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...
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
const Params & params() const
constexpr auto & StackPointerReg
constexpr enums::RiscvType RV32
constexpr enums::RiscvType RV64
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
int ContextID
Globally unique thread context ID.
Declarations of a non-full system Page Table.
const std::string & name()