master
c 96 lines 2.84 KB
Raw
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 #include "qemu/osdep.h"
4 #include "qemu.h"
5 #include "loader.h"
6 #include "elf.h"
7 #include "target_elf.h"
8
9
10 void elf_core_copy_regs(target_elf_gregset_t *r, const CPUArchState *env)
11 {
12 CPUSPARCState *e = (CPUSPARCState *)env;
13 int i;
14
15 memset(r, 0, sizeof(*r));
16
17 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
18 /* Linux kernel layout for sparc64 (arch/sparc/include/asm/elf_64.h):
19 * [0..7] G0-G7
20 * [8..15] O0-O7
21 * [16..23] L0-L7
22 * [24..31] I0-I7
23 * [32] TSTATE
24 * [33] TPC
25 * [34] TNPC
26 * [35] Y
27 */
28 for (i = 0; i < 8; i++) {
29 r->regs[i] = tswap64(env->gregs[i]);
30 r->regs[8 + i] = tswap64(env->regwptr[WREG_O0 + i]);
31 r->regs[16 + i] = tswap64(env->regwptr[WREG_L0 + i]);
32 r->regs[24 + i] = tswap64(env->regwptr[WREG_I0 + i]);
33 }
34 r->regs[32] = tswap64(sparc64_tstate(e));
35 r->regs[33] = tswap64(env->pc);
36 r->regs[34] = tswap64(env->npc);
37 r->regs[35] = tswap64(env->y);
38 #else
39 /* Linux kernel layout for sparc32 (arch/sparc/include/asm/elf_32.h):
40 * [0] PSR
41 * [1] PC
42 * [2] NPC
43 * [3] Y
44 * [4..11] G0-G7
45 * [12..19] O0-O7
46 * [20..27] L0-L7
47 * [28..35] I0-I7
48 * [36..37] reserved (stack_check)
49 */
50 r->regs[0] = tswap32(cpu_get_psr(e));
51 r->regs[1] = tswap32(env->pc);
52 r->regs[2] = tswap32(env->npc);
53 r->regs[3] = tswap32(env->y);
54 for (i = 0; i < 8; i++) {
55 r->regs[4 + i] = tswap32(env->gregs[i]);
56 r->regs[12 + i] = tswap32(env->regwptr[WREG_O0 + i]);
57 r->regs[20 + i] = tswap32(env->regwptr[WREG_L0 + i]);
58 r->regs[28 + i] = tswap32(env->regwptr[WREG_I0 + i]);
59 }
60 #endif
61 }
62
63 const char *get_elf_cpu_model(uint32_t eflags)
64 {
65 #ifdef TARGET_SPARC64
66 return "TI UltraSparc II";
67 #else
68 return "Fujitsu MB86904";
69 #endif
70 }
71
72 abi_ulong get_elf_hwcap(CPUState *cs)
73 {
74 /* There are not many sparc32 hwcap bits -- we have all of them. */
75 uint32_t r = HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR |
76 HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV;
77
78 #ifdef TARGET_SPARC64
79 CPUSPARCState *env = cpu_env(cs);
80 uint32_t features = env->def.features;
81
82 r |= HWCAP_SPARC_V9 | HWCAP_SPARC_V8PLUS;
83 /* 32x32 multiply and divide are efficient. */
84 r |= HWCAP_SPARC_MUL32 | HWCAP_SPARC_DIV32;
85 /* We don't have an internal feature bit for this. */
86 r |= HWCAP_SPARC_POPC;
87 r |= features & CPU_FEATURE_FSMULD ? HWCAP_SPARC_FSMULD : 0;
88 r |= features & CPU_FEATURE_VIS1 ? HWCAP_SPARC_VIS : 0;
89 r |= features & CPU_FEATURE_VIS2 ? HWCAP_SPARC_VIS2 : 0;
90 r |= features & CPU_FEATURE_FMAF ? HWCAP_SPARC_FMAF : 0;
91 r |= features & CPU_FEATURE_VIS3 ? HWCAP_SPARC_VIS3 : 0;
92 r |= features & CPU_FEATURE_IMA ? HWCAP_SPARC_IMA : 0;
93 #endif
94
95 return r;
96 }