* [Qemu-devel] KVM PowerPC support v3
@ 2008-12-16 0:17 Hollis Blanchard
2008-12-16 0:17 ` [Qemu-devel] [PATCH 1/4] Implement device tree support needed for Bamboo emulation Hollis Blanchard
2008-12-16 10:44 ` [Qemu-devel] KVM PowerPC support v3 Aurelien Jarno
0 siblings, 2 replies; 10+ messages in thread
From: Hollis Blanchard @ 2008-12-16 0:17 UTC (permalink / raw)
To: qemu-devel; +Cc: kvm-ppc
I've fixed the configure output in patch #1, and the comment in patch #4. Patch
#2 was already acked.
-Hollis
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 1/4] Implement device tree support needed for Bamboo emulation
2008-12-16 0:17 [Qemu-devel] KVM PowerPC support v3 Hollis Blanchard
@ 2008-12-16 0:17 ` Hollis Blanchard
2008-12-16 0:17 ` [Qemu-devel] [PATCH 2/4] Enable KVM for ppcemb Hollis Blanchard
` (2 more replies)
2008-12-16 10:44 ` [Qemu-devel] KVM PowerPC support v3 Aurelien Jarno
1 sibling, 3 replies; 10+ messages in thread
From: Hollis Blanchard @ 2008-12-16 0:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Hollis Blanchard, kvm-ppc
To implement the -kernel, -initrd, and -append options, 4xx board emulation
must load the guest kernel as if firmware had loaded it. Where u-boot would be
the firmware, we must load the flat device tree into memory and set key fields
such as /chosen/bootargs.
This patch introduces a dependency on libfdt for flat device tree support.
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
---
Fixed configure output.
---
Makefile.target | 4 ++
configure | 18 +++++++++
device_tree.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
device_tree.h | 26 ++++++++++++
libfdt_env.h | 41 ++++++++++++++++++++
5 files changed, 203 insertions(+), 0 deletions(-)
create mode 100644 device_tree.c
create mode 100644 device_tree.h
create mode 100644 libfdt_env.h
diff --git a/Makefile.target b/Makefile.target
index 8229b4f..d80ce2c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -655,6 +655,10 @@ OBJS+= heathrow_pic.o grackle_pci.o ppc_oldworld.o
OBJS+= unin_pci.o ppc_chrp.o
# PowerPC 4xx boards
OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
+ifdef FDT_LIBS
+OBJS+= device_tree.o
+LIBS+= $(FDT_LIBS)
+endif
# virtio support
OBJS+= virtio.o virtio-blk.o virtio-balloon.o
endif
diff --git a/configure b/configure
index abed7af..c4aa881 100755
--- a/configure
+++ b/configure
@@ -119,6 +119,7 @@ kvm="yes"
kerneldir=""
aix="no"
blobs="yes"
+fdt="yes"
# OS specific
targetos=`uname -s`
@@ -966,6 +967,18 @@ if $cc $ARCH_CFLAGS -o $TMPE $TMPC > /dev/null 2> /dev/null ; then
iovec=yes
fi
+##########################################
+# fdt probe
+if test "$fdt" = "yes" ; then
+ fdt=no
+ cat > $TMPC << EOF
+int main(void) { return 0; }
+EOF
+ if $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $TMPC -lfdt 2> /dev/null ; then
+ fdt=yes
+ fi
+fi
+
# Check if tools are available to build documentation.
if [ -x "`which texi2html 2>/dev/null`" ] && \
[ -x "`which pod2man 2>/dev/null`" ]; then
@@ -1061,6 +1074,7 @@ echo "vde support $vde"
echo "AIO support $aio"
echo "Install blobs $blobs"
echo "KVM support $kvm"
+echo "fdt support $fdt"
if test $sdl_too_old = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -1350,6 +1364,10 @@ fi
if test "$iovec" = "yes" ; then
echo "#define HAVE_IOVEC 1" >> $config_h
fi
+if test "$fdt" = "yes" ; then
+ echo "#define HAVE_FDT 1" >> $config_h
+ echo "FDT_LIBS=-lfdt" >> $config_mak
+fi
# XXX: suppress that
if [ "$bsd" = "yes" ] ; then
diff --git a/device_tree.c b/device_tree.c
new file mode 100644
index 0000000..2238682
--- /dev/null
+++ b/device_tree.c
@@ -0,0 +1,114 @@
+/*
+ * Functions to help device tree manipulation using libfdt.
+ * It also provides functions to read entries from device tree proc
+ * interface.
+ *
+ * Copyright 2008 IBM Corporation.
+ * Authors: Jerone Young <jyoung5@us.ibm.com>
+ * Hollis Blanchard <hollisb@us.ibm.com>
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "qemu-common.h"
+#include "sysemu.h"
+#include "device_tree.h"
+
+#include <libfdt.h>
+
+void *load_device_tree(const char *filename_path, void *load_addr)
+{
+ int dt_file_size;
+ int dt_file_load_size;
+ int new_dt_size;
+ int ret;
+ void *dt_file = NULL;
+ void *fdt;
+
+ dt_file_size = get_image_size(filename_path);
+ if (dt_file_size < 0) {
+ printf("Unable to get size of device tree file '%s'\n",
+ filename_path);
+ goto fail;
+ }
+
+ /* First allocate space in qemu for device tree */
+ dt_file = qemu_mallocz(dt_file_size);
+ if (dt_file == NULL) {
+ printf("Unable to allocate memory in qemu for device tree\n");
+ goto fail;
+ }
+
+ dt_file_load_size = load_image(filename_path, dt_file);
+
+ /* Second we place new copy of 2x size in guest memory
+ * This give us enough room for manipulation.
+ */
+ new_dt_size = dt_file_size * 2;
+
+ fdt = load_addr;
+ ret = fdt_open_into(dt_file, fdt, new_dt_size);
+ if (ret) {
+ printf("Unable to copy device tree in memory\n");
+ goto fail;
+ }
+
+ /* Check sanity of device tree */
+ if (fdt_check_header(fdt)) {
+ printf ("Device tree file loaded into memory is invalid: %s\n",
+ filename_path);
+ goto fail;
+ }
+ /* free qemu memory with old device tree */
+ qemu_free(dt_file);
+ return fdt;
+
+fail:
+ qemu_free(dt_file);
+ return NULL;
+}
+
+int qemu_devtree_setprop(void *fdt, const char *node_path,
+ const char *property, uint32_t *val_array, int size)
+{
+ int offset;
+
+ offset = fdt_path_offset(fdt, node_path);
+ if (offset < 0)
+ return offset;
+
+ return fdt_setprop(fdt, offset, property, val_array, size);
+}
+
+int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
+ const char *property, uint32_t val)
+{
+ int offset;
+
+ offset = fdt_path_offset(fdt, node_path);
+ if (offset < 0)
+ return offset;
+
+ return fdt_setprop_cell(fdt, offset, property, val);
+}
+
+int qemu_devtree_setprop_string(void *fdt, const char *node_path,
+ const char *property, const char *string)
+{
+ int offset;
+
+ offset = fdt_path_offset(fdt, node_path);
+ if (offset < 0)
+ return offset;
+
+ return fdt_setprop_string(fdt, offset, property, string);
+}
diff --git a/device_tree.h b/device_tree.h
new file mode 100644
index 0000000..9e6ef3d
--- /dev/null
+++ b/device_tree.h
@@ -0,0 +1,26 @@
+/*
+ * Header with function prototypes to help device tree manipulation using
+ * libfdt. It also provides functions to read entries from device tree proc
+ * interface.
+ *
+ * Copyright 2008 IBM Corporation.
+ * Authors: Jerone Young <jyoung5@us.ibm.com>
+ * Hollis Blanchard <hollisb@us.ibm.com>
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#ifndef __DEVICE_TREE_H__
+#define __DEVICE_TREE_H__
+
+void *load_device_tree(const char *filename_path, void *load_addr);
+
+int qemu_devtree_setprop(void *fdt, const char *node_path,
+ const char *property, uint32_t *val_array, int size);
+int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
+ const char *property, uint32_t val);
+int qemu_devtree_setprop_string(void *fdt, const char *node_path,
+ const char *property, const char *string);
+
+#endif /* __DEVICE_TREE_H__ */
diff --git a/libfdt_env.h b/libfdt_env.h
new file mode 100644
index 0000000..e154b8e
--- /dev/null
+++ b/libfdt_env.h
@@ -0,0 +1,41 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright IBM Corp. 2008
+ * Authors: Hollis Blanchard <hollisb@us.ibm.com>
+ *
+ */
+
+#ifndef _LIBFDT_ENV_H
+#define _LIBFDT_ENV_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <endian.h>
+#include <byteswap.h>
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define fdt32_to_cpu(x) (x)
+#define cpu_to_fdt32(x) (x)
+#define fdt64_to_cpu(x) (x)
+#define cpu_to_fdt64(x) (x)
+#else
+#define fdt32_to_cpu(x) (bswap_32((x)))
+#define cpu_to_fdt32(x) (bswap_32((x)))
+#define fdt64_to_cpu(x) (bswap_64((x)))
+#define cpu_to_fdt64(x) (bswap_64((x)))
+#endif
+
+#endif /* _LIBFDT_ENV_H */
--
1.5.6.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 2/4] Enable KVM for ppcemb.
2008-12-16 0:17 ` [Qemu-devel] [PATCH 1/4] Implement device tree support needed for Bamboo emulation Hollis Blanchard
@ 2008-12-16 0:17 ` Hollis Blanchard
2008-12-16 0:17 ` [Qemu-devel] [PATCH 3/4] PowerPC 440EP SoC emulation Hollis Blanchard
2008-12-16 0:17 ` [Qemu-devel] [PATCH 4/4] IBM PowerPC 440EP Bamboo reference board emulation Hollis Blanchard
2 siblings, 0 replies; 10+ messages in thread
From: Hollis Blanchard @ 2008-12-16 0:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Hollis Blanchard, kvm-ppc
Implement hooks called by generic KVM code.
Also add code that will copy the host's CPU and timebase frequencies to the
guest, which is necessary on KVM because the guest can directly access the
timebase.
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
Acked-by: Anthony Liguori <aliguori@us.ibm.com>
---
Makefile.target | 3 +
configure | 6 ++
target-ppc/helper.c | 5 +
target-ppc/kvm.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++++++
target-ppc/kvm_ppc.c | 110 +++++++++++++++++++++++++++
target-ppc/kvm_ppc.h | 15 ++++
6 files changed, 343 insertions(+), 0 deletions(-)
create mode 100644 target-ppc/kvm.c
create mode 100644 target-ppc/kvm_ppc.c
create mode 100644 target-ppc/kvm_ppc.h
diff --git a/Makefile.target b/Makefile.target
index d80ce2c..cbff562 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -659,6 +659,9 @@ ifdef FDT_LIBS
OBJS+= device_tree.o
LIBS+= $(FDT_LIBS)
endif
+ifdef CONFIG_KVM
+OBJS+= kvm_ppc.o
+endif
# virtio support
OBJS+= virtio.o virtio-blk.o virtio-balloon.o
endif
diff --git a/configure b/configure
index c4aa881..4f8bc5e 100755
--- a/configure
+++ b/configure
@@ -1491,6 +1491,7 @@ gdb_xml_files=""
# Make sure the target and host cpus are compatible
if test "$kvm" = "yes" -a ! \( "$target_cpu" = "$cpu" -o \
+ \( "$target_cpu" = "ppcemb" -a "$cpu" = "powerpc" \) -o \
\( "$target_cpu" = "x86_64" -a "$cpu" = "i386" \) -o \
\( "$target_cpu" = "i386" -a "$cpu" = "x86_64" \) \) ; then
kvm="no"
@@ -1585,6 +1586,11 @@ case "$target_cpu" in
echo "#define TARGET_ARCH \"ppcemb\"" >> $config_h
echo "#define TARGET_PPC 1" >> $config_h
echo "#define TARGET_PPCEMB 1" >> $config_h
+ if test "$kvm" = "yes" ; then
+ echo "CONFIG_KVM=yes" >> $config_mak
+ echo "KVM_CFLAGS=$kvm_cflags" >> $config_mak
+ echo "#define CONFIG_KVM 1" >> $config_h
+ fi
;;
ppc64)
echo "TARGET_ARCH=ppc64" >> $config_mak
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 538d9f3..4676d50 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -29,6 +29,7 @@
#include "exec-all.h"
#include "helper_regs.h"
#include "qemu-common.h"
+#include "kvm.h"
//#define DEBUG_MMU
//#define DEBUG_BATS
@@ -2920,6 +2921,10 @@ CPUPPCState *cpu_ppc_init (const char *cpu_model)
env->cpu_model_str = cpu_model;
cpu_ppc_register_internal(env, def);
cpu_ppc_reset(env);
+
+ if (kvm_enabled())
+ kvm_init_vcpu(env);
+
return env;
}
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
new file mode 100644
index 0000000..acbb1ab
--- /dev/null
+++ b/target-ppc/kvm.c
@@ -0,0 +1,204 @@
+/*
+ * PowerPC implementation of KVM hooks
+ *
+ * Copyright IBM Corp. 2007
+ *
+ * Authors:
+ * Jerone Young <jyoung5@us.ibm.com>
+ * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
+ * Hollis Blanchard <hollisb@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include <linux/kvm.h>
+
+#include "qemu-common.h"
+#include "qemu-timer.h"
+#include "sysemu.h"
+#include "kvm.h"
+#include "kvm_ppc.h"
+#include "cpu.h"
+#include "device_tree.h"
+
+//#define DEBUG_KVM
+
+#ifdef DEBUG_KVM
+#define dprintf(fmt, ...) \
+ do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define dprintf(fmt, ...) \
+ do { } while (0)
+#endif
+
+int kvm_arch_init(KVMState *s, int smp_cpus)
+{
+ return 0;
+}
+
+int kvm_arch_init_vcpu(CPUState *cenv)
+{
+ return 0;
+}
+
+int kvm_arch_put_registers(CPUState *env)
+{
+ struct kvm_regs regs;
+ int ret;
+ int i;
+
+ ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, ®s);
+ if (ret < 0)
+ return ret;
+
+ regs.ctr = env->ctr;
+ regs.lr = env->lr;
+ regs.xer = env->xer;
+ regs.msr = env->msr;
+ regs.pc = env->nip;
+
+ 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];
+
+ ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, ®s);
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+
+int kvm_arch_get_registers(CPUState *env)
+{
+ struct kvm_regs regs;
+ uint32_t i, ret;
+
+ ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, ®s);
+ if (ret < 0)
+ return ret;
+
+ env->ctr = regs.ctr;
+ env->lr = regs.lr;
+ env->xer = regs.xer;
+ env->msr = regs.msr;
+ 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];
+
+ return 0;
+}
+
+int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
+{
+ int r;
+ unsigned irq;
+
+ /* PowerPC Qemu tracks the various core input pins (interrupt, critical
+ * interrupt, reset, etc) in PPC-specific env->irq_input_state. */
+ if (run->ready_for_interrupt_injection &&
+ (env->interrupt_request & CPU_INTERRUPT_HARD) &&
+ (env->irq_input_state & (1<<PPC40x_INPUT_INT)))
+ {
+ /* 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;
+
+ dprintf("injected interrupt %d\n", irq);
+ r = kvm_vcpu_ioctl(env, KVM_INTERRUPT, &irq);
+ if (r < 0)
+ printf("cpu %d fail inject %x\n", env->cpu_index, irq);
+ }
+
+ /* We don't know if there are more interrupts pending after this. However,
+ * the guest will return to userspace in the course of handling this one
+ * anyways, so we will get a chance to deliver the rest. */
+ return 0;
+}
+
+int kvm_arch_post_run(CPUState *env, struct kvm_run *run)
+{
+ return 0;
+}
+
+static int kvmppc_handle_halt(CPUState *env)
+{
+ if (!(env->interrupt_request & CPU_INTERRUPT_HARD) && (msr_ee)) {
+ env->halted = 1;
+ env->exception_index = EXCP_HLT;
+ }
+
+ return 1;
+}
+
+/* map dcr access to existing qemu dcr emulation */
+static int kvmppc_handle_dcr_read(CPUState *env, uint32_t dcrn, uint32_t *data)
+{
+ if (ppc_dcr_read(env->dcr_env, dcrn, data) < 0)
+ fprintf(stderr, "Read to unhandled DCR (0x%x)\n", dcrn);
+
+ return 1;
+}
+
+static int kvmppc_handle_dcr_write(CPUState *env, uint32_t dcrn, uint32_t data)
+{
+ if (ppc_dcr_write(env->dcr_env, dcrn, data) < 0)
+ fprintf(stderr, "Write to unhandled DCR (0x%x)\n", dcrn);
+
+ return 1;
+}
+
+int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
+{
+ int ret = 0;
+
+ switch (run->exit_reason) {
+ case KVM_EXIT_DCR:
+ if (run->dcr.is_write) {
+ dprintf("handle dcr write\n");
+ ret = kvmppc_handle_dcr_write(env, run->dcr.dcrn, run->dcr.data);
+ } else {
+ dprintf("handle dcr read\n");
+ ret = kvmppc_handle_dcr_read(env, run->dcr.dcrn, &run->dcr.data);
+ }
+ break;
+ case KVM_EXIT_HLT:
+ dprintf("handle halt\n");
+ ret = kvmppc_handle_halt(env);
+ break;
+ }
+
+ return ret;
+}
+
diff --git a/target-ppc/kvm_ppc.c b/target-ppc/kvm_ppc.c
new file mode 100644
index 0000000..0caa5b9
--- /dev/null
+++ b/target-ppc/kvm_ppc.c
@@ -0,0 +1,110 @@
+/*
+ * PowerPC KVM support
+ *
+ * Copyright IBM Corp. 2008
+ *
+ * Authors:
+ * Hollis Blanchard <hollisb@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu-common.h"
+#include "qemu-timer.h"
+#include "kvm_ppc.h"
+#include "device_tree.h"
+
+#define PROC_DEVTREE_PATH "/proc/device-tree"
+
+static QEMUTimer *kvmppc_timer;
+static unsigned int kvmppc_timer_rate;
+
+#ifdef HAVE_FDT
+static int kvmppc_read_host_property(const char *node_path, const char *prop,
+ void *val, size_t len)
+{
+ char *path;
+ FILE *f;
+ int ret;
+ int pathlen;
+
+ pathlen = snprintf(NULL, 0, "%s/%s/%s", PROC_DEVTREE_PATH, node_path, prop)
+ + 1;
+ path = qemu_malloc(pathlen);
+ if (path == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ snprintf(path, pathlen, "%s/%s/%s", PROC_DEVTREE_PATH, node_path, prop);
+
+ f = fopen(path, "rb");
+ if (f == NULL) {
+ ret = errno;
+ goto free;
+ }
+
+ len = fread(val, len, 1, f);
+ if (len != 1) {
+ ret = ferror(f);
+ goto close;
+ }
+
+close:
+ fclose(f);
+free:
+ free(path);
+out:
+ return ret;
+}
+
+static int kvmppc_copy_host_cell(void *fdt, const char *node, const char *prop)
+{
+ uint32_t cell;
+ int ret;
+
+ ret = kvmppc_read_host_property(node, prop, &cell, sizeof(cell));
+ if (ret < 0) {
+ fprintf(stderr, "couldn't read host %s/%s\n", node, prop);
+ goto out;
+ }
+
+ ret = qemu_devtree_setprop_cell(fdt, node, prop, cell);
+ if (ret < 0) {
+ fprintf(stderr, "couldn't set guest %s/%s\n", node, prop);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+void kvmppc_fdt_update(void *fdt)
+{
+ /* Copy data from the host device tree into the guest. Since the guest can
+ * directly access the timebase without host involvement, we must expose
+ * the correct frequencies. */
+ kvmppc_copy_host_cell(fdt, "/cpus/cpu@0", "clock-frequency");
+ kvmppc_copy_host_cell(fdt, "/cpus/cpu@0", "timebase-frequency");
+}
+#endif
+
+static void kvmppc_timer_hack(void *opaque)
+{
+ qemu_service_io();
+ qemu_mod_timer(kvmppc_timer, qemu_get_clock(vm_clock) + kvmppc_timer_rate);
+}
+
+void kvmppc_init(void)
+{
+ /* XXX The only reason KVM yields control back to qemu is device IO. Since
+ * an idle guest does no IO, qemu's device model will never get a chance to
+ * run. So, until Qemu gains IO threads, we create this timer to ensure
+ * that the device model gets a chance to run. */
+ kvmppc_timer_rate = ticks_per_sec / 10;
+ kvmppc_timer = qemu_new_timer(vm_clock, &kvmppc_timer_hack, NULL);
+ qemu_mod_timer(kvmppc_timer, qemu_get_clock(vm_clock) + kvmppc_timer_rate);
+}
+
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
new file mode 100644
index 0000000..e536a88
--- /dev/null
+++ b/target-ppc/kvm_ppc.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2008 IBM Corporation.
+ * Authors: Hollis Blanchard <hollisb@us.ibm.com>
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#ifndef __KVM_PPC_H__
+#define __KVM_PPC_H__
+
+void kvmppc_init(void);
+void kvmppc_fdt_update(void *fdt);
+
+#endif /* __KVM_PPC_H__ */
--
1.5.6.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 3/4] PowerPC 440EP SoC emulation
2008-12-16 0:17 ` [Qemu-devel] [PATCH 1/4] Implement device tree support needed for Bamboo emulation Hollis Blanchard
2008-12-16 0:17 ` [Qemu-devel] [PATCH 2/4] Enable KVM for ppcemb Hollis Blanchard
@ 2008-12-16 0:17 ` Hollis Blanchard
2008-12-16 10:45 ` Aurelien Jarno
2008-12-16 0:17 ` [Qemu-devel] [PATCH 4/4] IBM PowerPC 440EP Bamboo reference board emulation Hollis Blanchard
2 siblings, 1 reply; 10+ messages in thread
From: Hollis Blanchard @ 2008-12-16 0:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Hollis Blanchard, kvm-ppc
Wire up the system-on-chip devices present on 440EP chips.
This patch is a little unusual in that qemu doesn't actually emulate the 440
core, but we use this board code with KVM (which does). If/when 440 core
emulation is supported, the kvm_enabled() hack can be removed.
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
---
Makefile.target | 1 +
hw/ppc440.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/ppc440.h | 20 +++++++++++
3 files changed, 124 insertions(+), 0 deletions(-)
create mode 100644 hw/ppc440.c
create mode 100644 hw/ppc440.h
diff --git a/Makefile.target b/Makefile.target
index cbff562..ef2d25f 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -655,6 +655,7 @@ OBJS+= heathrow_pic.o grackle_pci.o ppc_oldworld.o
OBJS+= unin_pci.o ppc_chrp.o
# PowerPC 4xx boards
OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
+OBJS+= ppc440.o
ifdef FDT_LIBS
OBJS+= device_tree.o
LIBS+= $(FDT_LIBS)
diff --git a/hw/ppc440.c b/hw/ppc440.c
new file mode 100644
index 0000000..00d82e4
--- /dev/null
+++ b/hw/ppc440.c
@@ -0,0 +1,103 @@
+/*
+ * Qemu PowerPC 440 chip emulation
+ *
+ * Copyright 2007 IBM Corporation.
+ * Authors:
+ * Jerone Young <jyoung5@us.ibm.com>
+ * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
+ * Hollis Blanchard <hollisb@us.ibm.com>
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#include "hw.h"
+#include "isa.h"
+#include "ppc.h"
+#include "ppc4xx.h"
+#include "ppc440.h"
+#include "ppc405.h"
+#include "sysemu.h"
+#include "kvm.h"
+
+#define PPC440EP_PCI_CONFIG 0xeec00000
+#define PPC440EP_PCI_INTACK 0xeed00000
+#define PPC440EP_PCI_SPECIAL 0xeed00000
+#define PPC440EP_PCI_REGS 0xef400000
+#define PPC440EP_PCI_IO 0xe8000000
+#define PPC440EP_PCI_IOLEN 0x00010000
+
+#define PPC440EP_SDRAM_NR_BANKS 4
+
+static const unsigned int ppc440ep_sdram_bank_sizes[] = {
+ 256<<20, 128<<20, 64<<20, 32<<20, 16<<20, 8<<20, 0
+};
+
+CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip,
+ const unsigned int pci_irq_nrs[4], int do_init)
+{
+ target_phys_addr_t ram_bases[PPC440EP_SDRAM_NR_BANKS];
+ target_phys_addr_t ram_sizes[PPC440EP_SDRAM_NR_BANKS];
+ CPUState *env;
+ ppc4xx_mmio_t *mmio;
+ qemu_irq *pic;
+ qemu_irq *irqs;
+ qemu_irq *pci_irqs;
+
+ env = cpu_ppc_init("440EP");
+ if (!env && kvm_enabled()) {
+ /* XXX Since qemu doesn't yet emulate 440, we just say it's a 405.
+ * Since KVM doesn't use qemu's CPU emulation it seems to be working
+ * OK. */
+ env = cpu_ppc_init("405");
+ }
+ if (!env) {
+ fprintf(stderr, "Unable to initialize CPU!\n");
+ exit(1);
+ }
+
+ ppc_dcr_init(env, NULL, NULL);
+
+ /* interrupt controller */
+ 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);
+
+ /* SDRAM controller */
+ memset(ram_bases, 0, sizeof(ram_bases));
+ memset(ram_sizes, 0, sizeof(ram_sizes));
+ *ram_size = ppc4xx_sdram_adjust(*ram_size, PPC440EP_SDRAM_NR_BANKS,
+ ram_bases, ram_sizes,
+ ppc440ep_sdram_bank_sizes);
+ /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */
+ ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_bases,
+ ram_sizes, do_init);
+
+ /* PCI */
+ pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4);
+ pci_irqs[0] = pic[pci_irq_nrs[0]];
+ pci_irqs[1] = pic[pci_irq_nrs[1]];
+ pci_irqs[2] = pic[pci_irq_nrs[2]];
+ pci_irqs[3] = pic[pci_irq_nrs[3]];
+ *pcip = ppc4xx_pci_init(env, pci_irqs,
+ PPC440EP_PCI_CONFIG,
+ PPC440EP_PCI_INTACK,
+ PPC440EP_PCI_SPECIAL,
+ PPC440EP_PCI_REGS);
+ if (!*pcip)
+ printf("couldn't create PCI controller!\n");
+
+ isa_mmio_init(PPC440EP_PCI_IO, PPC440EP_PCI_IOLEN);
+
+ /* MMIO -- most "miscellaneous" devices live above 0xef600000. */
+ mmio = ppc4xx_mmio_init(env, 0xef600000);
+
+ if (serial_hds[0])
+ ppc405_serial_init(env, mmio, 0x300, pic[0], serial_hds[0]);
+
+ if (serial_hds[1])
+ ppc405_serial_init(env, mmio, 0x400, pic[1], serial_hds[1]);
+
+ return env;
+}
diff --git a/hw/ppc440.h b/hw/ppc440.h
new file mode 100644
index 0000000..b6843eb
--- /dev/null
+++ b/hw/ppc440.h
@@ -0,0 +1,20 @@
+/*
+ * Qemu PowerPC 440 board emualtion
+ *
+ * Copyright 2007 IBM Corporation.
+ * Authors: Jerone Young <jyoung5@us.ibm.com>
+ * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the GNU GPL licence version 2 or later
+ *
+ */
+
+#ifndef QEMU_PPC440_H
+#define QEMU_PPC440_H
+
+#include "hw.h"
+
+CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip,
+ const unsigned int pci_irq_nrs[4], int do_init);
+
+#endif
--
1.5.6.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 4/4] IBM PowerPC 440EP Bamboo reference board emulation
2008-12-16 0:17 ` [Qemu-devel] [PATCH 1/4] Implement device tree support needed for Bamboo emulation Hollis Blanchard
2008-12-16 0:17 ` [Qemu-devel] [PATCH 2/4] Enable KVM for ppcemb Hollis Blanchard
2008-12-16 0:17 ` [Qemu-devel] [PATCH 3/4] PowerPC 440EP SoC emulation Hollis Blanchard
@ 2008-12-16 0:17 ` Hollis Blanchard
2008-12-16 10:47 ` Aurelien Jarno
2 siblings, 1 reply; 10+ messages in thread
From: Hollis Blanchard @ 2008-12-16 0:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Hollis Blanchard, kvm-ppc
Since most IO devices are integrated into the 440EP chip, "Bamboo support"
mostly entails implementing the -kernel, -initrd, and -append options.
These options are implemented by loading the guest as if u-boot had done it,
i.e. loading a flat device tree, updating it to hold initrd addresses, ram
size, and command line, and passing the FDT address in r3.
Since we use it with KVM, we enable the virtio block driver and include hooks
necessary for KVM support.
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
---
Made comment more specific.
---
Makefile | 2 +-
Makefile.target | 2 +-
hw/boards.h | 1 +
hw/ppc440_bamboo.c | 190 ++++++++++++++++++++++++++++++++++++++++
pc-bios/bamboo.dtb | Bin 0 -> 3163 bytes
pc-bios/bamboo.dts | 234 ++++++++++++++++++++++++++++++++++++++++++++++++++
target-ppc/machine.c | 1 +
7 files changed, 428 insertions(+), 2 deletions(-)
create mode 100644 hw/ppc440_bamboo.c
create mode 100644 pc-bios/bamboo.dtb
create mode 100644 pc-bios/bamboo.dts
diff --git a/Makefile b/Makefile
index 01f0121..85523d7 100644
--- a/Makefile
+++ b/Makefile
@@ -222,7 +222,7 @@ common de-ch es fo fr-ca hu ja mk nl-be pt sl tr
ifdef INSTALL_BLOBS
BLOBS=bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \
video.x openbios-sparc32 openbios-sparc64 pxe-ne2k_pci.bin \
-pxe-rtl8139.bin pxe-pcnet.bin pxe-e1000.bin
+pxe-rtl8139.bin pxe-pcnet.bin pxe-e1000.bin bamboo.dtb
else
BLOBS=
endif
diff --git a/Makefile.target b/Makefile.target
index ef2d25f..c4d0f05 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -655,7 +655,7 @@ OBJS+= heathrow_pic.o grackle_pci.o ppc_oldworld.o
OBJS+= unin_pci.o ppc_chrp.o
# PowerPC 4xx boards
OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
-OBJS+= ppc440.o
+OBJS+= ppc440.o ppc440_bamboo.o
ifdef FDT_LIBS
OBJS+= device_tree.o
LIBS+= $(FDT_LIBS)
diff --git a/hw/boards.h b/hw/boards.h
index a7b8126..bff1cf0 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -38,6 +38,7 @@ extern QEMUMachine core99_machine;
extern QEMUMachine heathrow_machine;
extern QEMUMachine ref405ep_machine;
extern QEMUMachine taihu_machine;
+extern QEMUMachine bamboo_machine;
/* mips_r4k.c */
extern QEMUMachine mips_machine;
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
new file mode 100644
index 0000000..a6fc758
--- /dev/null
+++ b/hw/ppc440_bamboo.c
@@ -0,0 +1,190 @@
+/*
+ * Qemu PowerPC 440 Bamboo board emulation
+ *
+ * Copyright 2007 IBM Corporation.
+ * Authors:
+ * Jerone Young <jyoung5@us.ibm.com>
+ * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
+ * Hollis Blanchard <hollisb@us.ibm.com>
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#include "config.h"
+#include "qemu-common.h"
+#include "net.h"
+#include "hw.h"
+#include "pci.h"
+#include "virtio-blk.h"
+#include "boards.h"
+#include "sysemu.h"
+#include "ppc440.h"
+#include "kvm.h"
+#include "kvm_ppc.h"
+#include "device_tree.h"
+
+#define BINARY_DEVICE_TREE_FILE "bamboo.dtb"
+
+static void *bamboo_load_device_tree(void *addr,
+ uint32_t ramsize,
+ target_phys_addr_t initrd_base,
+ target_phys_addr_t initrd_size,
+ const char *kernel_cmdline)
+{
+ void *fdt = NULL;
+#ifdef HAVE_FDT
+ uint32_t mem_reg_property[] = { 0, 0, ramsize };
+ char *path;
+ int pathlen;
+ int ret;
+
+ pathlen = snprintf(NULL, 0, "%s/%s", bios_dir, BINARY_DEVICE_TREE_FILE) + 1;
+ path = qemu_malloc(pathlen);
+ if (path == NULL)
+ return NULL;
+
+ snprintf(path, pathlen, "%s/%s", bios_dir, BINARY_DEVICE_TREE_FILE);
+
+ fdt = load_device_tree(path, addr);
+ free(path);
+ if (fdt == NULL)
+ goto out;
+
+ /* Manipulate device tree in memory. */
+
+ ret = qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,
+ sizeof(mem_reg_property));
+ if (ret < 0)
+ fprintf(stderr, "couldn't set /memory/reg\n");
+
+ ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
+ initrd_base);
+ if (ret < 0)
+ fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
+
+ ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
+ (initrd_base + initrd_size));
+ if (ret < 0)
+ fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
+
+ ret = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
+ kernel_cmdline);
+ if (ret < 0)
+ fprintf(stderr, "couldn't set /chosen/bootargs\n");
+
+ if (kvm_enabled())
+ kvmppc_fdt_update(fdt);
+
+out:
+#endif
+
+ return fdt;
+}
+
+static void bamboo_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)
+{
+ unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 };
+ NICInfo *nd;
+ PCIBus *pcibus;
+ CPUState *env;
+ uint64_t elf_entry;
+ uint64_t elf_lowaddr;
+ target_ulong entry = 0;
+ target_ulong loadaddr = 0;
+ target_long kernel_size = 0;
+ target_ulong initrd_base = 0;
+ target_long initrd_size = 0;
+ target_ulong dt_base = 0;
+ void *fdt;
+ int i;
+
+ /* Setup CPU. */
+ env = ppc440ep_init(&ram_size, &pcibus, pci_irq_nrs, 1);
+
+ if (pcibus) {
+ int unit_id = 0;
+
+ /* Add virtio block devices. */
+ while ((i = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) {
+ virtio_blk_init(pcibus, drives_table[i].bdrv);
+ unit_id++;
+ }
+
+ /* Register network interfaces. */
+ for (i = 0; i < nb_nics; i++) {
+ nd = &nd_table[i];
+ if (!nd->model) {
+ /* There are no PCI NICs on the Bamboo board, but there are
+ * PCI slots, so we can pick model whatever we want. */
+ nd->model = "e1000";
+ }
+ pci_nic_init(pcibus, nd, -1);
+ }
+ }
+
+ /* Load kernel. */
+ if (kernel_filename) {
+ kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
+ if (kernel_size < 0) {
+ kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_lowaddr,
+ NULL);
+ entry = elf_entry;
+ loadaddr = elf_lowaddr;
+ }
+ /* XXX try again as binary */
+ 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 + loadaddr;
+ 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);
+ }
+ }
+
+ /* If we're loading a kernel directly, we must load the device tree too. */
+ if (kernel_filename) {
+ if (initrd_base)
+ dt_base = initrd_base + initrd_size;
+ else
+ dt_base = kernel_size + loadaddr;
+
+ fdt = bamboo_load_device_tree(phys_ram_base + dt_base, ram_size,
+ initrd_base, initrd_size, kernel_cmdline);
+ if (fdt == NULL) {
+ fprintf(stderr, "couldn't load device tree\n");
+ exit(1);
+ }
+
+ /* Set initial guest state. */
+ env->gpr[1] = (16<<20) - 8;
+ env->gpr[3] = dt_base;
+ env->nip = entry;
+ /* XXX we currently depend on KVM to create some initial TLB entries. */
+ }
+
+ if (kvm_enabled())
+ kvmppc_init();
+}
+
+QEMUMachine bamboo_machine = {
+ .name = "bamboo",
+ .desc = "bamboo",
+ .init = bamboo_init,
+ .ram_require = 8<<20 | RAMSIZE_FIXED,
+};
diff --git a/pc-bios/bamboo.dtb b/pc-bios/bamboo.dtb
new file mode 100644
index 0000000000000000000000000000000000000000..81f971c64745aaf79152e1ed6f09e5d36137e461
GIT binary patch
literal 3163
zcmcImL5mzk6s|Ug7)f*!MATKBWg~i+W+!nr$w>!A=Hg)?!X8Alr@D5hN%wTy-Lvj4
z2qRv-_y<JrBKikB$>K%ul&il$FUf)@1qpuN>#Clb*$IMRL3O?Fy;rZk_o}+9?_GX)
zU#Uy)E2VBL_2ds2UqiowzV`6`kEcon-#|YDUT%R^oWuCIl^?_C@Y9g#LwpH+J<7E1
zj-qUo=YXw#V}+jay6BuAL}?OLrh?eUz6IG|>rHE;F3`nPoIQVtEf>ZnH#YhXdX4OO
z522%m_$l=Do%|D1?!4XY_j~W`&@$(7r-3c6-IsqkPZt+!Klt=;;NfG)9S?u8guha1
z230%%dk<63{bB42=s!=QIyo?q=KjAzX3ba!sYPb8ygUM$&l@i3xHm2jbx~ZKxyht9
zWjQVCQ0J4n%+u7AUag*m>qauly3<65sEsL<MNJIyWcv->)#Go`H24WnWgaK!T-NzO
zl;*J8D~khSfA5(y_f+z&;*yi;%e@nR&{=*oiOsD|pSD)II6D`*N6ls3+POtKa<N~5
zAnQWs)y1Oyrb<A4PC#>cQf54dnWuYyD0c90w%rSVeD)r2fZU=C0vc@{beD6Kd8><G
z*zav)eKh*I8mvKX^N6#^*<XYpv7qxJS#%~2sj64e87s((wjS4jB@T369E)r{Jb&&b
zo6DWpuSLh!f<Dq_c(Sw2Y{%eoBqyFT#%b$!?ytdjz=0WQ45Gh=QFub<@wCYD^!#1@
zu410QZ;a<-pF271+O>Ut=b>l5QoG8ONt6!E-pyX`^`5+O^koji#s;a)Pi;)9>o>Qz
zTR-qpcTPXz6z;LhIk;hUGzbs%?Fq!z{)P&E^6|R>u4c@Yb!2loj(qpX`3&#=f9B1w
z%e+PRXx^ML&tnyD)^?dU;|cHNhHi>|t06s)rG~HpE}oBM;d^J1Js&{M-|hpqO+8~{
zfJ3l~A9;}9BA?s;2OrY<S3d525k4l1ba<R4NmHfRvSR&swudx@a#`#}dVU}AyvX|`
z_W1?jpsg4oJewNZnq4Md{Jv_eu6xpGMC1Cb*|5+Oz+$-{mcJd$!}&uLnfN7i;mGeX
zudtB8c#ZLMZ3A0>48aFh=F28`=7SSR&3RQ1?ukrJ3-ake^n7wn{AUFn5@P#Wp7XH-
zO!9vF-GRoy82B~^<}IgR8fOir-x~Z1rT$#<5FXG6pIhp_o&5Rj$6jFiVxw&x9k%Bd
zEzMrM(AYYwY|l3~IpcD!^f<4~L|n-g_TbAc)O`z=!Pbh8AbdEF{o-a6$EB&NP@6QZ
z)Mk|&8!KmdY*MB3tib=#C^ah9WmrU|nbfL@+Oy+z6`O-Zn-A-w!l=^hE1l;0Zn#&P
zkEdp$k5rvxW`v(lPnCo^(qj{*$;5<QR>fyD&S$~g0C1WAO$oI~YbKJJdYs1!VW)@P
zVjN9kP+#>6rkFC`x7ZxYeDdD(9Hk&-G}*^5bE~e@K~mP!C=DgeX~}YgRbfm#cXCxK
i$|Q^M*T}1WIZ&8I1$uSYn+BETUDa_utr4dltA7BYxVh&5
literal 0
HcmV?d00001
diff --git a/pc-bios/bamboo.dts b/pc-bios/bamboo.dts
new file mode 100644
index 0000000..655442c
--- /dev/null
+++ b/pc-bios/bamboo.dts
@@ -0,0 +1,234 @@
+/*
+ * Device Tree Source for AMCC Bamboo
+ *
+ * Copyright (c) 2006, 2007 IBM Corp.
+ * Josh Boyer <jwboyer@linux.vnet.ibm.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ */
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ model = "amcc,bamboo";
+ compatible = "amcc,bamboo";
+ dcr-parent = <&/cpus/cpu@0>;
+
+ aliases {
+ serial0 = &UART0;
+ serial1 = &UART1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ model = "PowerPC,440EP";
+ reg = <0>;
+ clock-frequency = <1fca0550>;
+ timebase-frequency = <017d7840>;
+ i-cache-line-size = <20>;
+ d-cache-line-size = <20>;
+ i-cache-size = <8000>;
+ d-cache-size = <8000>;
+ dcr-controller;
+ dcr-access-method = "native";
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0 9000000>;
+ };
+
+ UIC0: interrupt-controller0 {
+ compatible = "ibm,uic-440ep","ibm,uic";
+ interrupt-controller;
+ cell-index = <0>;
+ dcr-reg = <0c0 009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ };
+/*
+ UIC1: interrupt-controller1 {
+ compatible = "ibm,uic-440ep","ibm,uic";
+ interrupt-controller;
+ cell-index = <1>;
+ dcr-reg = <0d0 009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <1e 4 1f 4>;
+ interrupt-parent = <&UIC0>;
+ };
+*/
+
+ SDR0: sdr {
+ compatible = "ibm,sdr-440ep";
+ dcr-reg = <00e 002>;
+ };
+
+ CPR0: cpr {
+ compatible = "ibm,cpr-440ep";
+ dcr-reg = <00c 002>;
+ };
+
+ plb {
+ compatible = "ibm,plb-440ep", "ibm,plb-440gp", "ibm,plb4";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges;
+ clock-frequency = <07f28154>;
+
+ SDRAM0: sdram {
+ compatible = "ibm,sdram-440ep", "ibm,sdram-405gp";
+ dcr-reg = <010 2>;
+ };
+
+ DMA0: dma {
+ compatible = "ibm,dma-440ep", "ibm,dma-440gp";
+ dcr-reg = <100 027>;
+ };
+
+ POB0: opb {
+ compatible = "ibm,opb-440ep", "ibm,opb-440gp", "ibm,opb";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ /* Bamboo is oddball in the 44x world and doesn't use the ERPN
+ * bits.
+ */
+ ranges = <00000000 0 00000000 80000000
+ 80000000 0 80000000 80000000>;
+ /* interrupt-parent = <&UIC1>; */
+ interrupts = <7 4>;
+ clock-frequency = <03f940aa>;
+
+ EBC0: ebc {
+ compatible = "ibm,ebc-440ep", "ibm,ebc-440gp", "ibm,ebc";
+ dcr-reg = <012 2>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clock-frequency = <03f940aa>;
+ interrupts = <5 1>;
+ /* interrupt-parent = <&UIC1>; */
+ };
+
+ UART0: serial@ef600300 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <ef600300 8>;
+ virtual-reg = <ef600300>;
+ clock-frequency = <00a8c000>;
+ current-speed = <1c200>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <0 4>;
+ };
+
+ UART1: serial@ef600400 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <ef600400 8>;
+ virtual-reg = <ef600400>;
+ clock-frequency = <00a8c000>;
+ current-speed = <0>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <1 4>;
+ };
+/*
+ UART2: serial@ef600500 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <ef600500 8>;
+ virtual-reg = <ef600500>;
+ clock-frequency = <0>;
+ current-speed = <0>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <3 4>;
+ };
+
+ UART3: serial@ef600600 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <ef600600 8>;
+ virtual-reg = <ef600600>;
+ clock-frequency = <0>;
+ current-speed = <0>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <4 4>;
+ };
+
+*/
+ IIC0: i2c@ef600700 {
+ device_type = "i2c";
+ compatible = "ibm,iic-440ep", "ibm,iic-440gp", "ibm,iic";
+ reg = <ef600700 14>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <2 4>;
+ };
+
+ IIC1: i2c@ef600800 {
+ device_type = "i2c";
+ compatible = "ibm,iic-440ep", "ibm,iic-440gp", "ibm,iic";
+ reg = <ef600800 14>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <7 4>;
+ };
+
+ ZMII0: emac-zmii@ef600d00 {
+ device_type = "zmii-interface";
+ compatible = "ibm,zmii-440ep", "ibm,zmii-440gp", "ibm,zmii";
+ reg = <ef600d00 c>;
+ };
+
+ };
+
+ PCI0: pci@ec000000 {
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "ibm,plb440ep-pci", "ibm,plb-pci";
+ primary;
+ reg = <0 eec00000 8 /* Config space access */
+ 0 eed00000 4 /* IACK */
+ 0 eed00000 4 /* Special cycle */
+ 0 ef400000 40>; /* Internal registers */
+
+ /* Outbound ranges, one memory and one IO,
+ * later cannot be changed. Chip supports a second
+ * IO range but we don't use it for now
+ */
+ ranges = <02000000 0 a0000000 0 a0000000 0 20000000
+ 01000000 0 00000000 0 e8000000 0 00010000>;
+
+ /* Inbound 2GB range starting at 0 */
+ dma-ranges = <42000000 0 0 0 0 0 80000000>;
+
+ /* Bamboo has all 4 IRQ pins tied together per slot */
+ interrupt-map-mask = <f800 0 0 0>;
+ interrupt-map = <
+ /* IDSEL 1 */
+ 0800 0 0 0 &UIC0 1c 8
+
+ /* IDSEL 2 */
+ 1000 0 0 0 &UIC0 1b 8
+
+ /* IDSEL 3 */
+ 1800 0 0 0 &UIC0 1a 8
+
+ /* IDSEL 4 */
+ 2000 0 0 0 &UIC0 19 8
+ >;
+ };
+
+ };
+
+ chosen {
+ linux,stdout-path = "/plb/opb/serial@ef600300";
+ };
+};
diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index be0cbe1..ea2257b 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -8,6 +8,7 @@ void register_machines(void)
qemu_register_machine(&prep_machine);
qemu_register_machine(&ref405ep_machine);
qemu_register_machine(&taihu_machine);
+ qemu_register_machine(&bamboo_machine);
}
void cpu_save(QEMUFile *f, void *opaque)
--
1.5.6.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] KVM PowerPC support v3
2008-12-16 0:17 [Qemu-devel] KVM PowerPC support v3 Hollis Blanchard
2008-12-16 0:17 ` [Qemu-devel] [PATCH 1/4] Implement device tree support needed for Bamboo emulation Hollis Blanchard
@ 2008-12-16 10:44 ` Aurelien Jarno
1 sibling, 0 replies; 10+ messages in thread
From: Aurelien Jarno @ 2008-12-16 10:44 UTC (permalink / raw)
To: qemu-devel; +Cc: kvm-ppc
On Mon, Dec 15, 2008 at 06:17:28PM -0600, Hollis Blanchard wrote:
> I've fixed the configure output in patch #1, and the comment in patch #4. Patch
> #2 was already acked.
>
Thanks, all applied. I still have a few questions though, see the
answer to individual patches.
--
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73
: :' : Debian developer | Electrical Engineer
`. `' aurel32@debian.org | aurelien@aurel32.net
`- people.debian.org/~aurel32 | www.aurel32.net
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH 3/4] PowerPC 440EP SoC emulation
2008-12-16 0:17 ` [Qemu-devel] [PATCH 3/4] PowerPC 440EP SoC emulation Hollis Blanchard
@ 2008-12-16 10:45 ` Aurelien Jarno
2008-12-16 15:37 ` Hollis Blanchard
0 siblings, 1 reply; 10+ messages in thread
From: Aurelien Jarno @ 2008-12-16 10:45 UTC (permalink / raw)
To: qemu-devel; +Cc: kvm-ppc, Hollis Blanchard
On Mon, Dec 15, 2008 at 06:17:31PM -0600, Hollis Blanchard wrote:
> Wire up the system-on-chip devices present on 440EP chips.
>
> This patch is a little unusual in that qemu doesn't actually emulate the 440
> core, but we use this board code with KVM (which does). If/when 440 core
> emulation is supported, the kvm_enabled() hack can be removed.
>
What are the mains differences between 405 and 440 cores? Would it be
easy to add support for 440 core in QEMU?
--
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73
: :' : Debian developer | Electrical Engineer
`. `' aurel32@debian.org | aurelien@aurel32.net
`- people.debian.org/~aurel32 | www.aurel32.net
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH 4/4] IBM PowerPC 440EP Bamboo reference board emulation
2008-12-16 0:17 ` [Qemu-devel] [PATCH 4/4] IBM PowerPC 440EP Bamboo reference board emulation Hollis Blanchard
@ 2008-12-16 10:47 ` Aurelien Jarno
2008-12-16 15:14 ` Hollis Blanchard
0 siblings, 1 reply; 10+ messages in thread
From: Aurelien Jarno @ 2008-12-16 10:47 UTC (permalink / raw)
To: qemu-devel; +Cc: kvm-ppc, Hollis Blanchard
On Mon, Dec 15, 2008 at 06:17:32PM -0600, Hollis Blanchard wrote:
> Since most IO devices are integrated into the 440EP chip, "Bamboo support"
> mostly entails implementing the -kernel, -initrd, and -append options.
>
> These options are implemented by loading the guest as if u-boot had done it,
> i.e. loading a flat device tree, updating it to hold initrd addresses, ram
> size, and command line, and passing the FDT address in r3.
>
> Since we use it with KVM, we enable the virtio block driver and include hooks
> necessary for KVM support.
>
> Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
> ---
> Made comment more specific.
> ---
> Makefile | 2 +-
> Makefile.target | 2 +-
> hw/boards.h | 1 +
> hw/ppc440_bamboo.c | 190 ++++++++++++++++++++++++++++++++++++++++
> pc-bios/bamboo.dtb | Bin 0 -> 3163 bytes
> pc-bios/bamboo.dts | 234 ++++++++++++++++++++++++++++++++++++++++++++++++++
I guess the .dtb file is generated from the .dts. Could you give us more
details about that? When the tools need to generate the dtb file are
installed on the build machine, we may want to generate the .dtb during
the build process.
--
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73
: :' : Debian developer | Electrical Engineer
`. `' aurel32@debian.org | aurelien@aurel32.net
`- people.debian.org/~aurel32 | www.aurel32.net
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH 4/4] IBM PowerPC 440EP Bamboo reference board emulation
2008-12-16 10:47 ` Aurelien Jarno
@ 2008-12-16 15:14 ` Hollis Blanchard
0 siblings, 0 replies; 10+ messages in thread
From: Hollis Blanchard @ 2008-12-16 15:14 UTC (permalink / raw)
To: Aurelien Jarno; +Cc: qemu-devel, kvm-ppc
On Tue, 2008-12-16 at 11:47 +0100, Aurelien Jarno wrote:
> On Mon, Dec 15, 2008 at 06:17:32PM -0600, Hollis Blanchard wrote:
> > Since most IO devices are integrated into the 440EP chip, "Bamboo support"
> > mostly entails implementing the -kernel, -initrd, and -append options.
> >
> > These options are implemented by loading the guest as if u-boot had done it,
> > i.e. loading a flat device tree, updating it to hold initrd addresses, ram
> > size, and command line, and passing the FDT address in r3.
> >
> > Since we use it with KVM, we enable the virtio block driver and include hooks
> > necessary for KVM support.
> >
> > Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
> > ---
> > Made comment more specific.
> > ---
> > Makefile | 2 +-
> > Makefile.target | 2 +-
> > hw/boards.h | 1 +
> > hw/ppc440_bamboo.c | 190 ++++++++++++++++++++++++++++++++++++++++
> > pc-bios/bamboo.dtb | Bin 0 -> 3163 bytes
> > pc-bios/bamboo.dts | 234 ++++++++++++++++++++++++++++++++++++++++++++++++++
>
> I guess the .dtb file is generated from the .dts. Could you give us more
> details about that? When the tools need to generate the dtb file are
> installed on the build machine, we may want to generate the .dtb during
> the build process.
The dtb file ("device tree binary") is generated from the dts ("device
tree source") by a tool called dtc, the device tree compiler.[1]
dtc is available in major distributions: in Fedora the package name is
"dtc"; in Debian it is "device-tree-compiler" (available in testing and
unstable).
[1] http://git.jdl.com/gitweb/?p=dtc.git;a=summary
--
Hollis Blanchard
IBM Linux Technology Center
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH 3/4] PowerPC 440EP SoC emulation
2008-12-16 10:45 ` Aurelien Jarno
@ 2008-12-16 15:37 ` Hollis Blanchard
0 siblings, 0 replies; 10+ messages in thread
From: Hollis Blanchard @ 2008-12-16 15:37 UTC (permalink / raw)
To: Aurelien Jarno; +Cc: qemu-devel, kvm-ppc
On Tue, 2008-12-16 at 11:45 +0100, Aurelien Jarno wrote:
> On Mon, Dec 15, 2008 at 06:17:31PM -0600, Hollis Blanchard wrote:
> > Wire up the system-on-chip devices present on 440EP chips.
> >
> > This patch is a little unusual in that qemu doesn't actually emulate the 440
> > core, but we use this board code with KVM (which does). If/when 440 core
> > emulation is supported, the kvm_enabled() hack can be removed.
> >
>
> What are the mains differences between 405 and 440 cores? Would it be
> easy to add support for 440 core in QEMU?
It's been a while since I programmed for the 405, but from memory:
Unlike the 405, the 440 is a Book E core. The biggest difference is that
there is no real mode; MMU translation is always active. MSR[IR] and DR
have been replaced with IS and DS, and those "address space" bits
contribute to the 41-bit virtual address (32-bit effective, 8-bit PID
like 405, 1-bit AS). The TLB organization is pretty much the same as 405
(64-entry fully associative), though the data in each entry has changed
a little.
Fixed interrupt vectors have been replaced with programmable ones, via
the IVPR base register and 16 IVOR registers, indicating the offset of
each vector from IVPR.
There is a Application Note that more fully lists the software
differences:
https://www.amcc.com/MyAMCC/retrieveDocument/PowerPC/440GP/PPC440GP_AN2020_SWC405GP.pdf
Because the MMU is always on, tlbia doesn't exist any more. There are a
few other minor instruction and register changes.
As I've mentioned, most 440 peripherals are the same or similar to 405,
which is definitely helpful.
--
Hollis Blanchard
IBM Linux Technology Center
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2008-12-16 15:38 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-12-16 0:17 [Qemu-devel] KVM PowerPC support v3 Hollis Blanchard
2008-12-16 0:17 ` [Qemu-devel] [PATCH 1/4] Implement device tree support needed for Bamboo emulation Hollis Blanchard
2008-12-16 0:17 ` [Qemu-devel] [PATCH 2/4] Enable KVM for ppcemb Hollis Blanchard
2008-12-16 0:17 ` [Qemu-devel] [PATCH 3/4] PowerPC 440EP SoC emulation Hollis Blanchard
2008-12-16 10:45 ` Aurelien Jarno
2008-12-16 15:37 ` Hollis Blanchard
2008-12-16 0:17 ` [Qemu-devel] [PATCH 4/4] IBM PowerPC 440EP Bamboo reference board emulation Hollis Blanchard
2008-12-16 10:47 ` Aurelien Jarno
2008-12-16 15:14 ` Hollis Blanchard
2008-12-16 10:44 ` [Qemu-devel] KVM PowerPC support v3 Aurelien Jarno
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).