summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--hw/spapr.c10
-rw-r--r--hw/spapr_vio.c40
-rw-r--r--hw/spapr_vty.c39
-rw-r--r--target-ppc/translate.c4
-rw-r--r--tcg/ppc64/tcg-target.c14
5 files changed, 84 insertions, 23 deletions
diff --git a/hw/spapr.c b/hw/spapr.c
index bdaa938b6b..2b901f105e 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -57,7 +57,7 @@
 #define FW_MAX_SIZE             0x400000
 #define FW_FILE_NAME            "slof.bin"
 
-#define MIN_RAM_SLOF		512UL
+#define MIN_RMA_SLOF		128UL
 
 #define TIMEBASE_FREQ           512000000ULL
 
@@ -407,7 +407,9 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     long pteg_shift = 17;
     char *filename;
 
-    spapr = g_malloc(sizeof(*spapr));
+    spapr = g_malloc0(sizeof(*spapr));
+    QLIST_INIT(&spapr->phbs);
+
     cpu_ppc_hypercall = emulate_spapr_hypercall;
 
     /* Allocate RMA if necessary */
@@ -560,9 +562,9 @@ static void ppc_spapr_init(ram_addr_t ram_size,
 
         spapr->entry_point = KERNEL_LOAD_ADDR;
     } else {
-        if (ram_size < (MIN_RAM_SLOF << 20)) {
+        if (rma_size < (MIN_RMA_SLOF << 20)) {
             fprintf(stderr, "qemu: pSeries SLOF firmware requires >= "
-                    "%ldM guest RAM\n", MIN_RAM_SLOF);
+                    "%ldM guest RMA (Real Mode Area memory)\n", MIN_RMA_SLOF);
             exit(1);
         }
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, FW_FILE_NAME);
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 25cfc9d912..2dcc0361ed 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -66,11 +66,24 @@ VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
     QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
         dev = (VIOsPAPRDevice *)qdev;
         if (dev->reg == reg) {
-            break;
+            return dev;
         }
     }
 
-    return dev;
+    return NULL;
+}
+
+static char *vio_format_dev_name(VIOsPAPRDevice *dev)
+{
+    VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)dev->qdev.info;
+    char *name;
+
+    /* Device tree style name device@reg */
+    if (asprintf(&name, "%s@%x", info->dt_name, dev->reg) < 0) {
+        return NULL;
+    }
+
+    return name;
 }
 
 #ifdef CONFIG_FDT
@@ -78,15 +91,21 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
                             void *fdt)
 {
     VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)dev->qdev.info;
-    int vdevice_off, node_off;
-    int ret;
+    int vdevice_off, node_off, ret;
+    char *dt_name;
 
     vdevice_off = fdt_path_offset(fdt, "/vdevice");
     if (vdevice_off < 0) {
         return vdevice_off;
     }
 
-    node_off = fdt_add_subnode(fdt, vdevice_off, dev->qdev.id);
+    dt_name = vio_format_dev_name(dev);
+    if (!dt_name) {
+        return -ENOMEM;
+    }
+
+    node_off = fdt_add_subnode(fdt, vdevice_off, dt_name);
+    free(dt_name);
     if (node_off < 0) {
         return node_off;
     }
@@ -608,12 +627,15 @@ static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo)
     VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
     char *id;
 
