|
|
1.1 root 1: /*
2: * PowerPC implementation of KVM hooks
3: *
4: * Copyright IBM Corp. 2007
5: *
6: * Authors:
7: * Jerone Young <[email protected]>
8: * Christian Ehrhardt <[email protected]>
9: * Hollis Blanchard <[email protected]>
10: *
11: * This work is licensed under the terms of the GNU GPL, version 2 or later.
12: * See the COPYING file in the top-level directory.
13: *
14: */
15:
16: #include <sys/types.h>
17: #include <sys/ioctl.h>
18: #include <sys/mman.h>
19:
20: #include <linux/kvm.h>
21:
22: #include "qemu-common.h"
23: #include "qemu-timer.h"
24: #include "sysemu.h"
25: #include "kvm.h"
26: #include "kvm_ppc.h"
27: #include "cpu.h"
28: #include "device_tree.h"
29:
30: //#define DEBUG_KVM
31:
32: #ifdef DEBUG_KVM
33: #define dprintf(fmt, ...) \
34: do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
35: #else
36: #define dprintf(fmt, ...) \
37: do { } while (0)
38: #endif
39:
1.1.1.3 ! root 40: /* XXX We have a race condition where we actually have a level triggered
! 41: * interrupt, but the infrastructure can't expose that yet, so the guest
! 42: * takes but ignores it, goes to sleep and never gets notified that there's
! 43: * still an interrupt pending.
! 44: *
! 45: * As a quick workaround, let's just wake up again 20 ms after we injected
! 46: * an interrupt. That way we can assure that we're always reinjecting
! 47: * interrupts in case the guest swallowed them.
! 48: */
! 49: static QEMUTimer *idle_timer;
! 50:
! 51: static void kvm_kick_env(void *env)
! 52: {
! 53: qemu_cpu_kick(env);
! 54: }
! 55:
1.1 root 56: int kvm_arch_init(KVMState *s, int smp_cpus)
57: {
58: return 0;
59: }
60:
61: int kvm_arch_init_vcpu(CPUState *cenv)
62: {
1.1.1.2 root 63: int ret = 0;
64: struct kvm_sregs sregs;
65:
66: sregs.pvr = cenv->spr[SPR_PVR];
67: ret = kvm_vcpu_ioctl(cenv, KVM_SET_SREGS, &sregs);
68:
1.1.1.3 ! root 69: idle_timer = qemu_new_timer(vm_clock, kvm_kick_env, cenv);
! 70:
1.1.1.2 root 71: return ret;
72: }
73:
74: void kvm_arch_reset_vcpu(CPUState *env)
75: {
1.1 root 76: }
77:
1.1.1.3 ! root 78: int kvm_arch_put_registers(CPUState *env, int level)
1.1 root 79: {
80: struct kvm_regs regs;
81: int ret;
82: int i;
83:
84: ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, ®s);
85: if (ret < 0)
86: return ret;
87:
88: regs.ctr = env->ctr;
89: regs.lr = env->lr;
90: regs.xer = env->xer;
91: regs.msr = env->msr;
92: regs.pc = env->nip;
93:
94: regs.srr0 = env->spr[SPR_SRR0];
95: regs.srr1 = env->spr[SPR_SRR1];
96:
97: regs.sprg0 = env->spr[SPR_SPRG0];
98: regs.sprg1 = env->spr[SPR_SPRG1];
99: regs.sprg2 = env->spr[SPR_SPRG2];
100: regs.sprg3 = env->spr[SPR_SPRG3];
101: regs.sprg4 = env->spr[SPR_SPRG4];
102: regs.sprg5 = env->spr[SPR_SPRG5];
103: regs.sprg6 = env->spr[SPR_SPRG6];
104: regs.sprg7 = env->spr[SPR_SPRG7];
105:
106: for (i = 0;i < 32; i++)
107: regs.gpr[i] = env->gpr[i];
108:
109: ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, ®s);
110: if (ret < 0)
111: return ret;
112:
113: return ret;
114: }
115:
116: int kvm_arch_get_registers(CPUState *env)
117: {
118: struct kvm_regs regs;
1.1.1.2 root 119: struct kvm_sregs sregs;
1.1 root 120: uint32_t i, ret;
121:
122: ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, ®s);
123: if (ret < 0)
124: return ret;
125:
1.1.1.2 root 126: ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs);
127: if (ret < 0)
128: return ret;
129:
1.1 root 130: env->ctr = regs.ctr;
131: env->lr = regs.lr;
132: env->xer = regs.xer;
133: env->msr = regs.msr;
134: env->nip = regs.pc;
135:
136: env->spr[SPR_SRR0] = regs.srr0;
137: env->spr[SPR_SRR1] = regs.srr1;
138:
139: env->spr[SPR_SPRG0] = regs.sprg0;
140: env->spr[SPR_SPRG1] = regs.sprg1;
141: env->spr[SPR_SPRG2] = regs.sprg2;
142: env->spr[SPR_SPRG3] = regs.sprg3;
143: env->spr[SPR_SPRG4] = regs.sprg4;
144: env->spr[SPR_SPRG5] = regs.sprg5;
145: env->spr[SPR_SPRG6] = regs.sprg6;
146: env->spr[SPR_SPRG7] = regs.sprg7;
147:
148: for (i = 0;i < 32; i++)
149: env->gpr[i] = regs.gpr[i];
150:
1.1.1.2 root 151: #ifdef KVM_CAP_PPC_SEGSTATE
152: if (kvm_check_extension(env->kvm_state, KVM_CAP_PPC_SEGSTATE)) {
153: env->sdr1 = sregs.u.s.sdr1;
154:
155: /* Sync SLB */
156: #ifdef TARGET_PPC64
157: for (i = 0; i < 64; i++) {
158: ppc_store_slb(env, sregs.u.s.ppc64.slb[i].slbe,
159: sregs.u.s.ppc64.slb[i].slbv);
160: }
161: #endif
162:
163: /* Sync SRs */
164: for (i = 0; i < 16; i++) {
165: env->sr[i] = sregs.u.s.ppc32.sr[i];
166: }
167:
168: /* Sync BATs */
169: for (i = 0; i < 8; i++) {
170: env->DBAT[0][i] = sregs.u.s.ppc32.dbat[i] & 0xffffffff;
171: env->DBAT[1][i] = sregs.u.s.ppc32.dbat[i] >> 32;
172: env->IBAT[0][i] = sregs.u.s.ppc32.ibat[i] & 0xffffffff;
173: env->IBAT[1][i] = sregs.u.s.ppc32.ibat[i] >> 32;
174: }
175: }
176: #endif
177:
1.1 root 178: return 0;
179: }
180:
1.1.1.2 root 181: #if defined(TARGET_PPCEMB)
182: #define PPC_INPUT_INT PPC40x_INPUT_INT
183: #elif defined(TARGET_PPC64)
184: #define PPC_INPUT_INT PPC970_INPUT_INT
185: #else
186: #define PPC_INPUT_INT PPC6xx_INPUT_INT
187: #endif
188:
1.1 root 189: int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
190: {
191: int r;
192: unsigned irq;
193:
194: /* PowerPC Qemu tracks the various core input pins (interrupt, critical
195: * interrupt, reset, etc) in PPC-specific env->irq_input_state. */
196: if (run->ready_for_interrupt_injection &&
197: (env->interrupt_request & CPU_INTERRUPT_HARD) &&
1.1.1.2 root 198: (env->irq_input_state & (1<<PPC_INPUT_INT)))
1.1 root 199: {
200: /* For now KVM disregards the 'irq' argument. However, in the
201: * future KVM could cache it in-kernel to avoid a heavyweight exit
202: * when reading the UIC.
203: */
204: irq = -1U;
205:
206: dprintf("injected interrupt %d\n", irq);
207: r = kvm_vcpu_ioctl(env, KVM_INTERRUPT, &irq);
208: if (r < 0)
209: printf("cpu %d fail inject %x\n", env->cpu_index, irq);
1.1.1.3 ! root 210:
! 211: /* Always wake up soon in case the interrupt was level based */
! 212: qemu_mod_timer(idle_timer, qemu_get_clock(vm_clock) +
! 213: (get_ticks_per_sec() / 50));
1.1 root 214: }
215:
216: /* We don't know if there are more interrupts pending after this. However,
217: * the guest will return to userspace in the course of handling this one
218: * anyways, so we will get a chance to deliver the rest. */
219: return 0;
220: }
221:
222: int kvm_arch_post_run(CPUState *env, struct kvm_run *run)
223: {
224: return 0;
225: }
226:
1.1.1.3 ! root 227: int kvm_arch_process_irqchip_events(CPUState *env)
! 228: {
! 229: return 0;
! 230: }
! 231:
1.1 root 232: static int kvmppc_handle_halt(CPUState *env)
233: {
234: if (!(env->interrupt_request & CPU_INTERRUPT_HARD) && (msr_ee)) {
235: env->halted = 1;
236: env->exception_index = EXCP_HLT;
237: }
238:
239: return 1;
240: }
241:
242: /* map dcr access to existing qemu dcr emulation */
243: static int kvmppc_handle_dcr_read(CPUState *env, uint32_t dcrn, uint32_t *data)
244: {
245: if (ppc_dcr_read(env->dcr_env, dcrn, data) < 0)
246: fprintf(stderr, "Read to unhandled DCR (0x%x)\n", dcrn);
247:
248: return 1;
249: }
250:
251: static int kvmppc_handle_dcr_write(CPUState *env, uint32_t dcrn, uint32_t data)
252: {
253: if (ppc_dcr_write(env->dcr_env, dcrn, data) < 0)
254: fprintf(stderr, "Write to unhandled DCR (0x%x)\n", dcrn);
255:
256: return 1;
257: }
258:
259: int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
260: {
261: int ret = 0;
262:
263: switch (run->exit_reason) {
264: case KVM_EXIT_DCR:
265: if (run->dcr.is_write) {
266: dprintf("handle dcr write\n");
267: ret = kvmppc_handle_dcr_write(env, run->dcr.dcrn, run->dcr.data);
268: } else {
269: dprintf("handle dcr read\n");
270: ret = kvmppc_handle_dcr_read(env, run->dcr.dcrn, &run->dcr.data);
271: }
272: break;
273: case KVM_EXIT_HLT:
274: dprintf("handle halt\n");
275: ret = kvmppc_handle_halt(env);
276: break;
277: }
278:
279: return ret;
280: }
281:
1.1.1.3 ! root 282: static int read_cpuinfo(const char *field, char *value, int len)
! 283: {
! 284: FILE *f;
! 285: int ret = -1;
! 286: int field_len = strlen(field);
! 287: char line[512];
! 288:
! 289: f = fopen("/proc/cpuinfo", "r");
! 290: if (!f) {
! 291: return -1;
! 292: }
! 293:
! 294: do {
! 295: if(!fgets(line, sizeof(line), f)) {
! 296: break;
! 297: }
! 298: if (!strncmp(line, field, field_len)) {
! 299: strncpy(value, line, len);
! 300: ret = 0;
! 301: break;
! 302: }
! 303: } while(*line);
! 304:
! 305: fclose(f);
! 306:
! 307: return ret;
! 308: }
! 309:
! 310: uint32_t kvmppc_get_tbfreq(void)
! 311: {
! 312: char line[512];
! 313: char *ns;
! 314: uint32_t retval = get_ticks_per_sec();
! 315:
! 316: if (read_cpuinfo("timebase", line, sizeof(line))) {
! 317: return retval;
! 318: }
! 319:
! 320: if (!(ns = strchr(line, ':'))) {
! 321: return retval;
! 322: }
! 323:
! 324: ns++;
! 325:
! 326: retval = atoi(ns);
! 327: return retval;
! 328: }
! 329:
! 330: bool kvm_arch_stop_on_emulation_error(CPUState *env)
! 331: {
! 332: return true;
! 333: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.