gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
process.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010, 2012, 2017-2018, 2023 Arm Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2007-2008 The Florida State University
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
41#include "arch/arm/process.hh"
42
43#include "arch/arm/page_size.hh"
44#include "arch/arm/regs/cc.hh"
45#include "arch/arm/regs/misc.hh"
46#include "arch/arm/types.hh"
49#include "base/logging.hh"
50#include "cpu/thread_context.hh"
51#include "debug/Stack.hh"
52#include "mem/page_table.hh"
53#include "params/Process.hh"
54#include "sim/aux_vector.hh"
55#include "sim/byteswap.hh"
56#include "sim/process_impl.hh"
57#include "sim/syscall_return.hh"
58#include "sim/system.hh"
59
60namespace gem5
61{
62
63using namespace ArmISA;
64
65ArmProcess::ArmProcess(const ProcessParams &params,
69 objFile),
70 arch(_arch)
71{
72 fatal_if(params.useArchPT, "Arch page tables not implemented.");
73}
74
77 : ArmProcess(params, objFile, _arch)
78{
79 Addr brk_point = roundUp(image.maxAddr(), PageBytes);
80 Addr stack_base = 0xbf000000L;
81 Addr max_stack_size = 8 * 1024 * 1024;
82 Addr next_thread_stack_base = stack_base - max_stack_size;
83 Addr mmap_end = 0x40000000L;
84
85 memState = std::make_shared<MemState>(
86 this, brk_point, stack_base, max_stack_size,
87 next_thread_stack_base, mmap_end);
88}
89
91 const ProcessParams &params, loader::ObjectFile *objFile,
92 loader::Arch _arch)
93 : ArmProcess(params, objFile, _arch)
94{
95 Addr brk_point = roundUp(image.maxAddr(), PageBytes);
96 Addr stack_base = 0x7fffff0000L;
97 Addr max_stack_size = 8 * 1024 * 1024;
98 Addr next_thread_stack_base = stack_base - max_stack_size;
99 Addr mmap_end = 0x4000000000L;
100
101 memState = std::make_shared<MemState>(
102 this, brk_point, stack_base, max_stack_size,
103 next_thread_stack_base, mmap_end);
104}
105
106void
108{
111 for (auto id: contextIds) {
112 ThreadContext *tc = system->threads[id];
113 CPACR cpacr = tc->readMiscReg(MISCREG_CPACR);
114 // Enable the floating point coprocessors.
115 cpacr.cp10 = 0x3;
116 cpacr.cp11 = 0x3;
117 tc->setMiscReg(MISCREG_CPACR, cpacr);
118 // Generically enable floating point support.
119 FPEXC fpexc = tc->readMiscReg(MISCREG_FPEXC);
120 fpexc.en = 1;
121 tc->setMiscReg(MISCREG_FPEXC, fpexc);
122 }
123}
124
125void
127{
130 for (auto id: contextIds) {
131 ThreadContext *tc = system->threads[id];
132 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
133 cpsr.mode = MODE_EL0T;
134 tc->setMiscReg(MISCREG_CPSR, cpsr);
135 CPACR cpacr = tc->readMiscReg(MISCREG_CPACR_EL1);
136 // Enable the floating point coprocessors.
137 cpacr.cp10 = 0x3;
138 cpacr.cp11 = 0x3;
139 // Enable SVE.
140 cpacr.zen = 0x3;
141 tc->setMiscReg(MISCREG_CPACR_EL1, cpacr);
142 // Generically enable floating point support.
143 FPEXC fpexc = tc->readMiscReg(MISCREG_FPEXC);
144 fpexc.en = 1;
145 tc->setMiscReg(MISCREG_FPEXC, fpexc);
146 }
147}
148
149uint32_t
151{
152 enum ArmCpuFeature
153 {
154 Arm_Swp = 1 << 0,
155 Arm_Half = 1 << 1,
156 Arm_Thumb = 1 << 2,
157 Arm_26Bit = 1 << 3,
158 Arm_FastMult = 1 << 4,
159 Arm_Fpa = 1 << 5,
160 Arm_Vfp = 1 << 6,
161 Arm_Edsp = 1 << 7,
162 Arm_Java = 1 << 8,
163 Arm_Iwmmxt = 1 << 9,
164 Arm_Crunch = 1 << 10,
165 Arm_ThumbEE = 1 << 11,
166 Arm_Neon = 1 << 12,
167 Arm_Vfpv3 = 1 << 13,
168 Arm_Vfpv3d16 = 1 << 14
169 };
170
171 return Arm_Swp | Arm_Half | Arm_Thumb | Arm_FastMult |
172 Arm_Vfp | Arm_Edsp | Arm_Neon |
173 Arm_Vfpv3 | Arm_Vfpv3d16;
174}
175
176uint32_t
178{
179 // In order to know what these flags mean, please refer to Linux
180 // /Documentation/arm64/elf_hwcaps.txt text file.
181 enum ArmCpuFeature
182 {
183 Arm_Fp = 1 << 0,
184 Arm_Asimd = 1 << 1,
185 Arm_Evtstrm = 1 << 2,
186 Arm_Aes = 1 << 3,
187 Arm_Pmull = 1 << 4,
188 Arm_Sha1 = 1 << 5,
189 Arm_Sha2 = 1 << 6,
190 Arm_Crc32 = 1 << 7,
191 Arm_Atomics = 1 << 8,
192 Arm_Fphp = 1 << 9,
193 Arm_Asimdhp = 1 << 10,
194 Arm_Cpuid = 1 << 11,
195 Arm_Asimdrdm = 1 << 12,
196 Arm_Jscvt = 1 << 13,
197 Arm_Fcma = 1 << 14,
198 Arm_Lrcpc = 1 << 15,
199 Arm_Dcpop = 1 << 16,
200 Arm_Sha3 = 1 << 17,
201 Arm_Sm3 = 1 << 18,
202 Arm_Sm4 = 1 << 19,
203 Arm_Asimddp = 1 << 20,
204 Arm_Sha512 = 1 << 21,
205 Arm_Sve = 1 << 22,
206 Arm_Asimdfhm = 1 << 23,
207 Arm_Dit = 1 << 24,
208 Arm_Uscat = 1 << 25,
209 Arm_Ilrcpc = 1 << 26,
210 Arm_Flagm = 1 << 27,
211 Arm_Sbss = 1 << 28,
212 Arm_Sb = 1 << 29,
213 Arm_Paca = 1 << 30,
214 Arm_Pacg = 1 << 31
215 };
216
217 uint32_t hwcap = 0;
218
219 ThreadContext *tc = system->threads[contextIds[0]];
220
221 const AA64PFR0 pf_r0 = tc->readMiscReg(MISCREG_ID_AA64PFR0_EL1);
222
223 hwcap |= (pf_r0.fp == 0) ? Arm_Fp : 0;
224 hwcap |= (pf_r0.fp == 1) ? Arm_Fphp | Arm_Fp : 0;
225 hwcap |= (pf_r0.advsimd == 0) ? Arm_Asimd : 0;
226 hwcap |= (pf_r0.advsimd == 1) ? Arm_Asimdhp | Arm_Asimd : 0;
227 hwcap |= (pf_r0.sve >= 1) ? Arm_Sve : 0;
228 hwcap |= (pf_r0.dit >= 1) ? Arm_Dit : 0;
229
230 const AA64ISAR0 isa_r0 = tc->readMiscReg(MISCREG_ID_AA64ISAR0_EL1);
231
232 hwcap |= (isa_r0.aes >= 1) ? Arm_Aes : 0;
233 hwcap |= (isa_r0.aes >= 2) ? Arm_Pmull : 0;
234 hwcap |= (isa_r0.sha1 >= 1) ? Arm_Sha1 : 0;
235 hwcap |= (isa_r0.sha2 >= 1) ? Arm_Sha2 : 0;
236 hwcap |= (isa_r0.sha2 >= 2) ? Arm_Sha512 : 0;
237 hwcap |= (isa_r0.crc32 >= 1) ? Arm_Crc32 : 0;
238 hwcap |= (isa_r0.atomic >= 1) ? Arm_Atomics : 0;
239 hwcap |= (isa_r0.rdm >= 1) ? Arm_Asimdrdm : 0;
240 hwcap |= (isa_r0.sha3 >= 1) ? Arm_Sha3 : 0;
241 hwcap |= (isa_r0.sm3 >= 1) ? Arm_Sm3 : 0;
242 hwcap |= (isa_r0.sm4 >= 1) ? Arm_Sm4 : 0;
243 hwcap |= (isa_r0.dp >= 1) ? Arm_Asimddp : 0;
244 hwcap |= (isa_r0.fhm >= 1) ? Arm_Asimdfhm : 0;
245 hwcap |= (isa_r0.ts >= 1) ? Arm_Flagm : 0;
246
247 const AA64ISAR1 isa_r1 = tc->readMiscReg(MISCREG_ID_AA64ISAR1_EL1);
248
249 hwcap |= (isa_r1.dpb >= 1) ? Arm_Dcpop : 0;
250 hwcap |= (isa_r1.jscvt >= 1) ? Arm_Jscvt : 0;
251 hwcap |= (isa_r1.fcma >= 1) ? Arm_Fcma : 0;
252 hwcap |= (isa_r1.lrcpc >= 1) ? Arm_Lrcpc : 0;
253 hwcap |= (isa_r1.lrcpc >= 2) ? Arm_Ilrcpc : 0;
254 hwcap |= (isa_r1.apa >= 1 || isa_r1.api >= 1) ? Arm_Paca : 0;
255 hwcap |= (isa_r1.gpa >= 1 || isa_r1.gpi >= 1) ? Arm_Pacg : 0;
256
257 const AA64MMFR2 mm_fr2 = tc->readMiscReg(MISCREG_ID_AA64MMFR2_EL1);
258
259 hwcap |= (mm_fr2.at >= 1) ? Arm_Uscat : 0;
260
261 return hwcap;
262}
263
264uint64_t
266{
267 enum ArmCpuFeature : uint64_t
268 {
269 Arm_None = 0,
270 Arm_Dcpodp = 1ULL << 0,
271 Arm_Sve2 = 1ULL<< 1,
272 Arm_Sveaes = 1ULL << 2,
273 Arm_Svepmull = 1ULL << 3,
274 Arm_Svebitperm = 1ULL << 4,
275 Arm_Svesha3 = 1ULL << 5,
276 Arm_Svesm4 = 1ULL << 6,
277 Arm_Flagm2 = 1ULL << 7,
278 Arm_Frint = 1ULL << 8,
279 Arm_Svei8mm = 1ULL << 9,
280 Arm_Svef32mm = 1ULL << 10,
281 Arm_Svef64mm = 1ULL << 11,
282 Arm_Svebf16 = 1ULL << 12,
283 Arm_I8mm = 1ULL << 13,
284 Arm_Bf16 = 1ULL << 14,
285 Arm_Dgh = 1ULL << 15,
286 Arm_Rng = 1ULL << 16,
287 Arm_Bti = 1ULL << 17,
288 Arm_Mte = 1ULL << 18,
289 Arm_Ecv = 1ULL << 19,
290 Arm_Afp = 1ULL << 20,
291 Arm_Rpres = 1ULL << 21,
292 Arm_Mte3 = 1ULL << 22,
293 Arm_Sme = 1ULL << 23,
294 Arm_Sme_I16i64 = 1ULL << 24,
295 Arm_Sme_F64f64 = 1ULL << 25,
296 Arm_Sme_I8i32 = 1ULL << 26,
297 Arm_Sme_F16f32 = 1ULL << 27,
298 Arm_Sme_B16f32 = 1ULL << 28,
299 Arm_Sme_F32f32 = 1ULL << 29,
300 Arm_Sme_Fa64 = 1ULL << 30,
301 Arm_Wfxt = 1ULL << 31,
302 Arm_Ebf16 = 1ULL << 32,
303 Arm_Sve_Ebf16 = 1ULL << 33,
304 Arm_Cssc = 1ULL << 34,
305 Arm_Rprfm = 1ULL << 35,
306 Arm_Sve2p1 = 1ULL << 36,
307 Arm_Sme2 = 1ULL << 37,
308 Arm_Sme2p1 = 1ULL << 38,
309 Arm_Sme_I16i32 = 1ULL << 39,
310 Arm_Sme_Bi32i32 = 1ULL << 40,
311 Arm_Sme_B16b16 = 1ULL << 41,
312 Arm_Sme_F16f16 = 1ULL << 42
313 };
314
315 uint64_t hwcap = 0;
316
317 ThreadContext *tc = system->threads[contextIds[0]];
318
319 const AA64ISAR0 isa_r0 = tc->readMiscReg(MISCREG_ID_AA64ISAR0_EL1);
320 hwcap |= (isa_r0.ts >= 2) ? Arm_Flagm2 : Arm_None;
321 hwcap |= (isa_r0.rndr >= 1) ? Arm_Rng : Arm_None;
322
323 const AA64ISAR1 isa_r1 = tc->readMiscReg(MISCREG_ID_AA64ISAR1_EL1);
324 hwcap |= (isa_r1.i8mm >= 1) ? Arm_I8mm : Arm_None;
325
326 const AA64ZFR0 zf_r0 = tc->readMiscReg(MISCREG_ID_AA64ZFR0_EL1);
327 hwcap |= (zf_r0.f32mm >= 1) ? Arm_Svef32mm : Arm_None;
328 hwcap |= (zf_r0.f64mm >= 1) ? Arm_Svef64mm : Arm_None;
329 hwcap |= (zf_r0.i8mm >= 1) ? Arm_Svei8mm : Arm_None;
330
331 const AA64PFR1 pf_r1 = tc->readMiscReg(MISCREG_ID_AA64PFR1_EL1);
332 hwcap |= (pf_r1.sme == 1) ? Arm_Sme : Arm_None;
333
334 const AA64SMFR0 smfr_r0 = tc->readMiscReg(MISCREG_ID_AA64SMFR0_EL1);
335 hwcap |= (smfr_r0.i16i64 == 0b1111) ? Arm_Sme_I16i64 : Arm_None;
336 hwcap |= (smfr_r0.f64f64 == 1) ? Arm_Sme_F64f64 : Arm_None;
337 hwcap |= (smfr_r0.i8i32 == 0b1111) ? Arm_Sme_I8i32 : Arm_None;
338 hwcap |= (smfr_r0.f16f32 == 1) ? Arm_Sme_F16f32 : Arm_None;
339 hwcap |= (smfr_r0.b16f32 == 1) ? Arm_Sme_B16f32 : Arm_None;
340 hwcap |= (smfr_r0.f32f32 == 1) ? Arm_Sme_F32f32 : Arm_None;
341 hwcap |= (smfr_r0.fa64 == 1) ? Arm_Sme_Fa64 : Arm_None;
342
343 return hwcap;
344}
345
346template <class IntType>
347void
348ArmProcess::argsInit(int pageSize, const RegId &spId)
349{
350 int intSize = sizeof(IntType);
351
353
354 std::string filename;
355 if (argv.size() < 1)
356 filename = "";
357 else
358 filename = argv[0];
359
360 //We want 16 byte alignment
361 uint64_t align = 16;
362
363 //Setup the auxilliary vectors. These will already have endian conversion.
364 //Auxilliary vectors are loaded only for elf formatted executables.
365 auto *elfObject = dynamic_cast<loader::ElfObject *>(objFile);
366 if (elfObject) {
367
368 if (objFile->getOpSys() == loader::Linux) {
369 //Bits which describe the system hardware capabilities
370 //XXX Figure out what these should be
373 //Frequency at which times() increments
374 auxv.emplace_back(gem5::auxv::Clktck, 0x64);
375 //Whether to enable "secure mode" in the executable
376 auxv.emplace_back(gem5::auxv::Secure, 0);
377 // Pointer to 16 bytes of random data
378 auxv.emplace_back(gem5::auxv::Random, 0);
379 //The filename of the program
380 auxv.emplace_back(gem5::auxv::Execfn, 0);
381 //The string "v71" -- ARM v7 architecture
382 auxv.emplace_back(gem5::auxv::Platform, 0);
383 }
384
385 //The system page size
387 // For statically linked executables, this is the virtual address of
388 // the program header tables if they appear in the executable image
389 auxv.emplace_back(gem5::auxv::Phdr, elfObject->programHeaderTable());
390 // This is the size of a program header entry from the elf file.
391 auxv.emplace_back(gem5::auxv::Phent, elfObject->programHeaderSize());
392 // This is the number of program headers from the original elf file.
393 auxv.emplace_back(gem5::auxv::Phnum, elfObject->programHeaderCount());
394 // This is the base address of the ELF interpreter; it should be
395 // zero for static executables or contain the base address for
396 // dynamic executables.
397 auxv.emplace_back(gem5::auxv::Base, getBias());
398 //XXX Figure out what this should be.
399 auxv.emplace_back(gem5::auxv::Flags, 0);
400 //The entry point to the program
401 auxv.emplace_back(gem5::auxv::Entry, objFile->entryPoint());
402 //Different user and group IDs
403 auxv.emplace_back(gem5::auxv::Uid, uid());
404 auxv.emplace_back(gem5::auxv::Euid, euid());
405 auxv.emplace_back(gem5::auxv::Gid, gid());
406 auxv.emplace_back(gem5::auxv::Egid, egid());
407 }
408
409 //Figure out how big the initial stack nedes to be
410
411 // A sentry NULL void pointer at the top of the stack.
412 int sentry_size = intSize;
413
414 std::string platform = "v71";
415 int platform_size = platform.size() + 1;
416
417 // Bytes for AT_RANDOM above, we'll just keep them 0
418 int aux_random_size = 16; // as per the specification
419
420 // The aux vectors are put on the stack in two groups. The first group are
421 // the vectors that are generated as the elf is loaded. The second group
422 // are the ones that were computed ahead of time and include the platform
423 // string.
424 int aux_data_size = filename.size() + 1;
425
426 int env_data_size = 0;
427 for (int i = 0; i < envp.size(); ++i) {
428 env_data_size += envp[i].size() + 1;
429 }
430 int arg_data_size = 0;
431 for (int i = 0; i < argv.size(); ++i) {
432 arg_data_size += argv[i].size() + 1;
433 }
434
435 int info_block_size =
436 sentry_size + env_data_size + arg_data_size +
437 aux_data_size + platform_size + aux_random_size;
438
439 //Each auxilliary vector is two 4 byte words
440 int aux_array_size = intSize * 2 * (auxv.size() + 1);
441
442 int envp_array_size = intSize * (envp.size() + 1);
443 int argv_array_size = intSize * (argv.size() + 1);
444
445 int argc_size = intSize;
446
447 //Figure out the size of the contents of the actual initial frame
448 int frame_size =
449 info_block_size +
450 aux_array_size +
451 envp_array_size +
452 argv_array_size +
453 argc_size;
454
455 //There needs to be padding after the auxiliary vector data so that the
456 //very bottom of the stack is aligned properly.
457 int partial_size = frame_size;
458 int aligned_partial_size = roundUp(partial_size, align);
459 int aux_padding = aligned_partial_size - partial_size;
460
461 int space_needed = frame_size + aux_padding;
462
463 memState->setStackMin(memState->getStackBase() - space_needed);
464 memState->setStackMin(roundDown(memState->getStackMin(), align));
465 memState->setStackSize(memState->getStackBase() - memState->getStackMin());
466
467 // map memory
468 memState->mapRegion(roundDown(memState->getStackMin(), pageSize),
469 roundUp(memState->getStackSize(), pageSize), "stack");
470
471 // map out initial stack contents
472 IntType sentry_base = memState->getStackBase() - sentry_size;
473 IntType aux_data_base = sentry_base - aux_data_size;
474 IntType env_data_base = aux_data_base - env_data_size;
475 IntType arg_data_base = env_data_base - arg_data_size;
476 IntType platform_base = arg_data_base - platform_size;
477 IntType aux_random_base = platform_base - aux_random_size;
478 IntType auxv_array_base = aux_random_base - aux_array_size - aux_padding;
479 IntType envp_array_base = auxv_array_base - envp_array_size;
480 IntType argv_array_base = envp_array_base - argv_array_size;
481 IntType argc_base = argv_array_base - argc_size;
482
483 DPRINTF(Stack, "The addresses of items on the initial stack:\n");
484 DPRINTF(Stack, "0x%x - aux data\n", aux_data_base);
485 DPRINTF(Stack, "0x%x - env data\n", env_data_base);
486 DPRINTF(Stack, "0x%x - arg data\n", arg_data_base);
487 DPRINTF(Stack, "0x%x - random data\n", aux_random_base);
488 DPRINTF(Stack, "0x%x - platform base\n", platform_base);
489 DPRINTF(Stack, "0x%x - auxv array\n", auxv_array_base);
490 DPRINTF(Stack, "0x%x - envp array\n", envp_array_base);
491 DPRINTF(Stack, "0x%x - argv array\n", argv_array_base);
492 DPRINTF(Stack, "0x%x - argc \n", argc_base);
493 DPRINTF(Stack, "0x%x - stack min\n", memState->getStackMin());
494
495 // write contents to stack
496
497 // figure out argc
498 IntType argc = argv.size();
499 IntType guestArgc = htole(argc);
500
501 //Write out the sentry void *
502 IntType sentry_NULL = 0;
503 initVirtMem->writeBlob(sentry_base, &sentry_NULL, sentry_size);
504
505 //Fix up the aux vectors which point to other data
506 for (int i = auxv.size() - 1; i >= 0; i--) {
507 if (auxv[i].type == gem5::auxv::Platform) {
508 auxv[i].val = platform_base;
509 initVirtMem->writeString(platform_base, platform.c_str());
510 } else if (auxv[i].type == gem5::auxv::Execfn) {
511 auxv[i].val = aux_data_base;
512 initVirtMem->writeString(aux_data_base, filename.c_str());
513 } else if (auxv[i].type == gem5::auxv::Random) {
514 auxv[i].val = aux_random_base;
515 // Just leave the value 0, we don't want randomness
516 }
517 }
518
519 //Copy the aux stuff
520 Addr auxv_array_end = auxv_array_base;
521 for (const auto &aux: auxv) {
522 initVirtMem->write(auxv_array_end, aux, ByteOrder::little);
523 auxv_array_end += sizeof(aux);
524 }
525 //Write out the terminating zeroed auxillary vector
526 const gem5::auxv::AuxVector<IntType> zero(0, 0);
527 initVirtMem->write(auxv_array_end, zero);
528 auxv_array_end += sizeof(zero);
529
530 copyStringArray(envp, envp_array_base, env_data_base,
531 ByteOrder::little, *initVirtMem);
532 copyStringArray(argv, argv_array_base, arg_data_base,
533 ByteOrder::little, *initVirtMem);
534
535 initVirtMem->writeBlob(argc_base, &guestArgc, intSize);
536
537 ThreadContext *tc = system->threads[contextIds[0]];
538 //Set the stack pointer register
539 tc->setReg(spId, memState->getStackMin());
540 //A pointer to a function to run when the program exits. We'll set this
541 //to zero explicitly to make sure this isn't used.
542 tc->setReg(ArgumentReg0, (RegVal)0);
543 //Set argument regs 1 and 2 to argv[0] and envp[0] respectively
544 if (argv.size() > 0) {
545 tc->setReg(ArgumentReg1, arg_data_base + arg_data_size -
546 argv[argv.size() - 1].size() - 1);
547 } else {
548 tc->setReg(ArgumentReg1, (RegVal)0);
549 }
550 if (envp.size() > 0) {
551 tc->setReg(ArgumentReg2, env_data_base + env_data_size -
552 envp[envp.size() - 1].size() - 1);
553 } else {
554 tc->setReg(ArgumentReg2, (RegVal)0);
555 }
556
557 PCState pc;
558 pc.thumb(arch == loader::Thumb);
559 pc.nextThumb(pc.thumb());
560 pc.aarch64(arch == loader::Arm64);
561 pc.nextAArch64(pc.aarch64());
562 pc.set(getStartPC() & ~mask(1));
563 tc->pcState(pc);
564
565 //Align the "stackMin" to a page boundary.
566 memState->setStackMin(roundDown(memState->getStackMin(), pageSize));
567}
568
569} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
ArmProcess32(const ProcessParams &params, loader::ObjectFile *objFile, loader::Arch _arch)
Definition process.cc:75
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition process.cc:107
uint32_t armHwcapImpl() const override
AArch32 AT_HWCAP.
Definition process.cc:150
uint64_t armHwcapImpl2() const override
Definition process.cc:265
ArmProcess64(const ProcessParams &params, loader::ObjectFile *objFile, loader::Arch _arch)
Definition process.cc:90
uint32_t armHwcapImpl() const override
AArch64 AT_HWCAP.
Definition process.cc:177
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition process.cc:126
IntType armHwcap2() const
Definition process.hh:74
IntType armHwcap() const
Definition process.hh:67
void argsInit(int pageSize, const RegId &spId)
Definition process.cc:348
loader::Arch arch
Definition process.hh:59
ArmProcess(const ProcessParams &params, loader::ObjectFile *objFile, loader::Arch _arch)
Definition process.cc:65
virtual std::string name() const
Definition named.hh:60
loader::MemoryImage image
Definition process.hh:236
uint64_t egid()
Definition process.hh:85
std::unique_ptr< SETranslatingPortProxy > initVirtMem
Definition process.hh:199
std::shared_ptr< MemState > memState
Definition process.hh:301
uint64_t pid()
Definition process.hh:86
uint64_t uid()
Definition process.hh:82
std::vector< std::string > argv
Definition process.hh:238
std::vector< ContextID > contextIds
Definition process.hh:176
System * system
Definition process.hh:179
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition process.cc:289
std::vector< std::string > envp
Definition process.hh:239
uint64_t gid()
Definition process.hh:84
Addr getStartPC()
Definition process.cc:537
Process(const ProcessParams &params, EmulationPageTable *pTable, loader::ObjectFile *obj_file)
Definition process.cc:113
loader::ObjectFile * objFile
Definition process.hh:235
Addr getBias()
Definition process.cc:529
uint64_t euid()
Definition process.hh:83
Register ID: describe an architectural register with its class and index.
Definition reg_class.hh:94
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
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:268
const Params & params() const
constexpr auto & Sp
Definition int.hh:274
constexpr RegId Sp0
Definition int.hh:233
constexpr auto & ArgumentReg0
Definition int.hh:650
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
constexpr auto & ArgumentReg2
Definition int.hh:652
constexpr auto & ArgumentReg1
Definition int.hh:651
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 33 > id
@ MISCREG_ID_AA64PFR0_EL1
Definition misc.hh:591
@ MISCREG_FPEXC
Definition misc.hh:93
@ MISCREG_ID_AA64ZFR0_EL1
Definition misc.hh:1139
@ MISCREG_CPACR
Definition misc.hh:259
@ MISCREG_ID_AA64ISAR1_EL1
Definition misc.hh:598
@ MISCREG_CPSR
Definition misc.hh:79
@ MISCREG_CPACR_EL1
Definition misc.hh:614
@ MISCREG_ID_AA64MMFR2_EL1
Definition misc.hh:906
@ MISCREG_ID_AA64ISAR0_EL1
Definition misc.hh:597
@ MISCREG_ID_AA64SMFR0_EL1
Definition misc.hh:1146
@ MISCREG_ID_AA64PFR1_EL1
Definition misc.hh:592
const Addr PageBytes
Definition page_size.hh:53
Bitfield< 4 > pc
Bitfield< 15 > system
Definition misc.hh:1032
Copyright (c) 2024 Arm Limited 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 htole(T value)
Definition byteswap.hh:172
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.

Generated on Mon May 26 2025 09:19:13 for gem5 by doxygen 1.13.2