Revision 81635574 target-arm/kvm.c
b/target-arm/kvm.c | ||
---|---|---|
43 | 43 |
int kvm_arch_init_vcpu(CPUState *cs) |
44 | 44 |
{ |
45 | 45 |
struct kvm_vcpu_init init; |
46 |
int ret; |
|
47 |
uint64_t v; |
|
48 |
struct kvm_one_reg r; |
|
46 | 49 |
|
47 | 50 |
init.target = KVM_ARM_TARGET_CORTEX_A15; |
48 | 51 |
memset(init.features, 0, sizeof(init.features)); |
49 |
return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); |
|
52 |
ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); |
|
53 |
if (ret) { |
|
54 |
return ret; |
|
55 |
} |
|
56 |
/* Query the kernel to make sure it supports 32 VFP |
|
57 |
* registers: QEMU's "cortex-a15" CPU is always a |
|
58 |
* VFP-D32 core. The simplest way to do this is just |
|
59 |
* to attempt to read register d31. |
|
60 |
*/ |
|
61 |
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP | 31; |
|
62 |
r.addr = (uintptr_t)(&v); |
|
63 |
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r); |
|
64 |
if (ret == ENOENT) { |
|
65 |
return EINVAL; |
|
66 |
} |
|
67 |
return ret; |
|
50 | 68 |
} |
51 | 69 |
|
52 | 70 |
typedef struct Reg { |
... | ... | |
72 | 90 |
offsetof(CPUARMState, QEMUFIELD) \ |
73 | 91 |
} |
74 | 92 |
|
93 |
#define VFPSYSREG(R) \ |
|
94 |
{ \ |
|
95 |
KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP | \ |
|
96 |
KVM_REG_ARM_VFP_##R, \ |
|
97 |
offsetof(CPUARMState, vfp.xregs[ARM_VFP_##R]) \ |
|
98 |
} |
|
99 |
|
|
75 | 100 |
static const Reg regs[] = { |
76 | 101 |
/* R0_usr .. R14_usr */ |
77 | 102 |
COREREG(usr_regs.uregs[0], regs[0]), |
... | ... | |
119 | 144 |
CP15REG(1, 0, 0, 0, cp15.c1_sys), /* SCTLR */ |
120 | 145 |
CP15REG(2, 0, 0, 2, cp15.c2_control), /* TTBCR */ |
121 | 146 |
CP15REG(3, 0, 0, 0, cp15.c3), /* DACR */ |
147 |
/* VFP system registers */ |
|
148 |
VFPSYSREG(FPSID), |
|
149 |
VFPSYSREG(MVFR1), |
|
150 |
VFPSYSREG(MVFR0), |
|
151 |
VFPSYSREG(FPEXC), |
|
152 |
VFPSYSREG(FPINST), |
|
153 |
VFPSYSREG(FPINST2), |
|
122 | 154 |
}; |
123 | 155 |
|
124 | 156 |
int kvm_arch_put_registers(CPUState *cs, int level) |
... | ... | |
128 | 160 |
struct kvm_one_reg r; |
129 | 161 |
int mode, bn; |
130 | 162 |
int ret, i; |
131 |
uint32_t cpsr; |
|
163 |
uint32_t cpsr, fpscr;
|
|
132 | 164 |
uint64_t ttbr; |
133 | 165 |
|
134 | 166 |
/* Make sure the banked regs are properly set */ |
... | ... | |
179 | 211 |
(2 << KVM_REG_ARM_CRM_SHIFT) | (1 << KVM_REG_ARM_OPC1_SHIFT); |
180 | 212 |
r.addr = (uintptr_t)(&ttbr); |
181 | 213 |
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r); |
214 |
if (ret) { |
|
215 |
return ret; |
|
216 |
} |
|
217 |
|
|
218 |
/* VFP registers */ |
|
219 |
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP; |
|
220 |
for (i = 0; i < 32; i++) { |
|
221 |
r.addr = (uintptr_t)(&env->vfp.regs[i]); |
|
222 |
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r); |
|
223 |
if (ret) { |
|
224 |
return ret; |
|
225 |
} |
|
226 |
r.id++; |
|
227 |
} |
|
228 |
|
|
229 |
r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP | |
|
230 |
KVM_REG_ARM_VFP_FPSCR; |
|
231 |
fpscr = vfp_get_fpscr(env); |
|
232 |
r.addr = (uintptr_t)&fpscr; |
|
233 |
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r); |
|
182 | 234 |
|
183 | 235 |
return ret; |
184 | 236 |
} |
... | ... | |
190 | 242 |
struct kvm_one_reg r; |
191 | 243 |
int mode, bn; |
192 | 244 |
int ret, i; |
193 |
uint32_t cpsr; |
|
245 |
uint32_t cpsr, fpscr;
|
|
194 | 246 |
uint64_t ttbr; |
195 | 247 |
|
196 | 248 |
for (i = 0; i < ARRAY_SIZE(regs); i++) { |
... | ... | |
255 | 307 |
env->cp15.c2_mask = ~(0xffffffffu >> env->cp15.c2_control); |
256 | 308 |
env->cp15.c2_base_mask = ~(0x3fffu >> env->cp15.c2_control); |
257 | 309 |
|
310 |
/* VFP registers */ |
|
311 |
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP; |
|
312 |
for (i = 0; i < 32; i++) { |
|
313 |
r.addr = (uintptr_t)(&env->vfp.regs[i]); |
|
314 |
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r); |
|
315 |
if (ret) { |
|
316 |
return ret; |
|
317 |
} |
|
318 |
r.id++; |
|
319 |
} |
|
320 |
|
|
321 |
r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP | |
|
322 |
KVM_REG_ARM_VFP_FPSCR; |
|
323 |
r.addr = (uintptr_t)&fpscr; |
|
324 |
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r); |
|
325 |
if (ret) { |
|
326 |
return ret; |
|
327 |
} |
|
328 |
vfp_set_fpscr(env, fpscr); |
|
329 |
|
|
258 | 330 |
return 0; |
259 | 331 |
} |
260 | 332 |
|
Also available in: Unified diff