Commit 3b68de85 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-3.0-20180612' into staging



ppc patch queue 2018-06-12

Here's another batch of ppc patches towards the 3.0 release.  There's
a fair bit here, because I've been working through my mail backlog
after a holiday.  There's not much of a central theme, amongst other
things we have:
    * ppc440 / sam460ex improvements
    * logging and error cleanups
    * 40p (PReP) bugfixes
    * Macintosh fixes and cleanups
    * Add emulation of the new POWER9 store-forwarding barrier
      instruction variant
    * Hotplug cleanups

# gpg: Signature made Tue 12 Jun 2018 07:43:21 BST
# gpg:                using RSA key 6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>"
# gpg:                 aka "David Gibson (Red Hat) <dgibson@redhat.com>"
# gpg:                 aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>"
# gpg:                 aka "David Gibson (kernel.org) <dwg@kernel.org>"
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-3.0-20180612: (33 commits)
  spapr_pci: Remove unhelpful pagesize warning
  xics_kvm: use KVM helpers
  ppc/pnv: fix LPC HC firmware address space
  spapr: handle cpu core unplug via hotplug handler chain
  spapr: handle pc-dimm unplug via hotplug handler chain
  spapr: introduce machine unplug handler
  spapr: move memory hotplug support check into spapr_memory_pre_plug()
  spapr: move lookup of the node into spapr_memory_plug()
  spapr: no need to verify the node
  target/ppc: Allow PIR read in privileged mode
  ppc4xx_i2c: Clean up and improve error logging
  target/ppc: extend eieio for POWER9
  mos6522: convert VMSTATE_TIMER_PTR_TEST to VMSTATE_TIMER_PTR
  mos6522: move timer frequency initialisation to mos6522_reset
  cuda: embed mos6522_cuda device directly rather than using QOM object link
  mos6522: fix vmstate_mos6522_timer version in vmstate_mos6522
  ppc: add missing FW_CFG_PPC_NVRAM_FLAT definition
  ppc: remove obsolete macio_init() definition from mac.h
  ppc: remove obsolete pci_pmac_init() definitions from mac.h
  hw/misc/mos6522: Add trailing '\n' to qemu_log() calls
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 98d11a6e 30f79dc1
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -766,8 +766,11 @@ F: hw/ppc/mac_newworld.c
F: hw/pci-host/uninorth.c
F: hw/pci-bridge/dec.[hc]
F: hw/misc/macio/
F: include/hw/ppc/mac_dbdma.h
F: hw/misc/mos6522.c
F: hw/nvram/mac_nvram.c
F: include/hw/misc/macio/
F: include/hw/misc/mos6522.h
F: include/hw/ppc/mac_dbdma.h

Old World
M: Alexander Graf <agraf@suse.de>
+51 −43
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@
#include "hw/hw.h"
#include "hw/i2c/ppc4xx_i2c.h"

#define PPC4xx_I2C_MEM_SIZE 0x12
#define PPC4xx_I2C_MEM_SIZE 18

#define IIC_CNTL_PT         (1 << 0)
#define IIC_CNTL_READ       (1 << 1)
@@ -70,7 +70,7 @@ static void ppc4xx_i2c_reset(DeviceState *s)
    i2c->intrmsk = 0;
    i2c->xfrcnt = 0;
    i2c->xtcntlss = 0;
    i2c->directcntl = 0x0f;
    i2c->directcntl = 0xf;
    i2c->intr = 0;
}

