Skip to content

Commit

Permalink
Merge branch 'ppc-next' of git://repo.or.cz/qemu/agraf
Browse files Browse the repository at this point in the history
* 'ppc-next' of git://repo.or.cz/qemu/agraf:
  PPC: Qdev'ify e500 pci
  PPC MPC7544DS: Use new TLB helper function
  PPC: Implement e500 (FSL) MMU
  PPC: Add another 64 bits to instruction feature mask
  PPC: Add GS MSR definition
  PPC: Make MPC8544DS emulation work w/o KVM
  PPC: Make MPC8544DS obey -cpu switch
  Fix off-by-one error in sizing pSeries hcall table
  ppc64: Fix out-of-tree builds
  kvm: ppc: warn user on PAGE_SIZE mismatch
  kvm: ppc: detect old headers
  monitor: add PPC BookE SPRs
  kvm: ppc: fixes for KVM_SET_SREGS on init
  ppc64: Don't try to build sPAPR RTAS on Darwin
  Place pseries vty devices at addresses more similar to existing machines
  Make pSeries 'model' property more closely resemble real hardware
  pseries: Increase maximum CPUs to 256
  • Loading branch information
aurel32 committed May 14, 2011
2 parents 86f1f2a + be13cc7 commit 091959d
Show file tree
Hide file tree
Showing 18 changed files with 1,664 additions and 276 deletions.
22 changes: 21 additions & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -1833,6 +1833,21 @@ recent kvm-kmod from http://sourceforge.net/projects/kvm."
fi
fi

##########################################
# test for ppc kvm pvr setting

if test "$kvm" = "yes" && test "$cpu" = "ppc" -o "$cpu" = "ppc64"; then
cat > $TMPC <<EOF
#include <asm/kvm.h>
int main(void) { struct kvm_sregs s; s.pvr = 0; return 0; }
EOF
if compile_prog "$kvm_cflags" "" ; then
kvm_ppc_pvr=yes
else
kvm_ppc_pvr=no
fi
fi

##########################################
# test for vhost net

Expand Down Expand Up @@ -2602,7 +2617,7 @@ if test \( "$cpu" = "i386" -o "$cpu" = "x86_64" \) -a \
"$softmmu" = yes ; then
roms="optionrom"
fi
if test "$cpu" = "ppc64" ; then
if test "$cpu" = "ppc64" -a "$targetos" != "Darwin" ; then
roms="$roms spapr-rtas"
fi

Expand Down Expand Up @@ -3324,6 +3339,9 @@ case "$target_arch2" in
if test $vhost_net = "yes" ; then
echo "CONFIG_VHOST_NET=y" >> $config_target_mak
fi
if test $kvm_ppc_pvr = "yes" ; then
echo "CONFIG_KVM_PPC_PVR=y" >> $config_target_mak
fi
fi
esac
if test "$target_bigendian" = "yes" ; then
Expand Down Expand Up @@ -3524,11 +3542,13 @@ done # for target in $targets

# build tree in object directory in case the source is not in the current directory
DIRS="tests tests/cris slirp audio block net pc-bios/optionrom"
DIRS="$DIRS pc-bios/spapr-rtas"
DIRS="$DIRS roms/seabios roms/vgabios"
DIRS="$DIRS fsdev ui"
FILES="Makefile tests/Makefile"
FILES="$FILES tests/cris/Makefile tests/cris/.gdbinit"
FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
FILES="$FILES pc-bios/spapr-rtas/Makefile"
FILES="$FILES roms/seabios/Makefile roms/vgabios/Makefile"
for bios_file in $source_path/pc-bios/*.bin $source_path/pc-bios/*.rom $source_path/pc-bios/*.dtb $source_path/pc-bios/openbios-*; do
FILES="$FILES pc-bios/`basename $bios_file`"
Expand Down
12 changes: 12 additions & 0 deletions hw/ppc.c
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,10 @@ uint64_t cpu_ppc_load_tbl (CPUState *env)
ppc_tb_t *tb_env = env->tb_env;
uint64_t tb;

if (kvm_enabled()) {
return env->spr[SPR_TBL];
}

tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);

Expand All @@ -471,6 +475,10 @@ static inline uint32_t _cpu_ppc_load_tbu(CPUState *env)

uint32_t cpu_ppc_load_tbu (CPUState *env)
{
if (kvm_enabled()) {
return env->spr[SPR_TBU];
}

return _cpu_ppc_load_tbu(env);
}

Expand Down Expand Up @@ -616,6 +624,10 @@ uint32_t cpu_ppc_load_decr (CPUState *env)
{
ppc_tb_t *tb_env = env->tb_env;

if (kvm_enabled()) {
return env->spr[SPR_DECR];
}

return _cpu_ppc_load_decr(env, tb_env->decr_next);
}

Expand Down
22 changes: 0 additions & 22 deletions hw/ppce500.h

This file was deleted.

113 changes: 87 additions & 26 deletions hw/ppce500_mpc8544ds.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@
#include "kvm_ppc.h"
#include "device_tree.h"
#include "openpic.h"
#include "ppce500.h"
#include "ppc.h"
#include "loader.h"
#include "elf.h"
#include "sysbus.h"

#define BINARY_DEVICE_TREE_FILE "mpc8544ds.dtb"
#define UIMAGE_LOAD_BASE 0
Expand All @@ -50,6 +51,12 @@
#define MPC8544_PCI_IO 0xE1000000
#define MPC8544_PCI_IOLEN 0x10000

struct boot_info
{
uint32_t dt_base;
uint32_t entry;
};

#ifdef CONFIG_FDT
static int mpc8544_copy_soc_cell(void *fdt, const char *node, const char *prop)
{
Expand Down Expand Up @@ -82,7 +89,7 @@ static int mpc8544_load_device_tree(target_phys_addr_t addr,
{
int ret = -1;
#ifdef CONFIG_FDT
uint32_t mem_reg_property[] = {0, ramsize};
uint32_t mem_reg_property[] = {0, cpu_to_be32(ramsize)};
char *filename;
int fdt_size;
void *fdt;
Expand All @@ -103,15 +110,19 @@ static int mpc8544_load_device_tree(target_phys_addr_t addr,
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");
if (initrd_size) {
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_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);
Expand Down Expand Up @@ -145,6 +156,13 @@ static int mpc8544_load_device_tree(target_phys_addr_t addr,

mpc8544_copy_soc_cell(fdt, buf, "clock-frequency");
mpc8544_copy_soc_cell(fdt, buf, "timebase-frequency");
} else {
const uint32_t freq = 400000000;

qemu_devtree_setprop_cell(fdt, "/cpus/PowerPC,8544@0",
"clock-frequency", freq);
qemu_devtree_setprop_cell(fdt, "/cpus/PowerPC,8544@0",
"timebase-frequency", freq);
}

ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
Expand All @@ -156,6 +174,35 @@ static int mpc8544_load_device_tree(target_phys_addr_t addr,
return ret;
}

/* Create -kernel TLB entries for BookE, linearly spanning 256MB. */
static void mmubooke_create_initial_mapping(CPUState *env,
target_ulong va,
target_phys_addr_t pa)
{
ppcemb_tlb_t *tlb = booke206_get_tlbe(env, 1, 0, 0);

tlb->attr = 0;
tlb->prot = PAGE_VALID | ((PAGE_READ | PAGE_WRITE | PAGE_EXEC) << 4);
tlb->size = 256 * 1024 * 1024;
tlb->EPN = va & TARGET_PAGE_MASK;
tlb->RPN = pa & TARGET_PAGE_MASK;
tlb->PID = 0;
}

