diff options
-rw-r--r-- | MAINTAINERS | 6 | ||||
-rw-r--r-- | default-configs/ppcemb-softmmu.mak | 1 | ||||
m--------- | dtc | 0 | ||||
-rw-r--r-- | hw/display/sm501.c | 30 | ||||
-rw-r--r-- | hw/i2c/ppc4xx_i2c.c | 198 | ||||
-rw-r--r-- | hw/ide/Makefile.objs | 1 | ||||
-rw-r--r-- | hw/ide/sii3112.c | 368 | ||||
-rw-r--r-- | hw/ide/trace-events | 5 | ||||
-rw-r--r-- | hw/ppc/pnv.c | 94 | ||||
-rw-r--r-- | hw/ppc/pnv_bmc.c | 2 | ||||
-rw-r--r-- | hw/ppc/pnv_core.c | 8 | ||||
-rw-r--r-- | hw/ppc/pnv_lpc.c | 16 | ||||
-rw-r--r-- | hw/ppc/pnv_psi.c | 4 | ||||
-rw-r--r-- | hw/ppc/pnv_xscom.c | 10 | ||||
-rw-r--r-- | hw/ppc/spapr.c | 2 | ||||
-rw-r--r-- | hw/ppc/spapr_pci.c | 6 | ||||
-rw-r--r-- | hw/ppc/spapr_pci_vfio.c | 47 | ||||
-rw-r--r-- | hw/ppc/spapr_rtas.c | 9 | ||||
-rw-r--r-- | include/hw/i2c/ppc4xx_i2c.h | 3 | ||||
-rw-r--r-- | include/hw/ppc/pnv.h | 10 | ||||
-rw-r--r-- | include/hw/ppc/pnv_xscom.h | 4 | ||||
-rw-r--r-- | pc-bios/README | 2 | ||||
-rw-r--r-- | pc-bios/slof.bin | bin | 905200 -> 913880 bytes | |||
-rw-r--r-- | qemu-doc.texi | 5 | ||||
m--------- | roms/SLOF | 0 | ||||
-rwxr-xr-x | scripts/device-crash-test | 1 | ||||
-rw-r--r-- | target/ppc/cpu.h | 56 | ||||
-rw-r--r-- | target/ppc/int_helper.c | 2 |
28 files changed, 703 insertions, 187 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 5628322fe6..4770f105d4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -766,6 +766,12 @@ L: qemu-ppc@nongnu.org S: Odd Fixes F: hw/ppc/virtex_ml507.c +sam460ex +M: BALATON Zoltan <balaton@eik.bme.hu> +L: qemu-ppc@nongnu.org +S: Maintained +F: hw/ide/sii3112.c + SH4 Machines ------------ R2D diff --git a/default-configs/ppcemb-softmmu.mak b/default-configs/ppcemb-softmmu.mak index 13917fb7a3..5db4618a5a 100644 --- a/default-configs/ppcemb-softmmu.mak +++ b/default-configs/ppcemb-softmmu.mak @@ -16,3 +16,4 @@ CONFIG_I8259=y CONFIG_XILINX=y CONFIG_XILINX_ETHLITE=y CONFIG_SM501=y +CONFIG_IDE_SII3112=y diff --git a/dtc b/dtc -Subproject 558cd81bdd432769b59bff01240c44f82cfb1a9 +Subproject e54388015af1fb4bf04d0bca99caba1074d9cc4 diff --git a/hw/display/sm501.c b/hw/display/sm501.c index 7f1822421a..4f7dc59b25 100644 --- a/hw/display/sm501.c +++ b/hw/display/sm501.c @@ -795,6 +795,8 @@ static uint64_t sm501_system_config_read(void *opaque, hwaddr addr, case SM501_ARBTRTN_CONTROL: ret = s->arbitration_control; break; + case SM501_COMMAND_LIST_STATUS: + ret = 0x00180002; /* FIFOs are empty, everything idle */ case SM501_IRQ_MASK: ret = s->irq_mask; break; @@ -812,6 +814,9 @@ static uint64_t sm501_system_config_read(void *opaque, hwaddr addr, case SM501_POWER_MODE_CONTROL: ret = s->power_mode_control; break; + case SM501_ENDIAN_CONTROL: + ret = 0; /* Only default little endian mode is supported */ + break; default: printf("sm501 system config : not implemented register read." @@ -865,6 +870,12 @@ static void sm501_system_config_write(void *opaque, hwaddr addr, case SM501_POWER_MODE_CONTROL: s->power_mode_control = value & 0x00000003; break; + case SM501_ENDIAN_CONTROL: + if (value & 0x00000001) { + printf("sm501 system config : big endian mode not implemented.\n"); + abort(); + } + break; default: printf("sm501 system config : not implemented register write." @@ -924,6 +935,9 @@ static uint64_t sm501_disp_ctrl_read(void *opaque, hwaddr addr, case SM501_DC_PANEL_PANNING_CONTROL: ret = s->dc_panel_panning_control; break; + case SM501_DC_PANEL_COLOR_KEY: + /* Not implemented yet */ + break; case SM501_DC_PANEL_FB_ADDR: ret = s->dc_panel_fb_addr; break; @@ -956,6 +970,19 @@ static uint64_t sm501_disp_ctrl_read(void *opaque, hwaddr addr, ret = s->dc_panel_v_sync; break; + case SM501_DC_PANEL_HWC_ADDR: + ret = s->dc_panel_hwc_addr; + break; + case SM501_DC_PANEL_HWC_LOC: + ret = s->dc_panel_hwc_location; + break; + case SM501_DC_PANEL_HWC_COLOR_1_2: + ret = s->dc_panel_hwc_color_1_2; + break; + case SM501_DC_PANEL_HWC_COLOR_3: + ret = s->dc_panel_hwc_color_3; + break; + case SM501_DC_VIDEO_CONTROL: ret = s->dc_video_control; break; @@ -1022,6 +1049,9 @@ static void sm501_disp_ctrl_write(void *opaque, hwaddr addr, case SM501_DC_PANEL_PANNING_CONTROL: s->dc_panel_panning_control = value & 0xFF3FFF3F; break; + case SM501_DC_PANEL_COLOR_KEY: + /* Not implemented yet */ + break; case SM501_DC_PANEL_FB_ADDR: s->dc_panel_fb_addr = value & 0x8FFFFFF0; break; diff --git a/hw/i2c/ppc4xx_i2c.c b/hw/i2c/ppc4xx_i2c.c index 5a6bde951e..e873a445da 100644 --- a/hw/i2c/ppc4xx_i2c.c +++ b/hw/i2c/ppc4xx_i2c.c @@ -2,6 +2,8 @@ * PPC4xx I2C controller emulation * * Copyright (c) 2007 Jocelyn Mayer + * Copyright (c) 2012 François Revol + * Copyright (c) 2016 BALATON Zoltan * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,26 +27,118 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu-common.h" +#include "qemu/log.h" #include "cpu.h" #include "hw/hw.h" #include "hw/i2c/ppc4xx_i2c.h" -/*#define DEBUG_I2C*/ +#define PPC4xx_I2C_MEM_SIZE 0x12 -#define PPC4xx_I2C_MEM_SIZE 0x11 +#define IIC_CNTL_PT (1 << 0) +#define IIC_CNTL_READ (1 << 1) +#define IIC_CNTL_CHT (1 << 2) +#define IIC_CNTL_RPST (1 << 3) + +#define IIC_STS_PT (1 << 0) +#define IIC_STS_ERR (1 << 2) +#define IIC_STS_MDBS (1 << 5) + +#define IIC_EXTSTS_XFRA (1 << 0) + +#define IIC_XTCNTLSS_SRST (1 << 0) + +static void ppc4xx_i2c_reset(DeviceState *s) +{ + PPC4xxI2CState *i2c = PPC4xx_I2C(s); + + /* FIXME: Should also reset bus? + *if (s->address != ADDR_RESET) { + * i2c_end_transfer(s->bus); + *} + */ + + i2c->mdata = 0; + i2c->lmadr = 0; + i2c->hmadr = 0; + i2c->cntl = 0; + i2c->mdcntl = 0; + i2c->sts = 0; + i2c->extsts = 0x8f; + i2c->sdata = 0; + i2c->lsadr = 0; + i2c->hsadr = 0; + i2c->clkdiv = 0; + i2c->intrmsk = 0; + i2c->xfrcnt = 0; + i2c->xtcntlss = 0; + i2c->directcntl = 0x0f; + i2c->intr = 0; +} + +static inline bool ppc4xx_i2c_is_master(PPC4xxI2CState *i2c) +{ + return true; +} static uint64_t ppc4xx_i2c_readb(void *opaque, hwaddr addr, unsigned int size) { PPC4xxI2CState *i2c = PPC4xx_I2C(opaque); uint64_t ret; -#ifdef DEBUG_I2C - printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr); -#endif switch (addr) { case 0x00: - /*i2c_readbyte(&i2c->mdata);*/ ret = i2c->mdata; + if (ppc4xx_i2c_is_master(i2c)) { + ret = 0xff; + + if (!(i2c->sts & IIC_STS_MDBS)) { + qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read " + "without starting transfer\n", + TYPE_PPC4xx_I2C, __func__); + } else { + int pending = (i2c->cntl >> 4) & 3; + + /* get the next byte */ + int byte = i2c_recv(i2c->bus); + + if (byte < 0) { + qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: read failed " + "for device 0x%02x\n", TYPE_PPC4xx_I2C, + __func__, i2c->lmadr); + ret = 0xff; + } else { + ret = byte; + /* Raise interrupt if enabled */ + /*ppc4xx_i2c_raise_interrupt(i2c)*/; + } + + if (!pending) { + i2c->sts &= ~IIC_STS_MDBS; + /*i2c_end_transfer(i2c->bus);*/ + /*} else if (i2c->cntl & (IIC_CNTL_RPST | IIC_CNTL_CHT)) {*/ + } else if (pending) { + /* current smbus implementation doesn't like + multibyte xfer repeated start */ + i2c_end_transfer(i2c->bus); + if (i2c_start_transfer(i2c->bus, i2c->lmadr >> 1, 1)) { + /* if non zero is returned, the adress is not valid */ + i2c->sts &= ~IIC_STS_PT; + i2c->sts |= IIC_STS_ERR; + i2c->extsts |= IIC_EXTSTS_XFRA; + } else { + /*i2c->sts |= IIC_STS_PT;*/ + i2c->sts |= IIC_STS_MDBS; + i2c->sts &= ~IIC_STS_ERR; + i2c->extsts = 0; + } + } + pending--; + i2c->cntl = (i2c->cntl & 0xcf) | (pending << 4); + } + } else { + qemu_log_mask(LOG_UNIMP, "[%s]%s: slave mode not implemented\n", + TYPE_PPC4xx_I2C, __func__); + } break; case 0x02: ret = i2c->sdata; @@ -88,13 +182,15 @@ static uint64_t ppc4xx_i2c_readb(void *opaque, hwaddr addr, unsigned int size) case 0x10: ret = i2c->directcntl; break; + case 0x11: + ret = i2c->intr; + break; default: - ret = 0x00; + qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%" + HWADDR_PRIx "\n", TYPE_PPC4xx_I2C, __func__, addr); + ret = 0; break; } -#ifdef DEBUG_I2C - printf("%s: addr " TARGET_FMT_plx " %02" PRIx64 "\n", __func__, addr, ret); -#endif return ret; } @@ -103,26 +199,70 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value, unsigned int size) { PPC4xxI2CState *i2c = opaque; -#ifdef DEBUG_I2C - printf("%s: addr " TARGET_FMT_plx " val %08" PRIx64 "\n", - __func__, addr, value); -#endif + switch (addr) { case 0x00: i2c->mdata = value; - /*i2c_sendbyte(&i2c->mdata);*/ + if (!i2c_bus_busy(i2c->bus)) { + /* assume we start a write transfer */ + if (i2c_start_transfer(i2c->bus, i2c->lmadr >> 1, 0)) { + /* if non zero is returned, the adress is not valid */ + i2c->sts &= ~IIC_STS_PT; + i2c->sts |= IIC_STS_ERR; + i2c->extsts |= IIC_EXTSTS_XFRA; + } else { + i2c->sts |= IIC_STS_PT; + i2c->sts &= ~IIC_STS_ERR; + i2c->extsts = 0; + } + } + if (i2c_bus_busy(i2c->bus)) { + if (i2c_send(i2c->bus, i2c->mdata)) { + /* if the target return non zero then end the transfer */ + i2c->sts &= ~IIC_STS_PT; + i2c->sts |= IIC_STS_ERR; + i2c->extsts |= IIC_EXTSTS_XFRA; + i2c_end_transfer(i2c->bus); + } + } break; case 0x02: i2c->sdata = value; break; case 0x04: i2c->lmadr = value; + if (i2c_bus_busy(i2c->bus)) { + i2c_end_transfer(i2c->bus); + } break; case 0x05: i2c->hmadr = value; break; case 0x06: i2c->cntl = value; + if (i2c->cntl & IIC_CNTL_PT) { + if (i2c->cntl & IIC_CNTL_READ) { + if (i2c_bus_busy(i2c->bus)) { + /* end previous transfer */ + i2c->sts &= ~IIC_STS_PT; + i2c_end_transfer(i2c->bus); + } + if (i2c_start_transfer(i2c->bus, i2c->lmadr >> 1, 1)) { + /* if non zero is returned, the adress is not valid */ + i2c->sts &= ~IIC_STS_PT; + i2c->sts |= IIC_STS_ERR; + i2c->extsts |= IIC_EXTSTS_XFRA; + } else { + /*i2c->sts |= IIC_STS_PT;*/ + i2c->sts |= IIC_STS_MDBS; + i2c->sts &= ~IIC_STS_ERR; + i2c->extsts = 0; + } + } else { + /* we actually already did the write transfer... */ + i2c->sts &= ~IIC_STS_PT; + } + } break; case 0x07: i2c->mdcntl = value & 0xDF; @@ -135,6 +275,7 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value, break; case 0x0A: i2c->lsadr = value; + /*i2c_set_slave_address(i2c->bus, i2c->lsadr);*/ break; case 0x0B: i2c->hsadr = value; @@ -149,11 +290,23 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value, i2c->xfrcnt = value & 0x77; break; case 0x0F: + if (value & IIC_XTCNTLSS_SRST) { + /* Is it actually a full reset? U-Boot sets some regs before */ + ppc4xx_i2c_reset(DEVICE(i2c)); + break; + } i2c->xtcntlss = value; break; case 0x10: i2c->directcntl = value & 0x7; break; + case 0x11: + 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); + break; } } @@ -167,21 +320,6 @@ static const MemoryRegionOps ppc4xx_i2c_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void ppc4xx_i2c_reset(DeviceState *s) -{ - PPC4xxI2CState *i2c = PPC4xx_I2C(s); - - i2c->mdata = 0x00; - i2c->sdata = 0x00; - i2c->cntl = 0x00; - i2c->mdcntl = 0x00; - i2c->sts = 0x00; - i2c->extsts = 0x00; - i2c->clkdiv = 0x00; - i2c->xfrcnt = 0x00; - i2c->directcntl = 0x0F; -} - static void ppc4xx_i2c_init(Object *o) { PPC4xxI2CState *s = PPC4xx_I2C(o); diff --git a/hw/ide/Makefile.objs b/hw/ide/Makefile.objs index f0edca3300..fc328ffbe8 100644 --- a/hw/ide/Makefile.objs +++ b/hw/ide/Makefile.objs @@ -11,3 +11,4 @@ common-obj-$(CONFIG_MICRODRIVE) += microdrive.o common-obj-$(CONFIG_AHCI) += ahci.o common-obj-$(CONFIG_AHCI) += ich.o common-obj-$(CONFIG_ALLWINNER_A10) += ahci-allwinner.o +common-obj-$(CONFIG_IDE_SII3112) += sii3112.o diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c new file mode 100644 index 0000000000..e2f5562bb7 --- /dev/null +++ b/hw/ide/sii3112.c @@ -0,0 +1,368 @@ +/* + * QEMU SiI3112A PCI to Serial ATA Controller Emulation + * + * Copyright (C) 2017 BALATON Zoltan <balaton@eik.bme.hu> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +/* For documentation on this and similar cards see: + * http://wiki.osdev.org/User:Quok/Silicon_Image_Datasheets + */ + +#include <qemu/osdep.h> +#include <hw/ide/pci.h> +#include "trace.h" + +#define TYPE_SII3112_PCI "sii3112" +#define SII3112_PCI(obj) OBJECT_CHECK(SiI3112PCIState, (obj), \ + TYPE_SII3112_PCI) + +typedef struct SiI3112Regs { + uint32_t confstat; + uint32_t scontrol; + uint16_t sien; + uint8_t swdata; +} SiI3112Regs; + +typedef struct SiI3112PCIState { + PCIIDEState i; + MemoryRegion mmio; + SiI3112Regs regs[2]; +} SiI3112PCIState; + +/* The sii3112_reg_read and sii3112_reg_write functions implement the + * Internal Register Space - BAR5 (section 6.7 of the data sheet). + */ + +static uint64_t sii3112_reg_read(void *opaque, hwaddr addr, + unsigned int size) +{ + SiI3112PCIState *d = opaque; + uint64_t val = 0; + + switch (addr) { + case 0x00: + val = d->i.bmdma[0].cmd; + break; + case 0x01: + val = d->regs[0].swdata; + break; + case 0x02: + val = d->i.bmdma[0].status; + break; + case 0x03: + val = 0; + break; + case 0x04 ... 0x07: + val = bmdma_addr_ioport_ops.read(&d->i.bmdma[0], addr - 4, size); + break; + case 0x08: + val = d->i.bmdma[1].cmd; + break; + case 0x09: + val = d->regs[1].swdata; + break; + case 0x0a: + val = d->i.bmdma[1].status; + break; + case 0x0b: + val = 0; + break; + case 0x0c ... 0x0f: + val = bmdma_addr_ioport_ops.read(&d->i.bmdma[1], addr - 12, size); + break; + case 0x10: + val = d->i.bmdma[0].cmd; + val |= (d->regs[0].confstat & (1UL << 11) ? (1 << 4) : 0); /*SATAINT0*/ + val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 6) : 0); /*SATAINT1*/ + val |= (d->i.bmdma[1].status & BM_STATUS_INT ? (1 << 14) : 0); + val |= d->i.bmdma[0].status << 16; + val |= d->i.bmdma[1].status << 24; + break; + case 0x18: + val = d->i.bmdma[1].cmd; + val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 4) : 0); + val |= d->i.bmdma[1].status << 16; + break; + case 0x80 ... 0x87: + if (size == 1) { + val = ide_ioport_read(&d->i.bus[0], addr - 0x80); + } else if (addr == 0x80) { + val = (size == 2) ? ide_data_readw(&d->i.bus[0], 0) : + ide_data_readl(&d->i.bus[0], 0); + } else { + val = (1ULL << (size * 8)) - 1; + } + break; + case 0x8a: + val = (size == 1) ? ide_status_read(&d->i.bus[0], 4) : + (1ULL << (size * 8)) - 1; + break; + case 0xa0: + val = d->regs[0].confstat; + break; + case 0xc0 ... 0xc7: + if (size == 1) { + val = ide_ioport_read(&d->i.bus[1], addr - 0xc0); + } else if (addr == 0xc0) { + val = (size == 2) ? ide_data_readw(&d->i.bus[1], 0) : + ide_data_readl(&d->i.bus[1], 0); + } else { + val = (1ULL << (size * 8)) - 1; + } + break; + case 0xca: + val = (size == 1) ? ide_status_read(&d->i.bus[0], 4) : + (1ULL << (size * 8)) - 1; + break; + case 0xe0: + val = d->regs[1].confstat; + break; + case 0x100: + val = d->regs[0].scontrol; + break; + case 0x104: + val = (d->i.bus[0].ifs[0].blk) ? 0x113 : 0; + break; + case 0x148: + val = d->regs[0].sien << 16; + break; + case 0x180: + val = d->regs[1].scontrol; + break; + case 0x184: + val = (d->i.bus[1].ifs[0].blk) ? 0x113 : 0; + break; + case 0x1c8: + val = d->regs[1].sien << 16; + break; + default: + val = 0; + } + trace_sii3112_read(size, addr, val); + return val; +} + +static void sii3112_reg_write(void *opaque, hwaddr addr, + uint64_t val, unsigned int size) +{ + SiI3112PCIState *d = opaque; + + trace_sii3112_write(size, addr, val); + switch (addr) { + case 0x00: + case 0x10: + bmdma_cmd_writeb(&d->i.bmdma[0], val); + break; + case 0x01: + case 0x11: + d->regs[0].swdata = val & 0x3f; + break; + case 0x02: + case 0x12: + d->i.bmdma[0].status = (val & 0x60) | (d->i.bmdma[0].status & 1) | + (d->i.bmdma[0].status & ~val & 6); + break; + case 0x04 ... 0x07: + bmdma_addr_ioport_ops.write(&d->i.bmdma[0], addr - 4, val, size); + break; + case 0x08: + case 0x18: + bmdma_cmd_writeb(&d->i.bmdma[1], val); + break; + case 0x09: + case 0x19: + d->regs[1].swdata = val & 0x3f; + break; + case 0x0a: + case 0x1a: + d->i.bmdma[1].status = (val & 0x60) | (d->i.bmdma[1].status & 1) | + (d->i.bmdma[1].status & ~val & 6); + break; + case 0x0c ... 0x0f: + bmdma_addr_ioport_ops.write(&d->i.bmdma[1], addr - 12, val, size); + break; + case 0x80 ... 0x87: + if (size == 1) { + ide_ioport_write(&d->i.bus[0], addr - 0x80, val); + } else if (addr == 0x80) { + if (size == 2) { + ide_data_writew(&d->i.bus[0], 0, val); + } else { + ide_data_writel(&d->i.bus[0], 0, val); + } + } + break; + case 0x8a: + if (size == 1) { + ide_cmd_write(&d->i.bus[0], 4, val); + } + break; + case 0xc0 ... 0xc7: + if (size == 1) { + ide_ioport_write(&d->i.bus[1], addr - 0xc0, val); + } else if (addr == 0xc0) { + if (size == 2) { + ide_data_writew(&d->i.bus[1], 0, val); + } else { + ide_data_writel(&d->i.bus[1], 0, val); + } + } + break; + case 0xca: + if (size == 1) { + ide_cmd_write(&d->i.bus[1], 4, val); + } + break; + case 0x100: + d->regs[0].scontrol = val & 0xfff; + if (val & 1) { + ide_bus_reset(&d->i.bus[0]); + } + break; + case 0x148: + d->regs[0].sien = (val >> 16) & 0x3eed; + break; + case 0x180: + d->regs[1].scontrol = val & 0xfff; + if (val & 1) { + ide_bus_reset(&d->i.bus[1]); + } + break; + case 0x1c8: + d->regs[1].sien = (val >> 16) & 0x3eed; + break; + default: + val = 0; + } +} + +static const MemoryRegionOps sii3112_reg_ops = { + .read = sii3112_reg_read, + .write = sii3112_reg_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +/* the PCI irq level is the logical OR of the two channels */ +static void sii3112_update_irq(SiI3112PCIState *s) +{ + int i, set = 0; + + for (i = 0; i < 2; i++) { + set |= s->regs[i].confstat & (1UL << 11); + } + pci_set_irq(PCI_DEVICE(s), (set ? 1 : 0)); +} + +static void sii3112_set_irq(void *opaque, int channel, int level) +{ + SiI3112PCIState *s = opaque; + + trace_sii3112_set_irq(channel, level); + if (level) { + s->regs[channel].confstat |= (1UL << 11); + } else { + s->regs[channel].confstat &= ~(1UL << 11); + } + + sii3112_update_irq(s); +} + +static void sii3112_reset(void *opaque) +{ + SiI3112PCIState *s = opaque; + int i; + + for (i = 0; i < 2; i++) { + s->regs[i].confstat = 0x6515 << 16; + ide_bus_reset(&s->i.bus[i]); + } +} + +static void sii3112_pci_realize(PCIDevice *dev, Error **errp) +{ + SiI3112PCIState *d = SII3112_PCI(dev); + PCIIDEState *s = PCI_IDE(dev); + MemoryRegion *mr; + qemu_irq *irq; + int i; + + pci_config_set_interrupt_pin(dev->config, 1); + pci_set_byte(dev->config + PCI_CACHE_LINE_SIZE, 8); + + /* BAR5 is in PCI memory space */ + memory_region_init_io(&d->mmio, OBJECT(d), &sii3112_reg_ops, d, + "sii3112.bar5", 0x200); + pci_register_bar(dev, 5, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio); + + /* BAR0-BAR4 are PCI I/O space aliases into BAR5 */ + mr = g_new(MemoryRegion, 1); + memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &d->mmio, 0x80, 8); + pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, mr); + mr = g_new(MemoryRegion, 1); + memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &d->mmio, 0x88, 4); + pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, mr); + mr = g_new(MemoryRegion, 1); + memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &d->mmio, 0xc0, 8); + pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, mr); + mr = g_new(MemoryRegion, 1); + memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &d->mmio, 0xc8, 4); + pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, mr); + mr = g_new(MemoryRegion, 1); + memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &d->mmio, 0, 16); + pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, mr); + + irq = qemu_allocate_irqs(sii3112_set_irq, d, 2); + for (i = 0; i < 2; i++) { + ide_bus_new(&s->bus[i], sizeof(s->bus[i]), DEVICE(dev), i, 1); + ide_init2(&s->bus[i], irq[i]); + + bmdma_init(&s->bus[i], &s->bmdma[i], s); + s->bmdma[i].bus = &s->bus[i]; + ide_register_restart_cb(&s->bus[i]); + } + qemu_register_reset(sii3112_reset, s); +} + +static void sii3112_pci_exitfn(PCIDevice *dev) +{ + PCIIDEState *d = PCI_IDE(dev); + int i; + + for (i = 0; i < 2; ++i) { + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io); + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport); + } +} + +static void sii3112_pci_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *pd = PCI_DEVICE_CLASS(klass); + + pd->vendor_id = 0x1095; + pd->device_id = 0x3112; + pd->class_id = PCI_CLASS_STORAGE_RAID; + pd->revision = 1; + pd->realize = sii3112_pci_realize; + pd->exit = sii3112_pci_exitfn; + dc->desc = "SiI3112A SATA controller"; + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); +} + +static const TypeInfo sii3112_pci_info = { + .name = TYPE_SII3112_PCI, + .parent = TYPE_PCI_IDE, + .instance_size = sizeof(SiI3112PCIState), + .class_init = sii3112_pci_class_init, +}; + +static void sii3112_register_types(void) +{ + type_register_static(&sii3112_pci_info); +} + +type_init(sii3112_register_types) diff --git a/hw/ide/trace-events b/hw/ide/trace-events index 601bd97d81..0c39cabe72 100644 --- a/hw/ide/trace-events +++ b/hw/ide/trace-events @@ -37,6 +37,11 @@ bmdma_addr_write(uint64_t data) "data: 0x%016"PRIx64 bmdma_read(uint64_t addr, uint8_t val) "bmdma: readb 0x%"PRIx64" : 0x%02x" bmdma_write(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%02"PRIx64 +# hw/ide/sii3112.c +sii3112_read(int size, uint64_t addr, uint64_t val) "bmdma: read (size %d) 0x%"PRIx64" : 0x%02"PRIx64 +sii3112_write(int size, uint64_t addr, uint64_t val) "bmdma: write (size %d) 0x%"PRIx64" : 0x%02"PRIx64 +sii3112_set_irq(int channel, int level) "channel %d level %d" + # hw/ide/via.c bmdma_read_via(uint64_t addr, uint32_t val) "bmdma: readb 0x%"PRIx64" : 0x%02x" bmdma_write_via(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%02"PRIx64 diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 94ffc8e137..9475e8479c 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -77,8 +77,7 @@ static const char *pnv_chip_core_typename(const PnvChip *o) * that has a different "affinity". In practice, it means one range * per chip. */ -static void powernv_populate_memory_node(void *fdt, int chip_id, hwaddr start, - hwaddr size) +static void pnv_dt_memory(void *fdt, int chip_id, hwaddr start, hwaddr size) { char *mem_name; uint64_t mem_reg_property[2]; @@ -119,7 +118,7 @@ static int get_cpus_node(void *fdt) * device tree, used in XSCOM to address cores and in interrupt * servers. */ -static void powernv_create_core_node(PnvChip *chip, PnvCore *pc, void *fdt) +static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt) { CPUState *cs = CPU(DEVICE(pc->threads)); DeviceClass *dc = DEVICE_GET_CLASS(cs); @@ -228,8 +227,8 @@ static void powernv_create_core_node(PnvChip *chip, PnvCore *pc, void *fdt) servers_prop, sizeof(servers_prop)))); } -static void powernv_populate_icp(PnvChip *chip, void *fdt, uint32_t pir, - uint32_t nr_threads) +static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir, + uint32_t nr_threads) { uint64_t addr = PNV_ICP_BASE(chip) | (pir << 12); char *name; @@ -277,13 +276,13 @@ static int pnv_chip_lpc_offset(PnvChip *chip, void *fdt) return offset; } -static void powernv_populate_chip(PnvChip *chip, void *fdt) +static void pnv_dt_chip(PnvChip *chip, void *fdt) { const char *typename = pnv_chip_core_typename(chip); size_t typesize = object_type_get_instance_size(typename); int i; - pnv_xscom_populate(chip, fdt, 0); + pnv_dt_xscom(chip, fdt, 0); /* The default LPC bus of a multichip system is on chip 0. It's * recognized by the firmware (skiboot) using a "primary" @@ -298,20 +297,18 @@ static void powernv_populate_chip(PnvChip *chip, void *fdt) for (i = 0; i < chip->nr_cores; i++) { PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize); - powernv_create_core_node(chip, pnv_core, fdt); + pnv_dt_core(chip, pnv_core, fdt); /* Interrupt Control Presenters (ICP). One per core. */ - powernv_populate_icp(chip, fdt, pnv_core->pir, - CPU_CORE(pnv_core)->nr_threads); + pnv_dt_icp(chip, fdt, pnv_core->pir, CPU_CORE(pnv_core)->nr_threads); } if (chip->ram_size) { - powernv_populate_memory_node(fdt, chip->chip_id, chip->ram_start, - chip->ram_size); + pnv_dt_memory(fdt, chip->chip_id, chip->ram_start, chip->ram_size); } } -static void powernv_populate_rtc(ISADevice *d, void *fdt, int lpc_off) +static void pnv_dt_rtc(ISADevice *d, void *fdt, int lpc_off) { uint32_t io_base = d->ioport_id; uint32_t io_regs[] = { @@ -331,7 +328,7 @@ static void powernv_populate_rtc(ISADevice *d, void *fdt, int lpc_off) _FDT((fdt_setprop_string(fdt, node, "compatible", "pnpPNP,b00"))); } -static void powernv_populate_serial(ISADevice *d, void *fdt, int lpc_off) +static void pnv_dt_serial(ISADevice *d, void *fdt, int lpc_off) { const char compatible[] = "ns16550\0pnpPNP,501"; uint32_t io_base = d->ioport_id; @@ -362,7 +359,7 @@ static void powernv_populate_serial(ISADevice *d, void *fdt, int lpc_off) _FDT((fdt_setprop_string(fdt, node, "device_type", "serial"))); } -static void powernv_populate_ipmi_bt(ISADevice *d, void *fdt, int lpc_off) +static void pnv_dt_ipmi_bt(ISADevice *d, void *fdt, int lpc_off) { const char compatible[] = "bt\0ipmi-bt"; uint32_t io_base; @@ -401,17 +398,17 @@ typedef struct ForeachPopulateArgs { int offset; } ForeachPopulateArgs; -static int powernv_populate_isa_device(DeviceState *dev, void *opaque) +static int pnv_dt_isa_device(DeviceState *dev, void *opaque) { ForeachPopulateArgs *args = opaque; ISADevice *d = ISA_DEVICE(dev); if (object_dynamic_cast(OBJECT(dev), TYPE_MC146818_RTC)) { - powernv_populate_rtc(d, args->fdt, args->offset); + pnv_dt_rtc(d, args->fdt, args->offset); } else if (object_dynamic_cast(OBJECT(dev), TYPE_ISA_SERIAL)) { - powernv_populate_serial(d, args->fdt, args->offset); + pnv_dt_serial(d, args->fdt, args->offset); } else if (object_dynamic_cast(OBJECT(dev), "isa-ipmi-bt")) { - powernv_populate_ipmi_bt(d, args->fdt, args->offset); + pnv_dt_ipmi_bt(d, args->fdt, args->offset); } else { error_report("unknown isa device %s@i%x", qdev_fw_name(dev), d->ioport_id); @@ -420,7 +417,7 @@ static int powernv_populate_isa_device(DeviceState *dev, void *opaque) return 0; } -static void powernv_populate_isa(ISABus *bus, void *fdt, int lpc_offset) +static void pnv_dt_isa(ISABus *bus, void *fdt, int lpc_offset) { ForeachPopulateArgs args = { .fdt = fdt, @@ -429,14 +426,13 @@ static void powernv_populate_isa(ISABus *bus, void *fdt, int lpc_offset) /* ISA devices are not necessarily parented to the ISA bus so we * can not use object_child_foreach() */ - qbus_walk_children(BUS(bus), powernv_populate_isa_device, - NULL, NULL, NULL, &args); + qbus_walk_children(BUS(bus), pnv_dt_isa_device, NULL, NULL, NULL, &args); } -static void *powernv_create_fdt(MachineState *machine) +static void *pnv_dt_create(MachineState *machine) { const char plat_compat[] = "qemu,powernv\0ibm,powernv"; - PnvMachineState *pnv = POWERNV_MACHINE(machine); + PnvMachineState *pnv = PNV_MACHINE(machine); void *fdt; char *buf; int off; @@ -479,15 +475,15 @@ static void *powernv_create_fdt(MachineState *machine) /* Populate device tree for each chip */ for (i = 0; i < pnv->num_chips; i++) { - powernv_populate_chip(pnv->chips[i], fdt); + pnv_dt_chip(pnv->chips[i], fdt); } /* Populate ISA devices on chip 0 */ lpc_offset = pnv_chip_lpc_offset(pnv->chips[0], fdt); - powernv_populate_isa(pnv->isa_bus, fdt, lpc_offset); + pnv_dt_isa(pnv->isa_bus, fdt, lpc_offset); if (pnv->bmc) { - pnv_bmc_populate_sensors(pnv->bmc, fdt); + pnv_dt_bmc_sensors(pnv->bmc, fdt); } return fdt; @@ -495,17 +491,17 @@ static void *powernv_create_fdt(MachineState *machine) static void pnv_powerdown_notify(Notifier *n, void *opaque) { - PnvMachineState *pnv = POWERNV_MACHINE(qdev_get_machine()); + PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine()); if (pnv->bmc) { pnv_bmc_powerdown(pnv->bmc); } } -static void ppc_powernv_reset(void) +static void pnv_reset(void) { MachineState *machine = MACHINE(qdev_get_machine()); - PnvMachineState *pnv = POWERNV_MACHINE(machine); + PnvMachineState *pnv = PNV_MACHINE(machine); void *fdt; Object *obj; @@ -524,7 +520,7 @@ static void ppc_powernv_reset(void) pnv->bmc = IPMI_BMC(obj); } - fdt = powernv_create_fdt(machine); + fdt = pnv_dt_create(machine); /* Pack resulting tree */ _FDT((fdt_pack(fdt))); @@ -552,9 +548,9 @@ static ISABus *pnv_isa_create(PnvChip *chip) return isa_bus; } -static void ppc_powernv_init(MachineState *machine) +static void pnv_init(MachineState *machine) { - PnvMachineState *pnv = POWERNV_MACHINE(machine); + PnvMachineState *pnv = PNV_MACHINE(machine); MemoryRegion *ram; char *fw_filename; long fw_size; @@ -567,7 +563,7 @@ static void ppc_powernv_init(MachineState *machine) } ram = g_new(MemoryRegion, 1); - memory_region_allocate_system_memory(ram, NULL, "ppc_powernv.ram", + memory_region_allocate_system_memory(ram, NULL, "pnv.ram", machine->ram_size); memory_region_add_subregion(get_system_memory(), 0, ram); @@ -974,7 +970,7 @@ static void pnv_chip_class_init(ObjectClass *klass, void *data) static ICSState *pnv_ics_get(XICSFabric *xi, int irq) { - PnvMachineState *pnv = POWERNV_MACHINE(xi); + PnvMachineState *pnv = PNV_MACHINE(xi); int i; for (i = 0; i < pnv->num_chips; i++) { @@ -987,7 +983,7 @@ static ICSState *pnv_ics_get(XICSFabric *xi, int irq) static void pnv_ics_resend(XICSFabric *xi) { - PnvMachineState *pnv = POWERNV_MACHINE(xi); + PnvMachineState *pnv = PNV_MACHINE(xi); int i; for (i = 0; i < pnv->num_chips; i++) { @@ -1021,7 +1017,7 @@ static ICPState *pnv_icp_get(XICSFabric *xi, int pir) static void pnv_pic_print_info(InterruptStatsProvider *obj, Monitor *mon) { - PnvMachineState *pnv = POWERNV_MACHINE(obj); + PnvMachineState *pnv = PNV_MACHINE(obj); int i; CPUState *cs; @@ -1039,13 +1035,13 @@ static void pnv_pic_print_info(InterruptStatsProvider *obj, static void pnv_get_num_chips(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { - visit_type_uint32(v, name, &POWERNV_MACHINE(obj)->num_chips, errp); + visit_type_uint32(v, name, &PNV_MACHINE(obj)->num_chips, errp); } static void pnv_set_num_chips(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { - PnvMachineState *pnv = POWERNV_MACHINE(obj); + PnvMachineState *pnv = PNV_MACHINE(obj); uint32_t num_chips; Error *local_err = NULL; @@ -1067,13 +1063,13 @@ static void pnv_set_num_chips(Object *obj, Visitor *v, const char *name, pnv->num_chips = num_chips; } -static void powernv_machine_initfn(Object *obj) +static void pnv_machine_initfn(Object *obj) { - PnvMachineState *pnv = POWERNV_MACHINE(obj); + PnvMachineState *pnv = PNV_MACHINE(obj); pnv->num_chips = 1; } -static void powernv_machine_class_props_init(ObjectClass *oc) +static void pnv_machine_class_props_init(ObjectClass *oc) { object_class_property_add(oc, "num-chips", "uint32", pnv_get_num_chips, pnv_set_num_chips, @@ -1083,15 +1079,15 @@ static void powernv_machine_class_props_init(ObjectClass *oc) NULL); } -static void powernv_machine_class_init(ObjectClass *oc, void *data) +static void pnv_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); XICSFabricClass *xic = XICS_FABRIC_CLASS(oc); InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc); mc->desc = "IBM PowerNV (Non-Virtualized)"; - mc->init = ppc_powernv_init; - mc->reset = ppc_powernv_reset; + mc->init = pnv_init; + mc->reset = pnv_reset; mc->max_cpus = MAX_CPUS; mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0"); mc->block_default_type = IF_IDE; /* Pnv provides a AHCI device for @@ -1104,7 +1100,7 @@ static void powernv_machine_class_init(ObjectClass *oc, void *data) xic->ics_resend = pnv_ics_resend; ispc->print_info = pnv_pic_print_info; - powernv_machine_class_props_init(oc); + pnv_machine_class_props_init(oc); } #define DEFINE_PNV_CHIP_TYPE(type, class_initfn) \ @@ -1116,11 +1112,11 @@ static void powernv_machine_class_init(ObjectClass *oc, void *data) static const TypeInfo types[] = { { - .name = TYPE_POWERNV_MACHINE, + .name = TYPE_PNV_MACHINE, .parent = TYPE_MACHINE, .instance_size = sizeof(PnvMachineState), - .instance_init = powernv_machine_initfn, - .class_init = powernv_machine_class_init, + .instance_init = pnv_machine_initfn, + .class_init = pnv_machine_class_init, .interfaces = (InterfaceInfo[]) { { TYPE_XICS_FABRIC }, { TYPE_INTERRUPT_STATS_PROVIDER }, diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c index 7b60b4c360..b2cf441ee7 100644 --- a/hw/ppc/pnv_bmc.c +++ b/hw/ppc/pnv_bmc.c @@ -73,7 +73,7 @@ void pnv_bmc_powerdown(IPMIBmc *bmc) pnv_gen_oem_sel(bmc, SOFT_OFF); } -void pnv_bmc_populate_sensors(IPMIBmc *bmc, void *fdt) +void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt) { int offset; int i; diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 03317db853..7e8a76df44 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -37,7 +37,7 @@ static const char *pnv_core_cpu_typename(PnvCore *pc) return cpu_type; } -static void powernv_cpu_reset(void *opaque) +static void pnv_cpu_reset(void *opaque) { PowerPCCPU *cpu = opaque; CPUState *cs = CPU(cpu); @@ -54,7 +54,7 @@ static void powernv_cpu_reset(void *opaque) env->msr |= MSR_HVB; /* Hypervisor mode */ } -static void powernv_cpu_init(PowerPCCPU *cpu, Error **errp) +static void pnv_cpu_init(PowerPCCPU *cpu, Error **errp) { CPUPPCState *env = &cpu->env; int core_pir; @@ -73,7 +73,7 @@ static void powernv_cpu_init(PowerPCCPU *cpu, Error **errp) /* Set time-base frequency to 512 MHz */ cpu_ppc_tb_init(env, PNV_TIMEBASE_FREQ); - qemu_register_reset(powernv_cpu_reset, cpu); + qemu_register_reset(pnv_cpu_reset, cpu); } /* @@ -139,7 +139,7 @@ static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp) return; } - powernv_cpu_init(cpu, &local_err); + pnv_cpu_init(cpu, &local_err); if (local_err) { error_propagate(errp, local_err); return; diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c index f03a80a29b..c42b4a8f6c 100644 --- a/hw/ppc/pnv_lpc.c +++ b/hw/ppc/pnv_lpc.c @@ -92,7 +92,7 @@ enum { #define LPC_HC_REGS_OPB_SIZE 0x00001000 -static int pnv_lpc_populate(PnvXScomInterface *dev, void *fdt, int xscom_offset) +static int pnv_lpc_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset) { const char compat[] = "ibm,power8-lpc\0ibm,lpc"; char *name; @@ -146,13 +146,13 @@ static bool opb_write(PnvLpcController *lpc, uint32_t addr, uint8_t *data, return success; } -#define ECCB_CTL_READ (1ull << (63 - 15)) +#define ECCB_CTL_READ PPC_BIT(15) #define ECCB_CTL_SZ_LSH (63 - 7) -#define ECCB_CTL_SZ_MASK (0xfull << ECCB_CTL_SZ_LSH) -#define ECCB_CTL_ADDR_MASK 0xffffffffu; +#define ECCB_CTL_SZ_MASK PPC_BITMASK(4, 7) +#define ECCB_CTL_ADDR_MASK PPC_BITMASK(32, 63) -#define ECCB_STAT_OP_DONE (1ull << (63 - 52)) -#define ECCB_STAT_OP_ERR (1ull << (63 - 52)) +#define ECCB_STAT_OP_DONE PPC_BIT(52) +#define ECCB_STAT_OP_ERR PPC_BIT(52) #define ECCB_STAT_RD_DATA_LSH (63 - 37) #define ECCB_STAT_RD_DATA_MASK (0xffffffff << ECCB_STAT_RD_DATA_LSH) @@ -482,7 +482,7 @@ static void pnv_lpc_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass); - xdc->populate = pnv_lpc_populate; + xdc->dt_xscom = pnv_lpc_dt_xscom; dc->realize = pnv_lpc_realize; } @@ -515,7 +515,7 @@ type_init(pnv_lpc_register_types) */ static void pnv_lpc_isa_irq_handler_cpld(void *opaque, int n, int level) { - PnvMachineState *pnv = POWERNV_MACHINE(qdev_get_machine()); + PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine()); uint32_t old_state = pnv->cpld_irqstate; PnvLpcController *lpc = PNV_LPC(opaque); diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c index 9876c26622..5b969127c3 100644 --- a/hw/ppc/pnv_psi.c +++ b/hw/ppc/pnv_psi.c @@ -510,7 +510,7 @@ static void pnv_psi_realize(DeviceState *dev, Error **errp) } } -static int pnv_psi_populate(PnvXScomInterface *dev, void *fdt, int xscom_offset) +static int pnv_psi_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset) { const char compat[] = "ibm,power8-psihb-x\0ibm,psihb-x"; char *name; @@ -546,7 +546,7 @@ static void pnv_psi_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass); - xdc->populate = pnv_psi_populate; + xdc->dt_xscom = pnv_psi_dt_xscom; dc->realize = pnv_psi_realize; dc->props = pnv_psi_properties; diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c index 38bc85f117..e51d634f40 100644 --- a/hw/ppc/pnv_xscom.c +++ b/hw/ppc/pnv_xscom.c @@ -207,15 +207,15 @@ typedef struct ForeachPopulateArgs { int xscom_offset; } ForeachPopulateArgs; -static int xscom_populate_child(Object *child, void *opaque) +static int xscom_dt_child(Object *child, void *opaque) { if (object_dynamic_cast(child, TYPE_PNV_XSCOM_INTERFACE)) { ForeachPopulateArgs *args = opaque; PnvXScomInterface *xd = PNV_XSCOM_INTERFACE(child); PnvXScomInterfaceClass *xc = PNV_XSCOM_INTERFACE_GET_CLASS(xd); - if (xc->populate) { - _FDT((xc->populate(xd, args->fdt, args->xscom_offset))); + if (xc->dt_xscom) { + _FDT((xc->dt_xscom(xd, args->fdt, args->xscom_offset))); } } return 0; @@ -224,7 +224,7 @@ static int xscom_populate_child(Object *child, void *opaque) static const char compat_p8[] = "ibm,power8-xscom\0ibm,xscom"; static const char compat_p9[] = "ibm,power9-xscom\0ibm,xscom"; -int pnv_xscom_populate(PnvChip *chip, void *fdt, int root_offset) +int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset) { uint64_t reg[] = { cpu_to_be64(PNV_XSCOM_BASE(chip)), cpu_to_be64(PNV_XSCOM_SIZE) }; @@ -255,7 +255,7 @@ int pnv_xscom_populate(PnvChip *chip, void *fdt, int root_offset) args.fdt = fdt; args.xscom_offset = xscom_offset; - object_child_foreach(OBJECT(chip), xscom_populate_child, &args); + object_child_foreach(OBJECT(chip), xscom_dt_child, &args); return 0; } diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 6785a90c60..dfd352c473 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1504,7 +1504,7 @@ static void spapr_machine_reset(void) spapr_ovec_cleanup(spapr->ov5_cas); spapr->ov5_cas = spapr_ovec_new(); - ppc_set_compat_all(spapr->max_compat_pvr, &error_fatal); + ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal); } fdt = spapr_build_fdt(spapr, rtas_addr, spapr->rtas_size); diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 88797b3d36..695c820911 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1696,9 +1696,9 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) /* DMA setup */ if (((sphb->page_size_mask & qemu_getrampagesize()) == 0) && kvm_enabled()) { - error_report("System page size 0x%lx is not enabled in page_size_mask " - "(0x%"PRIx64"). Performance may be slow", - qemu_getrampagesize(), sphb->page_size_mask); + warn_report("System page size 0x%lx is not enabled in page_size_mask " + "(0x%"PRIx64"). Performance may be slow", + qemu_getrampagesize(), sphb->page_size_mask); } for (i = 0; i < windows_supported; ++i) { diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c index 8448e0b024..053efb03bd 100644 --- a/hw/ppc/spapr_pci_vfio.c +++ b/hw/ppc/spapr_pci_vfio.c @@ -29,31 +29,6 @@ #include "qemu/error-report.h" #include "sysemu/qtest.h" -#define TYPE_SPAPR_PCI_VFIO_HOST_BRIDGE "spapr-pci-vfio-host-bridge" - -#define SPAPR_PCI_VFIO_HOST_BRIDGE(obj) \ - OBJECT_CHECK(sPAPRPHBVFIOState, (obj), TYPE_SPAPR_PCI_VFIO_HOST_BRIDGE) - -typedef struct sPAPRPHBVFIOState sPAPRPHBVFIOState; - -struct sPAPRPHBVFIOState { - sPAPRPHBState phb; - - int32_t iommugroupid; -}; - -static Property spapr_phb_vfio_properties[] = { - DEFINE_PROP_INT32("iommu", sPAPRPHBVFIOState, iommugroupid, -1), - DEFINE_PROP_END_OF_LIST(), -}; - -static void spapr_phb_vfio_instance_init(Object *obj) -{ - if (!qtest_enabled()) { - error_report("spapr-pci-vfio-host-bridge is deprecated"); - } -} - bool spapr_phb_eeh_available(sPAPRPHBState *sphb) { return vfio_eeh_as_ok(&sphb->iommu_as); @@ -218,25 +193,3 @@ int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb) return RTAS_OUT_SUCCESS; } - -static void spapr_phb_vfio_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->props = spapr_phb_vfio_properties; -} - -static const TypeInfo spapr_phb_vfio_info = { - .name = TYPE_SPAPR_PCI_VFIO_HOST_BRIDGE, - .parent = TYPE_SPAPR_PCI_HOST_BRIDGE, - .instance_size = sizeof(sPAPRPHBVFIOState), - .instance_init = spapr_phb_vfio_instance_init, - .class_init = spapr_phb_vfio_class_init, -}; - -static void spapr_pci_vfio_register_types(void) -{ - type_register_static(&spapr_phb_vfio_info); -} - -type_init(spapr_pci_vfio_register_types) diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 4bb939d3d1..2b89e1d448 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -163,6 +163,7 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr, CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); + Error *local_err = NULL; if (!cs->halted) { rtas_st(rets, 0, RTAS_OUT_HW_ERROR); @@ -174,6 +175,14 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr, * new cpu enters */ kvm_cpu_synchronize_state(cs); + /* Set compatibility mode to match existing cpus */ + ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &local_err); + if (local_err) { + error_report_err(local_err); + rtas_st(rets, 0, RTAS_OUT_HW_ERROR); + return; + } + env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME); /* Enable Power-saving mode Exit Cause exceptions for the new CPU */ diff --git a/include/hw/i2c/ppc4xx_i2c.h b/include/hw/i2c/ppc4xx_i2c.h index 3450bda577..3c603071bd 100644 --- a/include/hw/i2c/ppc4xx_i2c.h +++ b/include/hw/i2c/ppc4xx_i2c.h @@ -2,6 +2,8 @@ * PPC4xx I2C controller emulation * * Copyright (c) 2007 Jocelyn Mayer + * Copyright (c) 2012 François Revol + * Copyright (c) 2016 BALATON Zoltan * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -55,6 +57,7 @@ typedef struct PPC4xxI2CState { uint8_t xfrcnt; uint8_t xtcntlss; uint8_t directcntl; + uint8_t intr; } PPC4xxI2CState; #endif /* PPC4XX_I2C_H */ diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index 59524cd42b..61896f9fd7 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -26,7 +26,7 @@ #include "hw/ppc/pnv_psi.h" #include "hw/ppc/pnv_occ.h" -#define TYPE_PNV_CHIP "powernv-chip" +#define TYPE_PNV_CHIP "pnv-chip" #define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP) #define PNV_CHIP_CLASS(klass) \ OBJECT_CLASS_CHECK(PnvChipClass, (klass), TYPE_PNV_CHIP) @@ -117,9 +117,9 @@ typedef struct PnvChipClass { #define PNV_CHIP_INDEX(chip) \ (((chip)->chip_id >> 2) * 2 + ((chip)->chip_id & 0x3)) -#define TYPE_POWERNV_MACHINE MACHINE_TYPE_NAME("powernv") -#define POWERNV_MACHINE(obj) \ - OBJECT_CHECK(PnvMachineState, (obj), TYPE_POWERNV_MACHINE) +#define TYPE_PNV_MACHINE MACHINE_TYPE_NAME("powernv") +#define PNV_MACHINE(obj) \ + OBJECT_CHECK(PnvMachineState, (obj), TYPE_PNV_MACHINE) typedef struct PnvMachineState { /*< private >*/ @@ -144,7 +144,7 @@ typedef struct PnvMachineState { /* * BMC helpers */ -void pnv_bmc_populate_sensors(IPMIBmc *bmc, void *fdt); +void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt); void pnv_bmc_powerdown(IPMIBmc *bmc); /* diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h index 38077b4796..7252e219e2 100644 --- a/include/hw/ppc/pnv_xscom.h +++ b/include/hw/ppc/pnv_xscom.h @@ -36,7 +36,7 @@ typedef struct PnvXScomInterface { typedef struct PnvXScomInterfaceClass { InterfaceClass parent; - int (*populate)(PnvXScomInterface *dev, void *fdt, int offset); + int (*dt_xscom)(PnvXScomInterface *dev, void *fdt, int offset); } PnvXScomInterfaceClass; /* @@ -67,7 +67,7 @@ typedef struct PnvXScomInterfaceClass { #define PNV_XSCOM_OCC_SIZE 0x6000 extern void pnv_xscom_realize(PnvChip *chip, Error **errp); -extern int pnv_xscom_populate(PnvChip *chip, void *fdt, int offset); +extern int pnv_dt_xscom(PnvChip *chip, void *fdt, int offset); extern void pnv_xscom_add_subregion(PnvChip *chip, hwaddr offset, MemoryRegion *mr); diff --git a/pc-bios/README b/pc-bios/README index 25fc6ce63f..a843e1e8b1 100644 --- a/pc-bios/README +++ b/pc-bios/README @@ -17,7 +17,7 @@ - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware implementation for certain IBM POWER hardware. The sources are at https://github.com/aik/SLOF, and the image currently in qemu is - built from git tag qemu-slof-20170724. + built from git tag qemu-slof-20171214. - sgabios (the Serial Graphics Adapter option ROM) provides a means for legacy x86 software to communicate with an attached serial console as diff --git a/pc-bios/slof.bin b/pc-bios/slof.bin Binary files differindex 6bb48d40a0..d46c83efb7 100644 --- a/pc-bios/slof.bin +++ b/pc-bios/slof.bin diff --git a/qemu-doc.texi b/qemu-doc.texi index 9d0159832e..a3d2054c90 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -2757,11 +2757,6 @@ The ``host_net_remove'' command is replaced by the ``netdev_del'' command. The ``ivshmem'' device type is replaced by either the ``ivshmem-plain'' or ``ivshmem-doorbell`` device types. -@subsection spapr-pci-vfio-host-bridge (since 2.6.0) - -The ``spapr-pci-vfio-host-bridge'' device type is replaced by -the ``spapr-pci-host-bridge'' device type. - @section System emulator machines @subsection Xilinx EP108 (since 2.11.0) diff --git a/roms/SLOF b/roms/SLOF -Subproject 89f519f09bf850918b60526e50409afb663418a +Subproject fa981320a1e0968d6fc1b8de319723ff8212b33 diff --git a/scripts/device-crash-test b/scripts/device-crash-test index c11fd81c52..827d8ec2af 100755 --- a/scripts/device-crash-test +++ b/scripts/device-crash-test @@ -119,7 +119,6 @@ ERROR_WHITELIST = [ {'device':'scsi-generic', 'expected':True}, # drive property not set {'device':'scsi-hd', 'expected':True}, # drive property not set {'device':'spapr-pci-host-bridge', 'expected':True}, # BUID not specified for PHB - {'device':'spapr-pci-vfio-host-bridge', 'expected':True}, # BUID not specified for PHB {'device':'spapr-rng', 'expected':True}, # spapr-rng needs an RNG backend! {'device':'spapr-vty', 'expected':True}, # chardev property not set {'device':'tpm-tis', 'expected':True}, # tpm_tis: backend driver with id (null) could not be found diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 370b05e76e..a5e49f23e9 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -93,6 +93,19 @@ #define PPC_BITMASK(bs, be) ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs)) #define PPC_BITMASK32(bs, be) ((PPC_BIT32(bs) - PPC_BIT32(be)) | \ PPC_BIT32(bs)) +#define PPC_BITMASK8(bs, be) ((PPC_BIT8(bs) - PPC_BIT8(be)) | PPC_BIT8(bs)) + +#if HOST_LONG_BITS == 32 +# define MASK_TO_LSH(m) (__builtin_ffsll(m) - 1) +#elif HOST_LONG_BITS == 64 +# define MASK_TO_LSH(m) (__builtin_ffsl(m) - 1) +#else +# error Unknown sizeof long +#endif + +#define GETFIELD(m, v) (((v) & (m)) >> MASK_TO_LSH(m)) +#define SETFIELD(m, v, val) \ + (((v) & ~(m)) | ((((typeof(v))(val)) << MASK_TO_LSH(m)) & (m))) /*****************************************************************************/ /* Exception vectors definitions */ @@ -2349,32 +2362,31 @@ enum { /* Processor Compatibility mask (PCR) */ enum { - PCR_COMPAT_2_05 = 1ull << (63-62), - PCR_COMPAT_2_06 = 1ull << (63-61), - PCR_COMPAT_2_07 = 1ull << (63-60), - PCR_COMPAT_3_00 = 1ull << (63-59), - PCR_VEC_DIS = 1ull << (63-0), /* Vec. disable (bit NA since POWER8) */ - PCR_VSX_DIS = 1ull << (63-1), /* VSX disable (bit NA since POWER8) */ - PCR_TM_DIS = 1ull << (63-2), /* Trans. memory disable (POWER8) */ + PCR_COMPAT_2_05 = PPC_BIT(62), + PCR_COMPAT_2_06 = PPC_BIT(61), + PCR_COMPAT_2_07 = PPC_BIT(60), + PCR_COMPAT_3_00 = PPC_BIT(59), + PCR_VEC_DIS = PPC_BIT(0), /* Vec. disable (bit NA since POWER8) */ + PCR_VSX_DIS = PPC_BIT(1), /* VSX disable (bit NA since POWER8) */ + PCR_TM_DIS = PPC_BIT(2), /* Trans. memory disable (POWER8) */ }; /* HMER/HMEER */ enum { - HMER_MALFUNCTION_ALERT = 1ull << (63 - 0), - HMER_PROC_RECV_DONE = 1ull << (63 - 2), - HMER_PROC_RECV_ERROR_MASKED = 1ull << (63 - 3), - HMER_TFAC_ERROR = 1ull << (63 - 4), - HMER_TFMR_PARITY_ERROR = 1ull << (63 - 5), - HMER_XSCOM_FAIL = 1ull << (63 - 8), - HMER_XSCOM_DONE = 1ull << (63 - 9), - HMER_PROC_RECV_AGAIN = 1ull << (63 - 11), - HMER_WARN_RISE = 1ull << (63 - 14), - HMER_WARN_FALL = 1ull << (63 - 15), - HMER_SCOM_FIR_HMI = 1ull << (63 - 16), - HMER_TRIG_FIR_HMI = 1ull << (63 - 17), - HMER_HYP_RESOURCE_ERR = 1ull << (63 - 20), - HMER_XSCOM_STATUS_MASK = 7ull << (63 - 23), - HMER_XSCOM_STATUS_LSH = (63 - 23), + HMER_MALFUNCTION_ALERT = PPC_BIT(0), + HMER_PROC_RECV_DONE = PPC_BIT(2), + HMER_PROC_RECV_ERROR_MASKED = PPC_BIT(3), + HMER_TFAC_ERROR = PPC_BIT(4), + HMER_TFMR_PARITY_ERROR = PPC_BIT(5), + HMER_XSCOM_FAIL = PPC_BIT(8), + HMER_XSCOM_DONE = PPC_BIT(9), + HMER_PROC_RECV_AGAIN = PPC_BIT(11), + HMER_WARN_RISE = PPC_BIT(14), + HMER_WARN_FALL = PPC_BIT(15), + HMER_SCOM_FIR_HMI = PPC_BIT(16), + HMER_TRIG_FIR_HMI = PPC_BIT(17), + HMER_HYP_RESOURCE_ERR = PPC_BIT(20), + HMER_XSCOM_STATUS_MASK = PPC_BITMASK(21, 23), }; /* Alternate Interrupt Location (AIL) */ diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 1c013a0ee3..3a50f1e1b7 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -183,7 +183,7 @@ uint64_t helper_bpermd(uint64_t rs, uint64_t rb) for (i = 0; i < 8; i++) { int index = (rs >> (i*8)) & 0xFF; if (index < 64) { - if (rb & (1ull << (63-index))) { + if (rb & PPC_BIT(index)) { ra |= 1 << i; } } |