@@ -85,7 +85,7 @@ static uint64_t ppc4xx_i2c_readb(void *opaque, hwaddr addr, unsigned int size)
    uint64_t ret;

    switch (addr) {
    case 0x00:
    case 0:
        ret = i2c->mdata;
        if (ppc4xx_i2c_is_master(i2c)) {
            ret = 0xff;
@@ -139,58 +139,62 @@ static uint64_t ppc4xx_i2c_readb(void *opaque, hwaddr addr, unsigned int size)
                          TYPE_PPC4xx_I2C, __func__);
        }
        break;
    case 0x02:
    case 2:
        ret = i2c->sdata;
        break;
    case 0x04:
    case 4:
        ret = i2c->lmadr;
        break;
    case 0x05:
    case 5:
        ret = i2c->hmadr;
        break;
    case 0x06:
    case 6:
        ret = i2c->cntl;
        break;
    case 0x07:
    case 7:
        ret = i2c->mdcntl;
        break;
    case 0x08:
    case 8:
        ret = i2c->sts;
        break;
    case 0x09:
    case 9:
        ret = i2c->extsts;
        break;
    case 0x0A:
    case 10:
        ret = i2c->lsadr;
        break;
    case 0x0B:
    case 11:
        ret = i2c->hsadr;
        break;
    case 0x0C:
    case 12:
        ret = i2c->clkdiv;
        break;
    case 0x0D:
    case 13:
        ret = i2c->intrmsk;
        break;
    case 0x0E:
    case 14:
        ret = i2c->xfrcnt;
        break;
    case 0x0F:
    case 15:
        ret = i2c->xtcntlss;
        break;
    case 0x10:
    case 16:
        ret = i2c->directcntl;
        break;
    case 0x11:
    case 17:
        ret = i2c->intr;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
                      HWADDR_PRIx "\n", TYPE_PPC4xx_I2C, __func__, addr);
        if (addr < PPC4xx_I2C_MEM_SIZE) {
            qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register 0x%"
                          HWADDR_PRIx "\n", __func__, addr);
        } else {
            qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address 0x%"
                          HWADDR_PRIx "\n", __func__, addr);
        }
        ret = 0;
        break;
    }

    return ret;
}

