gem5  [DEVELOP-FOR-23.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) 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 
60 namespace gem5
61 {
62 
63 using namespace ArmISA;
64 
65 ArmProcess::ArmProcess(const ProcessParams &params,
66  loader::ObjectFile *objFile, loader::Arch _arch)
67  : Process(params,
68  new EmulationPageTable(params.name, params.pid, PageBytes),
69  objFile),
70  arch(_arch)
71 {
72  fatal_if(params.useArchPT, "Arch page tables not implemented.");
73 }
74 
75 ArmProcess32::ArmProcess32(const ProcessParams &params,
76  loader::ObjectFile *objFile, loader::Arch _arch)
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 
106 void
108 {
110  argsInit<uint32_t>(PageBytes, int_reg::Sp);
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 
125 void
127 {
129  argsInit<uint64_t>(PageBytes, int_reg::Sp0);
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 
149 uint32_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_ThumbEE | Arm_Neon |
173  Arm_Vfpv3 | Arm_Vfpv3d16;
174 }
175 
176 uint32_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 
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 
264 uint64_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 
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  return hwcap;
332 }
333 
334 template <class IntType>
335 void
336 ArmProcess::argsInit(int pageSize, const RegId &spId)
337 {
338  int intSize = sizeof(IntType);
339 
341 
342  std::string filename;
343  if (argv.size() < 1)
344  filename = "";
345  else
346  filename = argv[0];
347 
348  //We want 16 byte alignment
349  uint64_t align = 16;
350 
351  //Setup the auxilliary vectors. These will already have endian conversion.
352  //Auxilliary vectors are loaded only for elf formatted executables.
353  auto *elfObject = dynamic_cast<loader::ElfObject *>(objFile);
354  if (elfObject) {
355 
356  if (objFile->getOpSys() == loader::Linux) {
357  //Bits which describe the system hardware capabilities
358  //XXX Figure out what these should be
359  auxv.emplace_back(gem5::auxv::Hwcap, armHwcap<IntType>());
360  auxv.emplace_back(gem5::auxv::Hwcap2, armHwcap2<IntType>());
361  //Frequency at which times() increments
362  auxv.emplace_back(gem5::auxv::Clktck, 0x64);
363  //Whether to enable "secure mode" in the executable
364  auxv.emplace_back(gem5::auxv::Secure, 0);
365  // Pointer to 16 bytes of random data
366  auxv.emplace_back(gem5::auxv::Random, 0);
367  //The filename of the program
368  auxv.emplace_back(gem5::auxv::Execfn, 0);
369  //The string "v71" -- ARM v7 architecture
370  auxv.emplace_back(gem5::auxv::Platform, 0);
371  }
372 
373  //The system page size
374  auxv.emplace_back(gem5::auxv::Pagesz, ArmISA::PageBytes);
375  // For statically linked executables, this is the virtual address of
376  // the program header tables if they appear in the executable image
377  auxv.emplace_back(gem5::auxv::Phdr, elfObject->programHeaderTable());
378  // This is the size of a program header entry from the elf file.
379  auxv.emplace_back(gem5::auxv::Phent, elfObject->programHeaderSize());
380  // This is the number of program headers from the original elf file.
381  auxv.emplace_back(gem5::auxv::Phnum, elfObject->programHeaderCount());
382  // This is the base address of the ELF interpreter; it should be
383  // zero for static executables or contain the base address for
384  // dynamic executables.
385  auxv.emplace_back(gem5::auxv::Base, getBias());
386  //XXX Figure out what this should be.
387  auxv.emplace_back(gem5::auxv::Flags, 0);
388  //The entry point to the program
389  auxv.emplace_back(gem5::auxv::Entry, objFile->entryPoint());
390  //Different user and group IDs
391  auxv.emplace_back(gem5::auxv::Uid, uid());
392  auxv.emplace_back(gem5::auxv::Euid, euid());
393  auxv.emplace_back(gem5::auxv::Gid, gid());
394  auxv.emplace_back(gem5::auxv::Egid, egid());
395  }
396 
397  //Figure out how big the initial stack nedes to be
398 
399  // A sentry NULL void pointer at the top of the stack.
400  int sentry_size = intSize;
401 
402  std::string platform = "v71";
403  int platform_size = platform.size() + 1;
404 
405  // Bytes for AT_RANDOM above, we'll just keep them 0
406  int aux_random_size = 16; // as per the specification
407 
408  // The aux vectors are put on the stack in two groups. The first group are
409  // the vectors that are generated as the elf is loaded. The second group
410  // are the ones that were computed ahead of time and include the platform
411  // string.
412  int aux_data_size = filename.size() + 1;
413 
414  int env_data_size = 0;
415  for (int i = 0; i < envp.size(); ++i) {
416  env_data_size += envp[i].size() + 1;
417  }
418  int arg_data_size = 0;
419  for (int i = 0; i < argv.size(); ++i) {
420  arg_data_size += argv[i].size() + 1;
421  }
422 
423  int info_block_size =
424  sentry_size + env_data_size + arg_data_size +
425  aux_data_size + platform_size + aux_random_size;
426 
427  //Each auxilliary vector is two 4 byte words
428  int aux_array_size = intSize * 2 * (auxv.size() + 1);
429 
430  int envp_array_size = intSize * (envp.size() + 1);
431  int argv_array_size = intSize * (argv.size() + 1);
432 
433  int argc_size = intSize;
434 
435  //Figure out the size of the contents of the actual initial frame
436  int frame_size =
437  info_block_size +
438  aux_array_size +
439  envp_array_size +
440  argv_array_size +
441  argc_size;
442 
443  //There needs to be padding after the auxiliary vector data so that the
444  //very bottom of the stack is aligned properly.
445  int partial_size = frame_size;
446  int aligned_partial_size = roundUp(partial_size, align);
447  int aux_padding = aligned_partial_size - partial_size;
448 
449  int space_needed = frame_size + aux_padding;
450 
451  memState->setStackMin(memState->getStackBase() - space_needed);
452  memState->setStackMin(roundDown(memState->getStackMin(), align));
453  memState->setStackSize(memState->getStackBase() - memState->getStackMin());
454 
455  // map memory
456  memState->mapRegion(roundDown(memState->getStackMin(), pageSize),
457  roundUp(memState->getStackSize(), pageSize), "stack");
458 
459  // map out initial stack contents
460  IntType sentry_base = memState->getStackBase() - sentry_size;
461  IntType aux_data_base = sentry_base - aux_data_size;
462  IntType env_data_base = aux_data_base - env_data_size;
463  IntType arg_data_base = env_data_base - arg_data_size;
464  IntType platform_base = arg_data_base - platform_size;
465  IntType aux_random_base = platform_base - aux_random_size;
466  IntType auxv_array_base = aux_random_base - aux_array_size - aux_padding;
467  IntType envp_array_base = auxv_array_base - envp_array_size;
468  IntType argv_array_base = envp_array_base - argv_array_size;
469  IntType argc_base = argv_array_base - argc_size;
470 
471  DPRINTF(Stack, "The addresses of items on the initial stack:\n");
472  DPRINTF(Stack, "0x%x - aux data\n", aux_data_base);
473  DPRINTF(Stack, "0x%x - env data\n", env_data_base);
474  DPRINTF(Stack, "0x%x - arg data\n", arg_data_base);
475  DPRINTF(Stack, "0x%x - random data\n", aux_random_base);
476  DPRINTF(Stack, "0x%x - platform base\n", platform_base);
477  DPRINTF(Stack, "0x%x - auxv array\n", auxv_array_base);
478  DPRINTF(Stack, "0x%x - envp array\n", envp_array_base);
479  DPRINTF(Stack, "0x%x - argv array\n", argv_array_base);
480  DPRINTF(Stack, "0x%x - argc \n", argc_base);
481  DPRINTF(Stack, "0x%x - stack min\n", memState->getStackMin());
482 
483  // write contents to stack
484 
485  // figure out argc
486  IntType argc = argv.size();
487  IntType guestArgc = htole(argc);
488 
489  //Write out the sentry void *
490  IntType sentry_NULL = 0;
491  initVirtMem->writeBlob(sentry_base, &sentry_NULL, sentry_size);
492 
493  //Fix up the aux vectors which point to other data
494  for (int i = auxv.size() - 1; i >= 0; i--) {
495  if (auxv[i].type == gem5::auxv::Platform) {
496  auxv[i].val = platform_base;
497  initVirtMem->writeString(platform_base, platform.c_str());
498  } else if (auxv[i].type == gem5::auxv::Execfn) {
499  auxv[i].val = aux_data_base;
500  initVirtMem->writeString(aux_data_base, filename.c_str());
501  } else if (auxv[i].type == gem5::auxv::Random) {
502  auxv[i].val = aux_random_base;
503  // Just leave the value 0, we don't want randomness
504  }
505  }
506 
507  //Copy the aux stuff
508  Addr auxv_array_end = auxv_array_base;
509  for (const auto &aux: auxv) {
510  initVirtMem->write(auxv_array_end, aux, ByteOrder::little);
511  auxv_array_end += sizeof(aux);
512  }
513  //Write out the terminating zeroed auxillary vector
514  const gem5::auxv::AuxVector<IntType> zero(0, 0);
515  initVirtMem->write(auxv_array_end, zero);
516  auxv_array_end += sizeof(zero);
517 
518  copyStringArray(envp, envp_array_base, env_data_base,
519  ByteOrder::little, *initVirtMem);
520  copyStringArray(argv, argv_array_base, arg_data_base,
521  ByteOrder::little, *initVirtMem);
522 
523  initVirtMem->writeBlob(argc_base, &guestArgc, intSize);
524 
526  //Set the stack pointer register
527  tc->setReg(spId, memState->getStackMin());
528  //A pointer to a function to run when the program exits. We'll set this
529  //to zero explicitly to make sure this isn't used.
530  tc->setReg(ArgumentReg0, (RegVal)0);
531  //Set argument regs 1 and 2 to argv[0] and envp[0] respectively
532  if (argv.size() > 0) {
533  tc->setReg(ArgumentReg1, arg_data_base + arg_data_size -
534  argv[argv.size() - 1].size() - 1);
535  } else {
536  tc->setReg(ArgumentReg1, (RegVal)0);
537  }
538  if (envp.size() > 0) {
539  tc->setReg(ArgumentReg2, env_data_base + env_data_size -
540  envp[envp.size() - 1].size() - 1);
541  } else {
542  tc->setReg(ArgumentReg2, (RegVal)0);
543  }
544 
545  PCState pc;
546  pc.thumb(arch == loader::Thumb);
547  pc.nextThumb(pc.thumb());
548  pc.aarch64(arch == loader::Arm64);
549  pc.nextAArch64(pc.aarch64());
550  pc.set(getStartPC() & ~mask(1));
551  tc->pcState(pc);
552 
553  //Align the "stackMin" to a page boundary.
554  memState->setStackMin(roundDown(memState->getStackMin(), pageSize));
555 }
556 
557 } // namespace gem5
gem5::ArmISA::MISCREG_CPSR
@ MISCREG_CPSR
Definition: misc.hh:66
gem5::loader::MemoryImage::maxAddr
Addr maxAddr() const
Definition: memory_image.hh:135
gem5::auxv::Platform
@ Platform
Definition: aux_vector.hh:82
gem5::Process::euid
uint64_t euid()
Definition: process.hh:83
gem5::ArmProcess::ArmProcess
ArmProcess(const ProcessParams &params, loader::ObjectFile *objFile, loader::Arch _arch)
Definition: process.cc:65
gem5::ThreadContext::readMiscReg
virtual RegVal readMiscReg(RegIndex misc_reg)=0
gem5::ArmISA::ArgumentReg0
constexpr auto & ArgumentReg0
Definition: int.hh:650
gem5::EmulationPageTable
Definition: page_table.hh:53
gem5::loader::ObjectFile
Definition: object_file.hh:96
gem5::auxv::Gid
@ Gid
Definition: aux_vector.hh:80
gem5::RegVal
uint64_t RegVal
Definition: types.hh:173
system.hh
gem5::ArmISA::int_reg::Sp0
constexpr RegId Sp0
Definition: int.hh:233
gem5::X86ISA::L
Bitfield< 7, 0 > L
Definition: int.hh:62
gem5::Process::getStartPC
Addr getStartPC()
Definition: process.cc:497
gem5::Process::initVirtMem
std::unique_ptr< SETranslatingPortProxy > initVirtMem
Definition: process.hh:187
gem5::loader::ObjectFile::entryPoint
Addr entryPoint() const
Definition: object_file.hh:136
gem5::ArmISA::ArgumentReg2
constexpr auto & ArgumentReg2
Definition: int.hh:652
gem5::auxv::Random
@ Random
Definition: aux_vector.hh:87
gem5::Process::getBias
Addr getBias()
Definition: process.cc:489
gem5::auxv::Hwcap
@ Hwcap
Definition: aux_vector.hh:83
gem5::ThreadContext::pcState
virtual const PCStateBase & pcState() const =0
gem5::loader::ElfObject
Definition: elf_object.hh:63
gem5::Process::initState
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition: process.cc:288
process_impl.hh
gem5::Process::egid
uint64_t egid()
Definition: process.hh:85
std::vector
STL vector class.
Definition: stl.hh:37
gem5::ArmProcess64::armHwcapImpl
uint32_t armHwcapImpl() const override
AArch64 AT_HWCAP.
Definition: process.cc:177
gem5::auxv::Phent
@ Phent
Definition: aux_vector.hh:71
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:67
types.hh
gem5::Process::gid
uint64_t gid()
Definition: process.hh:84
gem5::PowerISA::PCState
Definition: pcstate.hh:42
cc.hh
gem5::Process::memState
std::shared_ptr< MemState > memState
Definition: process.hh:289
sc_dt::align
void align(const scfx_rep &lhs, const scfx_rep &rhs, int &new_wp, int &len_mant, scfx_mant_ref &lhs_mant, scfx_mant_ref &rhs_mant)
Definition: scfx_rep.cc:2083
gem5::loader::Arm64
@ Arm64
Definition: object_file.hh:69
gem5::mask
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
Definition: bitfield.hh:63
gem5::Process::uid
uint64_t uid()
Definition: process.hh:82
gem5::auxv::Base
@ Base
Definition: aux_vector.hh:74
gem5::auxv::Pagesz
@ Pagesz
Definition: aux_vector.hh:73
elf_object.hh
gem5::ArmProcess64::armHwcapImpl2
uint64_t armHwcapImpl2() const override
Definition: process.cc:265
syscall_return.hh
gem5::auxv::Secure
@ Secure
Definition: aux_vector.hh:85
gem5::ArmISA::int_reg::Sp
constexpr auto & Sp
Definition: int.hh:274
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
gem5::ArmISA::MISCREG_ID_AA64MMFR2_EL1
@ MISCREG_ID_AA64MMFR2_EL1
Definition: misc.hh:844
gem5::ArmProcess32::armHwcapImpl
uint32_t armHwcapImpl() const override
AArch32 AT_HWCAP.
Definition: process.cc:150
gem5::SimObject::params
const Params & params() const
Definition: sim_object.hh:176
gem5::auxv::Clktck
@ Clktck
Definition: aux_vector.hh:84
gem5::VegaISA::PageBytes
const Addr PageBytes
Definition: page_size.hh:42
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:210
gem5::ArmISA::MISCREG_FPEXC
@ MISCREG_FPEXC
Definition: misc.hh:80
gem5::ArmProcess
Definition: process.hh:56
gem5::copyStringArray
void copyStringArray(std::vector< std::string > &strings, AddrType array_ptr, AddrType data_ptr, const ByteOrder bo, PortProxy &memProxy)
Definition: process_impl.hh:43
gem5::X86ISA::type
type
Definition: misc.hh:734
gem5::auxv::AuxVector
Definition: aux_vector.hh:43
gem5::auxv::Phdr
@ Phdr
Definition: aux_vector.hh:70
gem5::ArmProcess64::initState
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition: process.cc:126
gem5::ArmISA::MISCREG_CPACR_EL1
@ MISCREG_CPACR_EL1
Definition: misc.hh:587
gem5::Process::argv
std::vector< std::string > argv
Definition: process.hh:226
gem5::ArmProcess::arch
loader::Arch arch
Definition: process.hh:59
gem5::loader::Arch
Arch
Definition: object_file.hh:61
gem5::roundDown
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
Definition: intmath.hh:279
gem5::loader::ObjectFile::getOpSys
OpSys getOpSys() const
Definition: object_file.hh:127
gem5::auxv::Egid
@ Egid
Definition: aux_vector.hh:81
gem5::auxv::Entry
@ Entry
Definition: aux_vector.hh:76
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::Process::envp
std::vector< std::string > envp
Definition: process.hh:227
gem5::auxv::Phnum
@ Phnum
Definition: aux_vector.hh:72
name
const std::string & name()
Definition: trace.cc:48
gem5::ArmISA::MISCREG_ID_AA64ISAR1_EL1
@ MISCREG_ID_AA64ISAR1_EL1
Definition: misc.hh:573
gem5::ArmISA::MISCREG_ID_AA64ZFR0_EL1
@ MISCREG_ID_AA64ZFR0_EL1
Definition: misc.hh:1076
gem5::Process
Definition: process.hh:67
gem5::auxv::Execfn
@ Execfn
Definition: aux_vector.hh:89
gem5::loader::Thumb
@ Thumb
Definition: object_file.hh:71
gem5::ArmProcess::argsInit
void argsInit(int pageSize, const RegId &spId)
Definition: process.cc:336
gem5::auxv::Hwcap2
@ Hwcap2
Definition: aux_vector.hh:88
aux_vector.hh
gem5::ArmISA::MODE_EL0T
@ MODE_EL0T
Definition: types.hh:281
gem5::System::threads
Threads threads
Definition: system.hh:310
misc.hh
gem5::ThreadContext::setMiscReg
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
gem5::MipsISA::pc
Bitfield< 4 > pc
Definition: pra_constants.hh:243
gem5::htole
T htole(T value)
Definition: byteswap.hh:172
gem5::auxv::Uid
@ Uid
Definition: aux_vector.hh:78
gem5::ArmISA::PageBytes
const Addr PageBytes
Definition: page_size.hh:53
gem5::roundUp
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
Definition: intmath.hh:260
logging.hh
gem5::Process::system
System * system
Definition: process.hh:173
gem5::ArmISA::id
Bitfield< 33 > id
Definition: misc_types.hh:305
gem5::auxv::Euid
@ Euid
Definition: aux_vector.hh:79
gem5::Process::contextIds
std::vector< ContextID > contextIds
Definition: process.hh:170
page_size.hh
gem5::ArmProcess32::initState
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition: process.cc:107
fatal_if
#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
page_table.hh
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::ArmISA::MISCREG_ID_AA64PFR0_EL1
@ MISCREG_ID_AA64PFR0_EL1
Definition: misc.hh:566
process.hh
gem5::auxv::Flags
@ Flags
Definition: aux_vector.hh:75
object_file.hh
gem5::ArmISA::MISCREG_CPACR
@ MISCREG_CPACR
Definition: misc.hh:246
gem5::ArmProcess64::ArmProcess64
ArmProcess64(const ProcessParams &params, loader::ObjectFile *objFile, loader::Arch _arch)
Definition: process.cc:90
gem5::ArmProcess32::ArmProcess32
ArmProcess32(const ProcessParams &params, loader::ObjectFile *objFile, loader::Arch _arch)
Definition: process.cc:75
gem5::Process::image
loader::MemoryImage image
Definition: process.hh:224
thread_context.hh
gem5::Process::objFile
loader::ObjectFile * objFile
Definition: process.hh:223
gem5::ArmISA::MISCREG_ID_AA64ISAR0_EL1
@ MISCREG_ID_AA64ISAR0_EL1
Definition: misc.hh:572
gem5::loader::Linux
@ Linux
Definition: object_file.hh:84
byteswap.hh
gem5::RegId
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:92
gem5::ArmISA::ArgumentReg1
constexpr auto & ArgumentReg1
Definition: int.hh:651
gem5::ThreadContext::setReg
virtual void setReg(const RegId &reg, RegVal val)
Definition: thread_context.cc:188

Generated on Sun Jul 30 2023 01:56:49 for gem5 by doxygen 1.8.17