static void mpc8544ds_cpu_reset(void *opaque)
{
CPUState *env = opaque;
struct boot_info *bi = env->load_info;

cpu_reset(env);

/* Set initial guest state. */
env->gpr[1] = (16<<20) - 8;
env->gpr[3] = bi->dt_base;
env->nip = bi->entry;
mmubooke_create_initial_mapping(env, 0, 0);
}

static void mpc8544ds_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
Expand All @@ -175,15 +222,28 @@ static void mpc8544ds_init(ram_addr_t ram_size,
target_long initrd_size=0;
int i=0;
unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
qemu_irq *irqs, *mpic, *pci_irqs;
qemu_irq *irqs, *mpic;
DeviceState *dev;
struct boot_info *boot_info;

/* Setup CPU */
env = cpu_ppc_init("e500v2_v30");
if (cpu_model == NULL) {
cpu_model = "e500v2_v30";
}

env = cpu_ppc_init(cpu_model);
if (!env) {
fprintf(stderr, "Unable to initialize CPU!\n");
exit(1);
}

/* XXX register timer? */
ppc_emb_timers_init(env, 400000000, PPC_INTERRUPT_DECR);
ppc_dcr_init(env, NULL, NULL);

/* Register reset handler */
qemu_register_reset(mpc8544ds_cpu_reset, env);

/* Fixup Memory size on a alignment boundary */
ram_size &= ~(RAM_SIZES_ALIGN - 1);

Expand Down Expand Up @@ -211,12 +271,11 @@ static void mpc8544ds_init(ram_addr_t ram_size,
}

/* PCI */
pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4);
pci_irqs[0] = mpic[pci_irq_nrs[0]];
pci_irqs[1] = mpic[pci_irq_nrs[1]];
pci_irqs[2] = mpic[pci_irq_nrs[2]];
pci_irqs[3] = mpic[pci_irq_nrs[3]];
pci_bus = ppce500_pci_init(pci_irqs, MPC8544_PCI_REGS_BASE);
dev = sysbus_create_varargs("e500-pcihost", MPC8544_PCI_REGS_BASE,
mpic[pci_irq_nrs[0]], mpic[pci_irq_nrs[1]],
mpic[pci_irq_nrs[2]], mpic[pci_irq_nrs[3]],
NULL);
pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
if (!pci_bus)
printf("couldn't create PCI controller!\n");

Expand Down Expand Up @@ -259,26 +318,28 @@ static void mpc8544ds_init(ram_addr_t ram_size,
}
}

boot_info = qemu_mallocz(sizeof(struct boot_info));

/* If we're loading a kernel directly, we must load the device tree too. */
if (kernel_filename) {
#ifndef CONFIG_FDT
cpu_abort(env, "Compiled without FDT support - can't load kernel\n");
#endif
dt_base = (kernel_size + DTC_LOAD_PAD) & ~DTC_PAD_MASK;
if (mpc8544_load_device_tree(dt_base, ram_size,
initrd_base, initrd_size, kernel_cmdline) < 0) {
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. */
boot_info->entry = entry;
boot_info->dt_base = dt_base;
}
env->load_info = boot_info;

if (kvm_enabled())
if (kvm_enabled()) {
kvmppc_init();

return;
}
}

static QEMUMachine mpc8544ds_machine = {
Expand Down
Loading

0 comments on commit 091959d

Please sign in to comment.