* [kvm-ppc-devel] [PATCH 4 of 4] Add powerpc kvm qemu support
@ 2008-01-18 21:50 Jerone Young
2008-01-22 15:15 ` Nathan Lynch
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Jerone Young @ 2008-01-18 21:50 UTC (permalink / raw)
To: kvm-ppc
# HG changeset patch
# User Jerone Young <jyoung5@us.ibm.com>
# Date 1200692014 21600
# Node ID 1c5b26c965e85986cc93c6b905394a8b2a6b5950
# Parent c1641ad67444cc0401fe3462b33dd88df01beae0
Add powerpc kvm qemu support
This patch adds code needed for support of powerpc in kvm qemu.
Signed-off-by: Jerone Young <jyoung5@us.ibm.com>
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
* * *
[PATCH] fill kvm_callback with arch specific dcr_read/dcr_write callbacks
This Patch adds the callback assignment and handlers for powerpc_dcr_read
and ppc_dcr_write which are called from libkvm.
This is the part of the patch that changes powerpc code and will be folded
to our combined patch for qemu-kvm-powerpc.c.
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
qemu-kvm-powerpc.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
* * *
* * *
[PATCH] cr not used
cr not used (not part of CPUState in qemu for ppc), but we don't need that
comment anymore.
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
* * *
[PATCH] hflags works using qemu helper function
qemu has a calculation function to get valid hflags (as appliable to ppc) out
of env->msr. This patch uses this function from target-ppc/helper_regs.h to
solve that - remove todo
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
* * *
[TODO] is available for ppc (at least atm)
is available for ppc (at least atm), remove todo
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
* * *
[TOFOLD] interrupt injection is available in USE_KVM ifdefs
interrupt injection is available in USE_KVM ifdefs, remove todo
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
* * *
* * *
* * *
[PATCH] fix ppc440_init argument list
This argument list did not match the call from main in vl.c
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
ppc440_boards_kvm.c | 1 -
1 files changed, 1 deletion(-)
* * *
[PATCH] remove old shortcuts
these are no longer needed - patch will be fold into add_qemu_code later
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
ppc440_boards_kvm.c | 7 -------
1 files changed, 7 deletions(-)
* * *
diff --git a/qemu/Makefile.target b/qemu/Makefile.target
--- a/qemu/Makefile.target
+++ b/qemu/Makefile.target
@@ -299,7 +299,7 @@ OBJS+= libqemu.a
# cpu emulator library
LIBOBJS=exec.o kqemu.o qemu-kvm.o translate-op.o translate-all.o cpu-exec.o\
- translate.o op.o host-utils.o qemu-kvm-helper.o
+ translate.o op.o host-utils.o
ifdef CONFIG_SOFTFLOAT
LIBOBJS+=fpu/softfloat.o
else
@@ -310,15 +310,18 @@ ifeq ($(TARGET_ARCH), i386)
ifeq ($(TARGET_ARCH), i386)
LIBOBJS+=helper.o helper2.o
LIBOBJS+=qemu-kvm-x86.o kvm-tpr-opt.o
+LIBOBJS+=qemu-kvm-helper.o
endif
ifeq ($(TARGET_ARCH), x86_64)
LIBOBJS+=helper.o helper2.o
LIBOBJS+=qemu-kvm-x86.o kvm-tpr-opt.o
+LIBOBJS+=qemu-kvm-helper.o
endif
ifeq ($(TARGET_BASE_ARCH), ppc)
LIBOBJS+= op_helper.o helper.o
+LIBOBJS+= qemu-kvm-powerpc.o
endif
ifeq ($(TARGET_BASE_ARCH), mips)
@@ -477,6 +480,7 @@ ifeq ($(TARGET_BASE_ARCH), ia64)
ifeq ($(TARGET_BASE_ARCH), ia64)
# Hardware support
VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
+VL_OBJS+= cirrus_vga.o
VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o ipf.o
VL_OBJS+= cirrus_vga.o parallel.o acpi.o piix_pci.o
VL_OBJS+= usb-uhci.o smbus_eeprom.o
@@ -486,6 +490,7 @@ CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOI
CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
# shared objects
VL_OBJS+= ppc.o ide.o vga.o $(SOUND_HW) dma.o openpic.o
+VL_OBJS+= cirrus_vga.o
# PREP target
VL_OBJS+= pckbd.o ps2.o serial.o i8259.o i8254.o fdc.o m48t59.o mc146818rtc.o
VL_OBJS+= prep_pci.o ppc_prep.o
@@ -497,6 +502,7 @@ VL_OBJS+= unin_pci.o ppc_chrp.o
VL_OBJS+= unin_pci.o ppc_chrp.o
# PowerPC 4xx boards
VL_OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc405_uc.o ppc405_boards.o
+VL_OBJS+= $(LIBOBJS) ppc440_boards_kvm.o
endif
ifeq ($(TARGET_BASE_ARCH), mips)
VL_OBJS+= mips_r4k.o mips_malta.o mips_pica61.o mips_mipssim.o
@@ -656,6 +662,10 @@ firmware.o: firmware.c
$(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
endif
+ifeq ($(TARGET_ARCH), ppc)
+qemu-kvm-powerpc.o: qemu-kvm-powerpc.c qemu-kvm.h
+endif
+
cpu-exec.o: cpu-exec.c
$(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
diff --git a/qemu/configure b/qemu/configure
--- a/qemu/configure
+++ b/qemu/configure
@@ -199,6 +199,9 @@ if [ "$cpu" = "ia64" ] ; then
kvm="yes"
gdbstub="no"
slirp="no"
+fi
+if [ "$cpu" = "powerpc" ]; then
+ kvm="yes"
fi
;;
esac
@@ -1067,7 +1070,7 @@ echo "#define CONFIG_QEMU_PREFIX \"$inte
configure_kvm() {
if test $kvm = "yes" -a "$target_softmmu" = "yes" -a \
- \( "$cpu" = "i386" -o "$cpu" = "x86_64" -o "$cpu" = "ia64" \); then
+ \( "$cpu" = "i386" -o "$cpu" = "x86_64" -o "$cpu" = "ia64" -o "$cpu" = "powerpc" \); then
echo "#define USE_KVM 1" >> $config_h
echo "CONFIG_KVM_KERNEL_INC=$kernel_path/include" >> $config_mak
fi
@@ -1118,6 +1121,7 @@ elif test "$target_cpu" = "ppcemb" ; the
echo "#define TARGET_ARCH \"ppcemb\"" >> $config_h
echo "#define TARGET_PPC 1" >> $config_h
echo "#define TARGET_PPCEMB 1" >> $config_h
+ configure_kvm
elif test "$target_cpu" = "ppc64" ; then
echo "TARGET_ARCH=ppc64" >> $config_mak
echo "TARGET_ABI_DIR=ppc" >> $config_mak
diff --git a/qemu/hw/boards.h b/qemu/hw/boards.h
--- a/qemu/hw/boards.h
+++ b/qemu/hw/boards.h
@@ -32,6 +32,7 @@ extern QEMUMachine heathrow_machine;
extern QEMUMachine heathrow_machine;
extern QEMUMachine ref405ep_machine;
extern QEMUMachine taihu_machine;
+extern QEMUMachine bambookvm_machine;
/* mips_r4k.c */
extern QEMUMachine mips_machine;
diff --git a/qemu/hw/ppc440_boards_kvm.c b/qemu/hw/ppc440_boards_kvm.c
new file mode 100644
--- /dev/null
+++ b/qemu/hw/ppc440_boards_kvm.c
@@ -0,0 +1,251 @@
+/*
+ * Qemu PowerPC 440 board emualtion with KVM enlightnments
+ *
+ * Copyright 2007 IBM Corporation.
+ * Added by: Jerone Young <jyoung5@us.ibm.com>
+ *
+ * This work is licensed under the GNU LGPL license, version 2.
+ *
+ */
+
+/* XXX THIS CODE IS STILL DRAFT! DO NOT POST TO THE LIST! */
+
+#include <sys/mman.h>
+
+#include "hw.h"
+#include "ppc.h"
+#include "ppc405.h"
+#include "pc.h"
+#include "qemu-timer.h"
+#include "sysemu.h"
+#include "exec-all.h"
+#include "boards.h"
+
+#include "qemu-kvm.h"
+
+#define DEFAULT_RAM_SIZE 32*1024*1024
+
+#define KERNEL_LOAD_ADDR 0x400000 /* uboot loader puts kernel at 4MB */
+
+
+/* PPC 440 refrence demo board
+ *
+ * KVM 440 PowerPC CPU
+ *
+ * SDRAM (0x00000000)
+ */
+
+#define DCRN_CPR0_CFGADDR 0xc
+#define DCRN_CPR0_CFGDATA 0xd
+#define CPR0_PLLC0 0x0020
+#define CPR0_PLLD0 0x0060
+
+struct cpr0
+{
+ uint32_t cfgaddr;
+};
+
+static void dcr_write_cpr0(void *opaque, int dcrn, target_ulong val)
+{
+ struct cpr0 *cpr0 = opaque;
+
+ switch (dcrn) {
+ case DCRN_CPR0_CFGADDR:
+ cpr0->cfgaddr = val;
+ break;
+ }
+}
+
+static target_ulong dcr_read_cpr0(void *opaque, int dcrn)
+{
+ struct cpr0 *cpr0 = opaque;
+
+ switch (dcrn) {
+ case DCRN_CPR0_CFGDATA:
+ switch (cpr0->cfgaddr) {
+ case CPR0_PLLD0:
+ return 0x08020203;
+ }
+ break;
+ }
+ return 0;
+}
+
+//figure out where serial_hds is initialized!
+void ppc440_init(CPUState *env,
+ target_phys_addr_t ram_bases[2],
+ target_phys_addr_t ram_sizes[2],
+ qemu_irq **picp,
+ int do_init)
+{
+ ppc4xx_mmio_t *mmio;
+ qemu_irq *pic, *irqs;
+ struct cpr0 *cpr0;
+ ram_addr_t offset;
+ int i;
+
+ printf("Inside %s\n", __func__);
+
+ ppc_dcr_init(env, NULL, NULL);
+
+ /* mmio */
+ printf("setup mmio\n");
+ mmio = ppc4xx_mmio_init(env, 0xEF600000);
+
+ // universal controller
+ printf("setup universal controller\n");
+ irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
+ irqs[PPCUIC_OUTPUT_INT] + ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT];
+ irqs[PPCUIC_OUTPUT_CINT] + ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT];
+ pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
+ *picp = pic;
+
+ /* SDRAM controller */
+ printf("trying to setup sdram controller\n");
+ ppc405_sdram_init(env, pic[14], 2, ram_bases, ram_sizes, do_init);
+ offset = 0;
+ for (i = 0; i < 2; i++)
+ offset += ram_sizes[i];
+
+ /* serial ports on page 126 of 440EP user manual */
+ if (serial_hds[0]) {
+ printf("Initializing first serial port\n");
+ ppc405_serial_init(env, mmio,0x300, pic[31], serial_hds[0]);
+ }
+ if (serial_hds[1]) {
+ printf("Initializing 2nd serial port\n");
+ ppc405_serial_init(env, mmio,0x400, pic[30], serial_hds[1]);
+ }
+
+ cpr0 = qemu_mallocz(sizeof(struct cpr0));
+ ppc_dcr_register(env, DCRN_CPR0_CFGADDR, cpr0, NULL, dcr_write_cpr0);
+ ppc_dcr_register(env, DCRN_CPR0_CFGDATA, cpr0, dcr_read_cpr0, NULL);
+}
+
+
+static void bambooKVM_init(ram_addr_t ram_size, int vga_ram_size,
+ const char *boot_device, DisplayState *ds,
+ const char *kernel_filename,
+ const char *kernel_cmdline,
+ const char *initrd_filename,
+ const char *cpu_model)
+{
+ target_phys_addr_t ram_bases[2], ram_sizes[2];
+ qemu_irq *pic;
+ CPUState *env;
+ target_ulong ep;
+ int is_linux=1; /* Will assume allways is Linux for now */
+ long kernel_size=0;
+ target_ulong initrd_base=0;
+ target_ulong initrd_size=0;
+
+ printf("Entering %s\n", __func__);
+
+ /* Setup Memory */
+ if (ram_size)
+ {
+ printf("Ram size specified on command line is %d\n", (int)ram_size);
+ }
+ else {
+ printf("Using defualt ram size of %iMB\n",
+ (DEFAULT_RAM_SIZE/1024)/1024);
+
+ ram_size = DEFAULT_RAM_SIZE;
+ }
+
+ /* XXX For simplicity we will just have everything to into one
+ memory stick. Until of course this needs to be changed */
+ ram_bases[0] = 0x0;
+ ram_sizes[0] = 0x08000000;
+ ram_bases[1] = 0x0;
+ ram_sizes[1] = 0x01000000;
+
+ printf("Ram size of domain is %d bytes\n", (int)ram_size);
+
+ /* Setup CPU */
+ /*XXX Change ppc_defs[] target-ppc/translate_init.c
+ is the table you want to look at for the value or arg
+ To try "440EP" you have to define TODO_USER_ONLY
+ */
+ env = cpu_ppc_init("405");
+ if (!env) {
+ fprintf(stderr, "Unable to initilize CPU!\n");
+ exit(1);
+ }
+
+ /* Allocate IRQ controller */
+ /* XXX not sure but this appears not be needed any more */
+ //ppc405_irq_init(env);
+
+ /* call init */
+ printf("Calling function ppc440_init\n");
+ ppc440_init(env, ram_bases, ram_sizes, &pic,1);
+ printf("Done calling ppc440_init\n");
+
+ /* Setup KVM context */
+ if (kvm_qemu_init()) {
+ fprintf(stderr, "Could not init kvm qemu\n");
+ exit(1);
+ }
+
+ if (kvm_qemu_create_context() < 0) {
+ fprintf(stderr, "Could not create KVM context\n");
+ exit(1);
+ }
+ cpu_register_physical_memory(0, ram_size, 0);
+ kvm_cpu_register_physical_memory(0, ram_size, 0);
+
+ /* load kernel with uboot loader */
+ printf("%s: load kernel\n", __func__);
+ kernel_size = load_uboot(kernel_filename, &ep, &is_linux);
+ if (kernel_size < 0) {
+ fprintf(stderr, "qemu: could not load kernel '%s'\n",
+ kernel_filename);
+ exit(1);
+ }
+
+ /* load initrd */
+ if (initrd_filename) {
+ initrd_base = kernel_size + KERNEL_LOAD_ADDR;
+ initrd_size = load_image(initrd_filename,
+ phys_ram_base + initrd_base);
+
+ if (initrd_size < 0) {
+ fprintf(stderr,
+ "qemu: could not load initial ram disk '%s'\n",
+ initrd_filename);
+ exit(1);
+ }
+ }
+
+ /* XXX insert TLB entries */
+ env->gpr[1] = (16<<20) - 8;
+ env->gpr[4] = initrd_base;
+ env->gpr[5] = initrd_size;
+
+ /* Set program counter (ip in x86 terms .... but it's ep in ppc) */
+ env->nip = ep;
+ printf("Program Counter (ep) is being set to 0x%08x\n", ep);
+
+ /* lock RAM */
+ mlock(phys_ram_base, phys_ram_size);
+
+ /* run in kvm */
+ /* XXX SMP IS NOT SUPPORTED YET */
+ printf("%s: running kvm functions\n", __func__);
+ env->cpu_index = 0;
+
+ /* XXX need a call to set ep */
+ printf("%s: loading kvm registers\n", __func__);
+ kvm_load_registers(env);
+
+ printf("%s: DONE\n", __func__);
+}
+
+QEMUMachine bambookvm_machine = {
+ "bambooKVM",
+ "bambooKVM",
+ bambooKVM_init,
+};
diff --git a/qemu/qemu-kvm-powerpc.c b/qemu/qemu-kvm-powerpc.c
new file mode 100644
--- /dev/null
+++ b/qemu/qemu-kvm-powerpc.c
@@ -0,0 +1,207 @@
+
+#include "config.h"
+#include "config-host.h"
+
+extern int kvm_allowed;
+extern int kvm_irqchip;
+
+#ifdef USE_KVM
+
+#include <string.h>
+#include "hw/hw.h"
+#include "sysemu.h"
+#include "cpu.h"
+#include "helper_regs.h"
+
+#include "qemu-kvm.h"
+#include <libkvm.h>
+#include <pthread.h>
+#include <sys/utsname.h>
+
+extern kvm_context_t kvm_context;
+extern __thread CPUState *vcpu_env;
+
+/* TODOs
+ * - figure out if this current code actually works!
+ * - ppc hflags work, but we need to check if generic code use hflags not
+ supportet by ppc (atm it only uses some halt related flags that become
+ interesting for smp support
+ */
+
+void cpu_reset(CPUState *env)
+{
+ /* XXX TODO */
+ /* currently we do not do anything here, but the idea
+ * is to reset any CPU registers to it's startup state.
+ * This is used in qemu-kvm.c
+ * in function:
+ */
+}
+
+
+int kvm_arch_qemu_create_context(void)
+{
+ return 0;
+}
+
+void kvm_arch_load_regs(CPUState *env)
+{
+ struct kvm_regs regs;
+ int rc,i;
+
+ rc = kvm_get_regs(kvm_context, env->cpu_index, ®s);
+ if (rc = -1)
+ perror("kvm_get_regs FAILED");
+
+ /* cr is untouched in qemu and not existant in CPUState fr ppr */
+ regs.pc = env->nip;
+
+ regs.ctr = env->ctr;
+ regs.lr = env->lr;
+ regs.xer = ppc_load_xer(env);
+ regs.msr = env->msr;
+ /* hflags is a morphed to MSR on ppc, no need to sync that down to kvm */
+
+ regs.srr0 = env->spr[SPR_SRR0];
+ regs.srr1 = env->spr[SPR_SRR1];
+
+ regs.sprg0 = env->spr[SPR_SPRG0];
+ regs.sprg1 = env->spr[SPR_SPRG1];
+ regs.sprg2 = env->spr[SPR_SPRG2];
+ regs.sprg3 = env->spr[SPR_SPRG3];
+ regs.sprg4 = env->spr[SPR_SPRG4];
+ regs.sprg5 = env->spr[SPR_SPRG5];
+ regs.sprg6 = env->spr[SPR_SPRG6];
+ regs.sprg7 = env->spr[SPR_SPRG7];
+
+ for (i = 0;i < 32; i++){
+ regs.gpr[i] = env->gpr[i];
+ regs.fpr[i] = env->fpr[i];
+ }
+
+ rc = kvm_set_regs(kvm_context, env->cpu_index, ®s);
+ if (rc = -1)
+ perror("kvm_set_regs FAILED");
+}
+
+
+void kvm_arch_save_regs(CPUState *env)
+{
+ struct kvm_regs regs;
+ uint32_t i, rc;
+
+ rc = kvm_get_regs(kvm_context, env->cpu_index, ®s);
+ if (rc = -1)
+ perror("kvm_get_regs FAILED");
+
+ env->ctr =regs.ctr;
+ env->lr = regs.lr;
+ ppc_store_xer(env,regs.xer);
+ env->msr = regs.msr;
+ /* calculate hflags based on the current msr using the ppc qemu helper */
+ hreg_compute_hflags(env);
+
+ env->nip = regs.pc;
+
+ env->spr[SPR_SRR0] = regs.srr0;
+ env->spr[SPR_SRR1] = regs.srr1;
+
+ env->spr[SPR_SPRG0] = regs.sprg0;
+ env->spr[SPR_SPRG1] = regs.sprg1;
+ env->spr[SPR_SPRG2] = regs.sprg2;
+ env->spr[SPR_SPRG3] = regs.sprg3;
+ env->spr[SPR_SPRG4] = regs.sprg4;
+ env->spr[SPR_SPRG5] = regs.sprg5;
+ env->spr[SPR_SPRG6] = regs.sprg6;
+ env->spr[SPR_SPRG7] = regs.sprg7;
+
+ for (i = 0;i < 32; i++){
+ env->gpr[i] = regs.gpr[i];
+ env->fpr[i] = regs.fpr[i];
+ }
+
+}
+
+int kvm_arch_qemu_init_env(CPUState *cenv)
+{
+ return 0;
+}
+
+int kvm_arch_halt(void *opaque, int vcpu)
+{
+ CPUState *env = cpu_single_env;
+
+ if (!(env->interrupt_request & CPU_INTERRUPT_HARD)
+ && (env->msr & (1<<MSR_EE)))
+ {
+ env->halted = 1;
+ env->exception_index = EXCP_HLT;
+ }
+ return 1;
+}
+
+void kvm_arch_pre_kvm_run(void *opaque, int vcpu)
+{
+ return;
+}
+
+void kvm_arch_post_kvm_run(void *opaque, int vcpu)
+{
+ CPUState *env = vcpu_env;
+ cpu_single_env = env;
+ env->ready_for_interrupt_injection = \
+ kvm_is_ready_for_interrupt_injection(kvm_context, vcpu);
+}
+
+int kvm_arch_has_work(CPUState *env)
+{
+ if ((env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXIT)) &&
+ (env->msr & (1<<MSR_EE)))
+ return 1;
+ return 0;
+}
+
+/*XXX NEED WORK BAD! */
+int kvm_arch_try_push_interrupts(void *opaque)
+{
+ CPUState *env = cpu_single_env;
+ int r, irq;
+/* XXX ready_for_interrupt_injection is gone! */
+ // if (env->ready_for_interrupt_injection &&
+ if (
+ (env->interrupt_request & CPU_INTERRUPT_HARD) &&
+ (env->msr & (1<<MSR_EE))) {
+ env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+/* XXX TODO all down here */
+/*
+ irq = cpu_get_pic_interrupt(env);
+ if (irq >= 0) {
+ r = kvm_inject_irq(kvm_context, env->cpu_index, irq);
+ if (r < 0)
+ printf("cpu %d fail inject %x\n", env->cpu_index, irq);
+ }
+*/
+ }
+
+ return (env->interrupt_request & CPU_INTERRUPT_HARD) != 0;
+}
+
+void kvm_arch_update_regs_for_sipi(CPUState *env)
+{
+ printf("%s: no kvm-powerpc multi processor support yet!\n", __func__);
+}
+
+/* map dcr access to existing qemu dcr emulation */
+int handle_powerpc_dcr_read(uint32_t dcrn, uint32_t *data)
+{
+ ppc_dcr_read(vcpu_env->dcr_env, dcrn, data);
+ return 0; /* XXX ignore failed DCR ops */
+}
+
+int handle_powerpc_dcr_write(uint32_t dcrn, uint32_t data)
+{
+ ppc_dcr_write(vcpu_env->dcr_env, dcrn, data);
+ return 0; /* XXX ignore failed DCR ops */
+}
+
+#endif
diff --git a/qemu/target-ppc/cpu.h b/qemu/target-ppc/cpu.h
--- a/qemu/target-ppc/cpu.h
+++ b/qemu/target-ppc/cpu.h
@@ -573,6 +573,11 @@ struct CPUPPCState {
target_ulong msr;
/* temporary general purpose registers */
ppc_gpr_t tgpr[4]; /* Used to speed-up TLB assist handlers */
+
+#ifdef USE_KVM
+ uint64_t tsc; /* time stamp counter */
+ uint8_t ready_for_interrupt_injection;
+#endif
/* Floating point execution context */
/* temporary float registers */
@@ -1421,4 +1426,11 @@ enum {
/*****************************************************************************/
+/* hidden flags (hflags) - used internally by qemu to represent additional
+ * cpu states.
+ */
+#define HF_HALTED_SHIFT 1
+
+#define HF_HALTED_MASK 1<<HF_HALTED_SHIFT
+
#endif /* !defined (__CPU_PPC_H__) */
diff --git a/qemu/vl.c b/qemu/vl.c
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -8318,6 +8318,7 @@ static void register_machines(void)
qemu_register_machine(&prep_machine);
qemu_register_machine(&ref405ep_machine);
qemu_register_machine(&taihu_machine);
+ qemu_register_machine(&bambookvm_machine);
#elif defined(TARGET_MIPS)
qemu_register_machine(&mips_machine);
qemu_register_machine(&mips_malta_machine);
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-ppc-devel mailing list
kvm-ppc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-ppc-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [kvm-ppc-devel] [PATCH 4 of 4] Add powerpc kvm qemu support
2008-01-18 21:50 [kvm-ppc-devel] [PATCH 4 of 4] Add powerpc kvm qemu support Jerone Young
@ 2008-01-22 15:15 ` Nathan Lynch
2008-01-22 19:09 ` Jerone Young
2008-01-25 23:34 ` Jerone Young
2 siblings, 0 replies; 4+ messages in thread
From: Nathan Lynch @ 2008-01-22 15:15 UTC (permalink / raw)
To: kvm-ppc
Jerone Young wrote:
> --- /dev/null
> +++ b/qemu/hw/ppc440_boards_kvm.c
> @@ -0,0 +1,251 @@
> +/*
> + * Qemu PowerPC 440 board emualtion with KVM enlightnments
enhancements?
> + *
> + * Copyright 2007 IBM Corporation.
> + * Added by: Jerone Young <jyoung5@us.ibm.com>
> + *
> + * This work is licensed under the GNU LGPL license, version 2.
> + *
> + */
> +
> +/* XXX THIS CODE IS STILL DRAFT! DO NOT POST TO THE LIST! */
heh
> +
> +#include <sys/mman.h>
> +
> +#include "hw.h"
> +#include "ppc.h"
> +#include "ppc405.h"
> +#include "pc.h"
> +#include "qemu-timer.h"
> +#include "sysemu.h"
> +#include "exec-all.h"
> +#include "boards.h"
> +
> +#include "qemu-kvm.h"
> +
> +#define DEFAULT_RAM_SIZE 32*1024*1024
You want parentheses around that expression.
> +static void bambooKVM_init(ram_addr_t ram_size, int vga_ram_size,
> + const char *boot_device, DisplayState *ds,
> + const char *kernel_filename,
> + const char *kernel_cmdline,
> + const char *initrd_filename,
> + const char *cpu_model)
> +{
....
> +
> + /* XXX insert TLB entries */
> + env->gpr[1] = (16<<20) - 8;
> + env->gpr[4] = initrd_base;
> + env->gpr[5] = initrd_size;
> +
> + /* Set program counter (ip in x86 terms .... but it's ep in ppc) */
> + env->nip = ep;
> + printf("Program Counter (ep) is being set to 0x%08x\n", ep);
> +
> + /* lock RAM */
> + mlock(phys_ram_base, phys_ram_size);
Do you care if that fails?
> +
> + /* run in kvm */
> + /* XXX SMP IS NOT SUPPORTED YET */
> + printf("%s: running kvm functions\n", __func__);
> + env->cpu_index = 0;
> +
> + /* XXX need a call to set ep */
> + printf("%s: loading kvm registers\n", __func__);
> + kvm_load_registers(env);
> +
> + printf("%s: DONE\n", __func__);
> +}
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-ppc-devel mailing list
kvm-ppc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-ppc-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [kvm-ppc-devel] [PATCH 4 of 4] Add powerpc kvm qemu support
2008-01-18 21:50 [kvm-ppc-devel] [PATCH 4 of 4] Add powerpc kvm qemu support Jerone Young
2008-01-22 15:15 ` Nathan Lynch
@ 2008-01-22 19:09 ` Jerone Young
2008-01-25 23:34 ` Jerone Young
2 siblings, 0 replies; 4+ messages in thread
From: Jerone Young @ 2008-01-22 19:09 UTC (permalink / raw)
To: kvm-ppc
On Tue, 2008-01-22 at 09:15 -0600, Nathan Lynch wrote:
> Jerone Young wrote:
> > --- /dev/null
> > +++ b/qemu/hw/ppc440_boards_kvm.c
> > @@ -0,0 +1,251 @@
> > +/*
> > + * Qemu PowerPC 440 board emualtion with KVM enlightnments
>
> enhancements?
>
> > + *
> > + * Copyright 2007 IBM Corporation.
> > + * Added by: Jerone Young <jyoung5@us.ibm.com>
> > + *
> > + * This work is licensed under the GNU LGPL license, version 2.
> > + *
> > + */
> > +
> > +/* XXX THIS CODE IS STILL DRAFT! DO NOT POST TO THE LIST! */
>
> heh
I've cleaned this up in our internal repo. I plan on sending these
patches every friday till we get them in upstream KVM. But it was a last
minute decision to send what we had to the list. Next one will be a LOT
cleaner.
>
>
> > +
> > +#include <sys/mman.h>
> > +
> > +#include "hw.h"
> > +#include "ppc.h"
> > +#include "ppc405.h"
> > +#include "pc.h"
> > +#include "qemu-timer.h"
> > +#include "sysemu.h"
> > +#include "exec-all.h"
> > +#include "boards.h"
> > +
> > +#include "qemu-kvm.h"
> > +
> > +#define DEFAULT_RAM_SIZE 32*1024*1024
>
> You want parentheses around that expression.
I've removed this now. But yes you are right, not having the parentheses
can cause problems if you have DEFAULT_RAM_SIZE^2 or something like
that.
>
>
> > +static void bambooKVM_init(ram_addr_t ram_size, int vga_ram_size,
> > + const char *boot_device, DisplayState *ds,
> > + const char *kernel_filename,
> > + const char *kernel_cmdline,
> > + const char *initrd_filename,
> > + const char *cpu_model)
> > +{
>
> ....
>
> > +
> > + /* XXX insert TLB entries */
> > + env->gpr[1] = (16<<20) - 8;
> > + env->gpr[4] = initrd_base;
> > + env->gpr[5] = initrd_size;
> > +
> > + /* Set program counter (ip in x86 terms .... but it's ep in ppc) */
> > + env->nip = ep;
> > + printf("Program Counter (ep) is being set to 0x%08x\n", ep);
> > +
> > + /* lock RAM */
> > + mlock(phys_ram_base, phys_ram_size);
>
> Do you care if that fails?
Good catch. I'll add a check for it.
>
>
> > +
> > + /* run in kvm */
> > + /* XXX SMP IS NOT SUPPORTED YET */
> > + printf("%s: running kvm functions\n", __func__);
> > + env->cpu_index = 0;
> > +
> > + /* XXX need a call to set ep */
> > + printf("%s: loading kvm registers\n", __func__);
> > + kvm_load_registers(env);
> > +
> > + printf("%s: DONE\n", __func__);
> > +}
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-ppc-devel mailing list
kvm-ppc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-ppc-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
* [kvm-ppc-devel] [PATCH 4 of 4] Add powerpc kvm qemu support
2008-01-18 21:50 [kvm-ppc-devel] [PATCH 4 of 4] Add powerpc kvm qemu support Jerone Young
2008-01-22 15:15 ` Nathan Lynch
2008-01-22 19:09 ` Jerone Young
@ 2008-01-25 23:34 ` Jerone Young
2 siblings, 0 replies; 4+ messages in thread
From: Jerone Young @ 2008-01-25 23:34 UTC (permalink / raw)
To: kvm-ppc
# HG changeset patch
# User Jerone Young <jyoung5@us.ibm.com>
# Date 1201288298 21600
# Node ID 8c7c65b2c7e8ecabe0e452e4098a5ff439dd9645
# Parent 1bba54954f3ed64959afc0d652fac4ccef714974
Add powerpc kvm qemu support
This patch adds code needed for support of powerpc in kvm qemu.
Signed-off-by: Jerone Young <jyoung5@us.ibm.com>
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
* * *
[PATCH] fill kvm_callback with arch specific dcr_read/dcr_write callbacks
This Patch adds the callback assignment and handlers for powerpc_dcr_read
and ppc_dcr_write which are called from libkvm.
This is the part of the patch that changes powerpc code and will be folded
to our combined patch for qemu-kvm-powerpc.c.
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
qemu-kvm-powerpc.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
* * *
* * *
[PATCH] cr not used
cr not used (not part of CPUState in qemu for ppc), but we don't need that
comment anymore.
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
* * *
[PATCH] hflags works using qemu helper function
qemu has a calculation function to get valid hflags (as appliable to ppc) out
of env->msr. This patch uses this function from target-ppc/helper_regs.h to
solve that - remove todo
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
* * *
[TODO] is available for ppc (at least atm)
is available for ppc (at least atm), remove todo
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
* * *
[TOFOLD] interrupt injection is available in USE_KVM ifdefs
interrupt injection is available in USE_KVM ifdefs, remove todo
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
* * *
* * *
* * *
[PATCH] fix ppc440_init argument list
This argument list did not match the call from main in vl.c
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
ppc440_boards_kvm.c | 1 -
1 files changed, 1 deletion(-)
* * *
[PATCH] remove old shortcuts
these are no longer needed - patch will be fold into add_qemu_code later
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
ppc440_boards_kvm.c | 7 -------
1 files changed, 7 deletions(-)
* * *
diff --git a/qemu/Makefile.target b/qemu/Makefile.target
--- a/qemu/Makefile.target
+++ b/qemu/Makefile.target
@@ -299,7 +299,7 @@ OBJS+= libqemu.a
# cpu emulator library
LIBOBJS=exec.o kqemu.o qemu-kvm.o translate-op.o translate-all.o cpu-exec.o\
- translate.o op.o host-utils.o qemu-kvm-helper.o
+ translate.o op.o host-utils.o
ifdef CONFIG_SOFTFLOAT
LIBOBJS+=fpu/softfloat.o
else
@@ -310,15 +310,18 @@ ifeq ($(TARGET_ARCH), i386)
ifeq ($(TARGET_ARCH), i386)
LIBOBJS+=helper.o helper2.o
LIBOBJS+=qemu-kvm-x86.o kvm-tpr-opt.o
+LIBOBJS+=qemu-kvm-helper.o
endif
ifeq ($(TARGET_ARCH), x86_64)
LIBOBJS+=helper.o helper2.o
LIBOBJS+=qemu-kvm-x86.o kvm-tpr-opt.o
+LIBOBJS+=qemu-kvm-helper.o
endif
ifeq ($(TARGET_BASE_ARCH), ppc)
LIBOBJS+= op_helper.o helper.o
+LIBOBJS+= qemu-kvm-powerpc.o
endif
ifeq ($(TARGET_BASE_ARCH), mips)
@@ -477,6 +480,7 @@ ifeq ($(TARGET_BASE_ARCH), ia64)
ifeq ($(TARGET_BASE_ARCH), ia64)
# Hardware support
VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
+VL_OBJS+= cirrus_vga.o
VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o ipf.o
VL_OBJS+= cirrus_vga.o parallel.o acpi.o piix_pci.o
VL_OBJS+= usb-uhci.o smbus_eeprom.o
@@ -486,6 +490,7 @@ CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOI
CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
# shared objects
VL_OBJS+= ppc.o ide.o vga.o $(SOUND_HW) dma.o openpic.o
+VL_OBJS+= cirrus_vga.o
# PREP target
VL_OBJS+= pckbd.o ps2.o serial.o i8259.o i8254.o fdc.o m48t59.o mc146818rtc.o
VL_OBJS+= prep_pci.o ppc_prep.o
@@ -497,6 +502,7 @@ VL_OBJS+= unin_pci.o ppc_chrp.o
VL_OBJS+= unin_pci.o ppc_chrp.o
# PowerPC 4xx boards
VL_OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc405_uc.o ppc405_boards.o
+VL_OBJS+= $(LIBOBJS) ppc440_boards_kvm.o
endif
ifeq ($(TARGET_BASE_ARCH), mips)
VL_OBJS+= mips_r4k.o mips_malta.o mips_pica61.o mips_mipssim.o
@@ -656,6 +662,10 @@ firmware.o: firmware.c
$(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
endif
+ifeq ($(TARGET_ARCH), ppc)
+qemu-kvm-powerpc.o: qemu-kvm-powerpc.c qemu-kvm.h
+endif
+
cpu-exec.o: cpu-exec.c
$(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
diff --git a/qemu/configure b/qemu/configure
--- a/qemu/configure
+++ b/qemu/configure
@@ -199,6 +199,9 @@ if [ "$cpu" = "ia64" ] ; then
kvm="yes"
gdbstub="no"
slirp="no"
+fi
+if [ "$cpu" = "powerpc" ]; then
+ kvm="yes"
fi
;;
esac
@@ -1067,7 +1070,7 @@ echo "#define CONFIG_QEMU_PREFIX \"$inte
configure_kvm() {
if test $kvm = "yes" -a "$target_softmmu" = "yes" -a \
- \( "$cpu" = "i386" -o "$cpu" = "x86_64" -o "$cpu" = "ia64" \); then
+ \( "$cpu" = "i386" -o "$cpu" = "x86_64" -o "$cpu" = "ia64" -o "$cpu" = "powerpc" \); then
echo "#define USE_KVM 1" >> $config_h
echo "CONFIG_KVM_KERNEL_INC=$kernel_path/include" >> $config_mak
fi
@@ -1118,6 +1121,7 @@ elif test "$target_cpu" = "ppcemb" ; the
echo "#define TARGET_ARCH \"ppcemb\"" >> $config_h
echo "#define TARGET_PPC 1" >> $config_h
echo "#define TARGET_PPCEMB 1" >> $config_h
+ configure_kvm
elif test "$target_cpu" = "ppc64" ; then
echo "TARGET_ARCH=ppc64" >> $config_mak
echo "TARGET_ABI_DIR=ppc" >> $config_mak
diff --git a/qemu/hw/boards.h b/qemu/hw/boards.h
--- a/qemu/hw/boards.h
+++ b/qemu/hw/boards.h
@@ -32,6 +32,7 @@ extern QEMUMachine heathrow_machine;
extern QEMUMachine heathrow_machine;
extern QEMUMachine ref405ep_machine;
extern QEMUMachine taihu_machine;
+extern QEMUMachine bambookvm_machine;
/* mips_r4k.c */
extern QEMUMachine mips_machine;
diff --git a/qemu/hw/ppc440_boards_kvm.c b/qemu/hw/ppc440_boards_kvm.c
new file mode 100644
--- /dev/null
+++ b/qemu/hw/ppc440_boards_kvm.c
@@ -0,0 +1,230 @@
+/*
+ * Qemu PowerPC 440 board emualtion with KVM enlightnments
+ *
+ * Copyright 2007 IBM Corporation.
+ * Added by: Jerone Young <jyoung5@us.ibm.com>
+ *
+ *
+ * This work is licensed under the GNU LGPL license, version 2.
+ *
+ */
+
+#include <sys/mman.h>
+
+#include "hw.h"
+#include "ppc.h"
+#include "ppc405.h"
+#include "pc.h"
+#include "qemu-timer.h"
+#include "sysemu.h"
+#include "exec-all.h"
+#include "boards.h"
+
+#include "qemu-kvm.h"
+
+#define KERNEL_LOAD_ADDR 0x400000 /* uboot loader puts kernel at 4MB */
+
+
+/* PPC 440 refrence demo board
+ *
+ * KVM 440 PowerPC CPU
+ *
+ * SDRAM (0x00000000)
+ */
+
+#define DCRN_CPR0_CFGADDR 0xc
+#define DCRN_CPR0_CFGDATA 0xd
+#define CPR0_PLLC0 0x0020
+#define CPR0_PLLD0 0x0060
+
+struct cpr0
+{
+ uint32_t cfgaddr;
+};
+
+static void dcr_write_cpr0(void *opaque, int dcrn, target_ulong val)
+{
+ struct cpr0 *cpr0 = opaque;
+
+ switch (dcrn) {
+ case DCRN_CPR0_CFGADDR:
+ cpr0->cfgaddr = val;
+ break;
+ }
+}
+
+static target_ulong dcr_read_cpr0(void *opaque, int dcrn)
+{
+ struct cpr0 *cpr0 = opaque;
+
+ switch (dcrn) {
+ case DCRN_CPR0_CFGDATA:
+ switch (cpr0->cfgaddr) {
+ case CPR0_PLLD0:
+ return 0x08020203;
+ }
+ break;
+ }
+ return 0;
+}
+
+void ppc440_init(CPUState *env,
+ target_phys_addr_t ram_bases[2],
+ target_phys_addr_t ram_sizes[2],
+ qemu_irq **picp,
+ int do_init)
+{
+ ppc4xx_mmio_t *mmio;
+ qemu_irq *pic, *irqs;
+ struct cpr0 *cpr0;
+ ram_addr_t offset;
+ int i;
+
+ printf("Inside %s\n", __func__);
+
+ ppc_dcr_init(env, NULL, NULL);
+
+ /* mmio */
+ printf("setup mmio\n");
+ mmio = ppc4xx_mmio_init(env, 0xEF600000);
+
+ /* universal controller */
+ printf("setup universal controller\n");
+ irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
+ irqs[PPCUIC_OUTPUT_INT] + ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT];
+ irqs[PPCUIC_OUTPUT_CINT] + ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT];
+ pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
+ *picp = pic;
+
+ /* SDRAM controller */
+ printf("trying to setup sdram controller\n");
+ ppc405_sdram_init(env, pic[14], 2, ram_bases, ram_sizes, do_init);
+ offset = 0;
+ for (i = 0; i < 2; i++)
+ offset += ram_sizes[i];
+
+ /* serial ports on page 126 of 440EP user manual */
+ if (serial_hds[0]) {
+ printf("Initializing first serial port\n");
+ ppc405_serial_init(env, mmio,0x300, pic[31], serial_hds[0]);
+ }
+ if (serial_hds[1]) {
+ printf("Initializing 2nd serial port\n");
+ ppc405_serial_init(env, mmio,0x400, pic[30], serial_hds[1]);
+ }
+
+ cpr0 = qemu_mallocz(sizeof(struct cpr0));
+ ppc_dcr_register(env, DCRN_CPR0_CFGADDR, cpr0, NULL, dcr_write_cpr0);
+ ppc_dcr_register(env, DCRN_CPR0_CFGDATA, cpr0, dcr_read_cpr0, NULL);
+}
+
+
+static void bambooKVM_init(ram_addr_t ram_size, int vga_ram_size,
+ const char *boot_device, DisplayState *ds,
+ const char *kernel_filename,
+ const char *kernel_cmdline,
+ const char *initrd_filename,
+ const char *cpu_model)
+{
+ target_phys_addr_t ram_bases[2], ram_sizes[2];
+ qemu_irq *pic;
+ CPUState *env;
+ target_ulong ep;
+ int is_linux=1; /* Will assume allways is Linux for now */
+ long kernel_size=0;
+ target_ulong initrd_base=0;
+ target_ulong initrd_size=0;
+
+ printf("%s: START\n", __func__);
+
+ /* Setup Memory */
+ if (ram_size) {
+ printf("Ram size specified on command line is %i bytes\n", (int)ram_size);
+ printf("WARNING: RAM is hard coded to 144MB\n");
+ }
+ else {
+ printf("Using defualt ram size of %iMB\n", ((int)ram_size/1024)/1024);
+ }
+
+ /* Each bank can only have memory in configurations of
+ * 16MB, 32MB, 64MB, 128MB, or 256MB
+ */
+ ram_bases[0] = 0x0;
+ ram_sizes[0] = 0x08000000;
+ ram_bases[1] = 0x0;
+ ram_sizes[1] = 0x01000000;
+
+ printf("Ram size of domain is %d bytes\n", (int)ram_size);
+
+ /* Setup CPU */
+ /* XXX We cheat for now and use 405 */
+ env = cpu_ppc_init("405");
+ if (!env) {
+ fprintf(stderr, "Unable to initilize CPU!\n");
+ exit(1);
+ }
+
+ /* call init */
+ printf("Calling function ppc440_init\n");
+ ppc440_init(env, ram_bases, ram_sizes, &pic,1);
+ printf("Done calling ppc440_init\n");
+
+ /* Register mem */
+ kvm_cpu_register_physical_memory(0, ram_size, 0);
+
+ /* load kernel with uboot loader */
+ printf("%s: load kernel\n", __func__);
+ kernel_size = load_uboot(kernel_filename, &ep, &is_linux);
+ if (kernel_size < 0) {
+ fprintf(stderr, "qemu: could not load kernel '%s'\n",
+ kernel_filename);
+ exit(1);
+ }
+
+ /* load initrd */
+ if (initrd_filename) {
+ initrd_base = kernel_size + KERNEL_LOAD_ADDR;
+ initrd_size = load_image(initrd_filename,
+ phys_ram_base + initrd_base);
+
+ if (initrd_size < 0) {
+ fprintf(stderr,
+ "qemu: could not load initial ram disk '%s'\n",
+ initrd_filename);
+ exit(1);
+ }
+ }
+
+ /* XXX insert TLB entries */
+ env->gpr[1] = (16<<20) - 8;
+ env->gpr[4] = initrd_base;
+ env->gpr[5] = initrd_size;
+
+ /* Set program counter (ip in x86 terms .... but it's ep in ppc) */
+ env->nip = ep;
+ printf("Program Counter (ep) is being set to 0x%08x\n", ep);
+
+ /* lock RAM */
+ if (mlock(phys_ram_base, phys_ram_size) < 0) {
+ printf("Unable to lock physical ram!\n");
+ exit(1);
+ }
+
+ /* run in kvm */
+ /* XXX SMP IS NOT SUPPORTED YET */
+ printf("%s: running kvm functions\n", __func__);
+ env->cpu_index = 0;
+
+ printf("%s: loading kvm registers\n", __func__);
+ kvm_load_registers(env);
+
+ printf("%s: DONE\n", __func__);
+}
+
+QEMUMachine bambookvm_machine = {
+ "bambooKVM",
+ "bambooKVM",
+ bambooKVM_init,
+};
diff --git a/qemu/qemu-kvm-powerpc.c b/qemu/qemu-kvm-powerpc.c
new file mode 100644
--- /dev/null
+++ b/qemu/qemu-kvm-powerpc.c
@@ -0,0 +1,204 @@
+
+#include "config.h"
+#include "config-host.h"
+
+extern int kvm_allowed;
+extern int kvm_irqchip;
+
+#ifdef USE_KVM
+
+#include <string.h>
+#include "hw/hw.h"
+#include "sysemu.h"
+#include "cpu.h"
+#include "helper_regs.h"
+
+#include "qemu-kvm.h"
+#include <libkvm.h>
+#include <pthread.h>
+#include <sys/utsname.h>
+
+extern kvm_context_t kvm_context;
+extern __thread CPUState *vcpu_env;
+
+/* TODOs
+ * - ppc hflags work, but we need to check if generic code use hflags not
+ supported by ppc (atm it only uses some halt related flags that become
+ interesting for smp support
+ */
+
+void cpu_reset(CPUState *env)
+{
+ /* lets see how this works out using qemu function to reset
+ * env structure
+ */
+ cpu_ppc_reset(env);
+
+}
+
+
+int kvm_arch_qemu_create_context(void)
+{
+ return 0;
+}
+
+void kvm_arch_load_regs(CPUState *env)
+{
+ struct kvm_regs regs;
+ int rc,i;
+
+ rc = kvm_get_regs(kvm_context, env->cpu_index, ®s);
+ if (rc = -1)
+ perror("kvm_get_regs FAILED");
+
+ /* cr is untouched in qemu and not existant in CPUState fr ppr */
+ regs.pc = env->nip;
+
+ regs.ctr = env->ctr;
+ regs.lr = env->lr;
+ regs.xer = ppc_load_xer(env);
+ regs.msr = env->msr;
+ /* hflags is a morphed to MSR on ppc, no need to sync that down to kvm */
+
+ regs.srr0 = env->spr[SPR_SRR0];
+ regs.srr1 = env->spr[SPR_SRR1];
+
+ regs.sprg0 = env->spr[SPR_SPRG0];
+ regs.sprg1 = env->spr[SPR_SPRG1];
+ regs.sprg2 = env->spr[SPR_SPRG2];
+ regs.sprg3 = env->spr[SPR_SPRG3];
+ regs.sprg4 = env->spr[SPR_SPRG4];
+ regs.sprg5 = env->spr[SPR_SPRG5];
+ regs.sprg6 = env->spr[SPR_SPRG6];
+ regs.sprg7 = env->spr[SPR_SPRG7];
+
+ for (i = 0;i < 32; i++){
+ regs.gpr[i] = env->gpr[i];
+ regs.fpr[i] = env->fpr[i];
+ }
+
+ rc = kvm_set_regs(kvm_context, env->cpu_index, ®s);
+ if (rc = -1)
+ perror("kvm_set_regs FAILED");
+}
+
+
+void kvm_arch_save_regs(CPUState *env)
+{
+ struct kvm_regs regs;
+ uint32_t i, rc;
+
+ rc = kvm_get_regs(kvm_context, env->cpu_index, ®s);
+ if (rc = -1)
+ perror("kvm_get_regs FAILED");
+
+ env->ctr =regs.ctr;
+ env->lr = regs.lr;
+ ppc_store_xer(env,regs.xer);
+ env->msr = regs.msr;
+ /* calculate hflags based on the current msr using the ppc qemu helper */
+ hreg_compute_hflags(env);
+
+ env->nip = regs.pc;
+
+ env->spr[SPR_SRR0] = regs.srr0;
+ env->spr[SPR_SRR1] = regs.srr1;
+
+ env->spr[SPR_SPRG0] = regs.sprg0;
+ env->spr[SPR_SPRG1] = regs.sprg1;
+ env->spr[SPR_SPRG2] = regs.sprg2;
+ env->spr[SPR_SPRG3] = regs.sprg3;
+ env->spr[SPR_SPRG4] = regs.sprg4;
+ env->spr[SPR_SPRG5] = regs.sprg5;
+ env->spr[SPR_SPRG6] = regs.sprg6;
+ env->spr[SPR_SPRG7] = regs.sprg7;
+
+ for (i = 0;i < 32; i++){
+ env->gpr[i] = regs.gpr[i];
+ env->fpr[i] = regs.fpr[i];
+ }
+
+}
+
+int kvm_arch_qemu_init_env(CPUState *cenv)
+{
+ return 0;
+}
+
+int kvm_arch_halt(void *opaque, int vcpu)
+{
+ CPUState *env = cpu_single_env;
+
+ if (!(env->interrupt_request & CPU_INTERRUPT_HARD)
+ && (msr_ee))
+ {
+ env->halted = 1;
+ env->exception_index = EXCP_HLT;
+ }
+ return 1;
+}
+
+void kvm_arch_pre_kvm_run(void *opaque, int vcpu)
+{
+ return;
+}
+
+void kvm_arch_post_kvm_run(void *opaque, int vcpu)
+{
+ CPUState *env = vcpu_env;
+ cpu_single_env = env;
+ env->ready_for_interrupt_injection = \
+ kvm_is_ready_for_interrupt_injection(kvm_context, vcpu);
+}
+
+int kvm_arch_has_work(CPUState *env)
+{
+ if ((env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXIT)) &&
+ (msr_ee))
+ return 1;
+ return 0;
+}
+
+int kvm_arch_try_push_interrupts(void *opaque)
+{
+ CPUState *env = cpu_single_env;
+ int r;
+ unsigned irq;
+
+ if (env->ready_for_interrupt_injection &&
+ (env->interrupt_request & CPU_INTERRUPT_HARD))
+ {
+ env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+
+ /* For now KVM disregards the 'irq' argument. However, in the
+ * future KVM could cache it in-kernel to avoid a heavyweight exit
+ * when reading the UIC. */
+ irq = -1U;
+
+ r = kvm_inject_irq(kvm_context, env->cpu_index, irq);
+ if (r < 0)
+ printf("cpu %d fail inject %x\n", env->cpu_index, irq);
+ }
+
+ return (env->interrupt_request & CPU_INTERRUPT_HARD) != 0;
+}
+
+void kvm_arch_update_regs_for_sipi(CPUState *env)
+{
+ printf("%s: no kvm-powerpc multi processor support yet!\n", __func__);
+}
+
+/* map dcr access to existing qemu dcr emulation */
+int handle_powerpc_dcr_read(uint32_t dcrn, uint32_t *data)
+{
+ ppc_dcr_read(vcpu_env->dcr_env, dcrn, data);
+ return 0; /* XXX ignore failed DCR ops */
+}
+
+int handle_powerpc_dcr_write(uint32_t dcrn, uint32_t data)
+{
+ ppc_dcr_write(vcpu_env->dcr_env, dcrn, data);
+ return 0; /* XXX ignore failed DCR ops */
+}
+
+#endif
diff --git a/qemu/target-ppc/cpu.h b/qemu/target-ppc/cpu.h
--- a/qemu/target-ppc/cpu.h
+++ b/qemu/target-ppc/cpu.h
@@ -573,6 +573,11 @@ struct CPUPPCState {
target_ulong msr;
/* temporary general purpose registers */
ppc_gpr_t tgpr[4]; /* Used to speed-up TLB assist handlers */
+
+#ifdef USE_KVM
+ uint64_t tsc; /* time stamp counter */
+ uint8_t ready_for_interrupt_injection;
+#endif
/* Floating point execution context */
/* temporary float registers */
@@ -1421,4 +1426,11 @@ enum {
/*****************************************************************************/
+/* hidden flags (hflags) - used internally by qemu to represent additional
+ * cpu states.
+ */
+#define HF_HALTED_SHIFT 1
+
+#define HF_HALTED_MASK 1<<HF_HALTED_SHIFT
+
#endif /* !defined (__CPU_PPC_H__) */
diff --git a/qemu/vl.c b/qemu/vl.c
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -8318,6 +8318,7 @@ static void register_machines(void)
qemu_register_machine(&prep_machine);
qemu_register_machine(&ref405ep_machine);
qemu_register_machine(&taihu_machine);
+ qemu_register_machine(&bambookvm_machine);
#elif defined(TARGET_MIPS)
qemu_register_machine(&mips_machine);
qemu_register_machine(&mips_malta_machine);
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-ppc-devel mailing list
kvm-ppc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-ppc-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-01-25 23:34 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-18 21:50 [kvm-ppc-devel] [PATCH 4 of 4] Add powerpc kvm qemu support Jerone Young
2008-01-22 15:15 ` Nathan Lynch
2008-01-22 19:09 ` Jerone Young
2008-01-25 23:34 ` Jerone Young
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.