gem5 v24.0.0.0
Loading...
Searching...
No Matches
process.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2003-2004 The Regents of The University of Michigan
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#include "arch/sparc/process.hh"
30
31#include "arch/sparc/asi.hh"
36#include "arch/sparc/types.hh"
39#include "base/logging.hh"
40#include "cpu/thread_context.hh"
41#include "debug/Stack.hh"
42#include "mem/page_table.hh"
43#include "params/Process.hh"
44#include "sim/aux_vector.hh"
45#include "sim/byteswap.hh"
46#include "sim/process_impl.hh"
47#include "sim/syscall_return.hh"
48#include "sim/system.hh"
49
50namespace gem5
51{
52
53using namespace SparcISA;
54
55SparcProcess::SparcProcess(const ProcessParams &params,
56 loader::ObjectFile *objFile, Addr _StackBias)
57 : Process(params,
58 new EmulationPageTable(params.name, params.pid, PageBytes),
59 objFile),
60 StackBias(_StackBias)
61{
62 fatal_if(params.useArchPT, "Arch page tables not implemented.");
63 // Initialize these to 0s
64 fillStart = 0;
65 spillStart = 0;
66}
67
68void
70{
72
74 // From the SPARC ABI
75
76 // Setup default FP state
78
80
81 /*
82 * Register window management registers
83 */
84
85 // No windows contain info from other programs
87 // There are no windows to pop
89 // All windows are available to save into
91 // All windows are "clean"
93 // Start with register window 0
94 tc->setMiscReg(MISCREG_CWP, 0);
95 // Always use spill and fill traps 0
97 // Set the trap level to 0
99 // Set the ASI register to something fixed
101
102 // Set the MMU Primary Context Register to hold the process' pid
104
105 // Enable floating point.
106 tc->setMiscReg(MISCREG_FPRS, 0x4);
107
108 /*
109 * T1 specific registers
110 */
111 // Turn on the icache, dcache, dtb translation, and itb translation.
113}
114
115void
117{
119
120 ThreadContext *tc = system->threads[contextIds[0]];
121 // The process runs in user mode with 32 bit addresses
122 PSTATE pstate = 0;
123 pstate.pef = 1;
124 pstate.ie = 1;
125 pstate.am = 1;
126 tc->setMiscReg(MISCREG_PSTATE, pstate);
127
128 argsInit(32 / 8, PageBytes);
129}
130
131void
133{
135
136 ThreadContext *tc = system->threads[contextIds[0]];
137 // The process runs in user mode
138 PSTATE pstate = 0;
139 pstate.pef = 1;
140 pstate.ie = 1;
141 tc->setMiscReg(MISCREG_PSTATE, pstate);
142
143 argsInit(sizeof(RegVal), PageBytes);
144}
145
146template<class IntType>
147void
149{
150 int intSize = sizeof(IntType);
151
153
154 std::string filename;
155 if (argv.size() < 1)
156 filename = "";
157 else
158 filename = argv[0];
159
160 // Even for a 32 bit process, the ABI says we still need to
161 // maintain double word alignment of the stack pointer.
162 uint64_t align = 16;
163
164 enum HardwareCaps
165 {
166 HwcapSparcFlush = 1,
167 HwcapSparcStbar = 2,
168 HwcapSparcSwap = 4,
169 HwcapSparcMuldiv = 8,
170 HwcapSparcV9 = 16,
171 // This one should technically only be set
172 // if there is a cheetah or cheetah_plus tlb,
173 // but we'll use it all the time
174 HwcapSparcUltra3 = 32
175 };
176
177 const int64_t hwcap =
178 HwcapSparcFlush |
179 HwcapSparcStbar |
180 HwcapSparcSwap |
181 HwcapSparcMuldiv |
182 HwcapSparcV9 |
183 HwcapSparcUltra3;
184
185 // Setup the auxilliary vectors. These will already have endian conversion.
186 // Auxilliary vectors are loaded only for elf formatted executables.
187 auto *elfObject = dynamic_cast<loader::ElfObject *>(objFile);
188 if (elfObject) {
189 // Bits which describe the system hardware capabilities
190 auxv.emplace_back(gem5::auxv::Hwcap, hwcap);
191 // The system page size
192 auxv.emplace_back(gem5::auxv::Pagesz, SparcISA::PageBytes);
193 // Defined to be 100 in the kernel source.
194 // Frequency at which times() increments
195 auxv.emplace_back(gem5::auxv::Clktck, 100);
196 // For statically linked executables, this is the virtual address of
197 // the program header tables if they appear in the executable image
198 auxv.emplace_back(gem5::auxv::Phdr, elfObject->programHeaderTable());
199 // This is the size of a program header entry from the elf file.
200 auxv.emplace_back(gem5::auxv::Phent, elfObject->programHeaderSize());
201 // This is the number of program headers from the original elf file.
202 auxv.emplace_back(gem5::auxv::Phnum, elfObject->programHeaderCount());
203 // This is the base address of the ELF interpreter; it should be
204 // zero for static executables or contain the base address for
205 // dynamic executables.
206 auxv.emplace_back(gem5::auxv::Base, getBias());
207 // This is hardwired to 0 in the elf loading code in the kernel
208 auxv.emplace_back(gem5::auxv::Flags, 0);
209 // The entry point to the program
210 auxv.emplace_back(gem5::auxv::Entry, objFile->entryPoint());
211 // Different user and group IDs
212 auxv.emplace_back(gem5::auxv::Uid, uid());
213 auxv.emplace_back(gem5::auxv::Euid, euid());
214 auxv.emplace_back(gem5::auxv::Gid, gid());
215 auxv.emplace_back(gem5::auxv::Egid, egid());
216 // Whether to enable "secure mode" in the executable
217 auxv.emplace_back(gem5::auxv::Secure, 0);
218 // The address of 16 "random" bytes.
219 auxv.emplace_back(gem5::auxv::Random, 0);
220 }
221
222 // Figure out how big the initial stack needs to be
223
224 // The unaccounted for 8 byte 0 at the top of the stack
225 int sentry_size = 8;
226
227 // This is the name of the file which is present on the initial stack
228 // It's purpose is to let the user space linker examine the original file.
229 int file_name_size = filename.size() + 1;
230
231 const int numRandomBytes = 16;
232 int aux_data_size = numRandomBytes;
233
234 int env_data_size = 0;
235 for (int i = 0; i < envp.size(); ++i) {
236 env_data_size += envp[i].size() + 1;
237 }
238 int arg_data_size = 0;
239 for (int i = 0; i < argv.size(); ++i) {
240 arg_data_size += argv[i].size() + 1;
241 }
242
243 // The info_block.
244 int base_info_block_size =
245 sentry_size + file_name_size + env_data_size + arg_data_size;
246
247 int info_block_size = roundUp(base_info_block_size, align);
248
249 int info_block_padding = info_block_size - base_info_block_size;
250
251 // Each auxilliary vector is two words
252 int aux_array_size = intSize * 2 * (auxv.size() + 1);
253
254 int envp_array_size = intSize * (envp.size() + 1);
255 int argv_array_size = intSize * (argv.size() + 1);
256
257 int argc_size = intSize;
258 int window_save_size = intSize * 16;
259
260 // Figure out the size of the contents of the actual initial frame
261 int frame_size =
262 aux_array_size +
263 envp_array_size +
264 argv_array_size +
265 argc_size +
266 window_save_size;
267
268 // There needs to be padding after the auxiliary vector data so that the
269 // very bottom of the stack is aligned properly.
270 int aligned_partial_size = roundUp(frame_size, align);
271 int aux_padding = aligned_partial_size - frame_size;
272
273 int space_needed =
274 info_block_size +
275 aux_data_size +
276 aux_padding +
277 frame_size;
278
279 memState->setStackMin(memState->getStackBase() - space_needed);
280 memState->setStackMin(roundDown(memState->getStackMin(), align));
281 memState->setStackSize(memState->getStackBase() - memState->getStackMin());
282
283 // Allocate space for the stack
284 memState->mapRegion(roundDown(memState->getStackMin(), pageSize),
285 roundUp(memState->getStackSize(), pageSize), "stack");
286
287 // map out initial stack contents
288 IntType sentry_base = memState->getStackBase() - sentry_size;
289 IntType file_name_base = sentry_base - file_name_size;
290 IntType env_data_base = file_name_base - env_data_size;
291 IntType arg_data_base = env_data_base - arg_data_size;
292 IntType aux_data_base = arg_data_base - info_block_padding - aux_data_size;
293 IntType auxv_array_base = aux_data_base - aux_array_size - aux_padding;
294 IntType envp_array_base = auxv_array_base - envp_array_size;
295 IntType argv_array_base = envp_array_base - argv_array_size;
296 IntType argc_base = argv_array_base - argc_size;
297 IntType window_save_base = argc_base - window_save_size;
298
299 DPRINTF(Stack, "The addresses of items on the initial stack:\n");
300 DPRINTF(Stack, "%#x - sentry NULL\n", sentry_base);
301 DPRINTF(Stack, "filename = %s\n", filename);
302 DPRINTF(Stack, "%#x - file name\n", file_name_base);
303 DPRINTF(Stack, "%#x - env data\n", env_data_base);
304 DPRINTF(Stack, "%#x - arg data\n", arg_data_base);
305 DPRINTF(Stack, "%#x - auxv array\n", auxv_array_base);
306 DPRINTF(Stack, "%#x - envp array\n", envp_array_base);
307 DPRINTF(Stack, "%#x - argv array\n", argv_array_base);
308 DPRINTF(Stack, "%#x - argc \n", argc_base);
309 DPRINTF(Stack, "%#x - window save\n", window_save_base);
310 DPRINTF(Stack, "%#x - stack min\n", memState->getStackMin());
311
312 assert(window_save_base == memState->getStackMin());
313
314 // write contents to stack
315
316 // figure out argc
317 IntType argc = argv.size();
318 IntType guestArgc = htobe(argc);
319
320 // Write out the sentry void *
321 uint64_t sentry_NULL = 0;
322 initVirtMem->writeBlob(sentry_base, &sentry_NULL, sentry_size);
323
324 // Write the file name
325 initVirtMem->writeString(file_name_base, filename.c_str());
326
327 // Fix up the aux vectors which point to data.
328 for (auto &aux: auxv) {
329 if (aux.type == gem5::auxv::Random)
330 aux.val = aux_data_base;
331 }
332
333 // Copy the aux stuff
334 Addr auxv_array_end = auxv_array_base;
335 for (const auto &aux: auxv) {
336 initVirtMem->write(auxv_array_end, aux, ByteOrder::big);
337 auxv_array_end += sizeof(aux);
338 }
339
340 // Write out the terminating zeroed auxilliary vector
341 const gem5::auxv::AuxVector<IntType> zero(0, 0);
342 initVirtMem->write(auxv_array_end, zero);
343 auxv_array_end += sizeof(zero);
344
345 copyStringArray(envp, envp_array_base, env_data_base,
346 ByteOrder::big, *initVirtMem);
347 copyStringArray(argv, argv_array_base, arg_data_base,
348 ByteOrder::big, *initVirtMem);
349
350 initVirtMem->writeBlob(argc_base, &guestArgc, intSize);
351
352 // Set up space for the trap handlers into the processes address space.
353 // Since the stack grows down and there is reserved address space abov
354 // it, we can put stuff above it and stay out of the way.
355 fillStart = memState->getStackBase();
357
359 // Set up the thread context to start running the process
360 // assert(NumArgumentRegs >= 2);
361 // tc->setReg(ArgumentReg[0], argc);
362 // tc->setReg(ArgumentReg[1], argv_array_base);
363 tc->setReg(StackPointerReg, memState->getStackMin() - StackBias);
364
365 // %g1 is a pointer to a function that should be run at exit. Since we
366 // don't have anything like that, it should be set to 0.
367 tc->setReg(int_reg::G1, (RegVal)0);
368
369 tc->pcState(getStartPC());
370
371 // Align the "stack_min" to a page boundary.
372 memState->setStackMin(roundDown(memState->getStackMin(), pageSize));
373}
374
375void
376Sparc64Process::argsInit(int intSize, int pageSize)
377{
379
380 // Stuff the trap handlers into the process address space
381 initVirtMem->writeBlob(fillStart,
383 initVirtMem->writeBlob(spillStart,
385}
386
387void
388Sparc32Process::argsInit(int intSize, int pageSize)
389{
391
392 // Stuff the trap handlers into the process address space
393 initVirtMem->writeBlob(fillStart,
395 initVirtMem->writeBlob(spillStart,
397}
398
399} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
uint64_t egid()
Definition process.hh:85
std::unique_ptr< SETranslatingPortProxy > initVirtMem
Definition process.hh:187
std::shared_ptr< MemState > memState
Definition process.hh:289
uint64_t uid()
Definition process.hh:82
std::vector< std::string > argv
Definition process.hh:226
uint64_t _pid
Definition process.hh:278
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
uint64_t gid()
Definition process.hh:84
Addr getStartPC()
Definition process.cc:497
loader::ObjectFile * objFile
Definition process.hh:223
Addr getBias()
Definition process.cc:489
uint64_t euid()
Definition process.hh:83
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition process.cc:116
void argsInit(int intSize, int pageSize)
Definition process.cc:388
void argsInit(int intSize, int pageSize)
Definition process.cc:376
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition process.cc:132
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition process.cc:69
void argsInit(int pageSize)
Definition process.cc:148
SparcProcess(const ProcessParams &params, loader::ObjectFile *objFile, Addr _StackBias)
Definition process.cc:55
const Addr StackBias
Definition process.hh:48
Threads threads
Definition system.hh:310
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
virtual void setMiscRegNoEffect(RegIndex misc_reg, RegVal val)=0
virtual void setReg(const RegId &reg, RegVal val)
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< 7 > i
Definition misc_types.hh:67
uint32_t MachInst
Definition types.hh:55
const Addr PageBytes
Definition page_size.hh:53
constexpr RegId Cleanwin
Definition int.hh:135
constexpr RegId Wstate
Definition int.hh:137
constexpr RegId G1
Definition int.hh:92
constexpr RegId Cansave
Definition int.hh:133
constexpr RegId Otherwin
Definition int.hh:136
constexpr RegId Canrestore
Definition int.hh:134
const MachInst spillHandler64[numSpillInsts]
Definition handlers.hh:117
@ MISCREG_PSTATE
Definition misc.hh:67
@ MISCREG_MMU_P_CONTEXT
MMU Internal Registers.
Definition misc.hh:91
@ MISCREG_MMU_LSU_CTRL
Definition misc.hh:94
@ MISCREG_ASI
Ancillary State Registers.
Definition misc.hh:47
@ MISCREG_FSR
Floating Point Status Register.
Definition misc.hh:88
const MachInst fillHandler64[numFillInsts]
Definition handlers.hh:45
const int numFillInsts
Definition handlers.hh:42
const MachInst fillHandler32[numFillInsts]
Definition handlers.hh:81
const int NWindows
const int numSpillInsts
Definition handlers.hh:43
const MachInst spillHandler32[numSpillInsts]
Definition handlers.hh:153
const Addr PageBytes
Definition page_size.hh:41
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 RegVal
Definition types.hh:173
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
T htobe(T value)
Definition byteswap.hh:174
void copyStringArray(std::vector< std::string > &strings, AddrType array_ptr, AddrType data_ptr, const ByteOrder bo, PortProxy &memProxy)
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