]> Git Repo - qemu.git/commitdiff
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.11-20170927' into staging
authorPeter Maydell <[email protected]>
Wed, 27 Sep 2017 17:20:31 +0000 (18:20 +0100)
committerPeter Maydell <[email protected]>
Wed, 27 Sep 2017 17:20:31 +0000 (18:20 +0100)
ppc patch queue 2017-09-27

Contains
 * a number of Mac machine type fixes
 * a number of embedded machine type fixes (preliminary to adding the
   Sam460ex board)
 * a important fix for handling of migration with KVM PR
 * assorted other minor fixes and cleanups

# gpg: Signature made Wed 27 Sep 2017 08:40:48 BST
# gpg:                using RSA key 0x6C38CACA20D9B392
# gpg: Good signature from "David Gibson <[email protected]>"
# gpg:                 aka "David Gibson (Red Hat) <[email protected]>"
# gpg:                 aka "David Gibson (ozlabs.org) <[email protected]>"
# gpg:                 aka "David Gibson (kernel.org) <[email protected]>"
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-2.11-20170927: (26 commits)
  macio: use object link between MACIO_IDE and MAC_DBDMA object
  macio: pass channel into MACIOIDEState via qdev property
  mac_dbdma: remove DBDMA_init() function
  mac_dbdma: QOMify
  mac_dbdma: remove unused IO fields from DBDMAState
  spapr: fix the value of SDR1 in kvmppc_put_books_sregs()
  ppc/pnv: check for OPAL firmware file presence
  ppc: remove all unused CPU definitions
  ppc: remove unused CPU definitions
  spapr_pci: make index property mandatory
  macio: convert pmac_ide_ops from old_mmio
  ppc/pnv: Improve macro parenthesization
  spapr: introduce helpers to migrate HPT chunks and the end marker
  ppc/kvm: generalize the use of kvmppc_get_htab_fd()
  ppc/kvm: change kvmppc_get_htab_fd() to return -errno on error
  ppc: Fix OpenPIC model
  ppc/ide/macio: Add missing registers
  ppc/mac: More rework of the DBDMA emulation
  ppc/mac: Advertise a high clock frequency for NewWorld Macs
  ppc: QOMify g3beige machine
  ...

Signed-off-by: Peter Maydell <[email protected]>
25 files changed:
hw/ide/macio.c
hw/intc/openpic.c
hw/misc/macio/mac_dbdma.c
hw/misc/macio/macio.c
hw/ppc/mac.h
hw/ppc/mac_newworld.c
hw/ppc/mac_oldworld.c
hw/ppc/pnv.c
hw/ppc/ppc405_uc.c
hw/ppc/spapr.c
hw/ppc/spapr_cpu_core.c
hw/ppc/spapr_hcall.c
hw/ppc/spapr_pci.c
hw/usb/hcd-ehci-sysbus.c
hw/usb/hcd-ehci.h
hw/usb/hcd-ohci.c
include/hw/ppc/mac_dbdma.h
include/hw/ppc/openpic.h
include/hw/ppc/pnv_xscom.h
target/ppc/cpu-models.c
target/ppc/cpu-models.h
target/ppc/cpu.h
target/ppc/kvm.c
target/ppc/kvm_ppc.h
target/ppc/translate_init.c

index 9742c005d1e20cecd3af54cc6aeb9b7c9b57b4b6..ce194c6cec2320917c70825b0bcccb0572af63cd 100644 (file)
@@ -255,114 +255,100 @@ static void pmac_ide_flush(DBDMA_io *io)
 }
 
 /* PowerMac IDE memory IO */
