4 * Add KVM PowerPC specific calls for qemu.
6 * Copyright 2007 IBM Corporation.
8 * Jerone Young <jyoung5@us.ibm.com>
9 * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
11 * This work is licensed under the GNU GPL licence version 2 or later.
16 #include "config-host.h"
23 #include "helper_regs.h"
28 #include <sys/utsname.h>
30 extern kvm_context_t kvm_context
;
32 void cpu_reset(CPUState
*env
)
34 memset(env
->breakpoints
, 0, sizeof(env
->breakpoints
));
39 int kvm_arch_qemu_create_context(void)
44 void kvm_arch_load_regs(CPUState
*env
)
49 rc
= kvm_get_regs(kvm_context
, env
->cpu_index
, ®s
);
51 perror("kvm_get_regs FAILED");
53 /* cr is untouched in qemu and not existant in CPUState fr ppr */
54 /* hflags is a morphed to MSR on ppc, no need to sync that down to kvm */
63 regs
.srr0
= env
->spr
[SPR_SRR0
];
64 regs
.srr1
= env
->spr
[SPR_SRR1
];
66 regs
.sprg0
= env
->spr
[SPR_SPRG0
];
67 regs
.sprg1
= env
->spr
[SPR_SPRG1
];
68 regs
.sprg2
= env
->spr
[SPR_SPRG2
];
69 regs
.sprg3
= env
->spr
[SPR_SPRG3
];
70 regs
.sprg4
= env
->spr
[SPR_SPRG4
];
71 regs
.sprg5
= env
->spr
[SPR_SPRG5
];
72 regs
.sprg6
= env
->spr
[SPR_SPRG6
];
73 regs
.sprg7
= env
->spr
[SPR_SPRG7
];
75 for (i
= 0;i
< 32; i
++){
76 regs
.gpr
[i
] = env
->gpr
[i
];
79 rc
= kvm_set_regs(kvm_context
, env
->cpu_index
, ®s
);
81 perror("kvm_set_regs FAILED");
85 void kvm_arch_save_regs(CPUState
*env
)
90 rc
= kvm_get_regs(kvm_context
, env
->cpu_index
, ®s
);
92 perror("kvm_get_regs FAILED");
98 /* calculate hflags based on the current msr using the ppc qemu helper */
99 hreg_compute_hflags(env
);
103 env
->spr
[SPR_SRR0
] = regs
.srr0
;
104 env
->spr
[SPR_SRR1
] = regs
.srr1
;
106 env
->spr
[SPR_SPRG0
] = regs
.sprg0
;
107 env
->spr
[SPR_SPRG1
] = regs
.sprg1
;
108 env
->spr
[SPR_SPRG2
] = regs
.sprg2
;
109 env
->spr
[SPR_SPRG3
] = regs
.sprg3
;
110 env
->spr
[SPR_SPRG4
] = regs
.sprg4
;
111 env
->spr
[SPR_SPRG5
] = regs
.sprg5
;
112 env
->spr
[SPR_SPRG6
] = regs
.sprg6
;
113 env
->spr
[SPR_SPRG7
] = regs
.sprg7
;
115 for (i
= 0;i
< 32; i
++){
116 env
->gpr
[i
] = regs
.gpr
[i
];
121 int kvm_arch_qemu_init_env(CPUState
*cenv
)
123 if (cenv
->cpu_index
== 0) {
124 /* load any registers set in env into
125 kvm for the first guest vcpu */
126 kvm_load_registers(cenv
);
132 int kvm_arch_halt(void *opaque
, int vcpu
)
134 CPUState
*env
= cpu_single_env
;
136 if (!(env
->interrupt_request
& CPU_INTERRUPT_HARD
)
140 env
->exception_index
= EXCP_HLT
;
145 void kvm_arch_pre_kvm_run(void *opaque
, CPUState
*env
)
150 void kvm_arch_post_kvm_run(void *opaque
, CPUState
*env
)
152 cpu_single_env
= env
;
155 int kvm_arch_has_work(CPUState
*env
)
157 if ((env
->interrupt_request
& (CPU_INTERRUPT_HARD
| CPU_INTERRUPT_EXIT
)) &&
163 int kvm_arch_try_push_interrupts(void *opaque
)
165 CPUState
*env
= cpu_single_env
;
169 /* PowerPC Qemu tracks the various core input pins (interrupt, critical
170 * interrupt, reset, etc) in PPC-specific env->irq_input_state. */
171 if (kvm_is_ready_for_interrupt_injection(kvm_context
, env
->cpu_index
) &&
172 (env
->irq_input_state
& (1<<PPC40x_INPUT_INT
)))
174 /* For now KVM disregards the 'irq' argument. However, in the
175 * future KVM could cache it in-kernel to avoid a heavyweight exit
176 * when reading the UIC.
180 r
= kvm_inject_irq(kvm_context
, env
->cpu_index
, irq
);
182 printf("cpu %d fail inject %x\n", env
->cpu_index
, irq
);
185 /* We don't know if there are more interrupts pending after this. However,
186 * the guest will return to userspace in the course of handling this one
187 * anyways, so we will get a chance to deliver the rest. */
191 int kvm_arch_try_push_nmi(void *opaque
)
193 /* no nmi irq, so discard that call for now and return success.
194 * This might later get mapped to something on powerpc too if we want
195 * to support the nmi monitor command somwhow */
199 void kvm_arch_update_regs_for_sipi(CPUState
*env
)
201 printf("%s: no kvm-powerpc multi processor support yet!\n", __func__
);
204 /* map dcr access to existing qemu dcr emulation */
205 int handle_powerpc_dcr_read(int vcpu
, uint32_t dcrn
, uint32_t *data
)
207 CPUState
*env
= cpu_single_env
;
208 if (ppc_dcr_read(env
->dcr_env
, dcrn
, data
) < 0)
209 fprintf(stderr
, "Read to unhandled DCR (0x%x)\n", dcrn
);
211 return 0; /* XXX ignore failed DCR ops */
214 int handle_powerpc_dcr_write(int vcpu
, uint32_t dcrn
, uint32_t data
)
216 CPUState
*env
= cpu_single_env
;
217 if (ppc_dcr_write(env
->dcr_env
, dcrn
, data
) < 0)
218 fprintf(stderr
, "Write to unhandled DCR (0x%x)\n", dcrn
);
220 return 0; /* XXX ignore failed DCR ops */
223 void kvm_arch_cpu_reset(CPUState
*env
)