blob: 181f1e00b59cda93b5184b5d27a6b1a37788606b [file]
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "qemu/osdep.h"
#include "qemu.h"
#include "loader.h"
#include "elf.h"
#include "target_elf.h"
void elf_core_copy_regs(target_elf_gregset_t *r, const CPUArchState *env)
{
CPUSPARCState *e = (CPUSPARCState *)env;
int i;
memset(r, 0, sizeof(*r));
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
/* Linux kernel layout for sparc64 (arch/sparc/include/asm/elf_64.h):
* [0..7] G0-G7
* [8..15] O0-O7
* [16..23] L0-L7
* [24..31] I0-I7
* [32] TSTATE
* [33] TPC
* [34] TNPC
* [35] Y
*/
for (i = 0; i < 8; i++) {
r->regs[i] = tswap64(env->gregs[i]);
r->regs[8 + i] = tswap64(env->regwptr[WREG_O0 + i]);
r->regs[16 + i] = tswap64(env->regwptr[WREG_L0 + i]);
r->regs[24 + i] = tswap64(env->regwptr[WREG_I0 + i]);
}
r->regs[32] = tswap64(sparc64_tstate(e));
r->regs[33] = tswap64(env->pc);
r->regs[34] = tswap64(env->npc);
r->regs[35] = tswap64(env->y);
#else
/* Linux kernel layout for sparc32 (arch/sparc/include/asm/elf_32.h):
* [0] PSR
* [1] PC
* [2] NPC
* [3] Y
* [4..11] G0-G7
* [12..19] O0-O7
* [20..27] L0-L7
* [28..35] I0-I7
* [36..37] reserved (stack_check)
*/
r->regs[0] = tswap32(cpu_get_psr(e));
r->regs[1] = tswap32(env->pc);
r->regs[2] = tswap32(env->npc);
r->regs[3] = tswap32(env->y);
for (i = 0; i < 8; i++) {
r->regs[4 + i] = tswap32(env->gregs[i]);
r->regs[12 + i] = tswap32(env->regwptr[WREG_O0 + i]);
r->regs[20 + i] = tswap32(env->regwptr[WREG_L0 + i]);
r->regs[28 + i] = tswap32(env->regwptr[WREG_I0 + i]);
}
#endif
}
const char *get_elf_cpu_model(uint32_t eflags)
{
#ifdef TARGET_SPARC64
return "TI UltraSparc II";
#else
return "Fujitsu MB86904";
#endif
}
abi_ulong get_elf_hwcap(CPUState *cs)
{
/* There are not many sparc32 hwcap bits -- we have all of them. */
uint32_t r = HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR |
HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV;
#ifdef TARGET_SPARC64
CPUSPARCState *env = cpu_env(cs);
uint32_t features = env->def.features;
r |= HWCAP_SPARC_V9 | HWCAP_SPARC_V8PLUS;
/* 32x32 multiply and divide are efficient. */
r |= HWCAP_SPARC_MUL32 | HWCAP_SPARC_DIV32;
/* We don't have an internal feature bit for this. */
r |= HWCAP_SPARC_POPC;
r |= features & CPU_FEATURE_FSMULD ? HWCAP_SPARC_FSMULD : 0;
r |= features & CPU_FEATURE_VIS1 ? HWCAP_SPARC_VIS : 0;
r |= features & CPU_FEATURE_VIS2 ? HWCAP_SPARC_VIS2 : 0;
r |= features & CPU_FEATURE_FMAF ? HWCAP_SPARC_FMAF : 0;
r |= features & CPU_FEATURE_VIS3 ? HWCAP_SPARC_VIS3 : 0;
r |= features & CPU_FEATURE_IMA ? HWCAP_SPARC_IMA : 0;
#endif
return r;
}