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