-static void pmac_ide_writeb (void *opaque,
-                             hwaddr addr, uint32_t val)
+static uint64_t pmac_ide_read(void *opaque, hwaddr addr, unsigned size)
 {
     MACIOIDEState *d = opaque;
-
-    addr = (addr & 0xFFF) >> 4;
-    switch (addr) {
-    case 1 ... 7:
-        ide_ioport_write(&d->bus, addr, val);
-        break;
-    case 8:
-    case 22:
-        ide_cmd_write(&d->bus, 0, val);
+    uint64_t retval = 0xffffffff;
+    int reg = addr >> 4;
+
+    switch (reg) {
+    case 0x0:
+        if (size == 2) {
+            retval = ide_data_readw(&d->bus, 0);
+        } else if (size == 4) {
+            retval = ide_data_readl(&d->bus, 0);
+        }
         break;
-    default:
+    case 0x1 ... 0x7:
+        if (size == 1) {
+            retval = ide_ioport_read(&d->bus, reg);
+        }
         break;
-    }
-}
-
-static uint32_t pmac_ide_readb (void *opaque,hwaddr addr)
-{
-    uint8_t retval;
-    MACIOIDEState *d = opaque;
-
-    addr = (addr & 0xFFF) >> 4;
-    switch (addr) {
-    case 1 ... 7:
-        retval = ide_ioport_read(&d->bus, addr);
+    case 0x8:
+    case 0x16:
+        if (size == 1) {
+            retval = ide_status_read(&d->bus, 0);
+        }
         break;
-    case 8:
-    case 22:
-        retval = ide_status_read(&d->bus, 0);
+    case 0x20:
+        if (size == 4) {
+            retval = d->timing_reg;
+        }
         break;
-    default:
-        retval = 0xFF;
+    case 0x30:
+        /* This is an interrupt state register that only exists
+         * in the KeyLargo and later variants. Bit 0x8000_0000
+         * latches the DMA interrupt and has to be written to
+         * clear. Bit 0x4000_0000 is an image of the disk
+         * interrupt. MacOS X relies on this and will hang if
+         * we don't provide at least the disk interrupt
+         */
+        if (size == 4) {
+            retval = d->irq_reg;
+        }
         break;
     }
-    return retval;
-}
-
-static void pmac_ide_writew (void *opaque,
-                             hwaddr addr, uint32_t val)
-{
-    MACIOIDEState *d = opaque;
-
-    addr = (addr & 0xFFF) >> 4;
-    val = bswap16(val);
-    if (addr == 0) {
-        ide_data_writew(&d->bus, 0, val);
-    }
-}
-
-static uint32_t pmac_ide_readw (void *opaque,hwaddr addr)
-{
-    uint16_t retval;
-    MACIOIDEState *d = opaque;
 
-    addr = (addr & 0xFFF) >> 4;
-    if (addr == 0) {
-        retval = ide_data_readw(&d->bus, 0);
-    } else {
-        retval = 0xFFFF;
-    }
-    retval = bswap16(retval);
     return retval;
 }
 
-static void pmac_ide_writel (void *opaque,
-                             hwaddr addr, uint32_t val)
-{
-    MACIOIDEState *d = opaque;
-
-    addr = (addr & 0xFFF) >> 4;
-    val = bswap32(val);
-    if (addr == 0) {
-        ide_data_writel(&d->bus, 0, val);
-    }
-}
 
-static uint32_t pmac_ide_readl (void *opaque,hwaddr addr)
+static void pmac_ide_write(void *opaque, hwaddr addr, uint64_t val,
+                           unsigned size)
 {
-    uint32_t retval;
     MACIOIDEState *d = opaque;
-
-    addr = (addr & 0xFFF) >> 4;
-    if (addr == 0) {
-        retval = ide_data_readl(&d->bus, 0);
-    } else {
-        retval = 0xFFFFFFFF;
+    int reg = addr >> 4;
+
+    switch (reg) {
+    case 0x0:
+        if (size == 2) {
+            ide_data_writew(&d->bus, 0, val);
+        } else if (size == 4) {
+            ide_data_writel(&d->bus, 0, val);
+        }
+        break;
+    case 0x1 ... 0x7:
+        if (size == 1) {
+            ide_ioport_write(&d->bus, reg, val);
+        }
+        break;
+    case 0x8:
+    case 0x16:
+        if (size == 1) {
+            ide_cmd_write(&d->bus, 0, val);
+        }
+        break;
+    case 0x20:
+        if (size == 4) {
+            d->timing_reg = val;
+        }
+        break;
+    case 0x30:
+        if (size == 4) {
+            if (val & 0x80000000u) {
+                d->irq_reg &= 0x7fffffff;
+            }
+        }
+        break;
     }
-    retval = bswap32(retval);
-    return retval;
 }
 
 static const MemoryRegionOps pmac_ide_ops = {
-    .old_mmio = {
-        .write = {
-            pmac_ide_writeb,
-            pmac_ide_writew,
-            pmac_ide_writel,
-        },
-        .read = {
-            pmac_ide_readb,
-            pmac_ide_readw,
-            pmac_ide_readl,
-        },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+    .read = pmac_ide_read,
+    .write = pmac_ide_write,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 4,
+    .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
 static const VMStateDescription vmstate_pmac = {
@@ -426,13 +412,32 @@ static void macio_ide_realizefn(DeviceState *dev, Error **errp)
 {
     MACIOIDEState *s = MACIO_IDE(dev);
 
-    ide_init2(&s->bus, s->irq);
+    ide_init2(&s->bus, s->ide_irq);
 
     /* Register DMA callbacks */
     s->dma.ops = &dbdma_ops;
     s->bus.dma = &s->dma;
 }
 
+static void pmac_ide_irq(void *opaque, int n, int level)
+{
+    MACIOIDEState *s = opaque;
+    uint32_t mask = 0x80000000u >> n;
+
+    /* We need to reflect the IRQ state in the irq register */
+    if (level) {
+        s->irq_reg |= mask;
+    } else {
+        s->irq_reg &= ~mask;
+    }
+
+    if (n) {
+        qemu_set_irq(s->real_ide_irq, level);
+    } else {
+        qemu_set_irq(s->real_dma_irq, level);
+    }
+}
+
 static void macio_ide_initfn(Object *obj)
 {
     SysBusDevice *d = SYS_BUS_DEVICE(obj);
@@ -441,16 +446,28 @@ static void macio_ide_initfn(Object *obj)
     ide_bus_new(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
     memory_region_init_io(&s->mem, obj, &pmac_ide_ops, s, "pmac-ide", 0x1000);
     sysbus_init_mmio(d, &s->mem);
-    sysbus_init_irq(d, &s->irq);
-    sysbus_init_irq(d, &s->dma_irq);
+    sysbus_init_irq(d, &s->real_ide_irq);
+    sysbus_init_irq(d, &s->real_dma_irq);
+    s->dma_irq = qemu_allocate_irq(pmac_ide_irq, s, 0);
+    s->ide_irq = qemu_allocate_irq(pmac_ide_irq, s, 1);
+
+    object_property_add_link(obj, "dbdma", TYPE_MAC_DBDMA,
+                             (Object **) &s->dbdma,
+                             qdev_prop_allow_set_link_before_realize, 0, NULL);
 }
 
+static Property macio_ide_properties[] = {
+    DEFINE_PROP_UINT32("channel", MACIOIDEState, channel, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void macio_ide_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
 
     dc->realize = macio_ide_realizefn;
     dc->reset = macio_ide_reset;
+    dc->props = macio_ide_properties;
     dc->vmsd = &vmstate_pmac;
     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 }
@@ -480,10 +497,9 @@ void macio_ide_init_drives(MACIOIDEState *s, DriveInfo **hd_table)
     }
 }
 
-void macio_ide_register_dma(MACIOIDEState *s, void *dbdma, int channel)
+void macio_ide_register_dma(MACIOIDEState *s)
 {
-    s->dbdma = dbdma;
-    DBDMA_register_channel(dbdma, channel, s->dma_irq,
+    DBDMA_register_channel(s->dbdma, s->channel, s->dma_irq,
                            pmac_ide_transfer, pmac_ide_flush, s);
 }
 
index 9dd285b92326314b72cffae31940624719c5a030..10d6e871fb6f51fc40ef561d2ce515a9e210f71b 100644 (file)
@@ -92,6 +92,16 @@ static int get_current_cpu(void);
 #define RAVEN_MAX_TMR      OPENPIC_MAX_TMR
 #define RAVEN_MAX_IPI      OPENPIC_MAX_IPI
 
+/* KeyLargo */
+#define KEYLARGO_MAX_CPU  4
+#define KEYLARGO_MAX_EXT  64
+#define KEYLARGO_MAX_IPI  4
+#define KEYLARGO_MAX_IRQ  (64 + KEYLARGO_MAX_IPI)
+#define KEYLARGO_MAX_TMR  0
+#define KEYLARGO_IPI_IRQ  (KEYLARGO_MAX_EXT) /* First IPI IRQ */
+/* Timers don't exist but this makes the code happy... */
+#define KEYLARGO_TMR_IRQ  (KEYLARGO_IPI_IRQ + KEYLARGO_MAX_IPI)
+
 /* Interrupt definitions */
 #define RAVEN_FE_IRQ     (RAVEN_MAX_EXT)     /* Internal functional IRQ */
 #define RAVEN_ERR_IRQ    (RAVEN_MAX_EXT + 1) /* Error IRQ */
@@ -120,6 +130,7 @@ static FslMpicInfo fsl_mpic_42 = {
 #define VID_REVISION_1_3   3
 
 #define VIR_GENERIC      0x00000000 /* Generic Vendor ID */
+#define VIR_MPIC2A       0x00004614 /* IBM MPIC-2A */
 
 #define GCR_RESET        0x80000000
 #define GCR_MODE_PASS    0x00000000
@@ -329,6 +340,8 @@ typedef struct OpenPICState {
     uint32_t nb_cpus;
     /* Timer registers */
     OpenPICTimer timers[OPENPIC_MAX_TMR];
+    uint32_t max_tmr;
+
     /* Shared MSI registers */
     OpenPICMSI msi[MAX_MSI];
     uint32_t max_irq;
@@ -1715,6 +1728,28 @@ static void openpic_realize(DeviceState *dev, Error **errp)
             return;
         }
 
+        map_list(opp, list_le, &list_count);
+        break;
+
+    case OPENPIC_MODEL_KEYLARGO:
+        opp->nb_irqs = KEYLARGO_MAX_EXT;
+        opp->vid = VID_REVISION_1_2;
+        opp->vir = VIR_GENERIC;
+        opp->vector_mask = 0xFF;
+        opp->tfrr_reset = 4160000;
+        opp->ivpr_reset = IVPR_MASK_MASK | IVPR_MODE_MASK;
+        opp->idr_reset = 0;
+        opp->max_irq = KEYLARGO_MAX_IRQ;
+        opp->irq_ipi0 = KEYLARGO_IPI_IRQ;
+        opp->irq_tim0 = KEYLARGO_TMR_IRQ;
+        opp->brr1 = -1;
+        opp->mpic_mode_mask = GCR_MODE_MIXED;
+
+        if (opp->nb_cpus != 1) {
+            error_setg(errp, "Only UP supported today");
+            return;
+        }
+
         map_list(opp, list_le, &list_count);
         break;
     }
index 15452b9a28331e2abfea7f6c1cd7ead43f38ccf8..0eddf2e700951a359e02ab2fa3317e39ca92c645 100644 (file)
@@ -96,9 +96,8 @@ static void dbdma_cmdptr_load(DBDMA_channel *ch)
 
 static void dbdma_cmdptr_save(DBDMA_channel *ch)
 {
-    DBDMA_DPRINTFCH(ch, "dbdma_cmdptr_save 0x%08x\n",
-                    ch->regs[DBDMA_CMDPTR_LO]);
-    DBDMA_DPRINTFCH(ch, "xfer_status 0x%08x res_count 0x%04x\n",
+    DBDMA_DPRINTFCH(ch, "-> update 0x%08x stat=0x%08x, res=0x%04x\n",
+                    ch->regs[DBDMA_CMDPTR_LO],
                     le16_to_cpu(ch->current.xfer_status),
                     le16_to_cpu(ch->current.res_count));
     dma_memory_write(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO],
@@ -166,15 +165,14 @@ static int conditional_wait(DBDMA_channel *ch)
     uint16_t sel_mask, sel_value;
     uint32_t status;
     int cond;
-
-    DBDMA_DPRINTFCH(ch, "conditional_wait\n");
+    int res = 0;
 
     wait = le16_to_cpu(current->command) & WAIT_MASK;
-
     switch(wait) {
     case WAIT_NEVER:  /* don't wait */
         return 0;
     case WAIT_ALWAYS: /* always wait */
+        DBDMA_DPRINTFCH(ch, "  [WAIT_ALWAYS]\n");
         return 1;
     }
 
@@ -187,15 +185,19 @@ static int conditional_wait(DBDMA_channel *ch)
 
     switch(wait) {
     case WAIT_IFSET:  /* wait if condition bit is 1 */
-        if (cond)
-            return 1;
-        return 0;
+        if (cond) {
+            res = 1;
+        }
+        DBDMA_DPRINTFCH(ch, "  [WAIT_IFSET=%d]\n", res);
+        break;
     case WAIT_IFCLR:  /* wait if condition bit is 0 */
-        if (!cond)
-            return 1;
-        return 0;
+        if (!cond) {
+            res = 1;
+        }
+        DBDMA_DPRINTFCH(ch, "  [WAIT_IFCLR=%d]\n", res);
+        break;
     }
-    return 0;
+    return res;
 }
 
 static void next(DBDMA_channel *ch)
@@ -226,8 +228,6 @@ static void conditional_branch(DBDMA_channel *ch)
     uint32_t status;
     int cond;
 
-    DBDMA_DPRINTFCH(ch, "conditional_branch\n");
-
     /* check if we must branch */
 
     br = le16_to_cpu(current->command) & BR_MASK;
@@ -237,6 +237,7 @@ static void conditional_branch(DBDMA_channel *ch)
         next(ch);
         return;
     case BR_ALWAYS: /* always branch */
+        DBDMA_DPRINTFCH(ch, "  [BR_ALWAYS]\n");
         branch(ch);
         return;
     }
@@ -250,16 +251,22 @@ static void conditional_branch(DBDMA_channel *ch)
 
     switch(br) {
     case BR_IFSET:  /* branch if condition bit is 1 */
-        if (cond)
+        if (cond) {
+            DBDMA_DPRINTFCH(ch, "  [BR_IFSET = 1]\n");
             branch(ch);
-        else
+        } else {
+            DBDMA_DPRINTFCH(ch, "  [BR_IFSET = 0]\n");
             next(ch);
+        }
         return;
     case BR_IFCLR:  /* branch if condition bit is 0 */
-        if (!cond)
+        if (!cond) {
+            DBDMA_DPRINTFCH(ch, "  [BR_IFCLR = 1]\n");
             branch(ch);
-        else
+        } else {
+            DBDMA_DPRINTFCH(ch, "  [BR_IFCLR = 0]\n");
             next(ch);
+        }
         return;
     }
 }
@@ -428,7 +435,7 @@ wait:
 
 static void stop(DBDMA_channel *ch)
 {
-    ch->regs[DBDMA_STATUS] &= ~(ACTIVE|DEAD|FLUSH);
+    ch->regs[DBDMA_STATUS] &= ~(ACTIVE);
 
     /* the stop command does not increment command pointer */
 }
@@ -471,18 +478,22 @@ static void channel_run(DBDMA_channel *ch)
 
     switch (cmd) {
     case OUTPUT_MORE:
+        DBDMA_DPRINTFCH(ch, "* OUTPUT_MORE *\n");
         start_output(ch, key, phy_addr, req_count, 0);
         return;
 
     case OUTPUT_LAST:
+        DBDMA_DPRINTFCH(ch, "* OUTPUT_LAST *\n");
         start_output(ch, key, phy_addr, req_count, 1);
         return;
 
     case INPUT_MORE:
+        DBDMA_DPRINTFCH(ch, "* INPUT_MORE *\n");
         start_input(ch, key, phy_addr, req_count, 0);
         return;
 
     case INPUT_LAST:
+        DBDMA_DPRINTFCH(ch, "* INPUT_LAST *\n");
         start_input(ch, key, phy_addr, req_count, 1);
         return;
     }
@@ -508,10 +519,12 @@ static void channel_run(DBDMA_channel *ch)
 
     switch (cmd) {
     case LOAD_WORD:
+        DBDMA_DPRINTFCH(ch, "* LOAD_WORD *\n");
         load_word(ch, key, phy_addr, req_count);
         return;
 
     case STORE_WORD:
+        DBDMA_DPRINTFCH(ch, "* STORE_WORD *\n");
         store_word(ch, key, phy_addr, req_count);
         return;
     }
@@ -562,43 +575,117 @@ void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
     ch->io.opaque = opaque;
 }
 
-static void
-dbdma_control_write(DBDMA_channel *ch)
+static void dbdma_control_write(DBDMA_channel *ch)
 {
     uint16_t mask, value;
     uint32_t status;
+    bool do_flush = false;
 
     mask = (ch->regs[DBDMA_CONTROL] >> 16) & 0xffff;
     value = ch->regs[DBDMA_CONTROL] & 0xffff;
 
-    value &= (RUN | PAUSE | FLUSH | WAKE | DEVSTAT);
-
+    /* This is the status register which we'll update
+     * appropriately and store back
+     */
     status = ch->regs[DBDMA_STATUS];
 
-    status = (value & mask) | (status & ~mask);
+    /* RUN and PAUSE are bits under SW control only
+     * FLUSH and WAKE are set by SW and cleared by HW
+     * DEAD, ACTIVE and BT are only under HW control
+     *
+     * We handle ACTIVE separately at the end of the
+     * logic to ensure all cases are covered.
+     */
 
-    if (status & WAKE)
-        status |= ACTIVE;
-    if (status & RUN) {
-        status |= ACTIVE;
-        status &= ~DEAD;
+    /* Setting RUN will tentatively activate the channel
+     */
+    if ((mask & RUN) && (value & RUN)) {
+        status |= RUN;
+        DBDMA_DPRINTFCH(ch, " Setting RUN !\n");
+    }
+
+    /* Clearing RUN 1->0 will stop the channel */
+    if ((mask & RUN) && !(value & RUN)) {
+        /* This has the side effect of clearing the DEAD bit */
+        status &= ~(DEAD | RUN);
+        DBDMA_DPRINTFCH(ch, " Clearing RUN !\n");
+    }
+
+    /* Setting WAKE wakes up an idle channel if it's running
+     *
+     * Note: The doc doesn't say so but assume that only works
+     * on a channel whose RUN bit is set.
+     *
+     * We set WAKE in status, it's not terribly useful as it will
+     * be cleared on the next command fetch but it seems to mimmic
+     * the HW behaviour and is useful for the way we handle
+     * ACTIVE further down.
+     */
+    if ((mask & WAKE) && (value & WAKE) && (status & RUN)) {
+        status |= WAKE;
+        DBDMA_DPRINTFCH(ch, " Setting WAKE !\n");
+    }
+
+    /* PAUSE being set will deactivate (or prevent activation)
+     * of the channel. We just copy it over for now, ACTIVE will
+     * be re-evaluated later.
+     */
+    if (mask & PAUSE) {
+        status = (status & ~PAUSE) | (value & PAUSE);
+        DBDMA_DPRINTFCH(ch, " %sing PAUSE !\n",
+                        (value & PAUSE) ? "sett" : "clear");
     }
-    if (status & PAUSE)
+
+    /* FLUSH is its own thing */
+    if ((mask & FLUSH) && (value & FLUSH))  {
+        DBDMA_DPRINTFCH(ch, " Setting FLUSH !\n");
+        /* We set flush directly in the status register, we do *NOT*
+         * set it in "status" so that it gets naturally cleared when
+         * we update the status register further down. That way it
+         * will be set only during the HW flush operation so it is
+         * visible to any completions happening during that time.
+         */
+        ch->regs[DBDMA_STATUS] |= FLUSH;
+        do_flush = true;
+    }
+
+    /* If either RUN or PAUSE is clear, so should ACTIVE be,
+     * otherwise, ACTIVE will be set if we modified RUN, PAUSE or
+     * set WAKE. That means that PAUSE was just cleared, RUN was
+     * just set or WAKE was just set.
+     */
+    if ((status & PAUSE) || !(status & RUN)) {
         status &= ~ACTIVE;
-    if ((ch->regs[DBDMA_STATUS] & RUN) && !(status & RUN)) {
-        /* RUN is cleared */
-        status &= ~(ACTIVE|DEAD);
+        DBDMA_DPRINTFCH(ch, "  -> ACTIVE down !\n");
+
+        /* We stopped processing, we want the underlying HW command
+         * to complete *before* we clear the ACTIVE bit. Otherwise
+         * we can get into a situation where the command status will
+         * have RUN or ACTIVE not set which is going to confuse the
+         * MacOS driver.
+         */
+        do_flush = true;
+    } else if (mask & (RUN | PAUSE)) {
+        status |= ACTIVE;
+        DBDMA_DPRINTFCH(ch, " -> ACTIVE up !\n");
+    } else if ((mask & WAKE) && (value & WAKE)) {
+        status |= ACTIVE;
+        DBDMA_DPRINTFCH(ch, " -> ACTIVE up !\n");
     }
 
-    if ((status & FLUSH) && ch->flush) {
+    DBDMA_DPRINTFCH(ch, " new status=0x%08x\n", status);
+
+    /* If we need to flush the underlying HW, do it now, this happens
+     * both on FLUSH commands and when stopping the channel for safety.
+     */
+    if (do_flush && ch->flush) {
         ch->flush(&ch->io);
-        status &= ~FLUSH;
     }
 
-    DBDMA_DPRINTFCH(ch, "    status 0x%08x\n", status);
-
+    /* Finally update the status register image */
     ch->regs[DBDMA_STATUS] = status;
 
+    /* If active, make sure the BH gets to run */
     if (status & ACTIVE) {
         DBDMA_kick(dbdma_from_ch(ch));
     }
@@ -666,13 +753,9 @@ static uint64_t dbdma_read(void *opaque, hwaddr addr,
 
     value = ch->regs[reg];
 
-    DBDMA_DPRINTFCH(ch, "readl 0x" TARGET_FMT_plx " => 0x%08x\n", addr, value);
-    DBDMA_DPRINTFCH(ch, "channel 0x%x reg 0x%x\n",
-                    (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
-
     switch(reg) {
     case DBDMA_CONTROL:
-        value = 0;
+        value = ch->regs[DBDMA_STATUS];
         break;
     case DBDMA_STATUS:
     case DBDMA_CMDPTR_LO:
@@ -698,6 +781,10 @@ static uint64_t dbdma_read(void *opaque, hwaddr addr,
         break;
     }
 
+    DBDMA_DPRINTFCH(ch, "readl 0x" TARGET_FMT_plx " => 0x%08x\n", addr, value);
+    DBDMA_DPRINTFCH(ch, "channel 0x%x reg 0x%x\n",
+                    (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
+
     return value;
 }
 
@@ -764,51 +851,49 @@ static const VMStateDescription vmstate_dbdma = {
     }
 };
 
-static void dbdma_reset(void *opaque)
+static void mac_dbdma_reset(DeviceState *d)
 {
-    DBDMAState *s = opaque;
+    DBDMAState *s = MAC_DBDMA(d);
     int i;
 
-    for (i = 0; i < DBDMA_CHANNELS; i++)
+    for (i = 0; i < DBDMA_CHANNELS; i++) {
         memset(s->channels[i].regs, 0, DBDMA_SIZE);
+    }
 }
 
 static void dbdma_unassigned_rw(DBDMA_io *io)
-{
-    DBDMA_channel *ch = io->channel;
-    qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
-                  __func__, ch->channel);
-    ch->io.processing = false;
-}
-
-static void dbdma_unassigned_flush(DBDMA_io *io)
 {
     DBDMA_channel *ch = io->channel;
     dbdma_cmd *current = &ch->current;
     uint16_t cmd;
     qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
                   __func__, ch->channel);
+    ch->io.processing = false;
 
     cmd = le16_to_cpu(current->command) & COMMAND_MASK;
     if (cmd == OUTPUT_MORE || cmd == OUTPUT_LAST ||
         cmd == INPUT_MORE || cmd == INPUT_LAST) {
-        current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS] | FLUSH);
+        current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
         current->res_count = cpu_to_le16(io->len);
         dbdma_cmdptr_save(ch);
     }
 }
 
-void* DBDMA_init (MemoryRegion **dbdma_mem)
+static void dbdma_unassigned_flush(DBDMA_io *io)
 {
-    DBDMAState *s;
-    int i;
+    DBDMA_channel *ch = io->channel;
+    qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n",
+                  __func__, ch->channel);
+}
 
-    s = g_malloc0(sizeof(DBDMAState));
+static void mac_dbdma_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DBDMAState *s = MAC_DBDMA(obj);
+    int i;
 
     for (i = 0; i < DBDMA_CHANNELS; i++) {
-        DBDMA_io *io = &s->channels[i].io;
         DBDMA_channel *ch = &s->channels[i];
-        qemu_iovec_init(&io->iov, 1);
 
         ch->rw = dbdma_unassigned_rw;
         ch->flush = dbdma_unassigned_flush;
@@ -816,12 +901,37 @@ void* DBDMA_init (MemoryRegion **dbdma_mem)
         ch->io.channel = ch;
     }
 
-    memory_region_init_io(&s->mem, NULL, &dbdma_ops, s, "dbdma", 0x1000);
-    *dbdma_mem = &s->mem;
-    vmstate_register(NULL, -1, &vmstate_dbdma, s);
-    qemu_register_reset(dbdma_reset, s);
+    memory_region_init_io(&s->mem, obj, &dbdma_ops, s, "dbdma", 0x1000);
+    sysbus_init_mmio(sbd, &s->mem);
+}
+
+static void mac_dbdma_realize(DeviceState *dev, Error **errp)
+{
+    DBDMAState *s = MAC_DBDMA(dev);
 
     s->bh = qemu_bh_new(DBDMA_run_bh, s);
+}
+
+static void mac_dbdma_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = mac_dbdma_realize;
+    dc->reset = mac_dbdma_reset;
+    dc->vmsd = &vmstate_dbdma;
+}
+
+static const TypeInfo mac_dbdma_type_info = {
+    .name = TYPE_MAC_DBDMA,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(DBDMAState),
+    .instance_init = mac_dbdma_init,
+    .class_init = mac_dbdma_class_init
+};
 
-    return s;
+static void mac_dbdma_register_types(void)
+{
+    type_register_static(&mac_dbdma_type_info);
 }
+
+type_init(mac_dbdma_register_types)
index 5d57f45dc6df174318d42ffff07e738abb4893d7..9aa7e7559b47122ee7a2cc51b7db8f0c9f453a45 100644 (file)
@@ -41,7 +41,7 @@ typedef struct MacIOState
 
     MemoryRegion bar;
     CUDAState cuda;
-    void *dbdma;
+    DBDMAState *dbdma;
     MemoryRegion *pic_mem;
     MemoryRegion *escc_mem;
     uint64_t frequency;
@@ -127,10 +127,15 @@ static void macio_common_realize(PCIDevice *d, Error **errp)
     MacIOState *s = MACIO(d);
     SysBusDevice *sysbus_dev;
     Error *err = NULL;
-    MemoryRegion *dbdma_mem;
 
-    s->dbdma = DBDMA_init(&dbdma_mem);
-    memory_region_add_subregion(&s->bar, 0x08000, dbdma_mem);
+    object_property_set_bool(OBJECT(s->dbdma), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_dev = SYS_BUS_DEVICE(s->dbdma);
+    memory_region_add_subregion(&s->bar, 0x08000,
+                                sysbus_mmio_get_region(sysbus_dev, 0));
 
     object_property_set_bool(OBJECT(&s->cuda), true, "realized", &err);
     if (err) {
@@ -154,7 +159,10 @@ static void macio_realize_ide(MacIOState *s, MACIOIDEState *ide,
     sysbus_dev = SYS_BUS_DEVICE(ide);
     sysbus_connect_irq(sysbus_dev, 0, irq0);
     sysbus_connect_irq(sysbus_dev, 1, irq1);
-    macio_ide_register_dma(ide, s->dbdma, dmaid);
+    qdev_prop_set_uint32(DEVICE(ide), "channel", dmaid);
+    object_property_set_link(OBJECT(ide), OBJECT(s->dbdma), "dbdma", errp);
+    macio_ide_register_dma(ide);
+
     object_property_set_bool(OBJECT(ide), true, "realized", errp);
 }
 
@@ -334,6 +342,9 @@ static void macio_instance_init(Object *obj)
     object_initialize(&s->cuda, sizeof(s->cuda), TYPE_CUDA);
     qdev_set_parent_bus(DEVICE(&s->cuda), sysbus_get_default());
     object_property_add_child(obj, "cuda", OBJECT(&s->cuda), NULL);
+
+    s->dbdma = MAC_DBDMA(object_new(TYPE_MAC_DBDMA));
+    object_property_add_child(obj, "dbdma", OBJECT(s->dbdma), NULL);
 }
 
 static const VMStateDescription vmstate_macio_oldworld = {
index 20cbddb4e465a9300b17bc47afac3dd3c6ab7edd..b501af16533d178f1614f55344bd2fddd2a935bd 100644 (file)
@@ -131,8 +131,10 @@ typedef struct MACIOIDEState {
     /*< private >*/
     SysBusDevice parent_obj;
     /*< public >*/
-
-    qemu_irq irq;
+    uint32_t channel;
+    qemu_irq real_ide_irq;
+    qemu_irq real_dma_irq;
+    qemu_irq ide_irq;
     qemu_irq dma_irq;
 
     MemoryRegion mem;
@@ -140,10 +142,12 @@ typedef struct MACIOIDEState {
     IDEDMA dma;
     void *dbdma;
     bool dma_active;
+    uint32_t timing_reg;
+    uint32_t irq_reg;
 } MACIOIDEState;
 
 void macio_ide_init_drives(MACIOIDEState *ide, DriveInfo **hd_table);
-void macio_ide_register_dma(MACIOIDEState *ide, void *dbdma, int channel);
+void macio_ide_register_dma(MACIOIDEState *ide);
 
 void macio_init(PCIDevice *dev,
                 MemoryRegion *pic_mem,
index d013c412d611a6a12844c59f43cb3992013b2a8a..6d0ace20ca5534a0342025247b76f4b504d0c9fc 100644 (file)
@@ -77,7 +77,7 @@
 #define MAX_IDE_BUS 2
 #define CFG_ADDR 0xf0000510
 #define TBFREQ (100UL * 1000UL * 1000UL)
-#define CLOCKFREQ (266UL * 1000UL * 1000UL)
+#define CLOCKFREQ (900UL * 1000UL * 1000UL)
 #define BUSFREQ (100UL * 1000UL * 1000UL)
 
 #define NDRV_VGA_FILENAME "qemu_vga.ndrv"
@@ -342,7 +342,7 @@ static void ppc_core99_init(MachineState *machine)
     pic = g_new0(qemu_irq, 64);
 
     dev = qdev_create(NULL, TYPE_OPENPIC);
-    qdev_prop_set_uint32(dev, "model", OPENPIC_MODEL_RAVEN);
+    qdev_prop_set_uint32(dev, "model", OPENPIC_MODEL_KEYLARGO);
     qdev_init_nofail(dev);
     s = SYS_BUS_DEVICE(dev);
     pic_mem = s->mmio[0].memory;
index 61838c3e6f5e979a937c7900e183936d3f171ce1..bc7c8b7bd748a2edd975a16937e43819758d501f 100644 (file)
@@ -371,8 +371,10 @@ static int heathrow_kvm_type(const char *arg)
     return 2;
 }
 
-static void heathrow_machine_init(MachineClass *mc)
+static void heathrow_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Heathrow based PowerMAC";
     mc->init = ppc_heathrow_init;
     mc->block_default_type = IF_IDE;
@@ -385,4 +387,15 @@ static void heathrow_machine_init(MachineClass *mc)
     mc->kvm_type = heathrow_kvm_type;
 }
 
-DEFINE_MACHINE("g3beige", heathrow_machine_init)
+static const TypeInfo ppc_heathrow_machine_info = {
+    .name          = MACHINE_TYPE_NAME("g3beige"),
+    .parent        = TYPE_MACHINE,
+    .class_init    = heathrow_class_init
+};
+
+static void ppc_heathrow_register_types(void)
+{
+    type_register_static(&ppc_heathrow_machine_info);
+}
+
+type_init(ppc_heathrow_register_types);
index 47221158d415318f5512f737dbf92847f5f35681..d46d91c76f5cdf7d7e6374c8f400fb09e1c6dbc8 100644 (file)
@@ -570,10 +570,14 @@ static void ppc_powernv_init(MachineState *machine)
     }
 
     fw_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+    if (!fw_filename) {
+        error_report("Could not find OPAL firmware '%s'", bios_name);
+        exit(1);
+    }
 
     fw_size = load_image_targphys(fw_filename, FW_LOAD_ADDR, FW_MAX_SIZE);
     if (fw_size < 0) {
-        error_report("Could not load OPAL '%s'", fw_filename);
+        error_report("Could not load OPAL firmware '%s'", fw_filename);
         exit(1);
     }
     g_free(fw_filename);
index e621d0aec502a4d2feebe8d64750d7b92a09c695..8e58065f5fc2d669c561833dcbff06858e904145 100644 (file)
@@ -105,9 +105,12 @@ ram_addr_t ppc405_set_bootinfo (CPUPPCState *env, ppc4xx_bd_info_t *bd,
 /*****************************************************************************/
 /* Peripheral local bus arbitrer */
 enum {
-    PLB0_BESR = 0x084,
-    PLB0_BEAR = 0x086,
-    PLB0_ACR  = 0x087,
+    PLB3A0_ACR = 0x077,
+    PLB4A0_ACR = 0x081,
+    PLB0_BESR  = 0x084,
+    PLB0_BEAR  = 0x086,
+    PLB0_ACR   = 0x087,
+    PLB4A1_ACR = 0x089,
 };
 
 typedef struct ppc4xx_plb_t ppc4xx_plb_t;
@@ -179,9 +182,12 @@ void ppc4xx_plb_init(CPUPPCState *env)
     ppc4xx_plb_t *plb;
 
     plb = g_malloc0(sizeof(ppc4xx_plb_t));
+    ppc_dcr_register(env, PLB3A0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
+    ppc_dcr_register(env, PLB4A0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
     ppc_dcr_register(env, PLB0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
     ppc_dcr_register(env, PLB0_BEAR, plb, &dcr_read_plb, &dcr_write_plb);
     ppc_dcr_register(env, PLB0_BESR, plb, &dcr_read_plb, &dcr_write_plb);
+    ppc_dcr_register(env, PLB4A1_ACR, plb, &dcr_read_plb, &dcr_write_plb);
     qemu_register_reset(ppc4xx_plb_reset, plb);
 }
 
index 17ea77618cb9c721cbc13f9bce2f0e411237b5c9..ff87f155d55ec3d216ed8a2f62e2ea1148d9b0e3 100644 (file)
@@ -1211,14 +1211,15 @@ static uint64_t spapr_get_patbe(PPCVirtualHypervisor *vhyp)
  */
 static int get_htab_fd(sPAPRMachineState *spapr)
 {
+    Error *local_err = NULL;
+
     if (spapr->htab_fd >= 0) {
         return spapr->htab_fd;
     }
 
-    spapr->htab_fd = kvmppc_get_htab_fd(false);
+    spapr->htab_fd = kvmppc_get_htab_fd(false, 0, &local_err);
     if (spapr->htab_fd < 0) {
-        error_report("Unable to open fd for reading hash table from KVM: %s",
-                     strerror(errno));
+        error_report_err(local_err);
     }
 
     return spapr->htab_fd;
@@ -1239,6 +1240,19 @@ static hwaddr spapr_hpt_mask(PPCVirtualHypervisor *vhyp)
     return HTAB_SIZE(spapr) / HASH_PTEG_SIZE_64 - 1;
 }
 
+static target_ulong spapr_encode_hpt_for_kvm_pr(PPCVirtualHypervisor *vhyp)
+{
+    sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+
+    assert(kvm_enabled());
+
+    if (!spapr->htab) {
+        return 0;
+    }
+
+    return (target_ulong)(uintptr_t)spapr->htab | (spapr->htab_shift - 18);
+}
+
 static const ppc_hash_pte64_t *spapr_map_hptes(PPCVirtualHypervisor *vhyp,
                                                 hwaddr ptex, int n)
 {
@@ -1708,6 +1722,23 @@ static int htab_save_setup(QEMUFile *f, void *opaque)
     return 0;
 }
 
+static void htab_save_chunk(QEMUFile *f, sPAPRMachineState *spapr,
+                            int chunkstart, int n_valid, int n_invalid)
+{
+    qemu_put_be32(f, chunkstart);
+    qemu_put_be16(f, n_valid);
+    qemu_put_be16(f, n_invalid);
+    qemu_put_buffer(f, HPTE(spapr->htab, chunkstart),
+                    HASH_PTE_SIZE_64 * n_valid);
+}
+
+static void htab_save_end_marker(QEMUFile *f)
+{
+    qemu_put_be32(f, 0);
+    qemu_put_be16(f, 0);
+    qemu_put_be16(f, 0);
+}
+
 static void htab_save_first_pass(QEMUFile *f, sPAPRMachineState *spapr,
                                  int64_t max_ns)
 {
@@ -1739,11 +1770,7 @@ static void htab_save_first_pass(QEMUFile *f, sPAPRMachineState *spapr,
         if (index > chunkstart) {
             int n_valid = index - chunkstart;
 
-            qemu_put_be32(f, chunkstart);
-            qemu_put_be16(f, n_valid);
-            qemu_put_be16(f, 0);
-            qemu_put_buffer(f, HPTE(spapr->htab, chunkstart),
-                            HASH_PTE_SIZE_64 * n_valid);
+            htab_save_chunk(f, spapr, chunkstart, n_valid, 0);
 
             if (has_timeout &&
                 (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - starttime) > max_ns) {
@@ -1805,11 +1832,7 @@ static int htab_save_later_pass(QEMUFile *f, sPAPRMachineState *spapr,
             int n_valid = invalidstart - chunkstart;
             int n_invalid = index - invalidstart;
 
-            qemu_put_be32(f, chunkstart);
-            qemu_put_be16(f, n_valid);
-            qemu_put_be16(f, n_invalid);
-            qemu_put_buffer(f, HPTE(spapr->htab, chunkstart),
-                            HASH_PTE_SIZE_64 * n_valid);
+            htab_save_chunk(f, spapr, chunkstart, n_valid, n_invalid);
             sent += index - chunkstart;
 
             if (!final && (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - starttime) > max_ns) {
@@ -1872,10 +1895,7 @@ static int htab_save_iterate(QEMUFile *f, void *opaque)
         rc = htab_save_later_pass(f, spapr, MAX_ITERATION_NS);
     }
 
-    /* End marker */
-    qemu_put_be32(f, 0);
-    qemu_put_be16(f, 0);
-    qemu_put_be16(f, 0);
+    htab_save_end_marker(f);
 
     return rc;
 }
@@ -1915,9 +1935,7 @@ static int htab_save_complete(QEMUFile *f, void *opaque)
     }
 
     /* End marker */
-    qemu_put_be32(f, 0);
-    qemu_put_be16(f, 0);
-    qemu_put_be16(f, 0);
+    htab_save_end_marker(f);
 
     return 0;
 }
@@ -1927,6 +1945,7 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id)
     sPAPRMachineState *spapr = opaque;
     uint32_t section_hdr;
     int fd = -1;
+    Error *local_err = NULL;
 
     if (version_id < 1 || version_id > 1) {
         error_report("htab_load() bad version");
@@ -1941,8 +1960,6 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id)
     }
 
     if (section_hdr) {
-        Error *local_err = NULL;
-
         /* First section gives the htab size */
         spapr_reallocate_hpt(spapr, section_hdr, &local_err);
         if (local_err) {
@@ -1955,10 +1972,10 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id)
     if (!spapr->htab) {
         assert(kvm_enabled());
 
-        fd = kvmppc_get_htab_fd(true);
+        fd = kvmppc_get_htab_fd(true, 0, &local_err);
         if (fd < 0) {
-            error_report("Unable to open fd to restore KVM hash table: %s",
-                         strerror(errno));
+            error_report_err(local_err);
+            return fd;
         }
     }
 
@@ -3600,6 +3617,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     vhc->unmap_hptes = spapr_unmap_hptes;
     vhc->store_hpte = spapr_store_hpte;
     vhc->get_patbe = spapr_get_patbe;
+    vhc->encode_hpt_for_kvm_pr = spapr_encode_hpt_for_kvm_pr;
     xic->ics_get = spapr_ics_get;
     xic->ics_resend = spapr_ics_resend;
     xic->icp_get = spapr_icp_get;
index c08ee7571a50933807dd76c3c573a6a376251acf..3e20b1d8864417be21d0052d0b80c9ce09164fa5 100644 (file)
@@ -18,6 +18,7 @@
 #include "hw/ppc/ppc.h"
 #include "target/ppc/mmu-hash64.h"
 #include "sysemu/numa.h"
+#include "sysemu/hw_accel.h"
 #include "qemu/error-report.h"
 
 void spapr_cpu_parse_features(sPAPRMachineState *spapr)
@@ -73,7 +74,6 @@ void spapr_cpu_parse_features(sPAPRMachineState *spapr)
 
 static void spapr_cpu_reset(void *opaque)
 {
-    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
     PowerPCCPU *cpu = opaque;
     CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
@@ -86,20 +86,6 @@ static void spapr_cpu_reset(void *opaque)
     cs->halted = 1;
 
     env->spr[SPR_HIOR] = 0;
-
-    /*
-     * This is a hack for the benefit of KVM PR - it abuses the SDR1
-     * slot in kvm_sregs to communicate the userspace address of the
-     * HPT
-     */
-    if (kvm_enabled()) {
-        env->spr[SPR_SDR1] = (target_ulong)(uintptr_t)spapr->htab
-            | (spapr->htab_shift - 18);
-        if (kvmppc_put_books_sregs(cpu) < 0) {
-            error_report("Unable to update SDR1 in KVM");
-            exit(1);
-        }
-    }
 }
 
 static void spapr_cpu_destroy(PowerPCCPU *cpu)
index 57bb411394ed00f486ebd1b2623cf4c346ff341f..8d72bb7c1c34f762394c3204b5526ff72bcda017 100644 (file)
@@ -686,6 +686,37 @@ static int rehash_hpt(PowerPCCPU *cpu,
     return H_SUCCESS;
 }
 
+static void do_push_sregs_to_kvm_pr(CPUState *cs, run_on_cpu_data data)
+{
+    int ret;
+
+    cpu_synchronize_state(cs);
+
+    ret = kvmppc_put_books_sregs(POWERPC_CPU(cs));
+    if (ret < 0) {
+        error_report("failed to push sregs to KVM: %s", strerror(-ret));
+        exit(1);
+    }
+}
+
+static void push_sregs_to_kvm_pr(sPAPRMachineState *spapr)
+{
+    CPUState *cs;
+
+    /*
+     * This is a hack for the benefit of KVM PR - it abuses the SDR1
+     * slot in kvm_sregs to communicate the userspace address of the
+     * HPT
+     */
+    if (!kvm_enabled() || !spapr->htab) {
+        return;
+    }
+
+    CPU_FOREACH(cs) {
+        run_on_cpu(cs, do_push_sregs_to_kvm_pr, RUN_ON_CPU_NULL);
+    }
+}
+
 static target_ulong h_resize_hpt_commit(PowerPCCPU *cpu,
                                         sPAPRMachineState *spapr,
                                         target_ulong opcode,
@@ -733,12 +764,7 @@ static target_ulong h_resize_hpt_commit(PowerPCCPU *cpu,
         spapr->htab = pending->hpt;
         spapr->htab_shift = pending->shift;
 
-        if (kvm_enabled()) {
-            /* For KVM PR, update the HPT pointer */
-            target_ulong sdr1 = (target_ulong)(uintptr_t)spapr->htab
-                | (spapr->htab_shift - 18);
-            kvmppc_update_sdr1(sdr1);
-        }
+        push_sregs_to_kvm_pr(spapr);
 
         pending->hpt = NULL; /* so it's not free()d */
     }
@@ -1564,12 +1590,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
              * the point this is called, nothing should have been
              * entered into the existing HPT */
             spapr_reallocate_hpt(spapr, maxshift, &error_fatal);
-            if (kvm_enabled()) {
-                /* For KVM PR, update the HPT pointer */
-                target_ulong sdr1 = (target_ulong)(uintptr_t)spapr->htab
-                    | (spapr->htab_shift - 18);
-                kvmppc_update_sdr1(sdr1);
-            }
+            push_sregs_to_kvm_pr(spapr);
         }
     }
 
index cf54160526fae4b2ba0093d86197da5601e619e5..6126c800440f41fdbf481f3c0be1d3f262c65cc4 100644 (file)
@@ -1523,16 +1523,6 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
         sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
         Error *local_err = NULL;
 
-        if ((sphb->buid != (uint64_t)-1) || (sphb->dma_liobn[0] != (uint32_t)-1)
-            || (sphb->dma_liobn[1] != (uint32_t)-1 && windows_supported == 2)
-            || (sphb->mem_win_addr != (hwaddr)-1)
-            || (sphb->mem64_win_addr != (hwaddr)-1)
-            || (sphb->io_win_addr != (hwaddr)-1)) {
-            error_setg(errp, "Either \"index\" or other parameters must"
-                       " be specified for PAPR PHB, not both");
-            return;
-        }
-
         smc->phb_placement(spapr, sphb->index,
                            &sphb->buid, &sphb->io_win_addr,
                            &sphb->mem_win_addr, &sphb->mem64_win_addr,
@@ -1541,46 +1531,20 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
             error_propagate(errp, local_err);
             return;
         }
-    }
-
-    if (sphb->buid == (uint64_t)-1) {
-        error_setg(errp, "BUID not specified for PHB");
-        return;
-    }
-
-    if ((sphb->dma_liobn[0] == (uint32_t)-1) ||
-        ((sphb->dma_liobn[1] == (uint32_t)-1) && (windows_supported > 1))) {
-        error_setg(errp, "LIOBN(s) not specified for PHB");
-        return;
-    }
-
-    if (sphb->mem_win_addr == (hwaddr)-1) {
-        error_setg(errp, "Memory window address not specified for PHB");
-        return;
-    }
-
-    if (sphb->io_win_addr == (hwaddr)-1) {
-        error_setg(errp, "IO window address not specified for PHB");
+    } else {
+        error_setg(errp, "\"index\" for PAPR PHB is mandatory");
         return;
     }
 
     if (sphb->mem64_win_size != 0) {
-        if (sphb->mem64_win_addr == (hwaddr)-1) {
-            error_setg(errp,
-                       "64-bit memory window address not specified for PHB");
-            return;
-        }
-
         if (sphb->mem_win_size > SPAPR_PCI_MEM32_WIN_SIZE) {
             error_setg(errp, "32-bit memory window of size 0x%"HWADDR_PRIx
                        " (max 2 GiB)", sphb->mem_win_size);
             return;
         }
 
-        if (sphb->mem64_win_pciaddr == (hwaddr)-1) {
-            /* 64-bit window defaults to identity mapping */
-            sphb->mem64_win_pciaddr = sphb->mem64_win_addr;
-        }
+        /* 64-bit window defaults to identity mapping */
+        sphb->mem64_win_pciaddr = sphb->mem64_win_addr;
     } else if (sphb->mem_win_size > SPAPR_PCI_MEM32_WIN_SIZE) {
         /*
          * For compatibility with old configuration, if no 64-bit MMIO
@@ -1622,18 +1586,16 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
     memory_region_add_subregion(get_system_memory(), sphb->mem_win_addr,
                                 &sphb->mem32window);
 
-    if (sphb->mem64_win_pciaddr != (hwaddr)-1) {
+    if (sphb->mem64_win_size != 0) {
         namebuf = g_strdup_printf("%s.mmio64-alias", sphb->dtbusname);
         memory_region_init_alias(&sphb->mem64window, OBJECT(sphb),
                                  namebuf, &sphb->memspace,
                                  sphb->mem64_win_pciaddr, sphb->mem64_win_size);
         g_free(namebuf);
 
-        if (sphb->mem64_win_addr != (hwaddr)-1) {
-            memory_region_add_subregion(get_system_memory(),
-                                        sphb->mem64_win_addr,
-                                        &sphb->mem64window);
-        }
+        memory_region_add_subregion(get_system_memory(),
+                                    sphb->mem64_win_addr,
+                                    &sphb->mem64window);
     }
 
     /* Initialize IO regions */
@@ -1789,18 +1751,10 @@ static void spapr_phb_reset(DeviceState *qdev)
 
 static Property spapr_phb_properties[] = {
     DEFINE_PROP_UINT32("index", sPAPRPHBState, index, -1),
-    DEFINE_PROP_UINT64("buid", sPAPRPHBState, buid, -1),
-    DEFINE_PROP_UINT32("liobn", sPAPRPHBState, dma_liobn[0], -1),
-    DEFINE_PROP_UINT32("liobn64", sPAPRPHBState, dma_liobn[1], -1),
-    DEFINE_PROP_UINT64("mem_win_addr", sPAPRPHBState, mem_win_addr, -1),
     DEFINE_PROP_UINT64("mem_win_size", sPAPRPHBState, mem_win_size,
                        SPAPR_PCI_MEM32_WIN_SIZE),
-    DEFINE_PROP_UINT64("mem64_win_addr", sPAPRPHBState, mem64_win_addr, -1),
     DEFINE_PROP_UINT64("mem64_win_size", sPAPRPHBState, mem64_win_size,
                        SPAPR_PCI_MEM64_WIN_SIZE),
-    DEFINE_PROP_UINT64("mem64_win_pciaddr", sPAPRPHBState, mem64_win_pciaddr,
-                       -1),
-    DEFINE_PROP_UINT64("io_win_addr", sPAPRPHBState, io_win_addr, -1),
     DEFINE_PROP_UINT64("io_win_size", sPAPRPHBState, io_win_size,
                        SPAPR_PCI_IO_WIN_SIZE),
     DEFINE_PROP_BOOL("dynamic-reconfiguration", sPAPRPHBState, dr_enabled,
index 6c20604d07497bc0c8066c226f3874f07670bf2a..3b83beb140d85be1df7fb4ea688f92f50011cc1c 100644 (file)
@@ -142,6 +142,30 @@ static const TypeInfo ehci_tegra2_type_info = {
     .class_init    = ehci_tegra2_class_init,
 };
 
+static void ehci_ppc4xx_init(Object *o)
+{
+    EHCISysBusState *s = SYS_BUS_EHCI(o);
+
+    s->ehci.companion_enable = true;
+}
+
+static void ehci_ppc4xx_class_init(ObjectClass *oc, void *data)
+{
+    SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    sec->capsbase = 0x0;
+    sec->opregbase = 0x10;
+    set_bit(DEVICE_CATEGORY_USB, dc->categories);
+}
+
+static const TypeInfo ehci_ppc4xx_type_info = {
+    .name          = TYPE_PPC4xx_EHCI,
+    .parent        = TYPE_SYS_BUS_EHCI,
+    .class_init    = ehci_ppc4xx_class_init,
+    .instance_init = ehci_ppc4xx_init,
+};
+
 /*
  * Faraday FUSBH200 USB 2.0 EHCI
  */
@@ -224,6 +248,7 @@ static void ehci_sysbus_register_types(void)
     type_register_static(&ehci_xlnx_type_info);
     type_register_static(&ehci_exynos4210_type_info);
     type_register_static(&ehci_tegra2_type_info);
+    type_register_static(&ehci_ppc4xx_type_info);
     type_register_static(&ehci_fusbh200_type_info);
 }
 
index 821f1ded435eca36a72fe4446af0cdff480b0437..0bc364b286110e118781a54a67479f871c1d340e 100644 (file)
@@ -344,6 +344,7 @@ typedef struct EHCIPCIState {
 #define TYPE_SYS_BUS_EHCI "sysbus-ehci-usb"
 #define TYPE_EXYNOS4210_EHCI "exynos4210-ehci-usb"
 #define TYPE_TEGRA2_EHCI "tegra2-ehci-usb"
+#define TYPE_PPC4xx_EHCI "ppc4xx-ehci-usb"
 #define TYPE_FUSBH200_EHCI "fusbh200-ehci-usb"
 
 #define SYS_BUS_EHCI(obj) \
index 267982e160b3f69e492efb73c7d54dae16dbfa44..17beeddb09a03778200ce61bbc1148febf153b5d 100644 (file)
@@ -1999,7 +1999,9 @@ typedef struct {
     /*< public >*/
 
     OHCIState ohci;
+    char *masterbus;
     uint32_t num_ports;
+    uint32_t firstport;
     dma_addr_t dma_offset;
 } OHCISysBusState;
 
@@ -2007,10 +2009,15 @@ static void ohci_realize_pxa(DeviceState *dev, Error **errp)
 {
     OHCISysBusState *s = SYSBUS_OHCI(dev);
     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    Error *err = NULL;
 
-    /* Cannot fail as we pass NULL for masterbus */
-    usb_ohci_init(&s->ohci, dev, s->num_ports, s->dma_offset, NULL, 0,
-                  &address_space_memory, &error_abort);
+    usb_ohci_init(&s->ohci, dev, s->num_ports, s->dma_offset,
+                  s->masterbus, s->firstport,
+                  &address_space_memory, &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
     sysbus_init_irq(sbd, &s->ohci.irq);
     sysbus_init_mmio(sbd, &s->ohci.mem);
 }
@@ -2142,7 +2149,9 @@ static const TypeInfo ohci_pci_info = {
 };
 
 static Property ohci_sysbus_properties[] = {
+    DEFINE_PROP_STRING("masterbus", OHCISysBusState, masterbus),
     DEFINE_PROP_UINT32("num-ports", OHCISysBusState, num_ports, 3),
+    DEFINE_PROP_UINT32("firstport", OHCISysBusState, firstport, 0),
     DEFINE_PROP_DMAADDR("dma-offset", OHCISysBusState, dma_offset, 0),
     DEFINE_PROP_END_OF_LIST(),
 };
index a8603877d79cddbdb433771d0f45aaec5c93b7e0..26cc469de483a9632946912bd722ec79441ccd63 100644 (file)
@@ -26,6 +26,7 @@
 #include "exec/memory.h"
 #include "qemu/iov.h"
 #include "sysemu/dma.h"
+#include "hw/sysbus.h"
 
 typedef struct DBDMA_io DBDMA_io;
 
@@ -42,10 +43,6 @@ struct DBDMA_io {
     DBDMA_end dma_end;
     /* DMA is in progress, don't start another one */
     bool processing;
-    /* unaligned last sector of a request */
-    uint8_t head_remainder[0x200];
-    uint8_t tail_remainder[0x200];
-    QEMUIOVector iov;
     /* DMA request */
     void *dma_mem;
     dma_addr_t dma_len;
@@ -164,6 +161,8 @@ typedef struct DBDMA_channel {
 } DBDMA_channel;
 
 typedef struct {
+    SysBusDevice parent_obj;
+
     MemoryRegion mem;
     DBDMA_channel channels[DBDMA_CHANNELS];
     QEMUBH *bh;
@@ -175,6 +174,8 @@ void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
                             DBDMA_rw rw, DBDMA_flush flush,
                             void *opaque);
 void DBDMA_kick(DBDMAState *dbdma);
-void* DBDMA_init (MemoryRegion **dbdma_mem);
+
+#define TYPE_MAC_DBDMA "mac-dbdma"
+#define MAC_DBDMA(obj) OBJECT_CHECK(DBDMAState, (obj), TYPE_MAC_DBDMA)
 
 #endif
index 6137e2d7a2f2d0ca0cc26f8f36ef0575949b3286..e55ce546aa49b05b212e990f98582518502d2c93 100644 (file)
@@ -20,6 +20,7 @@ enum {
 #define OPENPIC_MODEL_RAVEN       0
 #define OPENPIC_MODEL_FSL_MPIC_20 1
 #define OPENPIC_MODEL_FSL_MPIC_42 2
+#define OPENPIC_MODEL_KEYLARGO    3
 
 #define OPENPIC_MAX_SRC     256
 #define OPENPIC_MAX_TMR     4
index 3757b2cab94bfc4d5fec8baebc35f6e509bf96aa..38077b479699ce08f1e737181fdf7e187b058735 100644 (file)
@@ -54,7 +54,7 @@ typedef struct PnvXScomInterfaceClass {
  *   PCB SLAVE   0x110Fxxxx
  */
 
-#define PNV_XSCOM_EX_CORE_BASE(base, i) (base | (((uint64_t)i) << 24))
+#define PNV_XSCOM_EX_CORE_BASE(base, i) ((base) | ((uint64_t)(i) << 24))
 #define PNV_XSCOM_EX_CORE_SIZE    0x100000
 
 #define PNV_XSCOM_LPC_BASE        0xb0020
index 9626d6b7c40f57679b62d6248666b3a24cda6ce5..9d45702843d4e6658cec71bf9619dfaf6fd77ae4 100644 (file)
                 "PowerPC 440 EPb")
     POWERPC_DEF("440epx",        CPU_POWERPC_440EPX,                 440EP,
                 "PowerPC 440 EPX")
+    POWERPC_DEF("460exb",        CPU_POWERPC_460EXb,                 460EX,
+                "PowerPC 460 EXb")
 #if defined(TODO_USER_ONLY)
     POWERPC_DEF("440gpb",        CPU_POWERPC_440GPb,                 440GP,
                 "PowerPC 440 GPb")
@@ -786,6 +788,7 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
     { "x2vp50", "x2vp20" },
 
     { "440ep", "440epb" },
+    { "460ex", "460exb" },
 #if defined(TODO_USER_ONLY)
     { "440gp", "440gpc" },
     { "440gr", "440gra" },
index df31d7f49276eec2ee485b509492c4dc967052ac..25ef372d4c1dd3bc3d8f82eb34dc31a7311f8b37 100644 (file)
@@ -44,184 +44,55 @@ enum {
     /* PowerPC 401 cores */
     CPU_POWERPC_401A1              = 0x00210000,
     CPU_POWERPC_401B2              = 0x00220000,
-#if 0
-    CPU_POWERPC_401B3              = xxx,
-#endif
     CPU_POWERPC_401C2              = 0x00230000,
     CPU_POWERPC_401D2              = 0x00240000,
     CPU_POWERPC_401E2              = 0x00250000,
     CPU_POWERPC_401F2              = 0x00260000,
     CPU_POWERPC_401G2              = 0x00270000,
     /* PowerPC 401 microcontrolers */
-#if 0
-    CPU_POWERPC_401GF              = xxx,
-#endif
 #define CPU_POWERPC_IOP480           CPU_POWERPC_401B2
     /* IBM Processor for Network Resources */
     CPU_POWERPC_COBRA              = 0x10100000, /* XXX: 405 ? */
-#if 0
-    CPU_POWERPC_XIPCHIP            = xxx,
-#endif
     /* PowerPC 403 family */
     /* PowerPC 403 microcontrollers */
     CPU_POWERPC_403GA              = 0x00200011,
     CPU_POWERPC_403GB              = 0x00200100,
     CPU_POWERPC_403GC              = 0x00200200,
     CPU_POWERPC_403GCX             = 0x00201400,
-#if 0
-    CPU_POWERPC_403GP              = xxx,
-#endif
     /* PowerPC 405 family */
     /* PowerPC 405 cores */
-#if 0
-    CPU_POWERPC_405A3              = xxx,
-#endif
-#if 0
-    CPU_POWERPC_405A4              = xxx,
-#endif
-#if 0
-    CPU_POWERPC_405B3              = xxx,
-#endif
-#if 0
-    CPU_POWERPC_405B4              = xxx,
-#endif
-#if 0
-    CPU_POWERPC_405C3              = xxx,
-#endif
-#if 0
-    CPU_POWERPC_405C4              = xxx,
-#endif
     CPU_POWERPC_405D2              = 0x20010000,
-#if 0
-    CPU_POWERPC_405D3              = xxx,
-#endif
     CPU_POWERPC_405D4              = 0x41810000,
-#if 0
-    CPU_POWERPC_405D5              = xxx,
-#endif
-#if 0
-    CPU_POWERPC_405E4              = xxx,
-#endif
-#if 0
-    CPU_POWERPC_405F4              = xxx,
-#endif
-#if 0
-    CPU_POWERPC_405F5              = xxx,
-#endif
-#if 0
-    CPU_POWERPC_405F6              = xxx,
-#endif
     /* PowerPC 405 microcontrolers */
     /* XXX: missing 0x200108a0 */
     CPU_POWERPC_405CRa             = 0x40110041,
     CPU_POWERPC_405CRb             = 0x401100C5,
     CPU_POWERPC_405CRc             = 0x40110145,
     CPU_POWERPC_405EP              = 0x51210950,
-#if 0
-    CPU_POWERPC_405EXr             = xxx,
-#endif
     CPU_POWERPC_405EZ              = 0x41511460, /* 0x51210950 ? */
-#if 0
-    CPU_POWERPC_405FX              = xxx,
-#endif
     CPU_POWERPC_405GPa             = 0x40110000,
     CPU_POWERPC_405GPb             = 0x40110040,
     CPU_POWERPC_405GPc             = 0x40110082,
     CPU_POWERPC_405GPd             = 0x401100C4,
     CPU_POWERPC_405GPR             = 0x50910951,
-#if 0
-    CPU_POWERPC_405H               = xxx,
-#endif
-#if 0
-    CPU_POWERPC_405L               = xxx,
-#endif
     CPU_POWERPC_405LP              = 0x41F10000,
-#if 0
-    CPU_POWERPC_405PM              = xxx,
-#endif
-#if 0
-    CPU_POWERPC_405PS              = xxx,
-#endif
-#if 0
-    CPU_POWERPC_405S               = xxx,
-#endif
     /* IBM network processors */
     CPU_POWERPC_NPE405H            = 0x414100C0,
     CPU_POWERPC_NPE405H2           = 0x41410140,
     CPU_POWERPC_NPE405L            = 0x416100C0,
     CPU_POWERPC_NPE4GS3            = 0x40B10000,
-#if 0
-    CPU_POWERPC_NPCxx1             = xxx,
-#endif
-#if 0
-    CPU_POWERPC_NPR161             = xxx,
-#endif
-#if 0
-    CPU_POWERPC_LC77700            = xxx,
-#endif
     /* IBM STBxxx (PowerPC 401/403/405 core based microcontrollers) */
-#if 0
-    CPU_POWERPC_STB01000           = xxx,
-#endif
-#if 0
-    CPU_POWERPC_STB01010           = xxx,
-#endif
-#if 0
-    CPU_POWERPC_STB0210            = xxx, /* 401B3 */
-#endif
     CPU_POWERPC_STB03              = 0x40310000, /* 0x40130000 ? */
-#if 0
-    CPU_POWERPC_STB043             = xxx,
-#endif
-#if 0
-    CPU_POWERPC_STB045             = xxx,
-#endif
     CPU_POWERPC_STB04              = 0x41810000,
     CPU_POWERPC_STB25              = 0x51510950,
-#if 0
-    CPU_POWERPC_STB130             = xxx,
-#endif
     /* Xilinx cores */
     CPU_POWERPC_X2VP4              = 0x20010820,
     CPU_POWERPC_X2VP20             = 0x20010860,
-#if 0
-    CPU_POWERPC_ZL10310            = xxx,
-#endif
-#if 0
-    CPU_POWERPC_ZL10311            = xxx,
-#endif
-#if 0
-    CPU_POWERPC_ZL10320            = xxx,
-#endif
-#if 0
-    CPU_POWERPC_ZL10321            = xxx,
-#endif
     /* PowerPC 440 family */
     /* Generic PowerPC 440 */
 #define CPU_POWERPC_440              CPU_POWERPC_440GXf
     /* PowerPC 440 cores */
-#if 0
-    CPU_POWERPC_440A4              = xxx,
-#endif
     CPU_POWERPC_440_XILINX         = 0x7ff21910,
-#if 0
-    CPU_POWERPC_440A5              = xxx,
-#endif
-#if 0
-    CPU_POWERPC_440B4              = xxx,
-#endif
-#if 0
-    CPU_POWERPC_440F5              = xxx,
-#endif
-#if 0
-    CPU_POWERPC_440G5              = xxx,
-#endif
-#if 0
-    CPU_POWERPC_440H4              = xxx,
-#endif
-#if 0
-    CPU_POWERPC_440H6              = xxx,
-#endif
     /* PowerPC 440 microcontrolers */
     CPU_POWERPC_440EPa             = 0x42221850,
     CPU_POWERPC_440EPb             = 0x422218D3,
@@ -234,24 +105,10 @@ enum {
     CPU_POWERPC_440GXb             = 0x51B21851,
     CPU_POWERPC_440GXc             = 0x51B21892,
     CPU_POWERPC_440GXf             = 0x51B21894,
-#if 0
-    CPU_POWERPC_440S               = xxx,
-#endif
     CPU_POWERPC_440SP              = 0x53221850,
     CPU_POWERPC_440SP2             = 0x53221891,
     CPU_POWERPC_440SPE             = 0x53421890,
-    /* PowerPC 460 family */
-#if 0
-    /* Generic PowerPC 464 */
-#define CPU_POWERPC_464              CPU_POWERPC_464H90
-#endif
-    /* PowerPC 464 microcontrolers */
-#if 0
-    CPU_POWERPC_464H90             = xxx,
-#endif
-#if 0
-    CPU_POWERPC_464H90FP           = xxx,
-#endif
+    CPU_POWERPC_460EXb             = 0x130218A4, /* called 460 but 440 core */
     /* Freescale embedded PowerPC cores */
     /* PowerPC MPC 5xx cores (aka RCPU) */
     CPU_POWERPC_MPC5xx             = 0x00020020,
@@ -280,45 +137,8 @@ enum {
 #define CPU_POWERPC_MPC5200B_v21     CPU_POWERPC_G2LEgp1
     /* e200 family */
     /* e200 cores */
-#if 0
-    CPU_POWERPC_e200z0             = xxx,
-#endif
-#if 0
-    CPU_POWERPC_e200z1             = xxx,
-#endif
-#if 0 /* ? */
-    CPU_POWERPC_e200z3             = 0x81120000,
-#endif
     CPU_POWERPC_e200z5             = 0x81000000,
     CPU_POWERPC_e200z6             = 0x81120000,
-    /* MPC55xx microcontrollers */
-#define CPU_POWERPC_MPC55xx          CPU_POWERPC_MPC5567
-#if 0
-#define CPU_POWERPC_MPC5514E         CPU_POWERPC_MPC5514E_v1
-#define CPU_POWERPC_MPC5514E_v0      CPU_POWERPC_e200z0
-#define CPU_POWERPC_MPC5514E_v1      CPU_POWERPC_e200z1
-#define CPU_POWERPC_MPC5514G         CPU_POWERPC_MPC5514G_v1
-#define CPU_POWERPC_MPC5514G_v0      CPU_POWERPC_e200z0
-#define CPU_POWERPC_MPC5514G_v1      CPU_POWERPC_e200z1
-#define CPU_POWERPC_MPC5515S         CPU_POWERPC_e200z1
-#define CPU_POWERPC_MPC5516E         CPU_POWERPC_MPC5516E_v1
-#define CPU_POWERPC_MPC5516E_v0      CPU_POWERPC_e200z0
-#define CPU_POWERPC_MPC5516E_v1      CPU_POWERPC_e200z1
-#define CPU_POWERPC_MPC5516G         CPU_POWERPC_MPC5516G_v1
-#define CPU_POWERPC_MPC5516G_v0      CPU_POWERPC_e200z0
-#define CPU_POWERPC_MPC5516G_v1      CPU_POWERPC_e200z1
-#define CPU_POWERPC_MPC5516S         CPU_POWERPC_e200z1
-#endif
-#if 0
-#define CPU_POWERPC_MPC5533          CPU_POWERPC_e200z3
-#define CPU_POWERPC_MPC5534          CPU_POWERPC_e200z3
-#endif
-#define CPU_POWERPC_MPC5553          CPU_POWERPC_e200z6
-#define CPU_POWERPC_MPC5554          CPU_POWERPC_e200z6
-#define CPU_POWERPC_MPC5561          CPU_POWERPC_e200z6
-#define CPU_POWERPC_MPC5565          CPU_POWERPC_e200z6
-#define CPU_POWERPC_MPC5566          CPU_POWERPC_e200z6
-#define CPU_POWERPC_MPC5567          CPU_POWERPC_e200z6
     /* e300 family */
     /* e300 cores */
     CPU_POWERPC_e300c1             = 0x00830010,
@@ -326,11 +146,7 @@ enum {
     CPU_POWERPC_e300c3             = 0x00850010,
     CPU_POWERPC_e300c4             = 0x00860010,
     /* MPC83xx microcontrollers */
-#define CPU_POWERPC_MPC831x          CPU_POWERPC_e300c3
-#define CPU_POWERPC_MPC832x          CPU_POWERPC_e300c2
 #define CPU_POWERPC_MPC834x          CPU_POWERPC_e300c1
-#define CPU_POWERPC_MPC835x          CPU_POWERPC_e300c1
-#define CPU_POWERPC_MPC836x          CPU_POWERPC_e300c1
 #define CPU_POWERPC_MPC837x          CPU_POWERPC_e300c4
     /* e500 family */
     /* e500 cores  */
@@ -438,9 +254,6 @@ enum {
     /* XXX: missing 0x000a0100 */
     /* XXX: missing 0x00093102 */
     CPU_POWERPC_604R               = 0x000a0101,
-#if 0
-    CPU_POWERPC_604EV              = xxx, /* XXX: same as 604R ? */
-#endif
     /* PowerPC 740/750 cores (aka G3) */
     /* XXX: missing 0x00084202 */
     CPU_POWERPC_7x0_v10            = 0x00080100,
@@ -495,9 +308,6 @@ enum {
     CPU_POWERPC_7x5_v26            = 0x00083206,
     CPU_POWERPC_7x5_v27            = 0x00083207,
     CPU_POWERPC_7x5_v28            = 0x00083208,
-#if 0
-    CPU_POWERPC_7x5P               = xxx,
-#endif
     /* PowerPC 74xx cores (aka G4) */
     /* XXX: missing 0x000C1101 */
     CPU_POWERPC_7400_v10           = 0x000C0100,
@@ -585,12 +395,6 @@ enum {
     /* XXX: should be POWER (RIOS), RSC3308, RSC4608,
      * POWER2 (RIOS2) & RSC2 (P2SC) here
      */
-#if 0
-    CPU_POWER                      = xxx, /* 0x20000 ? 0x30000 for RSC ? */
-#endif
-#if 0
-    CPU_POWER2                     = xxx, /* 0x40000 ? */
-#endif
     /* PA Semi core */
     CPU_POWERPC_PA6T               = 0x00900000,
 };
@@ -614,60 +418,6 @@ enum {
     POWERPC_SVR_5200B_v20          = 0x80110020,
     POWERPC_SVR_5200B_v21          = 0x80110021,
 #define POWERPC_SVR_55xx             POWERPC_SVR_5567
-#if 0
-    POWERPC_SVR_5533               = xxx,
-#endif
-#if 0
-    POWERPC_SVR_5534               = xxx,
-#endif
-#if 0
-    POWERPC_SVR_5553               = xxx,
-#endif
-#if 0
-    POWERPC_SVR_5554               = xxx,
-#endif
-#if 0
-    POWERPC_SVR_5561               = xxx,
-#endif
-#if 0
-    POWERPC_SVR_5565               = xxx,
-#endif
-#if 0
-    POWERPC_SVR_5566               = xxx,
-#endif
-#if 0
-    POWERPC_SVR_5567               = xxx,
-#endif
-#if 0
-    POWERPC_SVR_8313               = xxx,
-#endif
-#if 0
-    POWERPC_SVR_8313E              = xxx,
-#endif
-#if 0
-    POWERPC_SVR_8314               = xxx,
-#endif
-#if 0
-    POWERPC_SVR_8314E              = xxx,
-#endif
-#if 0
-    POWERPC_SVR_8315               = xxx,
-#endif
-#if 0
-    POWERPC_SVR_8315E              = xxx,
-#endif
-#if 0
-    POWERPC_SVR_8321               = xxx,
-#endif
-#if 0
-    POWERPC_SVR_8321E              = xxx,
-#endif
-#if 0
-    POWERPC_SVR_8323               = xxx,
-#endif
-#if 0
-    POWERPC_SVR_8323E              = xxx,
-#endif
     POWERPC_SVR_8343               = 0x80570010,
     POWERPC_SVR_8343A              = 0x80570030,
     POWERPC_SVR_8343E              = 0x80560010,
@@ -684,12 +434,6 @@ enum {
     POWERPC_SVR_8349A              = 0x80510030,
     POWERPC_SVR_8349E              = 0x80500010,
     POWERPC_SVR_8349EA             = 0x80500030,
-#if 0
-    POWERPC_SVR_8358E              = xxx,
-#endif
-#if 0
-    POWERPC_SVR_8360E              = xxx,
-#endif
 #define POWERPC_SVR_E500             0x40000000
     POWERPC_SVR_8377               = 0x80C70010 | POWERPC_SVR_E500,
     POWERPC_SVR_8377E              = 0x80C60010 | POWERPC_SVR_E500,
index c9d3ffa89bcb9c59e27e5d847cb6be83709d7fed..64aef17f6fb7a0b7ecc753e8df36d8c2875630fc 100644 (file)
@@ -1243,6 +1243,7 @@ struct PPCVirtualHypervisorClass {
     void (*store_hpte)(PPCVirtualHypervisor *vhyp, hwaddr ptex,
                        uint64_t pte0, uint64_t pte1);
     uint64_t (*get_patbe)(PPCVirtualHypervisor *vhyp);
+    target_ulong (*encode_hpt_for_kvm_pr)(PPCVirtualHypervisor *vhyp);
 };
 
 #define TYPE_PPC_VIRTUAL_HYPERVISOR "ppc-virtual-hypervisor"
index 1deaf106d2b98c5e218bf84e66c06846cb038815..171d3d8040db02051d21e889171d2da903eced19 100644 (file)
@@ -131,7 +131,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
     cap_interrupt_level = kvm_check_extension(s, KVM_CAP_PPC_IRQ_LEVEL);
     cap_segstate = kvm_check_extension(s, KVM_CAP_PPC_SEGSTATE);
     cap_booke_sregs = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_SREGS);
-    cap_ppc_smt_possible = kvm_check_extension(s, KVM_CAP_PPC_SMT_POSSIBLE);
+    cap_ppc_smt_possible = kvm_vm_check_extension(s, KVM_CAP_PPC_SMT_POSSIBLE);
     cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
     cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
     cap_spapr_tce_64 = kvm_check_extension(s, KVM_CAP_SPAPR_TCE_64);
@@ -143,7 +143,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
     cap_ppc_watchdog = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_WATCHDOG);
     /* Note: we don't set cap_papr here, because this capability is
      * only activated after this by kvmppc_set_papr() */
-    cap_htab_fd = kvm_check_extension(s, KVM_CAP_PPC_HTAB_FD);
+    cap_htab_fd = kvm_vm_check_extension(s, KVM_CAP_PPC_HTAB_FD);
     cap_fixup_hcalls = kvm_check_extension(s, KVM_CAP_PPC_FIXUP_HCALL);
     cap_ppc_smt = kvm_vm_check_extension(s, KVM_CAP_PPC_SMT);
     cap_htm = kvm_vm_check_extension(s, KVM_CAP_PPC_HTM);
@@ -941,7 +941,13 @@ int kvmppc_put_books_sregs(PowerPCCPU *cpu)
 
     sregs.pvr = env->spr[SPR_PVR];
 
-    sregs.u.s.sdr1 = env->spr[SPR_SDR1];
+    if (cpu->vhyp) {
+        PPCVirtualHypervisorClass *vhc =
+            PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
+        sregs.u.s.sdr1 = vhc->encode_hpt_for_kvm_pr(cpu->vhyp);
+    } else {
+        sregs.u.s.sdr1 = env->spr[SPR_SDR1];
+    }
 
     /* Sync SLB */
 #ifdef TARGET_PPC64
@@ -2353,7 +2359,7 @@ int kvmppc_reset_htab(int shift_hint)
         /* Full emulation, tell caller to allocate htab itself */
         return 0;
     }
-    if (kvm_check_extension(kvm_state, KVM_CAP_PPC_ALLOC_HTAB)) {
+    if (kvm_vm_check_extension(kvm_state, KVM_CAP_PPC_ALLOC_HTAB)) {
         int ret;
         ret = kvm_vm_ioctl(kvm_state, KVM_PPC_ALLOCATE_HTAB, &shift);
         if (ret == -ENOTTY) {
@@ -2448,11 +2454,6 @@ bool kvmppc_has_cap_epr(void)
     return cap_epr;
 }
 
-bool kvmppc_has_cap_htab_fd(void)
-{
-    return cap_htab_fd;
-}
-
 bool kvmppc_has_cap_fixup_hcalls(void)
 {
     return cap_fixup_hcalls;
@@ -2555,19 +2556,29 @@ int kvmppc_define_rtas_kernel_token(uint32_t token, const char *function)
     return kvm_vm_ioctl(kvm_state, KVM_PPC_RTAS_DEFINE_TOKEN, &args);
 }
 
-int kvmppc_get_htab_fd(bool write)
+int kvmppc_get_htab_fd(bool write, uint64_t index, Error **errp)
 {
     struct kvm_get_htab_fd s = {
         .flags = write ? KVM_GET_HTAB_WRITE : 0,
-        .start_index = 0,
+        .start_index = index,
     };
+    int ret;
 
     if (!cap_htab_fd) {
-        fprintf(stderr, "KVM version doesn't support saving the hash table\n");
-        return -1;
+        error_setg(errp, "KVM version doesn't support %s the HPT",
+                   write ? "writing" : "reading");
+        return -ENOTSUP;
     }
 
-    return kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &s);
+    ret = kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &s);
+    if (ret < 0) {
+        error_setg(errp, "Unable to open fd for %s HPT %s KVM: %s",
+                   write ? "writing" : "reading", write ? "to" : "from",
+                   strerror(errno));
+        return -errno;
+    }
+
+    return ret;
 }
 
 int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize, int64_t max_ns)
@@ -2647,17 +2658,10 @@ void kvm_arch_init_irq_routing(KVMState *s)
 
 void kvmppc_read_hptes(ppc_hash_pte64_t *hptes, hwaddr ptex, int n)
 {
-    struct kvm_get_htab_fd ghf = {
-        .flags = 0,
-        .start_index = ptex,
-    };
     int fd, rc;
     int i;
 
-    fd = kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf);
-    if (fd < 0) {
-        hw_error("kvmppc_read_hptes: Unable to open HPT fd");
-    }
+    fd = kvmppc_get_htab_fd(false, ptex, &error_abort);
 
     i = 0;
     while (i < n) {
@@ -2699,19 +2703,13 @@ void kvmppc_read_hptes(ppc_hash_pte64_t *hptes, hwaddr ptex, int n)
 void kvmppc_write_hpte(hwaddr ptex, uint64_t pte0, uint64_t pte1)
 {
     int fd, rc;
-    struct kvm_get_htab_fd ghf;
     struct {
         struct kvm_get_htab_header hdr;
         uint64_t pte0;
         uint64_t pte1;
     } buf;
 
-    ghf.flags = 0;
-    ghf.start_index = 0;     /* Ignored */
-    fd = kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf);
-    if (fd < 0) {
-        hw_error("kvmppc_write_hpte: Unable to open HPT fd");
-    }
+    fd = kvmppc_get_htab_fd(true, 0 /* Ignored */, &error_abort);
 
     buf.hdr.n_valid = 1;
     buf.hdr.n_invalid = 0;
@@ -2806,30 +2804,6 @@ int kvmppc_resize_hpt_commit(PowerPCCPU *cpu, target_ulong flags, int shift)
     return kvm_vm_ioctl(cs->kvm_state, KVM_PPC_RESIZE_HPT_COMMIT, &rhpt);
 }
 
-static void kvmppc_pivot_hpt_cpu(CPUState *cs, run_on_cpu_data arg)
-{
-    target_ulong sdr1 = arg.target_ptr;
-    PowerPCCPU *cpu = POWERPC_CPU(cs);
-    CPUPPCState *env = &cpu->env;
-
-    /* This is just for the benefit of PR KVM */
-    cpu_synchronize_state(cs);
-    env->spr[SPR_SDR1] = sdr1;
-    if (kvmppc_put_books_sregs(cpu) < 0) {
-        error_report("Unable to update SDR1 in KVM");
-        exit(1);
-    }
-}
-
-void kvmppc_update_sdr1(target_ulong sdr1)
-{
-    CPUState *cs;
-
-    CPU_FOREACH(cs) {
-        run_on_cpu(cs, kvmppc_pivot_hpt_cpu, RUN_ON_CPU_TARGET_PTR(sdr1));
-    }
-}
-
 /*
  * This is a helper function to detect a post migration scenario
  * in which a guest, running as KVM-HV, freezes in cpu_post_load because
index f780e6ec7b7265731374550a1ba3dc0f64ee27b2..d6be38ecafbddae8b4b7455add9d3ee366ae495d 100644 (file)
@@ -51,8 +51,7 @@ uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift);
 #endif /* !CONFIG_USER_ONLY */
 bool kvmppc_has_cap_epr(void);
 int kvmppc_define_rtas_kernel_token(uint32_t token, const char *function);
-bool kvmppc_has_cap_htab_fd(void);
-int kvmppc_get_htab_fd(bool write);
+int kvmppc_get_htab_fd(bool write, uint64_t index, Error **errp);
 int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize, int64_t max_ns);
 int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index,
                            uint16_t n_valid, uint16_t n_invalid);
@@ -68,7 +67,6 @@ PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
 void kvmppc_check_papr_resize_hpt(Error **errp);
 int kvmppc_resize_hpt_prepare(PowerPCCPU *cpu, target_ulong flags, int shift);
 int kvmppc_resize_hpt_commit(PowerPCCPU *cpu, target_ulong flags, int shift);
-void kvmppc_update_sdr1(target_ulong sdr1);
 bool kvmppc_pvr_workaround_required(PowerPCCPU *cpu);
 
 bool kvmppc_is_mem_backend_page_size_ok(const char *obj_path);
@@ -246,12 +244,7 @@ static inline int kvmppc_define_rtas_kernel_token(uint32_t token,
     return -1;
 }
 
-static inline bool kvmppc_has_cap_htab_fd(void)
-{
-    return false;
-}
-
-static inline int kvmppc_get_htab_fd(bool write)
+static inline int kvmppc_get_htab_fd(bool write, uint64_t index, Error **errp)
 {
     return -1;
 }
@@ -331,11 +324,6 @@ static inline int kvmppc_resize_hpt_commit(PowerPCCPU *cpu,
     return -ENOSYS;
 }
 
-static inline void kvmppc_update_sdr1(target_ulong sdr1)
-{
-    abort();
-}
-
 #endif
 
 #ifndef CONFIG_KVM
index 466bf973478b4294f4f1a28b4c60d1684ad7a1a7..c6399a3a0d0d99558d5e8b42ffc0b6d6cee76f09 100644 (file)
@@ -3833,6 +3833,44 @@ POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
 }
 
+POWERPC_FAMILY(460EX)(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+    dc->desc = "PowerPC 460 EX";
+    pcc->init_proc = init_proc_440EP;
+    pcc->check_pow = check_pow_nocheck;
+    pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
+                       PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
+                       PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+                       PPC_FLOAT_STFIWX |
+                       PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_RFMCI |
+                       PPC_CACHE | PPC_CACHE_ICBI |
+                       PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+                       PPC_MEM_TLBSYNC | PPC_MFTB |
+                       PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
+                       PPC_440_SPEC;
+    pcc->msr_mask = (1ull << MSR_POW) |
+                    (1ull << MSR_CE) |
+                    (1ull << MSR_EE) |
+                    (1ull << MSR_PR) |
+                    (1ull << MSR_FP) |
+                    (1ull << MSR_ME) |
+                    (1ull << MSR_FE0) |
+                    (1ull << MSR_DWE) |
+                    (1ull << MSR_DE) |
+                    (1ull << MSR_FE1) |
+                    (1ull << MSR_IR) |
+                    (1ull << MSR_DR);
+    pcc->mmu_model = POWERPC_MMU_BOOKE;
+    pcc->excp_model = POWERPC_EXCP_BOOKE;
+    pcc->bus_model = PPC_FLAGS_INPUT_BookE;
+    pcc->bfd_mach = bfd_mach_ppc_403;
+    pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
+                 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
+}
+
 static void init_proc_440GP(CPUPPCState *env)
 {
     /* Time base */
This page took 0.097696 seconds and 4 git commands to generate.