51#include "debug/Stack.hh"
53#include "params/Process.hh"
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;
85 memState = std::make_shared<MemState>(
86 this, brk_point, stack_base, max_stack_size,
87 next_thread_stack_base, mmap_end);
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;
101 memState = std::make_shared<MemState>(
102 this, brk_point, stack_base, max_stack_size,
103 next_thread_stack_base, mmap_end);
158 Arm_FastMult = 1 << 4,
164 Arm_Crunch = 1 << 10,
165 Arm_ThumbEE = 1 << 11,
168 Arm_Vfpv3d16 = 1 << 14
171 return Arm_Swp | Arm_Half | Arm_Thumb | Arm_FastMult |
172 Arm_Vfp | Arm_Edsp | Arm_Neon |
173 Arm_Vfpv3 | Arm_Vfpv3d16;
185 Arm_Evtstrm = 1 << 2,
191 Arm_Atomics = 1 << 8,
193 Arm_Asimdhp = 1 << 10,
195 Arm_Asimdrdm = 1 << 12,
203 Arm_Asimddp = 1 << 20,
204 Arm_Sha512 = 1 << 21,
206 Arm_Asimdfhm = 1 << 23,
209 Arm_Ilrcpc = 1 << 26,
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;
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;
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;
259 hwcap |= (mm_fr2.at >= 1) ? Arm_Uscat : 0;
267 enum ArmCpuFeature : uint64_t
270 Arm_Dcpodp = 1ULL << 0,
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
320 hwcap |= (isa_r0.ts >= 2) ? Arm_Flagm2 : Arm_None;
321 hwcap |= (isa_r0.rndr >= 1) ? Arm_Rng : Arm_None;
324 hwcap |= (isa_r1.i8mm >= 1) ? Arm_I8mm : Arm_None;
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;
332 hwcap |= (pf_r1.sme == 1) ? Arm_Sme : Arm_None;
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;
346template <
class IntType>
350 int intSize =
sizeof(IntType);
354 std::string filename;
412 int sentry_size = intSize;
414 std::string platform =
"v71";
415 int platform_size = platform.size() + 1;
418 int aux_random_size = 16;
424 int aux_data_size = filename.size() + 1;
426 int env_data_size = 0;
427 for (
int i = 0;
i <
envp.size(); ++
i) {
428 env_data_size +=
envp[
i].size() + 1;
430 int arg_data_size = 0;
431 for (
int i = 0;
i <
argv.size(); ++
i) {
432 arg_data_size +=
argv[
i].size() + 1;
435 int info_block_size =
436 sentry_size + env_data_size + arg_data_size +
437 aux_data_size + platform_size + aux_random_size;
440 int aux_array_size = intSize * 2 * (
auxv.size() + 1);
442 int envp_array_size = intSize * (
envp.size() + 1);
443 int argv_array_size = intSize * (
argv.size() + 1);
445 int argc_size = intSize;
457 int partial_size = frame_size;
458 int aligned_partial_size =
roundUp(partial_size, align);
459 int aux_padding = aligned_partial_size - partial_size;
461 int space_needed = frame_size + aux_padding;
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;
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);
498 IntType argc =
argv.size();
499 IntType guestArgc =
htole(argc);
502 IntType sentry_NULL = 0;
503 initVirtMem->writeBlob(sentry_base, &sentry_NULL, sentry_size);
506 for (
int i =
auxv.size() - 1;
i >= 0;
i--) {
508 auxv[
i].val = platform_base;
509 initVirtMem->writeString(platform_base, platform.c_str());
511 auxv[
i].val = aux_data_base;
512 initVirtMem->writeString(aux_data_base, filename.c_str());
514 auxv[
i].val = aux_random_base;
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);
528 auxv_array_end +=
sizeof(zero);
535 initVirtMem->writeBlob(argc_base, &guestArgc, intSize);
544 if (
argv.size() > 0) {
550 if (
envp.size() > 0) {
559 pc.nextThumb(
pc.thumb());
561 pc.nextAArch64(
pc.aarch64());
ArmProcess32(const ProcessParams ¶ms, loader::ObjectFile *objFile, loader::Arch _arch)
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
uint32_t armHwcapImpl() const override
AArch32 AT_HWCAP.
uint64_t armHwcapImpl2() const override
ArmProcess64(const ProcessParams ¶ms, loader::ObjectFile *objFile, loader::Arch _arch)
uint32_t armHwcapImpl() const override
AArch64 AT_HWCAP.
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
IntType armHwcap2() const
void argsInit(int pageSize, const RegId &spId)
ArmProcess(const ProcessParams ¶ms, loader::ObjectFile *objFile, loader::Arch _arch)
virtual std::string name() const
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
Process(const ProcessParams ¶ms, EmulationPageTable *pTable, loader::ObjectFile *obj_file)
loader::ObjectFile * objFile
Register ID: describe an architectural register with its class and index.
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 ®, 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.
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 & ArgumentReg0
constexpr auto & ArgumentReg2
constexpr auto & ArgumentReg1
@ MISCREG_ID_AA64PFR0_EL1
@ MISCREG_ID_AA64ZFR0_EL1
@ MISCREG_ID_AA64ISAR1_EL1
@ MISCREG_ID_AA64MMFR2_EL1
@ MISCREG_ID_AA64ISAR0_EL1
@ MISCREG_ID_AA64SMFR0_EL1
@ MISCREG_ID_AA64PFR1_EL1
Copyright (c) 2024 Arm Limited All rights reserved.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
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.