@@ -200,7 +204,7 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value,
    PPC4xxI2CState *i2c = opaque;

    switch (addr) {
    case 0x00:
    case 0:
        i2c->mdata = value;
        if (!i2c_bus_busy(i2c->bus)) {
            /* assume we start a write transfer */
@@ -225,19 +229,19 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value,
            }
        }
        break;
    case 0x02:
    case 2:
        i2c->sdata = value;
        break;
    case 0x04:
    case 4:
        i2c->lmadr = value;
        if (i2c_bus_busy(i2c->bus)) {
            i2c_end_transfer(i2c->bus);
        }
        break;
    case 0x05:
    case 5:
        i2c->hmadr = value;
        break;
    case 0x06:
    case 6:
        i2c->cntl = value;
        if (i2c->cntl & IIC_CNTL_PT) {
            if (i2c->cntl & IIC_CNTL_READ) {
@@ -263,32 +267,31 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value,
            }
        }
        break;
    case 0x07:
        i2c->mdcntl = value & 0xDF;
    case 7:
        i2c->mdcntl = value & 0xdf;
        break;
    case 0x08:
        i2c->sts &= ~(value & 0x0A);
    case 8:
        i2c->sts &= ~(value & 0xa);
        break;
    case 0x09:
        i2c->extsts &= ~(value & 0x8F);
    case 9:
        i2c->extsts &= ~(value & 0x8f);
        break;
    case 0x0A:
    case 10:
        i2c->lsadr = value;
        /*i2c_set_slave_address(i2c->bus, i2c->lsadr);*/
        break;
    case 0x0B:
    case 11:
        i2c->hsadr = value;
        break;
    case 0x0C:
    case 12:
        i2c->clkdiv = value;
        break;
    case 0x0D:
    case 13:
        i2c->intrmsk = value;
        break;
    case 0x0E:
    case 14:
        i2c->xfrcnt = value & 0x77;
        break;
    case 0x0F:
    case 15:
        if (value & IIC_XTCNTLSS_SRST) {
            /* Is it actually a full reset? U-Boot sets some regs before */
            ppc4xx_i2c_reset(DEVICE(i2c));
@@ -296,15 +299,20 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value,
        }
        i2c->xtcntlss = value;
        break;
    case 0x10:
    case 16:
        i2c->directcntl = value & 0x7;
        break;
    case 0x11:
    case 17:
        i2c->intr = value;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
                      HWADDR_PRIx "\n", TYPE_PPC4xx_I2C, __func__, addr);
        if (addr < PPC4xx_I2C_MEM_SIZE) {
            qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register 0x%"
                          HWADDR_PRIx "\n", __func__, addr);
        } else {
            qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address 0x%"
                          HWADDR_PRIx "\n", __func__, addr);
        }
        break;
    }
}
+14 −38
Original line number Diff line number Diff line
@@ -56,10 +56,6 @@ static QLIST_HEAD(, KVMEnabledICP)
static void icp_get_kvm_state(ICPState *icp)
{
    uint64_t state;
    struct kvm_one_reg reg = {
        .id = KVM_REG_PPC_ICP_STATE,
        .addr = (uintptr_t)&state,
    };
    int ret;

    /* ICP for this CPU thread is not in use, exiting */
@@ -67,7 +63,7 @@ static void icp_get_kvm_state(ICPState *icp)
        return;
    }

    ret = kvm_vcpu_ioctl(icp->cs, KVM_GET_ONE_REG, &reg);
    ret = kvm_get_one_reg(icp->cs, KVM_REG_PPC_ICP_STATE, &state);
    if (ret != 0) {
        error_report("Unable to retrieve KVM interrupt controller state"
                " for CPU %ld: %s", kvm_arch_vcpu_id(icp->cs), strerror(errno));
@@ -96,10 +92,6 @@ static void icp_synchronize_state(ICPState *icp)
static int icp_set_kvm_state(ICPState *icp, int version_id)
{
    uint64_t state;
    struct kvm_one_reg reg = {
        .id = KVM_REG_PPC_ICP_STATE,
        .addr = (uintptr_t)&state,
    };
    int ret;

    /* ICP for this CPU thread is not in use, exiting */
@@ -111,7 +103,7 @@ static int icp_set_kvm_state(ICPState *icp, int version_id)
        | ((uint64_t)icp->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT)
        | ((uint64_t)icp->pending_priority << KVM_REG_PPC_ICP_PPRI_SHIFT);

    ret = kvm_vcpu_ioctl(icp->cs, KVM_SET_ONE_REG, &reg);
    ret = kvm_set_one_reg(icp->cs, KVM_REG_PPC_ICP_STATE, &state);
    if (ret != 0) {
        error_report("Unable to restore KVM interrupt controller state (0x%"
                PRIx64 ") for CPU %ld: %s", state, kvm_arch_vcpu_id(icp->cs),
@@ -185,21 +177,15 @@ static const TypeInfo icp_kvm_info = {
static void ics_get_kvm_state(ICSState *ics)
{
    uint64_t state;
    struct kvm_device_attr attr = {
        .flags = 0,
        .group = KVM_DEV_XICS_GRP_SOURCES,
        .addr = (uint64_t)(uintptr_t)&state,
    };
    int i;
    Error *local_err = NULL;

    for (i = 0; i < ics->nr_irqs; i++) {
        ICSIRQState *irq = &ics->irqs[i];
        int ret;

        attr.attr = i + ics->offset;

        ret = ioctl(kernel_xics_fd, KVM_GET_DEVICE_ATTR, &attr);
        if (ret != 0) {
        kvm_device_access(kernel_xics_fd, KVM_DEV_XICS_GRP_SOURCES,
                          i + ics->offset, &state, false, &local_err);
        if (local_err) {
            error_report("Unable to retrieve KVM interrupt controller state"
                    " for IRQ %d: %s", i + ics->offset, strerror(errno));
            exit(1);
@@ -255,19 +241,13 @@ static void ics_synchronize_state(ICSState *ics)
static int ics_set_kvm_state(ICSState *ics, int version_id)
{
    uint64_t state;
    struct kvm_device_attr attr = {
        .flags = 0,
        .group = KVM_DEV_XICS_GRP_SOURCES,
        .addr = (uint64_t)(uintptr_t)&state,
    };
    int i;
    Error *local_err = NULL;

    for (i = 0; i < ics->nr_irqs; i++) {
        ICSIRQState *irq = &ics->irqs[i];
        int ret;

        attr.attr = i + ics->offset;

        state = irq->server;
        state |= (uint64_t)(irq->saved_priority & KVM_XICS_PRIORITY_MASK)
            << KVM_XICS_PRIORITY_SHIFT;
@@ -293,8 +273,9 @@ static int ics_set_kvm_state(ICSState *ics, int version_id)
                state |= KVM_XICS_QUEUED;
        }

        ret = ioctl(kernel_xics_fd, KVM_SET_DEVICE_ATTR, &attr);
        if (ret != 0) {
        kvm_device_access(kernel_xics_fd, KVM_DEV_XICS_GRP_SOURCES,
                          i + ics->offset, &state, true, &local_err);
        if (local_err) {
            error_report("Unable to restore KVM interrupt controller state"
                    " for IRQs %d: %s", i + ics->offset, strerror(errno));
            return ret;
@@ -391,10 +372,6 @@ static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
int xics_kvm_init(sPAPRMachineState *spapr, Error **errp)
{
    int rc;
    struct kvm_create_device xics_create_device = {
        .type = KVM_DEV_TYPE_XICS,
        .flags = 0,
    };

    if (!kvm_enabled() || !kvm_check_extension(kvm_state, KVM_CAP_IRQ_XICS)) {
        error_setg(errp,
@@ -431,20 +408,19 @@ int xics_kvm_init(sPAPRMachineState *spapr, Error **errp)
        goto fail;
    }

    /* Create the kernel ICP */
    rc = kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &xics_create_device);
    /* Create the KVM XICS device */
    rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
    if (rc < 0) {
        error_setg_errno(errp, -rc, "Error on KVM_CREATE_DEVICE for XICS");
        goto fail;
    }

    kernel_xics_fd = xics_create_device.fd;

    kernel_xics_fd = rc;
    kvm_kernel_irqchip = true;
    kvm_msi_via_irqfd_allowed = true;
    kvm_gsi_direct_mapping = true;

    return rc;
    return 0;

fail:
    kvmppc_define_rtas_kernel_token(0, "ibm,set-xive");
+21 −29
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ static void cuda_receive_packet_from_host(CUDAState *s,
static uint64_t cuda_get_counter_value(MOS6522State *s, MOS6522Timer *ti)
{
    MOS6522CUDAState *mcs = container_of(s, MOS6522CUDAState, parent_obj);
    CUDAState *cs = mcs->cuda;
    CUDAState *cs = container_of(mcs, CUDAState, mos6522_cuda);

    /* Reverse of the tb calculation algorithm that Mac OS X uses on bootup */
    uint64_t tb_diff = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
@@ -78,7 +78,7 @@ static uint64_t cuda_get_counter_value(MOS6522State *s, MOS6522Timer *ti)
static uint64_t cuda_get_load_time(MOS6522State *s, MOS6522Timer *ti)
{
    MOS6522CUDAState *mcs = container_of(s, MOS6522CUDAState, parent_obj);
    CUDAState *cs = mcs->cuda;
    CUDAState *cs = container_of(mcs, CUDAState, mos6522_cuda);

    uint64_t load_time = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
                                  cs->tb_frequency, NANOSECONDS_PER_SECOND);
@@ -88,7 +88,7 @@ static uint64_t cuda_get_load_time(MOS6522State *s, MOS6522Timer *ti)
static void cuda_set_sr_int(void *opaque)
{
    CUDAState *s = opaque;
    MOS6522CUDAState *mcs = s->mos6522_cuda;
    MOS6522CUDAState *mcs = &s->mos6522_cuda;
    MOS6522State *ms = MOS6522(mcs);
    MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(ms);

@@ -97,7 +97,7 @@ static void cuda_set_sr_int(void *opaque)

static void cuda_delay_set_sr_int(CUDAState *s)
{
    MOS6522CUDAState *mcs = s->mos6522_cuda;
    MOS6522CUDAState *mcs = &s->mos6522_cuda;
    MOS6522State *ms = MOS6522(mcs);
    MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(ms);
    int64_t expire;
@@ -117,7 +117,7 @@ static void cuda_delay_set_sr_int(CUDAState *s)
/* NOTE: TIP and TREQ are negated */
static void cuda_update(CUDAState *s)
{
    MOS6522CUDAState *mcs = s->mos6522_cuda;
    MOS6522CUDAState *mcs = &s->mos6522_cuda;
    MOS6522State *ms = MOS6522(mcs);
    int packet_received, len;

@@ -462,7 +462,7 @@ static void cuda_receive_packet_from_host(CUDAState *s,
static uint64_t mos6522_cuda_read(void *opaque, hwaddr addr, unsigned size)
{
    CUDAState *s = opaque;
    MOS6522CUDAState *mcs = s->mos6522_cuda;
    MOS6522CUDAState *mcs = &s->mos6522_cuda;
    MOS6522State *ms = MOS6522(mcs);

    addr = (addr >> 9) & 0xf;
@@ -473,7 +473,7 @@ static void mos6522_cuda_write(void *opaque, hwaddr addr, uint64_t val,
                               unsigned size)
{
    CUDAState *s = opaque;
    MOS6522CUDAState *mcs = s->mos6522_cuda;
    MOS6522CUDAState *mcs = &s->mos6522_cuda;
    MOS6522State *ms = MOS6522(mcs);

    addr = (addr >> 9) & 0xf;
@@ -492,9 +492,11 @@ static const MemoryRegionOps mos6522_cuda_ops = {

static const VMStateDescription vmstate_cuda = {
    .name = "cuda",
    .version_id = 4,
    .minimum_version_id = 4,
    .version_id = 5,
    .minimum_version_id = 5,
    .fields = (VMStateField[]) {
        VMSTATE_STRUCT(mos6522_cuda.parent_obj, CUDAState, 0, vmstate_mos6522,
                       MOS6522State),
        VMSTATE_UINT8(last_b, CUDAState),
        VMSTATE_UINT8(last_acr, CUDAState),
        VMSTATE_INT32(data_in_size, CUDAState),
@@ -530,12 +532,8 @@ static void cuda_realize(DeviceState *dev, Error **errp)
    DeviceState *d;
    struct tm tm;

    d = qdev_create(NULL, TYPE_MOS6522_CUDA);
    object_property_set_link(OBJECT(d), OBJECT(s), "cuda", errp);
    qdev_init_nofail(d);
    s->mos6522_cuda = MOS6522_CUDA(d);

    /* Pass IRQ from 6522 */
    d = DEVICE(&s->mos6522_cuda);
    ms = MOS6522(d);
    sbd = SYS_BUS_DEVICE(s);
    sysbus_pass_irq(sbd, SYS_BUS_DEVICE(ms));
@@ -556,6 +554,10 @@ static void cuda_init(Object *obj)
    CUDAState *s = CUDA(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    object_initialize(&s->mos6522_cuda, sizeof(s->mos6522_cuda),
                      TYPE_MOS6522_CUDA);
    qdev_set_parent_bus(DEVICE(&s->mos6522_cuda), sysbus_get_default());

    memory_region_init_io(&s->mem, obj, &mos6522_cuda_ops, s, "cuda", 0x2000);
    sysbus_init_mmio(sbd, &s->mem);

@@ -590,37 +592,28 @@ static const TypeInfo cuda_type_info = {
static void mos6522_cuda_portB_write(MOS6522State *s)
{
    MOS6522CUDAState *mcs = container_of(s, MOS6522CUDAState, parent_obj);
    CUDAState *cs = container_of(mcs, CUDAState, mos6522_cuda);

    cuda_update(mcs->cuda);
    cuda_update(cs);
}

static void mos6522_cuda_realize(DeviceState *dev, Error **errp)
static void mos6522_cuda_reset(DeviceState *dev)
{
    MOS6522State *ms = MOS6522(dev);
    MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(ms);

    mdc->parent_realize(dev, errp);
    mdc->parent_reset(dev);

    ms->timers[0].frequency = CUDA_TIMER_FREQ;
    ms->timers[1].frequency = (SCALE_US * 6000) / 4700;
}

static void mos6522_cuda_init(Object *obj)
{
    MOS6522CUDAState *s = MOS6522_CUDA(obj);

    object_property_add_link(obj, "cuda", TYPE_CUDA,
                             (Object **) &s->cuda,
                             qdev_prop_allow_set_link_before_realize,
                             0, NULL);
}

static void mos6522_cuda_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);
    MOS6522DeviceClass *mdc = MOS6522_DEVICE_CLASS(oc);

    dc->realize = mos6522_cuda_realize;
    dc->reset = mos6522_cuda_reset;
    mdc->portB_write = mos6522_cuda_portB_write;
    mdc->get_timer1_counter_value = cuda_get_counter_value;
    mdc->get_timer2_counter_value = cuda_get_counter_value;
@@ -632,7 +625,6 @@ static const TypeInfo mos6522_cuda_type_info = {
    .name = TYPE_MOS6522_CUDA,
    .parent = TYPE_MOS6522,
    .instance_size = sizeof(MOS6522CUDAState),
    .instance_init = mos6522_cuda_init,
    .class_init = mos6522_cuda_class_init,
};

+3 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include "hw/char/escc.h"
#include "hw/misc/macio/macio.h"
#include "hw/intc/heathrow_pic.h"
#include "trace.h"

/* Note: this code is strongly inspirated from the corresponding code
 * in PearPC */
@@ -246,6 +247,7 @@ static void macio_oldworld_init(Object *obj)
static void timer_write(void *opaque, hwaddr addr, uint64_t value,
                       unsigned size)
{
    trace_macio_timer_write(addr, size, value);
}

static uint64_t timer_read(void *opaque, hwaddr addr, unsigned size)
@@ -266,6 +268,7 @@ static uint64_t timer_read(void *opaque, hwaddr addr, unsigned size)
        break;
    }

    trace_macio_timer_read(addr, size, value);
    return value;
}

Loading