-    if (asprintf(&id, "%s@%x", info->dt_name, dev->reg) < 0) {
-        return -1;
+    /* Don't overwrite ids assigned on the command line */
+    if (!dev->qdev.id) {
+        id = vio_format_dev_name(dev);
+        if (!id) {
+            return -1;
+        }
+        dev->qdev.id = id;
     }
 
-    dev->qdev.id = id;
-
     dev->qirq = spapr_allocate_irq(dev->vio_irq_num, &dev->vio_irq_num);
     if (!dev->qirq) {
         return -1;
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index a9d4b035e2..f23cc36231 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -58,12 +58,20 @@ static int spapr_vty_init(VIOsPAPRDevice *sdev)
 {
     VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)sdev;
 
+    if (!dev->chardev) {
+        fprintf(stderr, "spapr-vty: Can't create vty without a chardev!\n");
+        exit(1);
+    }
+
     qemu_chr_add_handlers(dev->chardev, vty_can_receive,
                           vty_receive, NULL, dev);
 
     return 0;
 }
 
+/* Forward declaration */
+static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg);
+
 static target_ulong h_put_term_char(CPUState *env, sPAPREnvironment *spapr,
                                     target_ulong opcode, target_ulong *args)
 {
@@ -71,9 +79,10 @@ static target_ulong h_put_term_char(CPUState *env, sPAPREnvironment *spapr,
     target_ulong len = args[1];
     target_ulong char0_7 = args[2];
     target_ulong char8_15 = args[3];
-    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRDevice *sdev;
     uint8_t buf[16];
 
+    sdev = vty_lookup(spapr, reg);
     if (!sdev) {
         return H_PARAMETER;
     }
@@ -97,9 +106,10 @@ static target_ulong h_get_term_char(CPUState *env, sPAPREnvironment *spapr,
     target_ulong *len = args + 0;
     target_ulong *char0_7 = args + 1;
     target_ulong *char8_15 = args + 2;
-    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRDevice *sdev;
     uint8_t buf[16];
 
+    sdev = vty_lookup(spapr, reg);
     if (!sdev) {
         return H_PARAMETER;
     }
@@ -140,12 +150,35 @@ static VIOsPAPRDeviceInfo spapr_vty = {
     .qdev.name = "spapr-vty",
     .qdev.size = sizeof(VIOsPAPRVTYDevice),
     .qdev.props = (Property[]) {
-        DEFINE_SPAPR_PROPERTIES(VIOsPAPRVTYDevice, sdev, 0, 0),
+        DEFINE_SPAPR_PROPERTIES(VIOsPAPRVTYDevice, sdev, SPAPR_VTY_BASE_ADDRESS, 0),
         DEFINE_PROP_CHR("chardev", VIOsPAPRVTYDevice, chardev),
         DEFINE_PROP_END_OF_LIST(),
     },
 };
 
+static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg)
+{
+    VIOsPAPRDevice *sdev;
+
+    sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    if (!sdev && reg == 0) {
+        DeviceState *qdev;
+
+        /* Hack for kernel early debug, which always specifies reg==0.
+         * We search all VIO devices, and grab the first available vty
+         * device.  This attempts to mimic existing PowerVM behaviour
+         * (early debug does work there, despite having no vty with
+         * reg==0. */
+        QTAILQ_FOREACH(qdev, &spapr->vio_bus->bus.children, sibling) {
+            if (qdev->info == &spapr_vty.qdev) {
+                return DO_UPCAST(VIOsPAPRDevice, qdev, qdev);
+            }
+        }
+    }
+
+    return sdev;
+}
+
 static void spapr_vty_register(void)
 {
     spapr_vio_bus_register_withprop(&spapr_vty);
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 99e995c7b6..66eae30209 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -298,8 +298,10 @@ static inline void gen_debug_exception(DisasContext *ctx)
 {
     TCGv_i32 t0;
 
-    if (ctx->exception != POWERPC_EXCP_BRANCH)
+    if ((ctx->exception != POWERPC_EXCP_BRANCH) &&
+        (ctx->exception != POWERPC_EXCP_SYNC)) {
         gen_update_nip(ctx, ctx->nip);
+    }
     t0 = tcg_const_i32(EXCP_DEBUG);
     gen_helper_raise_exception(t0);
     tcg_temp_free_i32(t0);
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 3d24cd4da4..41f1e85cc9 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -616,18 +616,19 @@ static void tcg_out_tlb_read (TCGContext *s, int r0, int r1, int r2,
 
 static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
 {
-    int addr_reg, data_reg, r0, r1, rbase, mem_index, s_bits, bswap;
+    int addr_reg, data_reg, r0, r1, rbase, bswap;
 #ifdef CONFIG_SOFTMMU
-    int r2;
+    int r2, mem_index, s_bits;
     void *label1_ptr, *label2_ptr;
 #endif
 
     data_reg = *args++;
     addr_reg = *args++;
+
+#ifdef CONFIG_SOFTMMU
     mem_index = *args;
     s_bits = opc & 3;
 
-#ifdef CONFIG_SOFTMMU
     r0 = 3;
     r1 = 4;
     r2 = 0;
@@ -763,17 +764,18 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
 
 static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
 {
-    int addr_reg, r0, r1, rbase, data_reg, mem_index, bswap;
+    int addr_reg, r0, r1, rbase, data_reg, bswap;
 #ifdef CONFIG_SOFTMMU
-    int r2;
+    int r2, mem_index;
     void *label1_ptr, *label2_ptr;
 #endif
 
     data_reg = *args++;
     addr_reg = *args++;
-    mem_index = *args;
 
 #ifdef CONFIG_SOFTMMU
+    mem_index = *args;
+
     r0 = 3;
     r1 = 4;
     r2 = 0;