1 /* Unicorn Emulator Engine */
2 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2015 */
3
4 #include "hw/boards.h"
5 #include "hw/arm/arm.h"
6 #include "sysemu/cpus.h"
7 #include "unicorn.h"
8 #include "cpu.h"
9 #include "unicorn_common.h"
10 #include "uc_priv.h"
11
12
13 const int ARM64_REGS_STORAGE_SIZE = offsetof(CPUARMState, tlb_table);
14
arm64_set_pc(struct uc_struct * uc,uint64_t address)15 static void arm64_set_pc(struct uc_struct *uc, uint64_t address)
16 {
17 ((CPUARMState *)uc->current_cpu->env_ptr)->pc = address;
18 }
19
20 void arm64_release(void* ctx);
21
arm64_release(void * ctx)22 void arm64_release(void* ctx)
23 {
24 struct uc_struct* uc;
25 ARMCPU* cpu;
26 TCGContext *s = (TCGContext *) ctx;
27
28 g_free(s->tb_ctx.tbs);
29 uc = s->uc;
30 cpu = (ARMCPU*) uc->cpu;
31 g_free(cpu->cpreg_indexes);
32 g_free(cpu->cpreg_values);
33 g_free(cpu->cpreg_vmstate_indexes);
34 g_free(cpu->cpreg_vmstate_values);
35
36 release_common(ctx);
37 }
38
arm64_reg_reset(struct uc_struct * uc)39 void arm64_reg_reset(struct uc_struct *uc)
40 {
41 CPUArchState *env = uc->cpu->env_ptr;
42 memset(env->xregs, 0, sizeof(env->xregs));
43
44 env->pc = 0;
45 }
46
arm64_reg_read(struct uc_struct * uc,unsigned int * regs,void ** vals,int count)47 int arm64_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int count)
48 {
49 CPUState *mycpu = uc->cpu;
50 int i;
51
52 for (i = 0; i < count; i++) {
53 unsigned int regid = regs[i];
54 void *value = vals[i];
55 // V & Q registers are the same
56 if (regid >= UC_ARM64_REG_V0 && regid <= UC_ARM64_REG_V31) {
57 regid += UC_ARM64_REG_Q0 - UC_ARM64_REG_V0;
58 }
59 if (regid >= UC_ARM64_REG_X0 && regid <= UC_ARM64_REG_X28) {
60 *(int64_t *)value = ARM_CPU(uc, mycpu)->env.xregs[regid - UC_ARM64_REG_X0];
61 } else if (regid >= UC_ARM64_REG_W0 && regid <= UC_ARM64_REG_W30) {
62 *(int32_t *)value = READ_DWORD(ARM_CPU(uc, mycpu)->env.xregs[regid - UC_ARM64_REG_W0]);
63 } else if (regid >= UC_ARM64_REG_Q0 && regid <= UC_ARM64_REG_Q31) {
64 float64 *dst = (float64*) value;
65 uint32_t reg_index = 2*(regid - UC_ARM64_REG_Q0);
66 dst[0] = ARM_CPU(uc, mycpu)->env.vfp.regs[reg_index];
67 dst[1] = ARM_CPU(uc, mycpu)->env.vfp.regs[reg_index+1];
68 } else if (regid >= UC_ARM64_REG_D0 && regid <= UC_ARM64_REG_D31) {
69 *(float64*)value = ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_D0)];
70 } else if (regid >= UC_ARM64_REG_S0 && regid <= UC_ARM64_REG_S31) {
71 *(int32_t*)value = READ_DWORD(ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_S0)]);
72 } else if (regid >= UC_ARM64_REG_H0 && regid <= UC_ARM64_REG_H31) {
73 *(int16_t*)value = READ_WORD(ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_H0)]);
74 } else if (regid >= UC_ARM64_REG_B0 && regid <= UC_ARM64_REG_B31) {
75 *(int8_t*)value = READ_BYTE_L(ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_B0)]);
76 } else if (regid >= UC_ARM64_REG_ELR_EL0 && regid <= UC_ARM64_REG_ELR_EL3) {
77 *(uint64_t*)value = ARM_CPU(uc, mycpu)->env.elr_el[regid - UC_ARM64_REG_ELR_EL0];
78 } else if (regid >= UC_ARM64_REG_SP_EL0 && regid <= UC_ARM64_REG_SP_EL3) {
79 *(uint64_t*)value = ARM_CPU(uc, mycpu)->env.sp_el[regid - UC_ARM64_REG_SP_EL0];
80 } else if (regid >= UC_ARM64_REG_ESR_EL0 && regid <= UC_ARM64_REG_ESR_EL3) {
81 *(uint64_t*)value = ARM_CPU(uc, mycpu)->env.cp15.esr_el[regid - UC_ARM64_REG_ESR_EL0];
82 } else if (regid >= UC_ARM64_REG_FAR_EL0 && regid <= UC_ARM64_REG_FAR_EL3) {
83 *(uint64_t*)value = ARM_CPU(uc, mycpu)->env.cp15.far_el[regid - UC_ARM64_REG_FAR_EL0];
84 } else if (regid >= UC_ARM64_REG_VBAR_EL0 && regid <= UC_ARM64_REG_VBAR_EL3) {
85 *(uint64_t*)value = ARM_CPU(uc, mycpu)->env.cp15.vbar_el[regid - UC_ARM64_REG_VBAR_EL0];
86 } else {
87 switch(regid) {
88 default: break;
89 case UC_ARM64_REG_CPACR_EL1:
90 *(uint32_t *)value = ARM_CPU(uc, mycpu)->env.cp15.c1_coproc;
91 break;
92 case UC_ARM64_REG_TPIDR_EL0:
93 *(int64_t *)value = ARM_CPU(uc, mycpu)->env.cp15.tpidr_el0;
94 break;
95 case UC_ARM64_REG_TPIDRRO_EL0:
96 *(int64_t *)value = ARM_CPU(uc, mycpu)->env.cp15.tpidrro_el0;
97 break;
98 case UC_ARM64_REG_TPIDR_EL1:
99 *(int64_t *)value = ARM_CPU(uc, mycpu)->env.cp15.tpidr_el1;
100 break;
101 case UC_ARM64_REG_X29:
102 *(int64_t *)value = ARM_CPU(uc, mycpu)->env.xregs[29];
103 break;
104 case UC_ARM64_REG_X30:
105 *(int64_t *)value = ARM_CPU(uc, mycpu)->env.xregs[30];
106 break;
107 case UC_ARM64_REG_PC:
108 *(uint64_t *)value = ARM_CPU(uc, mycpu)->env.pc;
109 break;
110 case UC_ARM64_REG_SP:
111 *(int64_t *)value = ARM_CPU(uc, mycpu)->env.xregs[31];
112 break;
113 case UC_ARM64_REG_NZCV:
114 *(int32_t *)value = cpsr_read(&ARM_CPU(uc, mycpu)->env) & CPSR_NZCV;
115 break;
116 case UC_ARM64_REG_PSTATE:
117 *(uint32_t *)value = pstate_read(&ARM_CPU(uc, mycpu)->env);
118 break;
119 case UC_ARM64_REG_TTBR0_EL1:
120 *(uint64_t *)value = ARM_CPU(uc, mycpu)->env.cp15.ttbr0_el1;
121 break;
122 case UC_ARM64_REG_TTBR1_EL1:
123 *(uint64_t *)value = ARM_CPU(uc, mycpu)->env.cp15.ttbr1_el1;
124 break;
125 case UC_ARM64_REG_PAR_EL1:
126 *(uint64_t *)value = ARM_CPU(uc, mycpu)->env.cp15.par_el1;
127 break;
128 case UC_ARM64_REG_MAIR_EL1:
129 *(uint64_t *)value = ARM_CPU(uc, mycpu)->env.cp15.mair_el1;
130 break;
131 }
132 }
133 }
134
135 return 0;
136 }
137
arm64_reg_write(struct uc_struct * uc,unsigned int * regs,void * const * vals,int count)138 int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, int count)
139 {
140 CPUState *mycpu = uc->cpu;
141 int i;
142
143 for (i = 0; i < count; i++) {
144 unsigned int regid = regs[i];
145 const void *value = vals[i];
146 if (regid >= UC_ARM64_REG_V0 && regid <= UC_ARM64_REG_V31) {
147 regid += UC_ARM64_REG_Q0 - UC_ARM64_REG_V0;
148 }
149 if (regid >= UC_ARM64_REG_X0 && regid <= UC_ARM64_REG_X28) {
150 ARM_CPU(uc, mycpu)->env.xregs[regid - UC_ARM64_REG_X0] = *(uint64_t *)value;
151 } else if (regid >= UC_ARM64_REG_W0 && regid <= UC_ARM64_REG_W30) {
152 WRITE_DWORD(ARM_CPU(uc, mycpu)->env.xregs[regid - UC_ARM64_REG_W0], *(uint32_t *)value);
153 } else if (regid >= UC_ARM64_REG_Q0 && regid <= UC_ARM64_REG_Q31) {
154 float64 *src = (float64*) value;
155 uint32_t reg_index = 2*(regid - UC_ARM64_REG_Q0);
156 ARM_CPU(uc, mycpu)->env.vfp.regs[reg_index] = src[0];
157 ARM_CPU(uc, mycpu)->env.vfp.regs[reg_index+1] = src[1];
158 } else if (regid >= UC_ARM64_REG_D0 && regid <= UC_ARM64_REG_D31) {
159 ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_D0)] = * (float64*) value;
160 } else if (regid >= UC_ARM64_REG_S0 && regid <= UC_ARM64_REG_S31) {
161 WRITE_DWORD(ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_S0)], *(int32_t*) value);
162 } else if (regid >= UC_ARM64_REG_H0 && regid <= UC_ARM64_REG_H31) {
163 WRITE_WORD(ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_H0)], *(int16_t*) value);
164 } else if (regid >= UC_ARM64_REG_B0 && regid <= UC_ARM64_REG_B31) {
165 WRITE_BYTE_L(ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_B0)], *(int8_t*) value);
166 } else if (regid >= UC_ARM64_REG_ELR_EL0 && regid <= UC_ARM64_REG_ELR_EL3) {
167 ARM_CPU(uc, mycpu)->env.elr_el[regid - UC_ARM64_REG_ELR_EL0] = *(uint64_t*)value;
168 } else if (regid >= UC_ARM64_REG_SP_EL0 && regid <= UC_ARM64_REG_SP_EL3) {
169 ARM_CPU(uc, mycpu)->env.sp_el[regid - UC_ARM64_REG_SP_EL0] = *(uint64_t*)value;
170 } else if (regid >= UC_ARM64_REG_ESR_EL0 && regid <= UC_ARM64_REG_ESR_EL3) {
171 ARM_CPU(uc, mycpu)->env.cp15.esr_el[regid - UC_ARM64_REG_ESR_EL0] = *(uint64_t*)value;
172 } else if (regid >= UC_ARM64_REG_FAR_EL0 && regid <= UC_ARM64_REG_FAR_EL3) {
173 ARM_CPU(uc, mycpu)->env.cp15.far_el[regid - UC_ARM64_REG_FAR_EL0] = *(uint64_t*)value;
174 } else if (regid >= UC_ARM64_REG_VBAR_EL0 && regid <= UC_ARM64_REG_VBAR_EL3) {
175 ARM_CPU(uc, mycpu)->env.cp15.vbar_el[regid - UC_ARM64_REG_VBAR_EL0] = *(uint64_t*)value;
176 } else {
177 switch(regid) {
178 default: break;
179 case UC_ARM64_REG_CPACR_EL1:
180 ARM_CPU(uc, mycpu)->env.cp15.c1_coproc = *(uint32_t *)value;
181 break;
182 case UC_ARM64_REG_TPIDR_EL0:
183 ARM_CPU(uc, mycpu)->env.cp15.tpidr_el0 = *(uint64_t *)value;
184 break;
185 case UC_ARM64_REG_TPIDRRO_EL0:
186 ARM_CPU(uc, mycpu)->env.cp15.tpidrro_el0 = *(uint64_t *)value;
187 break;
188 case UC_ARM64_REG_TPIDR_EL1:
189 ARM_CPU(uc, mycpu)->env.cp15.tpidr_el1 = *(uint64_t *)value;
190 break;
191 case UC_ARM64_REG_X29:
192 ARM_CPU(uc, mycpu)->env.xregs[29] = *(uint64_t *)value;
193 break;
194 case UC_ARM64_REG_X30:
195 ARM_CPU(uc, mycpu)->env.xregs[30] = *(uint64_t *)value;
196 break;
197 case UC_ARM64_REG_PC:
198 ARM_CPU(uc, mycpu)->env.pc = *(uint64_t *)value;
199 // force to quit execution and flush TB
200 uc->quit_request = true;
201 uc_emu_stop(uc);
202 break;
203 case UC_ARM64_REG_SP:
204 ARM_CPU(uc, mycpu)->env.xregs[31] = *(uint64_t *)value;
205 break;
206 case UC_ARM64_REG_NZCV:
207 cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value, CPSR_NZCV);
208 break;
209 case UC_ARM64_REG_PSTATE:
210 pstate_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value);
211 break;
212 case UC_ARM64_REG_TTBR0_EL1:
213 ARM_CPU(uc, mycpu)->env.cp15.ttbr0_el1 = *(uint64_t *)value;
214 break;
215 case UC_ARM64_REG_TTBR1_EL1:
216 ARM_CPU(uc, mycpu)->env.cp15.ttbr1_el1 = *(uint64_t *)value;
217 break;
218 case UC_ARM64_REG_PAR_EL1:
219 ARM_CPU(uc, mycpu)->env.cp15.par_el1 = *(uint64_t *)value;
220 break;
221 case UC_ARM64_REG_MAIR_EL1:
222 ARM_CPU(uc, mycpu)->env.cp15.mair_el1 = *(uint64_t *)value;
223 break;
224 }
225 }
226 }
227
228 return 0;
229 }
230
231 DEFAULT_VISIBILITY
232 #ifdef TARGET_WORDS_BIGENDIAN
arm64eb_uc_init(struct uc_struct * uc)233 void arm64eb_uc_init(struct uc_struct* uc)
234 #else
235 void arm64_uc_init(struct uc_struct* uc)
236 #endif
237 {
238 register_accel_types(uc);
239 arm_cpu_register_types(uc);
240 aarch64_cpu_register_types(uc);
241 machvirt_machine_init(uc);
242 uc->reg_read = arm64_reg_read;
243 uc->reg_write = arm64_reg_write;
244 uc->reg_reset = arm64_reg_reset;
245 uc->set_pc = arm64_set_pc;
246 uc->release = arm64_release;
247 uc_common_init(uc);
248 }
249