master
c 100 lines 2.79 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 "target_elf.h"
7
8
9 const char *get_elf_cpu_model(uint32_t eflags)
10 {
11 return "la464";
12 }
13
14 /* See arch/loongarch/include/uapi/asm/hwcap.h */
15 enum {
16 HWCAP_LOONGARCH_CPUCFG = (1 << 0),
17 HWCAP_LOONGARCH_LAM = (1 << 1),
18 HWCAP_LOONGARCH_UAL = (1 << 2),
19 HWCAP_LOONGARCH_FPU = (1 << 3),
20 HWCAP_LOONGARCH_LSX = (1 << 4),
21 HWCAP_LOONGARCH_LASX = (1 << 5),
22 HWCAP_LOONGARCH_CRC32 = (1 << 6),
23 HWCAP_LOONGARCH_COMPLEX = (1 << 7),
24 HWCAP_LOONGARCH_CRYPTO = (1 << 8),
25 HWCAP_LOONGARCH_LVZ = (1 << 9),
26 HWCAP_LOONGARCH_LBT_X86 = (1 << 10),
27 HWCAP_LOONGARCH_LBT_ARM = (1 << 11),
28 HWCAP_LOONGARCH_LBT_MIPS = (1 << 12),
29 };
30
31 const char *elf_hwcap_str(uint32_t bit)
32 {
33 static const char *hwcap_str[] = {
34 [__builtin_ctz(HWCAP_LOONGARCH_CPUCFG )] = "cpucfg",
35 [__builtin_ctz(HWCAP_LOONGARCH_LAM )] = "lam",
36 [__builtin_ctz(HWCAP_LOONGARCH_UAL )] = "lam_bh",
37 [__builtin_ctz(HWCAP_LOONGARCH_FPU )] = "fpu",
38 [__builtin_ctz(HWCAP_LOONGARCH_LSX )] = "lsx",
39 [__builtin_ctz(HWCAP_LOONGARCH_LASX )] = "lasx",
40 [__builtin_ctz(HWCAP_LOONGARCH_CRC32 )] = "crc32",
41 [__builtin_ctz(HWCAP_LOONGARCH_COMPLEX )] = "complex",
42 [__builtin_ctz(HWCAP_LOONGARCH_CRYPTO )] = "crypto",
43 [__builtin_ctz(HWCAP_LOONGARCH_LVZ )] = "lvz",
44 [__builtin_ctz(HWCAP_LOONGARCH_LBT_X86 )] = "lbt_x86",
45 [__builtin_ctz(HWCAP_LOONGARCH_LBT_ARM )] = "lbt_arm",
46 [__builtin_ctz(HWCAP_LOONGARCH_LBT_MIPS)] = "lbt_mips",
47 };
48
49 return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
50 }
51 abi_ulong get_elf_hwcap(CPUState *cs)
52 {
53 LoongArchCPU *cpu = LOONGARCH_CPU(cs);
54 abi_ulong hwcaps = 0;
55
56 hwcaps |= HWCAP_LOONGARCH_CRC32;
57
58 if (FIELD_EX32(cpu->env.cpucfg[1], CPUCFG1, UAL)) {
59 hwcaps |= HWCAP_LOONGARCH_UAL;
60 }
61
62 if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, FP)) {
63 hwcaps |= HWCAP_LOONGARCH_FPU;
64 }
65
66 if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LAM)) {
67 hwcaps |= HWCAP_LOONGARCH_LAM;
68 }
69
70 if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LSX)) {
71 hwcaps |= HWCAP_LOONGARCH_LSX;
72 }
73
74 if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LASX)) {
75 hwcaps |= HWCAP_LOONGARCH_LASX;
76 }
77
78 return hwcaps;
79 }
80
81 const char *get_elf_platform(CPUState *cs)
82 {
83 return "loongarch";
84 }
85
86 #define tswapreg(ptr) tswapal(ptr)
87
88 void elf_core_copy_regs(target_elf_gregset_t *r, const CPULoongArchState *env)
89 {
90 CPUSysState *sys = env_sys((CPULoongArchState *)env);
91
92 r->pt.regs[0] = 0;
93
94 for (int i = 1; i < ARRAY_SIZE(env->gpr); i++) {
95 r->pt.regs[i] = tswapreg(env->gpr[i]);
96 }
97
98 r->pt.csr_era = tswapreg(env->pc);
99 r->pt.csr_badv = tswapreg(sys->CSR_BADV);
100 }