diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/arm/armv7m.c | 12 | ||||
-rw-r--r-- | hw/arm/boot.c | 4 | ||||
-rw-r--r-- | hw/arm/musicpal.c | 8 | ||||
-rw-r--r-- | hw/arm/nseries.c | 4 | ||||
-rw-r--r-- | hw/arm/omap1.c | 12 | ||||
-rw-r--r-- | hw/arm/realview.c | 22 | ||||
-rw-r--r-- | hw/arm/versatilepb.c | 11 | ||||
-rw-r--r-- | hw/audio/marvell_88w8618.c | 3 | ||||
-rw-r--r-- | hw/block/fdc.c | 1 | ||||
-rw-r--r-- | hw/block/m25p80.c | 1 | ||||
-rw-r--r-- | hw/core/Makefile.objs | 1 | ||||
-rw-r--r-- | hw/core/qdev-addr.c | 78 | ||||
-rw-r--r-- | hw/display/pxa2xx_lcd.c | 2 | ||||
-rw-r--r-- | hw/display/sm501.c | 3 | ||||
-rw-r--r-- | hw/display/tcx.c | 1 | ||||
-rw-r--r-- | hw/dma/pxa2xx_dma.c | 2 | ||||
-rw-r--r-- | hw/dma/xilinx_axidma.c | 5 | ||||
-rw-r--r-- | hw/gpio/zaurus.c | 2 | ||||
-rw-r--r-- | hw/lm32/milkymist-hw.h | 1 | ||||
-rw-r--r-- | hw/microblaze/boot.c | 2 | ||||
-rw-r--r-- | hw/misc/Makefile.objs | 1 | ||||
-rw-r--r-- | hw/misc/macio/mac_dbdma.c | 8 | ||||
-rw-r--r-- | hw/misc/milkymist-pfpu.c | 4 | ||||
-rw-r--r-- | hw/misc/pci-testdev.c | 325 | ||||
-rw-r--r-- | hw/net/mcf_fec.c | 4 | ||||
-rw-r--r-- | hw/net/milkymist-minimac2.c | 1 | ||||
-rw-r--r-- | hw/pci-host/versatile.c | 399 | ||||
-rw-r--r-- | hw/ppc/ppc405_boards.c | 2 | ||||
-rw-r--r-- | hw/ppc/virtex_ml507.c | 2 | ||||
-rw-r--r-- | hw/sparc/sun4m.c | 1 | ||||
-rw-r--r-- | hw/virtio/virtio-balloon.c | 2 |
31 files changed, 736 insertions, 188 deletions
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index 2ae3576760..93422bc7be 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -56,7 +56,7 @@ static uint32_t bitband_readw(void *opaque, hwaddr offset) addr = bitband_addr(opaque, offset) & ~1; mask = (1 << ((offset >> 2) & 15)); mask = tswap16(mask); - cpu_physical_memory_read(addr, (uint8_t *)&v, 2); + cpu_physical_memory_read(addr, &v, 2); return (v & mask) != 0; } @@ -69,12 +69,12 @@ static void bitband_writew(void *opaque, hwaddr offset, addr = bitband_addr(opaque, offset) & ~1; mask = (1 << ((offset >> 2) & 15)); mask = tswap16(mask); - cpu_physical_memory_read(addr, (uint8_t *)&v, 2); + cpu_physical_memory_read(addr, &v, 2); if (value & 1) v |= mask; else v &= ~mask; - cpu_physical_memory_write(addr, (uint8_t *)&v, 2); + cpu_physical_memory_write(addr, &v, 2); } static uint32_t bitband_readl(void *opaque, hwaddr offset) @@ -85,7 +85,7 @@ static uint32_t bitband_readl(void *opaque, hwaddr offset) addr = bitband_addr(opaque, offset) & ~3; mask = (1 << ((offset >> 2) & 31)); mask = tswap32(mask); - cpu_physical_memory_read(addr, (uint8_t *)&v, 4); + cpu_physical_memory_read(addr, &v, 4); return (v & mask) != 0; } @@ -98,12 +98,12 @@ static void bitband_writel(void *opaque, hwaddr offset, addr = bitband_addr(opaque, offset) & ~3; mask = (1 << ((offset >> 2) & 31)); mask = tswap32(mask); - cpu_physical_memory_read(addr, (uint8_t *)&v, 4); + cpu_physical_memory_read(addr, &v, 4); if (value & 1) v |= mask; else v &= ~mask; - cpu_physical_memory_write(addr, (uint8_t *)&v, 4); + cpu_physical_memory_write(addr, &v, 4); } static const MemoryRegionOps bitband_ops = { diff --git a/hw/arm/boot.c b/hw/arm/boot.c index e9c09454ac..f451529fce 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -128,7 +128,7 @@ static void set_kernel_args(const struct arm_boot_info *info) int cmdline_size; cmdline_size = strlen(info->kernel_cmdline); - cpu_physical_memory_write(p + 8, (void *)info->kernel_cmdline, + cpu_physical_memory_write(p + 8, info->kernel_cmdline, cmdline_size + 1); cmdline_size = (cmdline_size >> 2) + 1; WRITE_WORD(p, cmdline_size + 2); @@ -219,7 +219,7 @@ static void set_kernel_args_old(const struct arm_boot_info *info) } s = info->kernel_cmdline; if (s) { - cpu_physical_memory_write(p, (void *)s, strlen(s) + 1); + cpu_physical_memory_write(p, s, strlen(s) + 1); } else { WRITE_WORD(p, 0); } diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c index 31586c652e..f33ba9a039 100644 --- a/hw/arm/musicpal.c +++ b/hw/arm/musicpal.c @@ -170,12 +170,12 @@ static void eth_rx_desc_put(uint32_t addr, mv88w8618_rx_desc *desc) cpu_to_le16s(&desc->buffer_size); cpu_to_le32s(&desc->buffer); cpu_to_le32s(&desc->next); - cpu_physical_memory_write(addr, (void *)desc, sizeof(*desc)); + cpu_physical_memory_write(addr, desc, sizeof(*desc)); } static void eth_rx_desc_get(uint32_t addr, mv88w8618_rx_desc *desc) { - cpu_physical_memory_read(addr, (void *)desc, sizeof(*desc)); + cpu_physical_memory_read(addr, desc, sizeof(*desc)); le32_to_cpus(&desc->cmdstat); le16_to_cpus(&desc->bytes); le16_to_cpus(&desc->buffer_size); @@ -229,12 +229,12 @@ static void eth_tx_desc_put(uint32_t addr, mv88w8618_tx_desc *desc) cpu_to_le16s(&desc->bytes); cpu_to_le32s(&desc->buffer); cpu_to_le32s(&desc->next); - cpu_physical_memory_write(addr, (void *)desc, sizeof(*desc)); + cpu_physical_memory_write(addr, desc, sizeof(*desc)); } static void eth_tx_desc_get(uint32_t addr, mv88w8618_tx_desc *desc) { - cpu_physical_memory_read(addr, (void *)desc, sizeof(*desc)); + cpu_physical_memory_read(addr, desc, sizeof(*desc)); le32_to_cpus(&desc->cmdstat); le16_to_cpus(&desc->res); le16_to_cpus(&desc->bytes); diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c index 4976438ae6..f6c9dc09ef 100644 --- a/hw/arm/nseries.c +++ b/hw/arm/nseries.c @@ -970,7 +970,7 @@ static void n800_gpmc_init(struct n800_s *s) (4 << 0); /* BASEADDRESS */ cpu_physical_memory_write(0x6800a078, /* GPMC_CONFIG7_0 */ - (void *) &config7, sizeof(config7)); + &config7, sizeof(config7)); } /* Setup sequence done by the bootloader */ @@ -982,7 +982,7 @@ static void n8x0_boot_init(void *opaque) /* PRCM setup */ #define omap_writel(addr, val) \ buf = (val); \ - cpu_physical_memory_write(addr, (void *) &buf, sizeof(buf)) + cpu_physical_memory_write(addr, &buf, sizeof(buf)) omap_writel(0x48008060, 0x41); /* PRCM_CLKSRC_CTRL */ omap_writel(0x48008070, 1); /* PRCM_CLKOUT_CTRL */ diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c index f59f0f291a..c06c642acc 100644 --- a/hw/arm/omap1.c +++ b/hw/arm/omap1.c @@ -31,7 +31,7 @@ uint32_t omap_badwidth_read8(void *opaque, hwaddr addr) uint8_t ret; OMAP_8B_REG(addr); - cpu_physical_memory_read(addr, (void *) &ret, 1); + cpu_physical_memory_read(addr, &ret, 1); return ret; } @@ -41,7 +41,7 @@ void omap_badwidth_write8(void *opaque, hwaddr addr, uint8_t val8 = value; OMAP_8B_REG(addr); - cpu_physical_memory_write(addr, (void *) &val8, 1); + cpu_physical_memory_write(addr, &val8, 1); } uint32_t omap_badwidth_read16(void *opaque, hwaddr addr) @@ -49,7 +49,7 @@ uint32_t omap_badwidth_read16(void *opaque, hwaddr addr) uint16_t ret; OMAP_16B_REG(addr); - cpu_physical_memory_read(addr, (void *) &ret, 2); + cpu_physical_memory_read(addr, &ret, 2); return ret; } @@ -59,7 +59,7 @@ void omap_badwidth_write16(void *opaque, hwaddr addr, uint16_t val16 = value; OMAP_16B_REG(addr); - cpu_physical_memory_write(addr, (void *) &val16, 2); + cpu_physical_memory_write(addr, &val16, 2); } uint32_t omap_badwidth_read32(void *opaque, hwaddr addr) @@ -67,7 +67,7 @@ uint32_t omap_badwidth_read32(void *opaque, hwaddr addr) uint32_t ret; OMAP_32B_REG(addr); - cpu_physical_memory_read(addr, (void *) &ret, 4); + cpu_physical_memory_read(addr, &ret, 4); return ret; } @@ -75,7 +75,7 @@ void omap_badwidth_write32(void *opaque, hwaddr addr, uint32_t value) { OMAP_32B_REG(addr); - cpu_physical_memory_write(addr, (void *) &value, 4); + cpu_physical_memory_write(addr, &value, 4); } /* MPU OS timers */ diff --git a/hw/arm/realview.c b/hw/arm/realview.c index feabfc58d4..d6f47bf4d4 100644 --- a/hw/arm/realview.c +++ b/hw/arm/realview.c @@ -217,9 +217,13 @@ static void realview_init(QEMUMachineInitArgs *args, dev = qdev_create(NULL, "realview_pci"); busdev = SYS_BUS_DEVICE(dev); qdev_init_nofail(dev); - sysbus_mmio_map(busdev, 0, 0x61000000); /* PCI self-config */ - sysbus_mmio_map(busdev, 1, 0x62000000); /* PCI config */ - sysbus_mmio_map(busdev, 2, 0x63000000); /* PCI I/O */ + sysbus_mmio_map(busdev, 0, 0x10019000); /* PCI controller registers */ + sysbus_mmio_map(busdev, 1, 0x60000000); /* PCI self-config */ + sysbus_mmio_map(busdev, 2, 0x61000000); /* PCI config */ + sysbus_mmio_map(busdev, 3, 0x62000000); /* PCI I/O */ + sysbus_mmio_map(busdev, 4, 0x63000000); /* PCI memory window 1 */ + sysbus_mmio_map(busdev, 5, 0x64000000); /* PCI memory window 2 */ + sysbus_mmio_map(busdev, 6, 0x68000000); /* PCI memory window 3 */ sysbus_connect_irq(busdev, 0, pic[48]); sysbus_connect_irq(busdev, 1, pic[49]); sysbus_connect_irq(busdev, 2, pic[50]); @@ -303,12 +307,12 @@ static void realview_init(QEMUMachineInitArgs *args, /* 0x58000000 PISMO. */ /* 0x5c000000 PISMO. */ /* 0x60000000 PCI. */ - /* 0x61000000 PCI Self Config. */ - /* 0x62000000 PCI Config. */ - /* 0x63000000 PCI IO. */ - /* 0x64000000 PCI mem 0. */ - /* 0x68000000 PCI mem 1. */ - /* 0x6c000000 PCI mem 2. */ + /* 0x60000000 PCI Self Config. */ + /* 0x61000000 PCI Config. */ + /* 0x62000000 PCI IO. */ + /* 0x63000000 PCI mem 0. */ + /* 0x64000000 PCI mem 1. */ + /* 0x68000000 PCI mem 2. */ /* ??? Hack to map an additional page of ram for the secondary CPU startup code. I guess this works on real hardware because the diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c index 25c665ab27..753757ea19 100644 --- a/hw/arm/versatilepb.c +++ b/hw/arm/versatilepb.c @@ -224,16 +224,19 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id) dev = qdev_create(NULL, "versatile_pci"); busdev = SYS_BUS_DEVICE(dev); qdev_init_nofail(dev); - sysbus_mmio_map(busdev, 0, 0x41000000); /* PCI self-config */ - sysbus_mmio_map(busdev, 1, 0x42000000); /* PCI config */ + sysbus_mmio_map(busdev, 0, 0x10001000); /* PCI controller regs */ + sysbus_mmio_map(busdev, 1, 0x41000000); /* PCI self-config */ + sysbus_mmio_map(busdev, 2, 0x42000000); /* PCI config */ + sysbus_mmio_map(busdev, 3, 0x43000000); /* PCI I/O */ + sysbus_mmio_map(busdev, 4, 0x44000000); /* PCI memory window 1 */ + sysbus_mmio_map(busdev, 5, 0x50000000); /* PCI memory window 2 */ + sysbus_mmio_map(busdev, 6, 0x60000000); /* PCI memory window 3 */ sysbus_connect_irq(busdev, 0, sic[27]); sysbus_connect_irq(busdev, 1, sic[28]); sysbus_connect_irq(busdev, 2, sic[29]); sysbus_connect_irq(busdev, 3, sic[30]); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci"); - /* The Versatile PCI bridge does not provide access to PCI IO space, - so many of the qemu PCI devices are not useable. */ for(n = 0; n < nb_nics; n++) { nd = &nd_table[n]; diff --git a/hw/audio/marvell_88w8618.c b/hw/audio/marvell_88w8618.c index f9b68fd311..de06dfd7d2 100644 --- a/hw/audio/marvell_88w8618.c +++ b/hw/audio/marvell_88w8618.c @@ -77,8 +77,7 @@ static void mv88w8618_audio_callback(void *opaque, int free_out, int free_in) if (block_size > 4096) { return; } - cpu_physical_memory_read(s->target_buffer + s->play_pos, (void *)buf, - block_size); + cpu_physical_memory_read(s->target_buffer + s->play_pos, buf, block_size); mem_buffer = buf; if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) { if (s->playback_mode & MP_AUDIO_MONO) { diff --git a/hw/block/fdc.c b/hw/block/fdc.c index 1ed874f074..f1f1fd7f3b 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -33,7 +33,6 @@ #include "qemu/timer.h" #include "hw/isa/isa.h" #include "hw/sysbus.h" -#include "hw/qdev-addr.h" #include "sysemu/blockdev.h" #include "sysemu/sysemu.h" #include "qemu/log.h" diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index efcc7f4c83..b3ca19ae52 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -24,7 +24,6 @@ #include "hw/hw.h" #include "sysemu/blockdev.h" #include "hw/ssi.h" -#include "hw/devices.h" #ifndef M25P80_ERR_DEBUG #define M25P80_ERR_DEBUG 0 diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs index 94109f32e2..950146c6ff 100644 --- a/hw/core/Makefile.objs +++ b/hw/core/Makefile.objs @@ -9,6 +9,5 @@ common-obj-$(CONFIG_PTIMER) += ptimer.o common-obj-$(CONFIG_SOFTMMU) += sysbus.o common-obj-$(CONFIG_SOFTMMU) += null-machine.o common-obj-$(CONFIG_SOFTMMU) += loader.o -common-obj-$(CONFIG_SOFTMMU) += qdev-addr.o common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o diff --git a/hw/core/qdev-addr.c b/hw/core/qdev-addr.c deleted file mode 100644 index 80a38bb017..0000000000 --- a/hw/core/qdev-addr.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "hw/qdev.h" -#include "hw/qdev-addr.h" -#include "exec/hwaddr.h" -#include "qapi/qmp/qerror.h" -#include "qapi/visitor.h" - -/* --- target physical address --- */ - -static int parse_taddr(DeviceState *dev, Property *prop, const char *str) -{ - hwaddr *ptr = qdev_get_prop_ptr(dev, prop); - - *ptr = strtoull(str, NULL, 16); - return 0; -} - -static int print_taddr(DeviceState *dev, Property *prop, char *dest, size_t len) -{ - hwaddr *ptr = qdev_get_prop_ptr(dev, prop); - return snprintf(dest, len, "0x" TARGET_FMT_plx, *ptr); -} - -static void get_taddr(Object *obj, Visitor *v, void *opaque, - const char *name, Error **errp) -{ - DeviceState *dev = DEVICE(obj); - Property *prop = opaque; - hwaddr *ptr = qdev_get_prop_ptr(dev, prop); - int64_t value; - - value = *ptr; - visit_type_int64(v, &value, name, errp); -} - -static void set_taddr(Object *obj, Visitor *v, void *opaque, - const char *name, Error **errp) -{ - DeviceState *dev = DEVICE(obj); - Property *prop = opaque; - hwaddr *ptr = qdev_get_prop_ptr(dev, prop); - Error *local_err = NULL; - int64_t value; - - if (dev->realized) { - qdev_prop_set_after_realize(dev, name, errp); - return; - } - - visit_type_int64(v, &value, name, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - if ((uint64_t)value <= (uint64_t) ~(hwaddr)0) { - *ptr = value; - } else { - error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, - dev->id?:"", name, value, (uint64_t) 0, - (uint64_t) ~(hwaddr)0); - } -} - - -PropertyInfo qdev_prop_taddr = { - .name = "taddr", - .parse = parse_taddr, - .print = print_taddr, - .get = get_taddr, - .set = set_taddr, -}; - -void qdev_prop_set_taddr(DeviceState *dev, const char *name, hwaddr value) -{ - Error *errp = NULL; - object_property_set_int(OBJECT(dev), value, name, &errp); - assert(!errp); - -} diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c index 12d9cd2808..76276cf7f1 100644 --- a/hw/display/pxa2xx_lcd.c +++ b/hw/display/pxa2xx_lcd.c @@ -315,7 +315,7 @@ static void pxa2xx_descriptor_load(PXA2xxLCDState *s) continue; } - cpu_physical_memory_read(descptr, (void *)&desc, sizeof(desc)); + cpu_physical_memory_read(descptr, &desc, sizeof(desc)); s->dma_ch[i].descriptor = tswap32(desc.fdaddr); s->dma_ch[i].source = tswap32(desc.fsaddr); s->dma_ch[i].id = tswap32(desc.fidr); diff --git a/hw/display/sm501.c b/hw/display/sm501.c index f0e6d7022f..916816fc24 100644 --- a/hw/display/sm501.c +++ b/hw/display/sm501.c @@ -28,7 +28,6 @@ #include "ui/console.h" #include "hw/devices.h" #include "hw/sysbus.h" -#include "hw/qdev-addr.h" #include "qemu/range.h" #include "ui/pixel_ops.h" @@ -1434,7 +1433,7 @@ void sm501_init(MemoryRegion *address_space_mem, uint32_t base, /* bridge to usb host emulation module */ dev = qdev_create(NULL, "sysbus-ohci"); qdev_prop_set_uint32(dev, "num-ports", 2); - qdev_prop_set_taddr(dev, "dma-offset", base); + qdev_prop_set_uint64(dev, "dma-offset", base); qdev_init_nofail(dev); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base + MMIO_BASE_OFFSET + SM501_USB_HOST); diff --git a/hw/display/tcx.c b/hw/display/tcx.c index 77c7191c76..d7465c63f1 100644 --- a/hw/display/tcx.c +++ b/hw/display/tcx.c @@ -26,7 +26,6 @@ #include "ui/console.h" #include "ui/pixel_ops.h" #include "hw/sysbus.h" -#include "hw/qdev-addr.h" #define MAXX 1024 #define MAXY 768 diff --git a/hw/dma/pxa2xx_dma.c b/hw/dma/pxa2xx_dma.c index 6e4c1f6d62..b60569fd88 100644 --- a/hw/dma/pxa2xx_dma.c +++ b/hw/dma/pxa2xx_dma.c @@ -151,7 +151,7 @@ static inline void pxa2xx_dma_descriptor_fetch( if ((s->chan[ch].descr & DDADR_BREN) && (s->chan[ch].state & DCSR_CMPST)) daddr += 32; - cpu_physical_memory_read(daddr, (uint8_t *) desc, 16); + cpu_physical_memory_read(daddr, desc, 16); s->chan[ch].descr = desc[DDADR]; s->chan[ch].src = desc[DSADR]; s->chan[ch].dest = desc[DTADR]; diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c index 1c23762210..3a3ef8aff3 100644 --- a/hw/dma/xilinx_axidma.c +++ b/hw/dma/xilinx_axidma.c @@ -26,7 +26,6 @@ #include "qemu/timer.h" #include "hw/ptimer.h" #include "qemu/log.h" -#include "hw/qdev-addr.h" #include "qapi/qmp/qerror.h" #include "hw/stream.h" @@ -197,7 +196,7 @@ static void stream_desc_load(struct Stream *s, hwaddr addr) { struct SDesc *d = &s->desc; - cpu_physical_memory_read(addr, (void *) d, sizeof *d); + cpu_physical_memory_read(addr, d, sizeof *d); /* Convert from LE into host endianness. */ d->buffer_address = le64_to_cpu(d->buffer_address); @@ -215,7 +214,7 @@ static void stream_desc_store(struct Stream *s, hwaddr addr) d->nxtdesc = cpu_to_le64(d->nxtdesc); d->control = cpu_to_le32(d->control); d->status = cpu_to_le32(d->status); - cpu_physical_memory_write(addr, (void *) d, sizeof *d); + cpu_physical_memory_write(addr, d, sizeof *d); } static void stream_update_irq(struct Stream *s) diff --git a/hw/gpio/zaurus.c b/hw/gpio/zaurus.c index d853ea1310..c6cdef3212 100644 --- a/hw/gpio/zaurus.c +++ b/hw/gpio/zaurus.c @@ -287,6 +287,6 @@ static struct QEMU_PACKED sl_param_info { void sl_bootparam_write(hwaddr ptr) { - cpu_physical_memory_write(ptr, (void *)&zaurus_bootparam, + cpu_physical_memory_write(ptr, &zaurus_bootparam, sizeof(struct sl_param_info)); } diff --git a/hw/lm32/milkymist-hw.h b/hw/lm32/milkymist-hw.h index 4e86c4e832..5317ce6e2d 100644 --- a/hw/lm32/milkymist-hw.h +++ b/hw/lm32/milkymist-hw.h @@ -2,7 +2,6 @@ #define QEMU_HW_MILKYMIST_H #include "hw/qdev.h" -#include "hw/qdev-addr.h" #include "net/net.h" static inline DeviceState *milkymist_uart_create(hwaddr base, diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c index 23cb11d70e..e543d886b8 100644 --- a/hw/microblaze/boot.c +++ b/hw/microblaze/boot.c @@ -80,7 +80,7 @@ static int microblaze_load_dtb(hwaddr addr, } } - cpu_physical_memory_write(addr, (void *)fdt, fdt_size); + cpu_physical_memory_write(addr, fdt, fdt_size); #else /* We lack libfdt so we cannot manipulate the fdt. Just pass on the blob to the kernel. */ diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index 03699c3365..11b18a4196 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -4,6 +4,7 @@ common-obj-$(CONFIG_TMP105) += tmp105.o common-obj-$(CONFIG_ISA_DEBUG) += debugexit.o common-obj-$(CONFIG_SGA) += sga.o common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o +common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o obj-$(CONFIG_VMPORT) += vmport.o diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c index a2363bbdf2..2fc7f87bb6 100644 --- a/hw/misc/macio/mac_dbdma.c +++ b/hw/misc/macio/mac_dbdma.c @@ -192,7 +192,7 @@ static void dbdma_cmdptr_load(DBDMA_channel *ch) DBDMA_DPRINTF("dbdma_cmdptr_load 0x%08x\n", ch->regs[DBDMA_CMDPTR_LO]); cpu_physical_memory_read(ch->regs[DBDMA_CMDPTR_LO], - (uint8_t*)&ch->current, sizeof(dbdma_cmd)); + &ch->current, sizeof(dbdma_cmd)); } static void dbdma_cmdptr_save(DBDMA_channel *ch) @@ -203,7 +203,7 @@ static void dbdma_cmdptr_save(DBDMA_channel *ch) le16_to_cpu(ch->current.xfer_status), le16_to_cpu(ch->current.res_count)); cpu_physical_memory_write(ch->regs[DBDMA_CMDPTR_LO], - (uint8_t*)&ch->current, sizeof(dbdma_cmd)); + &ch->current, sizeof(dbdma_cmd)); } static void kill_channel(DBDMA_channel *ch) @@ -454,7 +454,7 @@ static void load_word(DBDMA_channel *ch, int key, uint32_t addr, return; } - cpu_physical_memory_read(addr, (uint8_t*)&val, len); + cpu_physical_memory_read(addr, &val, len); if (len == 2) val = (val << 16) | (current->cmd_dep & 0x0000ffff); @@ -499,7 +499,7 @@ static void store_word(DBDMA_channel *ch, int key, uint32_t addr, else if (len == 1) val >>= 24; - cpu_physical_memory_write(addr, (uint8_t*)&val, len); + cpu_physical_memory_write(addr, &val, len); if (conditional_wait(ch)) goto wait; diff --git a/hw/misc/milkymist-pfpu.c b/hw/misc/milkymist-pfpu.c index ad44b4db22..fe1b039550 100644 --- a/hw/misc/milkymist-pfpu.c +++ b/hw/misc/milkymist-pfpu.c @@ -228,8 +228,8 @@ static int pfpu_decode_insn(MilkymistPFPUState *s) hwaddr dma_ptr = get_dma_address(s->regs[R_MESHBASE], s->gp_regs[GPR_X], s->gp_regs[GPR_Y]); - cpu_physical_memory_write(dma_ptr, (uint8_t *)&a, 4); - cpu_physical_memory_write(dma_ptr + 4, (uint8_t *)&b, 4); + cpu_physical_memory_write(dma_ptr, &a, 4); + cpu_physical_memory_write(dma_ptr + 4, &b, 4); s->regs[R_LASTDMA] = dma_ptr + 4; D_EXEC(qemu_log("VECTOUT a=%08x b=%08x dma=%08x\n", a, b, dma_ptr)); trace_milkymist_pfpu_vectout(a, b, dma_ptr); diff --git a/hw/misc/pci-testdev.c b/hw/misc/pci-testdev.c new file mode 100644 index 0000000000..71ce5a3e08 --- /dev/null +++ b/hw/misc/pci-testdev.c @@ -0,0 +1,325 @@ +/* + * QEMU PCI test device + * + * Copyright (c) 2012 Red Hat Inc. + * Author: Michael S. Tsirkin <mst@redhat.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + */ +#include "hw/hw.h" +#include "hw/pci/pci.h" +#include "qemu/event_notifier.h" +#include "qemu/osdep.h" + +typedef struct PCITestDevHdr { + uint8_t test; + uint8_t width; + uint8_t pad0[2]; + uint32_t offset; + uint8_t data; + uint8_t pad1[3]; + uint32_t count; + uint8_t name[]; +} PCITestDevHdr; + +typedef struct IOTest { + MemoryRegion *mr; + EventNotifier notifier; + bool hasnotifier; + unsigned size; + bool match_data; + PCITestDevHdr *hdr; + unsigned bufsize; +} IOTest; + +#define IOTEST_DATAMATCH 0xFA +#define IOTEST_NOMATCH 0xCE + +#define IOTEST_IOSIZE 128 +#define IOTEST_MEMSIZE 2048 + +static const char *iotest_test[] = { + "no-eventfd", + "wildcard-eventfd", + "datamatch-eventfd" +}; + +static const char *iotest_type[] = { + "mmio", + "portio" +}; + +#define IOTEST_TEST(i) (iotest_test[((i) % ARRAY_SIZE(iotest_test))]) +#define IOTEST_TYPE(i) (iotest_type[((i) / ARRAY_SIZE(iotest_test))]) +#define IOTEST_MAX_TEST (ARRAY_SIZE(iotest_test)) +#define IOTEST_MAX_TYPE (ARRAY_SIZE(iotest_type)) +#define IOTEST_MAX (IOTEST_MAX_TEST * IOTEST_MAX_TYPE) + +enum { + IOTEST_ACCESS_NAME, + IOTEST_ACCESS_DATA, + IOTEST_ACCESS_MAX, +}; + +#define IOTEST_ACCESS_TYPE uint8_t +#define IOTEST_ACCESS_WIDTH (sizeof(uint8_t)) + +typedef struct PCITestDevState { + PCIDevice dev; + MemoryRegion mmio; + MemoryRegion portio; + IOTest *tests; + int current; +} PCITestDevState; + +#define IOTEST_IS_MEM(i) (strcmp(IOTEST_TYPE(i), "portio")) +#define IOTEST_REGION(d, i) (IOTEST_IS_MEM(i) ? &(d)->mmio : &(d)->portio) +#define IOTEST_SIZE(i) (IOTEST_IS_MEM(i) ? IOTEST_MEMSIZE : IOTEST_IOSIZE) +#define IOTEST_PCI_BAR(i) (IOTEST_IS_MEM(i) ? PCI_BASE_ADDRESS_SPACE_MEMORY : \ + PCI_BASE_ADDRESS_SPACE_IO) + +static int pci_testdev_start(IOTest *test) +{ + test->hdr->count = 0; + if (!test->hasnotifier) { + return 0; + } + event_notifier_test_and_clear(&test->notifier); + memory_region_add_eventfd(test->mr, + le32_to_cpu(test->hdr->offset), + test->size, + test->match_data, + test->hdr->data, + &test->notifier); + return 0; +} + +static void pci_testdev_stop(IOTest *test) +{ + if (!test->hasnotifier) { + return; + } + memory_region_del_eventfd(test->mr, + le32_to_cpu(test->hdr->offset), + test->size, + test->match_data, + test->hdr->data, + &test->notifier); +} + +static void +pci_testdev_reset(PCITestDevState *d) +{ + if (d->current == -1) { + return; + } + pci_testdev_stop(&d->tests[d->current]); + d->current = -1; +} + +static void pci_testdev_inc(IOTest *test, unsigned inc) +{ + uint32_t c = le32_to_cpu(test->hdr->count); + test->hdr->count = cpu_to_le32(c + inc); +} + +static void +pci_testdev_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size, int type) +{ + PCITestDevState *d = opaque; + IOTest *test; + int t, r; + + if (addr == offsetof(PCITestDevHdr, test)) { + pci_testdev_reset(d); + if (val >= IOTEST_MAX_TEST) { + return; + } + t = type * IOTEST_MAX_TEST + val; + r = pci_testdev_start(&d->tests[t]); + if (r < 0) { + return; + } + d->current = t; + return; + } + if (d->current < 0) { + return; + } + test = &d->tests[d->current]; + if (addr != le32_to_cpu(test->hdr->offset)) { + return; + } + if (test->match_data && test->size != size) { + return; + } + if (test->match_data && val != test->hdr->data) { + return; + } + pci_testdev_inc(test, 1); +} + +static uint64_t +pci_testdev_read(void *opaque, hwaddr addr, unsigned size) +{ + PCITestDevState *d = opaque; + const char *buf; + IOTest *test; + if (d->current < 0) { + return 0; + } + test = &d->tests[d->current]; + buf = (const char *)test->hdr; + if (addr + size >= test->bufsize) { + return 0; + } + if (test->hasnotifier) { + event_notifier_test_and_clear(&test->notifier); + } + return buf[addr]; +} + +static void +pci_testdev_mmio_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + pci_testdev_write(opaque, addr, val, size, 0); +} + +static void +pci_testdev_pio_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + pci_testdev_write(opaque, addr, val, size, 1); +} + +static const MemoryRegionOps pci_testdev_mmio_ops = { + .read = pci_testdev_read, + .write = pci_testdev_mmio_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; + +static const MemoryRegionOps pci_testdev_pio_ops = { + .read = pci_testdev_read, + .write = pci_testdev_pio_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; + +static int pci_testdev_init(PCIDevice *pci_dev) +{ + PCITestDevState *d = DO_UPCAST(PCITestDevState, dev, pci_dev); + uint8_t *pci_conf; + char *name; + int r, i; + + pci_conf = d->dev.config; + + pci_conf[PCI_INTERRUPT_PIN] = 0; /* no interrupt pin */ + + memory_region_init_io(&d->mmio, &pci_testdev_mmio_ops, d, + "pci-testdev-mmio", IOTEST_MEMSIZE * 2); + memory_region_init_io(&d->portio, &pci_testdev_pio_ops, d, + "pci-testdev-portio", IOTEST_IOSIZE * 2); + pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio); + pci_register_bar(&d->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->portio); + + d->current = -1; + d->tests = g_malloc0(IOTEST_MAX * sizeof *d->tests); + for (i = 0; i < IOTEST_MAX; ++i) { + IOTest *test = &d->tests[i]; + name = g_strdup_printf("%s-%s", IOTEST_TYPE(i), IOTEST_TEST(i)); + test->bufsize = sizeof(PCITestDevHdr) + strlen(name) + 1; + test->hdr = g_malloc0(test->bufsize); + memcpy(test->hdr->name, name, strlen(name) + 1); + g_free(name); + test->hdr->offset = cpu_to_le32(IOTEST_SIZE(i) + i * IOTEST_ACCESS_WIDTH); + test->size = IOTEST_ACCESS_WIDTH; + test->match_data = strcmp(IOTEST_TEST(i), "wildcard-eventfd"); + test->hdr->test = i; + test->hdr->data = test->match_data ? IOTEST_DATAMATCH : IOTEST_NOMATCH; + test->hdr->width = IOTEST_ACCESS_WIDTH; + test->mr = IOTEST_REGION(d, i); + if (!strcmp(IOTEST_TEST(i), "no-eventfd")) { + test->hasnotifier = false; + continue; + } + r = event_notifier_init(&test->notifier, 0); + assert(r >= 0); + test->hasnotifier = true; + } + + return 0; +} + +static void +pci_testdev_uninit(PCIDevice *dev) +{ + PCITestDevState *d = DO_UPCAST(PCITestDevState, dev, dev); + int i; + + pci_testdev_reset(d); + for (i = 0; i < IOTEST_MAX; ++i) { + if (d->tests[i].hasnotifier) { + event_notifier_cleanup(&d->tests[i].notifier); + } + g_free(d->tests[i].hdr); + } + g_free(d->tests); + memory_region_destroy(&d->mmio); + memory_region_destroy(&d->portio); +} + +static void qdev_pci_testdev_reset(DeviceState *dev) +{ + PCITestDevState *d = DO_UPCAST(PCITestDevState, dev.qdev, dev); + pci_testdev_reset(d); +} + +static void pci_testdev_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->init = pci_testdev_init; + k->exit = pci_testdev_uninit; + k->vendor_id = PCI_VENDOR_ID_REDHAT; + k->device_id = PCI_DEVICE_ID_REDHAT_TEST; + k->revision = 0x00; + k->class_id = PCI_CLASS_OTHERS; + dc->desc = "PCI Test Device"; + dc->reset = qdev_pci_testdev_reset; +} + +static const TypeInfo pci_testdev_info = { + .name = "pci-testdev", + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(PCITestDevState), + .class_init = pci_testdev_class_init, +}; + +static void pci_testdev_register_types(void) +{ + type_register_static(&pci_testdev_info); +} + +type_init(pci_testdev_register_types) diff --git a/hw/net/mcf_fec.c b/hw/net/mcf_fec.c index 9b6805267d..2ef5a0d73d 100644 --- a/hw/net/mcf_fec.c +++ b/hw/net/mcf_fec.c @@ -108,7 +108,7 @@ typedef struct { static void mcf_fec_read_bd(mcf_fec_bd *bd, uint32_t addr) { - cpu_physical_memory_read(addr, (uint8_t *)bd, sizeof(*bd)); + cpu_physical_memory_read(addr, bd, sizeof(*bd)); be16_to_cpus(&bd->flags); be16_to_cpus(&bd->length); be32_to_cpus(&bd->data); @@ -120,7 +120,7 @@ static void mcf_fec_write_bd(mcf_fec_bd *bd, uint32_t addr) tmp.flags = cpu_to_be16(bd->flags); tmp.length = cpu_to_be16(bd->length); tmp.data = cpu_to_be32(bd->data); - cpu_physical_memory_write(addr, (uint8_t *)&tmp, sizeof(tmp)); + cpu_physical_memory_write(addr, &tmp, sizeof(tmp)); } static void mcf_fec_update(mcf_fec_state *s) diff --git a/hw/net/milkymist-minimac2.c b/hw/net/milkymist-minimac2.c index 29618e8efa..4ef6318418 100644 --- a/hw/net/milkymist-minimac2.c +++ b/hw/net/milkymist-minimac2.c @@ -27,7 +27,6 @@ #include "trace.h" #include "net/net.h" #include "qemu/error-report.h" -#include "hw/qdev-addr.h" #include <zlib.h> diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c index d67ca796fb..540daf75cc 100644 --- a/hw/pci-host/versatile.c +++ b/hw/pci-host/versatile.c @@ -9,34 +9,235 @@ #include "hw/sysbus.h" #include "hw/pci/pci.h" +#include "hw/pci/pci_bus.h" #include "hw/pci/pci_host.h" #include "exec/address-spaces.h" +/* Old and buggy versions of QEMU used the wrong mapping from + * PCI IRQs to system interrupt lines. Unfortunately the Linux + * kernel also had the corresponding bug in setting up interrupts + * (so older kernels work on QEMU and not on real hardware). + * We automatically detect these broken kernels and flip back + * to the broken irq mapping by spotting guest writes to the + * PCI_INTERRUPT_LINE register to see where the guest thinks + * interrupts are going to be routed. So we start in state + * ASSUME_OK on reset, and transition to either BROKEN or + * FORCE_OK at the first write to an INTERRUPT_LINE register for + * a slot where broken and correct interrupt mapping would differ. + * Once in either BROKEN or FORCE_OK we never transition again; + * this allows a newer kernel to use the INTERRUPT_LINE + * registers arbitrarily once it has indicated that it isn't + * broken in its init code somewhere. + */ +enum { + PCI_VPB_IRQMAP_ASSUME_OK, + PCI_VPB_IRQMAP_BROKEN, + PCI_VPB_IRQMAP_FORCE_OK, +}; + typedef struct { - SysBusDevice busdev; + PCIHostState parent_obj; + qemu_irq irq[4]; - int realview; + MemoryRegion controlregs; MemoryRegion mem_config; MemoryRegion mem_config2; - MemoryRegion isa; + /* Containers representing the PCI address spaces */ + MemoryRegion pci_io_space; + MemoryRegion pci_mem_space; + /* Alias regions into PCI address spaces which we expose as sysbus regions. + * The offsets into pci_mem_space are controlled by the imap registers. + */ + MemoryRegion pci_io_window; + MemoryRegion pci_mem_window[3]; + PCIBus pci_bus; + PCIDevice pci_dev; + + /* Constant for life of device: */ + int realview; + uint32_t mem_win_size[3]; + + /* Variable state: */ + uint32_t imap[3]; + uint32_t smap[3]; + uint32_t selfid; + uint32_t flags; + uint8_t irq_mapping; } PCIVPBState; -static inline uint32_t vpb_pci_config_addr(hwaddr addr) +static void pci_vpb_update_window(PCIVPBState *s, int i) +{ + /* Adjust the offset of the alias region we use for + * the memory window i to account for a change in the + * value of the corresponding IMAP register. + * Note that the semantics of the IMAP register differ + * for realview and versatile variants of the controller. + */ + hwaddr offset; + if (s->realview) { + /* Top bits of register (masked according to window size) provide + * top bits of PCI address. + */ + offset = s->imap[i] & ~(s->mem_win_size[i] - 1); + } else { + /* Bottom 4 bits of register provide top 4 bits of PCI address */ + offset = s->imap[i] << 28; + } + memory_region_set_alias_offset(&s->pci_mem_window[i], offset); +} + +static void pci_vpb_update_all_windows(PCIVPBState *s) +{ + /* Update all alias windows based on the current register state */ + int i; + + for (i = 0; i < 3; i++) { + pci_vpb_update_window(s, i); + } +} + +static int pci_vpb_post_load(void *opaque, int version_id) { - return addr & 0xffffff; + PCIVPBState *s = opaque; + pci_vpb_update_all_windows(s); + return 0; +} + +static const VMStateDescription pci_vpb_vmstate = { + .name = "versatile-pci", + .version_id = 1, + .minimum_version_id = 1, + .post_load = pci_vpb_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(imap, PCIVPBState, 3), + VMSTATE_UINT32_ARRAY(smap, PCIVPBState, 3), + VMSTATE_UINT32(selfid, PCIVPBState), + VMSTATE_UINT32(flags, PCIVPBState), + VMSTATE_UINT8(irq_mapping, PCIVPBState), + VMSTATE_END_OF_LIST() + } +}; + +#define TYPE_VERSATILE_PCI "versatile_pci" +#define PCI_VPB(obj) \ + OBJECT_CHECK(PCIVPBState, (obj), TYPE_VERSATILE_PCI) + +#define TYPE_VERSATILE_PCI_HOST "versatile_pci_host" +#define PCI_VPB_HOST(obj) \ + OBJECT_CHECK(PCIDevice, (obj), TYPE_VERSATILE_PCIHOST) + +typedef enum { + PCI_IMAP0 = 0x0, + PCI_IMAP1 = 0x4, + PCI_IMAP2 = 0x8, + PCI_SELFID = 0xc, + PCI_FLAGS = 0x10, + PCI_SMAP0 = 0x14, + PCI_SMAP1 = 0x18, + PCI_SMAP2 = 0x1c, +} PCIVPBControlRegs; + +static void pci_vpb_reg_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ + PCIVPBState *s = opaque; + + switch (addr) { + case PCI_IMAP0: + case PCI_IMAP1: + case PCI_IMAP2: + { + int win = (addr - PCI_IMAP0) >> 2; + s->imap[win] = val; + pci_vpb_update_window(s, win); + break; + } + case PCI_SELFID: + s->selfid = val; + break; + case PCI_FLAGS: + s->flags = val; + break; + case PCI_SMAP0: + case PCI_SMAP1: + case PCI_SMAP2: + { + int win = (addr - PCI_SMAP0) >> 2; + s->smap[win] = val; + break; + } + default: + qemu_log_mask(LOG_GUEST_ERROR, + "pci_vpb_reg_write: Bad offset %x\n", (int)addr); + break; + } +} + +static uint64_t pci_vpb_reg_read(void *opaque, hwaddr addr, + unsigned size) +{ + PCIVPBState *s = opaque; + + switch (addr) { + case PCI_IMAP0: + case PCI_IMAP1: + case PCI_IMAP2: + { + int win = (addr - PCI_IMAP0) >> 2; + return s->imap[win]; + } + case PCI_SELFID: + return s->selfid; + case PCI_FLAGS: + return s->flags; + case PCI_SMAP0: + case PCI_SMAP1: + case PCI_SMAP2: + { + int win = (addr - PCI_SMAP0) >> 2; + return s->smap[win]; + } + default: + qemu_log_mask(LOG_GUEST_ERROR, + "pci_vpb_reg_read: Bad offset %x\n", (int)addr); + return 0; + } } +static const MemoryRegionOps pci_vpb_reg_ops = { + .read = pci_vpb_reg_read, + .write = pci_vpb_reg_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + static void pci_vpb_config_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { - pci_data_write(opaque, vpb_pci_config_addr(addr), val, size); + PCIVPBState *s = opaque; + if (!s->realview && (addr & 0xff) == PCI_INTERRUPT_LINE + && s->irq_mapping == PCI_VPB_IRQMAP_ASSUME_OK) { + uint8_t devfn = addr >> 8; + if ((PCI_SLOT(devfn) % PCI_NUM_PINS) != 2) { + if (val == 27) { + s->irq_mapping = PCI_VPB_IRQMAP_BROKEN; + } else { + s->irq_mapping = PCI_VPB_IRQMAP_FORCE_OK; + } + } + } + pci_data_write(&s->pci_bus, addr, val, size); } static uint64_t pci_vpb_config_read(void *opaque, hwaddr addr, unsigned size) { + PCIVPBState *s = opaque; uint32_t val; - val = pci_data_read(opaque, vpb_pci_config_addr(addr), size); + val = pci_data_read(&s->pci_bus, addr, size); return val; } @@ -48,7 +249,47 @@ static const MemoryRegionOps pci_vpb_config_ops = { static int pci_vpb_map_irq(PCIDevice *d, int irq_num) { - return irq_num; + PCIVPBState *s = container_of(d->bus, PCIVPBState, pci_bus); + + if (s->irq_mapping == PCI_VPB_IRQMAP_BROKEN) { + /* Legacy broken IRQ mapping for compatibility with old and + * buggy Linux guests + */ + return irq_num; + } + + /* Slot to IRQ mapping for RealView Platform Baseboard 926 backplane + * name slot IntA IntB IntC IntD + * A 31 IRQ28 IRQ29 IRQ30 IRQ27 + * B 30 IRQ27 IRQ28 IRQ29 IRQ30 + * C 29 IRQ30 IRQ27 IRQ28 IRQ29 + * Slot C is for the host bridge; A and B the peripherals. + * Our output irqs 0..3 correspond to the baseboard's 27..30. + * + * This mapping function takes account of an oddity in the PB926 + * board wiring, where the FPGA's P_nINTA input is connected to + * the INTB connection on the board PCI edge connector, P_nINTB + * is connected to INTC, and so on, so everything is one number + * further round from where you might expect. + */ + return pci_swizzle_map_irq_fn(d, irq_num + 2); +} + +static int pci_vpb_rv_map_irq(PCIDevice *d, int irq_num) +{ + /* Slot to IRQ mapping for RealView EB and PB1176 backplane + * name slot IntA IntB IntC IntD + * A 31 IRQ50 IRQ51 IRQ48 IRQ49 + * B 30 IRQ49 IRQ50 IRQ51 IRQ48 + * C 29 IRQ48 IRQ49 IRQ50 IRQ51 + * Slot C is for the host bridge; A and B the peripherals. + * Our output irqs 0..3 correspond to the baseboard's 48..51. + * + * The PB1176 and EB boards don't have the PB926 wiring oddity + * described above; P_nINTA connects to INTA, P_nINTB to INTB + * and so on, which is why this mapping function is different. + */ + return pci_swizzle_map_irq_fn(d, irq_num + 3); } static void pci_vpb_set_irq(void *opaque, int irq_num, int level) @@ -58,53 +299,109 @@ static void pci_vpb_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(pic[irq_num], level); } -static int pci_vpb_init(SysBusDevice *dev) +static void pci_vpb_reset(DeviceState *d) +{ + PCIVPBState *s = PCI_VPB(d); + + s->imap[0] = 0; + s->imap[1] = 0; + s->imap[2] = 0; + s->smap[0] = 0; + s->smap[1] = 0; + s->smap[2] = 0; + s->selfid = 0; + s->flags = 0; + s->irq_mapping = PCI_VPB_IRQMAP_ASSUME_OK; + + pci_vpb_update_all_windows(s); +} + +static void pci_vpb_init(Object *obj) { - PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev); - PCIBus *bus; + PCIHostState *h = PCI_HOST_BRIDGE(obj); + PCIVPBState *s = PCI_VPB(obj); + + memory_region_init(&s->pci_io_space, "pci_io", 1ULL << 32); + memory_region_init(&s->pci_mem_space, "pci_mem", 1ULL << 32); + + pci_bus_new_inplace(&s->pci_bus, DEVICE(obj), "pci", + &s->pci_mem_space, &s->pci_io_space, + PCI_DEVFN(11, 0), TYPE_PCI_BUS); + h->bus = &s->pci_bus; + + object_initialize(&s->pci_dev, TYPE_VERSATILE_PCI_HOST); + qdev_set_parent_bus(DEVICE(&s->pci_dev), BUS(&s->pci_bus)); + object_property_set_int(OBJECT(&s->pci_dev), PCI_DEVFN(29, 0), "addr", + NULL); + + /* Window sizes for VersatilePB; realview_pci's init will override */ + s->mem_win_size[0] = 0x0c000000; + s->mem_win_size[1] = 0x10000000; + s->mem_win_size[2] = 0x10000000; +} + +static void pci_vpb_realize(DeviceState *dev, Error **errp) +{ + PCIVPBState *s = PCI_VPB(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + pci_map_irq_fn mapfn; int i; for (i = 0; i < 4; i++) { - sysbus_init_irq(dev, &s->irq[i]); + sysbus_init_irq(sbd, &s->irq[i]); + } + + if (s->realview) { + mapfn = pci_vpb_rv_map_irq; + } else { + mapfn = pci_vpb_map_irq; } - bus = pci_register_bus(&dev->qdev, "pci", - pci_vpb_set_irq, pci_vpb_map_irq, s->irq, - get_system_memory(), get_system_io(), - PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); - /* ??? Register memory space. */ + pci_bus_irqs(&s->pci_bus, pci_vpb_set_irq, mapfn, s->irq, 4); /* Our memory regions are: - * 0 : PCI self config window - * 1 : PCI config window - * 2 : PCI IO window (realview_pci only) + * 0 : our control registers + * 1 : PCI self config window + * 2 : PCI config window + * 3 : PCI IO window + * 4..6 : PCI memory windows */ - memory_region_init_io(&s->mem_config, &pci_vpb_config_ops, bus, + memory_region_init_io(&s->controlregs, &pci_vpb_reg_ops, s, "pci-vpb-regs", + 0x1000); + sysbus_init_mmio(sbd, &s->controlregs); + memory_region_init_io(&s->mem_config, &pci_vpb_config_ops, s, "pci-vpb-selfconfig", 0x1000000); - sysbus_init_mmio(dev, &s->mem_config); - memory_region_init_io(&s->mem_config2, &pci_vpb_config_ops, bus, + sysbus_init_mmio(sbd, &s->mem_config); + memory_region_init_io(&s->mem_config2, &pci_vpb_config_ops, s, "pci-vpb-config", 0x1000000); - sysbus_init_mmio(dev, &s->mem_config2); - if (s->realview) { - isa_mmio_setup(&s->isa, 0x0100000); - sysbus_init_mmio(dev, &s->isa); - } + sysbus_init_mmio(sbd, &s->mem_config2); - pci_create_simple(bus, -1, "versatile_pci_host"); - return 0; -} + /* The window into I/O space is always into a fixed base address; + * its size is the same for both realview and versatile. + */ + memory_region_init_alias(&s->pci_io_window, "pci-vbp-io-window", + &s->pci_io_space, 0, 0x100000); -static int pci_realview_init(SysBusDevice *dev) -{ - PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev); - s->realview = 1; - return pci_vpb_init(dev); + sysbus_init_mmio(sbd, &s->pci_io_space); + + /* Create the alias regions corresponding to our three windows onto + * PCI memory space. The sizes vary from board to board; the base + * offsets are guest controllable via the IMAP registers. + */ + for (i = 0; i < 3; i++) { + memory_region_init_alias(&s->pci_mem_window[i], "pci-vbp-window", + &s->pci_mem_space, 0, s->mem_win_size[i]); + sysbus_init_mmio(sbd, &s->pci_mem_window[i]); + } + + /* TODO Remove once realize propagates to child devices. */ + object_property_set_bool(OBJECT(&s->pci_dev), true, "realized", errp); } static int versatile_pci_host_init(PCIDevice *d) { pci_set_word(d->config + PCI_STATUS, - PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM); + PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM); pci_set_byte(d->config + PCI_LATENCY_TIMER, 0x10); return 0; } @@ -120,7 +417,7 @@ static void versatile_pci_host_class_init(ObjectClass *klass, void *data) } static const TypeInfo versatile_pci_host_info = { - .name = "versatile_pci_host", + .name = TYPE_VERSATILE_PCI_HOST, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIDevice), .class_init = versatile_pci_host_class_init, @@ -128,30 +425,36 @@ static const TypeInfo versatile_pci_host_info = { static void pci_vpb_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); - sdc->init = pci_vpb_init; + dc->realize = pci_vpb_realize; + dc->reset = pci_vpb_reset; + dc->vmsd = &pci_vpb_vmstate; } static const TypeInfo pci_vpb_info = { - .name = "versatile_pci", - .parent = TYPE_SYS_BUS_DEVICE, + .name = TYPE_VERSATILE_PCI, + .parent = TYPE_PCI_HOST_BRIDGE, .instance_size = sizeof(PCIVPBState), + .instance_init = pci_vpb_init, .class_init = pci_vpb_class_init, }; -static void pci_realview_class_init(ObjectClass *klass, void *data) +static void pci_realview_init(Object *obj) { - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); + PCIVPBState *s = PCI_VPB(obj); - sdc->init = pci_realview_init; + s->realview = 1; + /* The PCI window sizes are different on Realview boards */ + s->mem_win_size[0] = 0x01000000; + s->mem_win_size[1] = 0x04000000; + s->mem_win_size[2] = 0x08000000; } static const TypeInfo pci_realview_info = { .name = "realview_pci", - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(PCIVPBState), - .class_init = pci_realview_class_init, + .parent = TYPE_VERSATILE_PCI, + .instance_init = pci_realview_init, }; static void versatile_pci_register_types(void) diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c index 8e56b16648..f0c7ee9abd 100644 --- a/hw/ppc/ppc405_boards.c +++ b/hw/ppc/ppc405_boards.c @@ -337,7 +337,7 @@ static void ref405ep_init(QEMUMachineInitArgs *args) if (kernel_cmdline != NULL) { len = strlen(kernel_cmdline); bdloc -= ((len + 255) & ~255); - cpu_physical_memory_write(bdloc, (void *)kernel_cmdline, len + 1); + cpu_physical_memory_write(bdloc, kernel_cmdline, len + 1); env->gpr[6] = bdloc; env->gpr[7] = bdloc + len; } else { diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c index 6728ba7ea0..1b4ce760e6 100644 --- a/hw/ppc/virtex_ml507.c +++ b/hw/ppc/virtex_ml507.c @@ -161,7 +161,7 @@ static int xilinx_load_device_tree(hwaddr addr, r = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs", kernel_cmdline); if (r < 0) fprintf(stderr, "couldn't set /chosen/bootargs\n"); - cpu_physical_memory_write (addr, (void *)fdt, fdt_size); + cpu_physical_memory_write(addr, fdt, fdt_size); #else /* We lack libfdt so we cannot manipulate the fdt. Just pass on the blob to the kernel. */ diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index 31beb32885..635115f097 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -37,7 +37,6 @@ #include "hw/nvram/fw_cfg.h" #include "hw/char/escc.h" #include "hw/empty_slot.h" -#include "hw/qdev-addr.h" #include "hw/loader.h" #include "elf.h" #include "sysemu/blockdev.h" diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index c2c446eb9b..76e32ceef8 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -275,7 +275,7 @@ static void virtio_balloon_set_config(VirtIODevice *vdev, dev->actual = le32_to_cpu(config.actual); if (dev->actual != oldactual) { qemu_balloon_changed(ram_size - - (dev->actual << VIRTIO_BALLOON_PFN_SHIFT)); + ((ram_addr_t) dev->actual << VIRTIO_BALLOON_PFN_SHIFT)); } } |