diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/ac97.c | 88 | ||||
-rw-r--r-- | hw/apb_pci.c | 1 | ||||
-rw-r--r-- | hw/axis_dev88.c | 21 | ||||
-rw-r--r-- | hw/bonito.c | 1 | ||||
-rw-r--r-- | hw/cirrus_vga.c | 459 | ||||
-rw-r--r-- | hw/cris_pic_cpu.c | 1 | ||||
-rw-r--r-- | hw/cuda.c | 6 | ||||
-rw-r--r-- | hw/e1000.c | 113 | ||||
-rw-r--r-- | hw/eepro100.c | 181 | ||||
-rw-r--r-- | hw/es1370.c | 43 | ||||
-rw-r--r-- | hw/escc.c | 42 | ||||
-rw-r--r-- | hw/escc.h | 2 | ||||
-rw-r--r-- | hw/etraxfs.c | 159 | ||||
-rw-r--r-- | hw/etraxfs.h | 19 | ||||
-rw-r--r-- | hw/etraxfs_eth.c | 84 | ||||
-rw-r--r-- | hw/etraxfs_ser.c | 10 | ||||
-rw-r--r-- | hw/grackle_pci.c | 8 | ||||
-rw-r--r-- | hw/gt64xxx.c | 4 | ||||
-rw-r--r-- | hw/heathrow_pic.c | 29 | ||||
-rw-r--r-- | hw/hid.c | 76 | ||||
-rw-r--r-- | hw/hid.h | 1 | ||||
-rw-r--r-- | hw/hw.h | 20 | ||||
-rw-r--r-- | hw/ide.h | 2 | ||||
-rw-r--r-- | hw/ide/ahci.c | 31 | ||||
-rw-r--r-- | hw/ide/ahci.h | 2 | ||||
-rw-r--r-- | hw/ide/cmd646.c | 204 | ||||
-rw-r--r-- | hw/ide/ich.c | 3 | ||||
-rw-r--r-- | hw/ide/macio.c | 36 | ||||
-rw-r--r-- | hw/ide/pci.c | 25 | ||||
-rw-r--r-- | hw/ide/pci.h | 19 | ||||
-rw-r--r-- | hw/ide/piix.c | 63 | ||||
-rw-r--r-- | hw/ide/via.c | 64 | ||||
-rw-r--r-- | hw/intel-hda.c | 35 | ||||
-rw-r--r-- | hw/isa.h | 2 | ||||
-rw-r--r-- | hw/isa_mmio.c | 29 | ||||
-rw-r--r-- | hw/ivshmem.c | 158 | ||||
-rw-r--r-- | hw/kvmclock.c | 7 | ||||
-rw-r--r-- | hw/lance.c | 31 | ||||
-rw-r--r-- | hw/lsi53c895a.c | 257 | ||||
-rw-r--r-- | hw/mac_dbdma.c | 32 | ||||
-rw-r--r-- | hw/mac_dbdma.h | 4 | ||||
-rw-r--r-- | hw/mac_nvram.c | 39 | ||||
-rw-r--r-- | hw/macio.c | 73 | ||||
-rw-r--r-- | hw/milkymist-softusb.c | 122 | ||||
-rw-r--r-- | hw/msix.c | 64 | ||||
-rw-r--r-- | hw/msix.h | 6 | ||||
-rw-r--r-- | hw/ne2000-isa.c | 13 | ||||
-rw-r--r-- | hw/ne2000.c | 77 | ||||
-rw-r--r-- | hw/ne2000.h | 8 | ||||
-rw-r--r-- | hw/openpic.c | 81 | ||||
-rw-r--r-- | hw/openpic.h | 2 | ||||
-rw-r--r-- | hw/pc.h | 4 | ||||
-rw-r--r-- | hw/pc_piix.c | 6 | ||||
-rw-r--r-- | hw/pci.c | 133 | ||||
-rw-r--r-- | hw/pci.h | 26 | ||||
-rw-r--r-- | hw/pci_internals.h | 3 | ||||
-rw-r--r-- | hw/pcnet-pci.c | 74 | ||||
-rw-r--r-- | hw/pcnet.h | 4 | ||||
-rw-r--r-- | hw/piix_pci.c | 14 | ||||
-rw-r--r-- | hw/ppc4xx_pci.c | 1 | ||||
-rw-r--r-- | hw/ppc_mac.h | 27 | ||||
-rw-r--r-- | hw/ppc_newworld.c | 34 | ||||
-rw-r--r-- | hw/ppc_oldworld.c | 27 | ||||
-rw-r--r-- | hw/ppc_prep.c | 2 | ||||
-rw-r--r-- | hw/ppce500_pci.c | 7 | ||||
-rw-r--r-- | hw/prep_pci.c | 8 | ||||
-rw-r--r-- | hw/prep_pci.h | 4 | ||||
-rw-r--r-- | hw/qxl-render.c | 2 | ||||
-rw-r--r-- | hw/qxl.c | 142 | ||||
-rw-r--r-- | hw/qxl.h | 6 | ||||
-rw-r--r-- | hw/rtl8139.c | 70 | ||||
-rw-r--r-- | hw/sh_pci.c | 4 | ||||
-rw-r--r-- | hw/sun4u.c | 49 | ||||
-rw-r--r-- | hw/unin_pci.c | 16 | ||||
-rw-r--r-- | hw/usb-ehci.c | 36 | ||||
-rw-r--r-- | hw/usb-hid.c | 58 | ||||
-rw-r--r-- | hw/usb-ohci.c | 2 | ||||
-rw-r--r-- | hw/usb-uhci.c | 41 | ||||
-rw-r--r-- | hw/usb.h | 3 | ||||
-rw-r--r-- | hw/versatile_pci.c | 2 | ||||
-rw-r--r-- | hw/vga-isa-mm.c | 46 | ||||
-rw-r--r-- | hw/vga-isa.c | 10 | ||||
-rw-r--r-- | hw/vga-pci.c | 27 | ||||
-rw-r--r-- | hw/vga.c | 178 | ||||
-rw-r--r-- | hw/vga_int.h | 18 | ||||
-rw-r--r-- | hw/virtio-pci.c | 85 | ||||
-rw-r--r-- | hw/virtio-pci.h | 3 | ||||
-rw-r--r-- | hw/vmware_vga.c | 153 | ||||
-rw-r--r-- | hw/wdt_i6300esb.c | 43 | ||||
-rw-r--r-- | hw/xen_platform.c | 82 |
90 files changed, 1863 insertions, 2444 deletions
@@ -160,8 +160,9 @@ typedef struct AC97LinkState { SWVoiceIn *voice_mc; int invalid_freq[3]; uint8_t silence[128]; - uint32_t base[2]; int bup_flag; + MemoryRegion io_nam; + MemoryRegion io_nabm; } AC97LinkState; enum { @@ -583,7 +584,7 @@ static uint32_t nam_readw (void *opaque, uint32_t addr) { AC97LinkState *s = opaque; uint32_t val = ~0U; - uint32_t index = addr - s->base[0]; + uint32_t index = addr; s->cas = 0; val = mixer_load (s, index); return val; @@ -611,7 +612,7 @@ static void nam_writeb (void *opaque, uint32_t addr, uint32_t val) static void nam_writew (void *opaque, uint32_t addr, uint32_t val) { AC97LinkState *s = opaque; - uint32_t index = addr - s->base[0]; + uint32_t index = addr; s->cas = 0; switch (index) { case AC97_Reset: @@ -714,7 +715,7 @@ static uint32_t nabm_readb (void *opaque, uint32_t addr) { AC97LinkState *s = opaque; AC97BusMasterRegs *r = NULL; - uint32_t index = addr - s->base[1]; + uint32_t index = addr; uint32_t val = ~0U; switch (index) { @@ -769,7 +770,7 @@ static uint32_t nabm_readw (void *opaque, uint32_t addr) { AC97LinkState *s = opaque; AC97BusMasterRegs *r = NULL; - uint32_t index = addr - s->base[1]; + uint32_t index = addr; uint32_t val = ~0U; switch (index) { @@ -798,7 +799,7 @@ static uint32_t nabm_readl (void *opaque, uint32_t addr) { AC97LinkState *s = opaque; AC97BusMasterRegs *r = NULL; - uint32_t index = addr - s->base[1]; + uint32_t index = addr; uint32_t val = ~0U; switch (index) { @@ -848,7 +849,7 @@ static void nabm_writeb (void *opaque, uint32_t addr, uint32_t val) { AC97LinkState *s = opaque; AC97BusMasterRegs *r = NULL; - uint32_t index = addr - s->base[1]; + uint32_t index = addr; switch (index) { case PI_LVI: case PO_LVI: @@ -904,7 +905,7 @@ static void nabm_writew (void *opaque, uint32_t addr, uint32_t val) { AC97LinkState *s = opaque; AC97BusMasterRegs *r = NULL; - uint32_t index = addr - s->base[1]; + uint32_t index = addr; switch (index) { case PI_SR: case PO_SR: @@ -924,7 +925,7 @@ static void nabm_writel (void *opaque, uint32_t addr, uint32_t val) { AC97LinkState *s = opaque; AC97BusMasterRegs *r = NULL; - uint32_t index = addr - s->base[1]; + uint32_t index = addr; switch (index) { case PI_BDBAR: case PO_BDBAR: @@ -1230,31 +1231,33 @@ static const VMStateDescription vmstate_ac97 = { } }; -static void ac97_map (PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, pci_dev); - PCIDevice *d = &s->dev; - - if (!region_num) { - s->base[0] = addr; - register_ioport_read (addr, 256 * 1, 1, nam_readb, d); - register_ioport_read (addr, 256 * 2, 2, nam_readw, d); - register_ioport_read (addr, 256 * 4, 4, nam_readl, d); - register_ioport_write (addr, 256 * 1, 1, nam_writeb, d); - register_ioport_write (addr, 256 * 2, 2, nam_writew, d); - register_ioport_write (addr, 256 * 4, 4, nam_writel, d); - } - else { - s->base[1] = addr; - register_ioport_read (addr, 64 * 1, 1, nabm_readb, d); - register_ioport_read (addr, 64 * 2, 2, nabm_readw, d); - register_ioport_read (addr, 64 * 4, 4, nabm_readl, d); - register_ioport_write (addr, 64 * 1, 1, nabm_writeb, d); - register_ioport_write (addr, 64 * 2, 2, nabm_writew, d); - register_ioport_write (addr, 64 * 4, 4, nabm_writel, d); - } -} +static const MemoryRegionPortio nam_portio[] = { + { 0, 256 * 1, 1, .read = nam_readb, }, + { 0, 256 * 2, 2, .read = nam_readw, }, + { 0, 256 * 4, 4, .read = nam_readl, }, + { 0, 256 * 1, 1, .write = nam_writeb, }, + { 0, 256 * 2, 2, .write = nam_writew, }, + { 0, 256 * 4, 4, .write = nam_writel, }, + PORTIO_END_OF_LIST(), +}; + +static const MemoryRegionOps ac97_io_nam_ops = { + .old_portio = nam_portio, +}; + +static const MemoryRegionPortio nabm_portio[] = { + { 0, 64 * 1, 1, .read = nabm_readb, }, + { 0, 64 * 2, 2, .read = nabm_readw, }, + { 0, 64 * 4, 4, .read = nabm_readl, }, + { 0, 64 * 1, 1, .write = nabm_writeb, }, + { 0, 64 * 2, 2, .write = nabm_writew, }, + { 0, 64 * 4, 4, .write = nabm_writel, }, + PORTIO_END_OF_LIST() +}; + +static const MemoryRegionOps ac97_io_nabm_ops = { + .old_portio = nabm_portio, +}; static void ac97_on_reset (void *opaque) { @@ -1311,15 +1314,25 @@ static int ac97_initfn (PCIDevice *dev) /* TODO: RST# value should be 0. */ c[PCI_INTERRUPT_PIN] = 0x01; /* intr_pn interrupt pin ro */ - pci_register_bar (&s->dev, 0, 256 * 4, PCI_BASE_ADDRESS_SPACE_IO, - ac97_map); - pci_register_bar (&s->dev, 1, 64 * 4, PCI_BASE_ADDRESS_SPACE_IO, ac97_map); + memory_region_init_io (&s->io_nam, &ac97_io_nam_ops, s, "ac97-nam", 1024); + memory_region_init_io (&s->io_nabm, &ac97_io_nabm_ops, s, "ac97-nabm", 256); + pci_register_bar (&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nam); + pci_register_bar (&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nabm); qemu_register_reset (ac97_on_reset, s); AUD_register_card ("ac97", &s->card); ac97_on_reset (s); return 0; } +static int ac97_exitfn (PCIDevice *dev) +{ + AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, dev); + + memory_region_destroy (&s->io_nam); + memory_region_destroy (&s->io_nabm); + return 0; +} + int ac97_init (PCIBus *bus) { pci_create_simple (bus, -1, "AC97"); @@ -1332,6 +1345,7 @@ static PCIDeviceInfo ac97_info = { .qdev.size = sizeof (AC97LinkState), .qdev.vmsd = &vmstate_ac97, .init = ac97_initfn, + .exit = ac97_exitfn, .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = PCI_DEVICE_ID_INTEL_82801AA_5, .revision = 0x01, diff --git a/hw/apb_pci.c b/hw/apb_pci.c index 8b9939c06a..163822617b 100644 --- a/hw/apb_pci.c +++ b/hw/apb_pci.c @@ -348,6 +348,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, d->bus = pci_register_bus(&d->busdev.qdev, "pci", pci_apb_set_irq, pci_pbm_map_irq, d, get_system_memory(), + get_system_io(), 0, 32); pci_bus_set_mem_base(d->bus, mem_base); diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c index e0a8c14c12..d9002a5e2c 100644 --- a/hw/axis_dev88.c +++ b/hw/axis_dev88.c @@ -255,7 +255,7 @@ void axisdev88_init (ram_addr_t ram_size, DriveInfo *nand; qemu_irq irq[30], nmi[2], *cpu_irq; void *etraxfs_dmac; - struct etraxfs_dma_client *eth[2] = {NULL, NULL}; + struct etraxfs_dma_client *dma_eth; int i; int nand_regs; int gpio_regs; @@ -315,16 +315,18 @@ void axisdev88_init (ram_addr_t ram_size, } /* Add the two ethernet blocks. */ - eth[0] = etraxfs_eth_init(&nd_table[0], 0x30034000, 1); - if (nb_nics > 1) - eth[1] = etraxfs_eth_init(&nd_table[1], 0x30036000, 2); + dma_eth = qemu_mallocz(sizeof dma_eth[0] * 4); /* Allocate 4 channels. */ + etraxfs_eth_init(&nd_table[0], 0x30034000, 1, &dma_eth[0], &dma_eth[1]); + if (nb_nics > 1) { + etraxfs_eth_init(&nd_table[1], 0x30036000, 2, &dma_eth[2], &dma_eth[3]); + } /* The DMA Connector block is missing, hardwire things for now. */ - etraxfs_dmac_connect_client(etraxfs_dmac, 0, eth[0]); - etraxfs_dmac_connect_client(etraxfs_dmac, 1, eth[0] + 1); - if (eth[1]) { - etraxfs_dmac_connect_client(etraxfs_dmac, 6, eth[1]); - etraxfs_dmac_connect_client(etraxfs_dmac, 7, eth[1] + 1); + etraxfs_dmac_connect_client(etraxfs_dmac, 0, &dma_eth[0]); + etraxfs_dmac_connect_client(etraxfs_dmac, 1, &dma_eth[1]); + if (nb_nics > 1) { + etraxfs_dmac_connect_client(etraxfs_dmac, 6, &dma_eth[2]); + etraxfs_dmac_connect_client(etraxfs_dmac, 7, &dma_eth[3]); } /* 2 timers. */ @@ -350,6 +352,7 @@ static QEMUMachine axisdev88_machine = { .name = "axis-dev88", .desc = "AXIS devboard 88", .init = axisdev88_init, + .is_default = 1, }; static void axisdev88_machine_init(void) diff --git a/hw/bonito.c b/hw/bonito.c index 5f62dda6e2..8708e95688 100644 --- a/hw/bonito.c +++ b/hw/bonito.c @@ -775,6 +775,7 @@ PCIBus *bonito_init(qemu_irq *pic) pcihost = FROM_SYSBUS(BonitoState, sysbus_from_qdev(dev)); b = pci_register_bus(&pcihost->busdev.qdev, "pci", pci_bonito_set_irq, pci_bonito_map_irq, pic, get_system_memory(), + get_system_io(), 0x28, 32); pcihost->bus = b; qdev_init_nofail(dev); diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index f39d1f82ff..b48930994a 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -32,6 +32,7 @@ #include "console.h" #include "vga_int.h" #include "loader.h" +#include "exec-memory.h" /* * TODO: @@ -200,9 +201,14 @@ typedef void (*cirrus_fill_t)(struct CirrusVGAState *s, typedef struct CirrusVGAState { VGACommonState vga; - int cirrus_linear_io_addr; - int cirrus_linear_bitblt_io_addr; - int cirrus_mmio_io_addr; + MemoryRegion cirrus_linear_io; + MemoryRegion cirrus_linear_bitblt_io; + MemoryRegion cirrus_mmio_io; + MemoryRegion pci_bar; + bool linear_vram; /* vga.vram mapped over cirrus_linear_io */ + MemoryRegion low_mem_container; /* container for 0xa0000-0xc0000 */ + MemoryRegion low_mem; /* always mapped, overridden by: */ + MemoryRegion *cirrus_bank[2]; /* aliases at 0xa0000-0xb0000 */ uint32_t cirrus_addr_mask; uint32_t linear_mmio_mask; uint8_t cirrus_shadow_gr0; @@ -612,7 +618,7 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask; off_cur &= TARGET_PAGE_MASK; while (off_cur < off_cur_end) { - cpu_physical_memory_set_dirty(s->vga.vram_offset + off_cur); + memory_region_set_dirty(&s->vga.vram, off_cur); off_cur += TARGET_PAGE_SIZE; } off_begin += off_pitch; @@ -1177,12 +1183,6 @@ static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index) } if (limit > 0) { - /* Thinking about changing bank base? First, drop the dirty bitmap information - * on the current location, otherwise we lose this pointer forever */ - if (s->vga.lfb_vram_mapped) { - target_phys_addr_t base_addr = isa_mem_base + 0xa0000 + bank_index * 0x8000; - cpu_physical_sync_dirty_bitmap(base_addr, base_addr + 0x8000); - } s->cirrus_bank_base[bank_index] = offset; s->cirrus_bank_limit[bank_index] = limit; } else { @@ -1921,8 +1921,8 @@ static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s, val <<= 1; dst++; } - cpu_physical_memory_set_dirty(s->vga.vram_offset + offset); - cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 7); + memory_region_set_dirty(&s->vga.vram, offset); + memory_region_set_dirty(&s->vga.vram, offset + 7); } static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, @@ -1946,8 +1946,8 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, val <<= 1; dst += 2; } - cpu_physical_memory_set_dirty(s->vga.vram_offset + offset); - cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 15); + memory_region_set_dirty(&s->vga.vram, offset); + memory_region_set_dirty(&s->vga.vram, offset + 15); } /*************************************** @@ -1956,7 +1956,9 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, * ***************************************/ -static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr) +static uint64_t cirrus_vga_mem_read(void *opaque, + target_phys_addr_t addr, + uint32_t size) { CirrusVGAState *s = opaque; unsigned bank_index; @@ -1964,11 +1966,9 @@ static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr) uint32_t val; if ((s->vga.sr[0x07] & 0x01) == 0) { - return vga_mem_readb(s, addr); + return vga_mem_readb(&s->vga, addr); } - addr &= 0x1ffff; - if (addr < 0x10000) { /* XXX handle bitblt */ /* video memory */ @@ -2000,28 +2000,10 @@ static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr) return val; } -static uint32_t cirrus_vga_mem_readw(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - - v = cirrus_vga_mem_readb(opaque, addr); - v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8; - return v; -} - -static uint32_t cirrus_vga_mem_readl(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - - v = cirrus_vga_mem_readb(opaque, addr); - v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8; - v |= cirrus_vga_mem_readb(opaque, addr + 2) << 16; - v |= cirrus_vga_mem_readb(opaque, addr + 3) << 24; - return v; -} - -static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, - uint32_t mem_value) +static void cirrus_vga_mem_write(void *opaque, + target_phys_addr_t addr, + uint64_t mem_value, + uint32_t size) { CirrusVGAState *s = opaque; unsigned bank_index; @@ -2029,12 +2011,10 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, unsigned mode; if ((s->vga.sr[0x07] & 0x01) == 0) { - vga_mem_writeb(s, addr, mem_value); + vga_mem_writeb(&s->vga, addr, mem_value); return; } - addr &= 0x1ffff; - if (addr < 0x10000) { if (s->cirrus_srcptr != s->cirrus_srcptr_end) { /* bitblt */ @@ -2057,8 +2037,7 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, mode = s->vga.gr[0x05] & 0x7; if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) { *(s->vga.vram_ptr + bank_offset) = mem_value; - cpu_physical_memory_set_dirty(s->vga.vram_offset + - bank_offset); + memory_region_set_dirty(&s->vga.vram, bank_offset); } else { if ((s->vga.gr[0x0B] & 0x14) != 0x14) { cirrus_mem_writeb_mode4and5_8bpp(s, mode, @@ -2085,30 +2064,14 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, } } -static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - cirrus_vga_mem_writeb(opaque, addr, val & 0xff); - cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - cirrus_vga_mem_writeb(opaque, addr, val & 0xff); - cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff); - cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff); - cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff); -} - -static CPUReadMemoryFunc * const cirrus_vga_mem_read[3] = { - cirrus_vga_mem_readb, - cirrus_vga_mem_readw, - cirrus_vga_mem_readl, -}; - -static CPUWriteMemoryFunc * const cirrus_vga_mem_write[3] = { - cirrus_vga_mem_writeb, - cirrus_vga_mem_writew, - cirrus_vga_mem_writel, +static const MemoryRegionOps cirrus_vga_mem_ops = { + .read = cirrus_vga_mem_read, + .write = cirrus_vga_mem_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, }; /*************************************** @@ -2287,7 +2250,8 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y) * ***************************************/ -static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr) +static uint64_t cirrus_linear_read(void *opaque, target_phys_addr_t addr, + unsigned size) { CirrusVGAState *s = opaque; uint32_t ret; @@ -2315,28 +2279,8 @@ static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr) return ret; } -static uint32_t cirrus_linear_readw(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - - v = cirrus_linear_readb(opaque, addr); - v |= cirrus_linear_readb(opaque, addr + 1) << 8; - return v; -} - -static uint32_t cirrus_linear_readl(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - - v = cirrus_linear_readb(opaque, addr); - v |= cirrus_linear_readb(opaque, addr + 1) << 8; - v |= cirrus_linear_readb(opaque, addr + 2) << 16; - v |= cirrus_linear_readb(opaque, addr + 3) << 24; - return v; -} - -static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr, - uint32_t val) +static void cirrus_linear_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { CirrusVGAState *s = opaque; unsigned mode; @@ -2365,7 +2309,7 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr, mode = s->vga.gr[0x05] & 0x7; if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) { *(s->vga.vram_ptr + addr) = (uint8_t) val; - cpu_physical_memory_set_dirty(s->vga.vram_offset + addr); + memory_region_set_dirty(&s->vga.vram, addr); } else { if ((s->vga.gr[0x0B] & 0x14) != 0x14) { cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val); @@ -2376,35 +2320,6 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr, } } -static void cirrus_linear_writew(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - cirrus_linear_writeb(opaque, addr, val & 0xff); - cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - cirrus_linear_writeb(opaque, addr, val & 0xff); - cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff); - cirrus_linear_writeb(opaque, addr + 2, (val >> 16) & 0xff); - cirrus_linear_writeb(opaque, addr + 3, (val >> 24) & 0xff); -} - - -static CPUReadMemoryFunc * const cirrus_linear_read[3] = { - cirrus_linear_readb, - cirrus_linear_readw, - cirrus_linear_readl, -}; - -static CPUWriteMemoryFunc * const cirrus_linear_write[3] = { - cirrus_linear_writeb, - cirrus_linear_writew, - cirrus_linear_writel, -}; - /*************************************** * * system to screen memory access @@ -2412,37 +2327,23 @@ static CPUWriteMemoryFunc * const cirrus_linear_write[3] = { ***************************************/ -static uint32_t cirrus_linear_bitblt_readb(void *opaque, target_phys_addr_t addr) +static uint64_t cirrus_linear_bitblt_read(void *opaque, + target_phys_addr_t addr, + unsigned size) { + CirrusVGAState *s = opaque; uint32_t ret; /* XXX handle bitblt */ + (void)s; ret = 0xff; return ret; } -static uint32_t cirrus_linear_bitblt_readw(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - - v = cirrus_linear_bitblt_readb(opaque, addr); - v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8; - return v; -} - -static uint32_t cirrus_linear_bitblt_readl(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - - v = cirrus_linear_bitblt_readb(opaque, addr); - v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8; - v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 16; - v |= cirrus_linear_bitblt_readb(opaque, addr + 3) << 24; - return v; -} - -static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr, - uint32_t val) +static void cirrus_linear_bitblt_write(void *opaque, + target_phys_addr_t addr, + uint64_t val, + unsigned size) { CirrusVGAState *s = opaque; @@ -2455,83 +2356,70 @@ static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr, } } -static void cirrus_linear_bitblt_writew(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff); - cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff); - cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff); - cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 16) & 0xff); - cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff); -} - - -static CPUReadMemoryFunc * const cirrus_linear_bitblt_read[3] = { - cirrus_linear_bitblt_readb, - cirrus_linear_bitblt_readw, - cirrus_linear_bitblt_readl, -}; - -static CPUWriteMemoryFunc * const cirrus_linear_bitblt_write[3] = { - cirrus_linear_bitblt_writeb, - cirrus_linear_bitblt_writew, - cirrus_linear_bitblt_writel, +static const MemoryRegionOps cirrus_linear_bitblt_io_ops = { + .read = cirrus_linear_bitblt_read, + .write = cirrus_linear_bitblt_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, }; -static void map_linear_vram(CirrusVGAState *s) +static void unmap_bank(CirrusVGAState *s, unsigned bank) { - if (!s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) { - s->vga.map_addr = s->vga.lfb_addr; - s->vga.map_end = s->vga.lfb_end; - cpu_register_physical_memory_log(s->vga.map_addr, - s->vga.map_end - s->vga.map_addr, - s->vga.vram_offset, 0, true); + if (s->cirrus_bank[bank]) { + memory_region_del_subregion(&s->low_mem_container, + s->cirrus_bank[bank]); + memory_region_destroy(s->cirrus_bank[bank]); + qemu_free(s->cirrus_bank[bank]); + s->cirrus_bank[bank] = NULL; } +} - if (!s->vga.map_addr) - return; - - s->vga.lfb_vram_mapped = 0; +static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank) +{ + MemoryRegion *mr; + static const char *names[] = { "vga.bank0", "vga.bank1" }; if (!(s->cirrus_srcptr != s->cirrus_srcptr_end) && !((s->vga.sr[0x07] & 0x01) == 0) && !((s->vga.gr[0x0B] & 0x14) == 0x14) && !(s->vga.gr[0x0B] & 0x02)) { - cpu_register_physical_memory_log(isa_mem_base + 0xa0000, 0x8000, - (s->vga.vram_offset + - s->cirrus_bank_base[0]) | - IO_MEM_RAM, 0, true); - cpu_register_physical_memory_log(isa_mem_base + 0xa8000, 0x8000, - (s->vga.vram_offset + - s->cirrus_bank_base[1]) | - IO_MEM_RAM, 0, true); - - s->vga.lfb_vram_mapped = 1; - } - else { - cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000, - s->vga.vga_io_memory); + mr = qemu_malloc(sizeof(*mr)); + memory_region_init_alias(mr, names[bank], &s->vga.vram, + s->cirrus_bank_base[bank], 0x8000); + memory_region_add_subregion_overlap( + &s->low_mem_container, + 0x8000 * bank, + mr, + 1); + unmap_bank(s, bank); + s->cirrus_bank[bank] = mr; + } else { + unmap_bank(s, bank); } +} - vga_dirty_log_start(&s->vga); +static void map_linear_vram(CirrusVGAState *s) +{ + if (!s->linear_vram) { + s->linear_vram = true; + memory_region_add_subregion_overlap(&s->pci_bar, 0, &s->vga.vram, 1); + } + map_linear_vram_bank(s, 0); + map_linear_vram_bank(s, 1); } static void unmap_linear_vram(CirrusVGAState *s) { - if (s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) { - s->vga.map_addr = s->vga.map_end = 0; - cpu_register_physical_memory(s->vga.lfb_addr, s->vga.vram_size, - s->cirrus_linear_io_addr); + if (s->linear_vram) { + s->linear_vram = false; + memory_region_del_subregion(&s->pci_bar, &s->vga.vram); } - cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000, - s->vga.vga_io_memory); + unmap_bank(s, 0); + unmap_bank(s, 1); } /* Compute the memory access functions */ @@ -2765,12 +2653,11 @@ static void cirrus_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) * ***************************************/ -static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr) +static uint64_t cirrus_mmio_read(void *opaque, target_phys_addr_t addr, + unsigned size) { CirrusVGAState *s = opaque; - addr &= CIRRUS_PNPMMIO_SIZE - 1; - if (addr >= 0x100) { return cirrus_mmio_blt_read(s, addr - 0x100); } else { @@ -2778,33 +2665,11 @@ static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr) } } -static uint32_t cirrus_mmio_readw(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - - v = cirrus_mmio_readb(opaque, addr); - v |= cirrus_mmio_readb(opaque, addr + 1) << 8; - return v; -} - -static uint32_t cirrus_mmio_readl(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - - v = cirrus_mmio_readb(opaque, addr); - v |= cirrus_mmio_readb(opaque, addr + 1) << 8; - v |= cirrus_mmio_readb(opaque, addr + 2) << 16; - v |= cirrus_mmio_readb(opaque, addr + 3) << 24; - return v; -} - -static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr, - uint32_t val) +static void cirrus_mmio_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { CirrusVGAState *s = opaque; - addr &= CIRRUS_PNPMMIO_SIZE - 1; - if (addr >= 0x100) { cirrus_mmio_blt_write(s, addr - 0x100, val); } else { @@ -2812,33 +2677,14 @@ static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr, } } -static void cirrus_mmio_writew(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - cirrus_mmio_writeb(opaque, addr, val & 0xff); - cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - cirrus_mmio_writeb(opaque, addr, val & 0xff); - cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff); - cirrus_mmio_writeb(opaque, addr + 2, (val >> 16) & 0xff); - cirrus_mmio_writeb(opaque, addr + 3, (val >> 24) & 0xff); -} - - -static CPUReadMemoryFunc * const cirrus_mmio_read[3] = { - cirrus_mmio_readb, - cirrus_mmio_readw, - cirrus_mmio_readl, -}; - -static CPUWriteMemoryFunc * const cirrus_mmio_write[3] = { - cirrus_mmio_writeb, - cirrus_mmio_writew, - cirrus_mmio_writel, +static const MemoryRegionOps cirrus_mmio_io_ops = { + .read = cirrus_mmio_read, + .write = cirrus_mmio_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, }; /* load/save state */ @@ -2947,6 +2793,16 @@ static void cirrus_reset(void *opaque) s->cirrus_hidden_dac_data = 0; } +static const MemoryRegionOps cirrus_linear_io_ops = { + .read = cirrus_linear_read, + .write = cirrus_linear_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; + static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci) { int i; @@ -2993,28 +2849,33 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci) register_ioport_read(0x3ba, 1, 1, cirrus_vga_ioport_read, s); register_ioport_read(0x3da, 1, 1, cirrus_vga_ioport_read, s); - s->vga.vga_io_memory = cpu_register_io_memory(cirrus_vga_mem_read, - cirrus_vga_mem_write, s, - DEVICE_LITTLE_ENDIAN); - cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000, - s->vga.vga_io_memory); - qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000); + memory_region_init(&s->low_mem_container, + "cirrus-lowmem-container", + 0x20000); + + memory_region_init_io(&s->low_mem, &cirrus_vga_mem_ops, s, + "cirrus-low-memory", 0x20000); + memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem); + memory_region_add_subregion_overlap(get_system_memory(), + isa_mem_base + 0x000a0000, + &s->low_mem_container, + 1); + memory_region_set_coalescing(&s->low_mem); /* I/O handler for LFB */ - s->cirrus_linear_io_addr = - cpu_register_io_memory(cirrus_linear_read, cirrus_linear_write, s, - DEVICE_LITTLE_ENDIAN); + memory_region_init_io(&s->cirrus_linear_io, &cirrus_linear_io_ops, s, + "cirrus-linear-io", VGA_RAM_SIZE); /* I/O handler for LFB */ - s->cirrus_linear_bitblt_io_addr = - cpu_register_io_memory(cirrus_linear_bitblt_read, - cirrus_linear_bitblt_write, s, - DEVICE_LITTLE_ENDIAN); + memory_region_init_io(&s->cirrus_linear_bitblt_io, + &cirrus_linear_bitblt_io_ops, + s, + "cirrus-bitblt-mmio", + 0x400000); /* I/O handler for memory-mapped I/O */ - s->cirrus_mmio_io_addr = - cpu_register_io_memory(cirrus_mmio_read, cirrus_mmio_write, s, - DEVICE_LITTLE_ENDIAN); + memory_region_init_io(&s->cirrus_mmio_io, &cirrus_mmio_io_ops, s, + "cirrus-mmio", CIRRUS_PNPMMIO_SIZE); s->real_vram_size = (s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024; @@ -3060,42 +2921,6 @@ void isa_cirrus_vga_init(void) * ***************************************/ -static void cirrus_pci_lfb_map(PCIDevice *d, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - CirrusVGAState *s = &DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga; - - /* XXX: add byte swapping apertures */ - cpu_register_physical_memory(addr, s->vga.vram_size, - s->cirrus_linear_io_addr); - cpu_register_physical_memory(addr + 0x1000000, 0x400000, - s->cirrus_linear_bitblt_io_addr); - - s->vga.map_addr = s->vga.map_end = 0; - s->vga.lfb_addr = addr & TARGET_PAGE_MASK; - s->vga.lfb_end = ((addr + VGA_RAM_SIZE) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; - /* account for overflow */ - if (s->vga.lfb_end < addr + VGA_RAM_SIZE) - s->vga.lfb_end = addr + VGA_RAM_SIZE; - - vga_dirty_log_start(&s->vga); -} - -static void pci_cirrus_write_config(PCIDevice *d, - uint32_t address, uint32_t val, int len) -{ - PCICirrusVGAState *pvs = DO_UPCAST(PCICirrusVGAState, dev, d); - CirrusVGAState *s = &pvs->cirrus_vga; - - pci_default_write_config(d, address, val, len); - if (s->vga.map_addr && d->io_regions[0].addr == PCI_BAR_UNMAPPED) { - s->vga.map_addr = 0; - s->vga.lfb_addr = 0; - s->vga.lfb_end = 0; - } - cirrus_update_memory_access(s); -} - static int pci_cirrus_vga_initfn(PCIDevice *dev) { PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev); @@ -3112,15 +2937,20 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev) /* setup PCI */ + memory_region_init(&s->pci_bar, "cirrus-pci-bar0", 0x2000000); + + /* XXX: add byte swapping apertures */ + memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io); + memory_region_add_subregion(&s->pci_bar, 0x1000000, + &s->cirrus_linear_bitblt_io); + /* setup memory space */ /* memory #0 LFB */ /* memory #1 memory-mapped I/O */ /* XXX: s->vga.vram_size must be a power of two */ - pci_register_bar(&d->dev, 0, 0x2000000, - PCI_BASE_ADDRESS_MEM_PREFETCH, cirrus_pci_lfb_map); + pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->pci_bar); if (device_id == CIRRUS_ID_CLGD5446) { - pci_register_bar_simple(&d->dev, 1, CIRRUS_PNPMMIO_SIZE, 0, - s->cirrus_mmio_io_addr); + pci_register_bar(&d->dev, 1, 0, &s->cirrus_mmio_io); } return 0; } @@ -3138,7 +2968,6 @@ static PCIDeviceInfo cirrus_vga_info = { .no_hotplug = 1, .init = pci_cirrus_vga_initfn, .romfile = VGABIOS_CIRRUS_FILENAME, - .config_write = pci_cirrus_write_config, .vendor_id = PCI_VENDOR_ID_CIRRUS, .device_id = CIRRUS_ID_CLGD5446, .class_id = PCI_CLASS_DISPLAY_VGA, diff --git a/hw/cris_pic_cpu.c b/hw/cris_pic_cpu.c index a92d445f29..7f1e4ab855 100644 --- a/hw/cris_pic_cpu.c +++ b/hw/cris_pic_cpu.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ +#include "sysbus.h" #include "hw.h" #include "pc.h" #include "etraxfs.h" @@ -117,6 +117,7 @@ typedef struct CUDATimer { } CUDATimer; typedef struct CUDAState { + MemoryRegion mem; /* cuda registers */ uint8_t b; /* B-side data */ uint8_t a; /* A-side data */ @@ -722,7 +723,7 @@ static void cuda_reset(void *opaque) set_counter(s, &s->timers[1], 0xffff); } -void cuda_init (int *cuda_mem_index, qemu_irq irq) +void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq) { struct tm tm; CUDAState *s = &cuda_state; @@ -738,8 +739,9 @@ void cuda_init (int *cuda_mem_index, qemu_irq irq) s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET; s->adb_poll_timer = qemu_new_timer_ns(vm_clock, cuda_adb_poll, s); - *cuda_mem_index = cpu_register_io_memory(cuda_read, cuda_write, s, + cpu_register_io_memory(cuda_read, cuda_write, s, DEVICE_NATIVE_ENDIAN); + *cuda_mem = &s->mem; vmstate_register(NULL, -1, &vmstate_cuda, s); qemu_register_reset(cuda_reset, s); } diff --git a/hw/e1000.c b/hw/e1000.c index 96d84f91ae..29b453f7b1 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -82,7 +82,8 @@ typedef struct E1000State_st { PCIDevice dev; NICState *nic; NICConf conf; - int mmio_index; + MemoryRegion mmio; + MemoryRegion io; uint32_t mac_reg[0x8000]; uint16_t phy_reg[0x20]; @@ -151,14 +152,6 @@ static const char phy_regcap[0x20] = { }; static void -ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, - pcibus_t size, int type) -{ - DBGOUT(IO, "e1000_ioport_map addr=0x%04"FMT_PCIBUS - " size=0x%08"FMT_PCIBUS"\n", addr, size); -} - -static void set_interrupt_cause(E1000State *s, int index, uint32_t val) { if (val) @@ -905,7 +898,8 @@ static void (*macreg_writeops[])(E1000State *, int, uint32_t) = { enum { NWRITEOPS = ARRAY_SIZE(macreg_writeops) }; static void -e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val) +e1000_mmio_write(void *opaque, target_phys_addr_t addr, uint64_t val, + unsigned size) { E1000State *s = opaque; unsigned int index = (addr & 0x1ffff) >> 2; @@ -913,31 +907,15 @@ e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val) if (index < NWRITEOPS && macreg_writeops[index]) { macreg_writeops[index](s, index, val); } else if (index < NREADOPS && macreg_readops[index]) { - DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04x\n", index<<2, val); + DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04"PRIx64"\n", index<<2, val); } else { - DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08x\n", + DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08"PRIx64"\n", index<<2, val); } } -static void -e1000_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - // emulate hw without byte enables: no RMW - e1000_mmio_writel(opaque, addr & ~3, - (val & 0xffff) << (8*(addr & 3))); -} - -static void -e1000_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - // emulate hw without byte enables: no RMW - e1000_mmio_writel(opaque, addr & ~3, - (val & 0xff) << (8*(addr & 3))); -} - -static uint32_t -e1000_mmio_readl(void *opaque, target_phys_addr_t addr) +static uint64_t +e1000_mmio_read(void *opaque, target_phys_addr_t addr, unsigned size) { E1000State *s = opaque; unsigned int index = (addr & 0x1ffff) >> 2; @@ -950,20 +928,39 @@ e1000_mmio_readl(void *opaque, target_phys_addr_t addr) return 0; } -static uint32_t -e1000_mmio_readb(void *opaque, target_phys_addr_t addr) +static const MemoryRegionOps e1000_mmio_ops = { + .read = e1000_mmio_read, + .write = e1000_mmio_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + +static uint64_t e1000_io_read(void *opaque, target_phys_addr_t addr, + unsigned size) { - return ((e1000_mmio_readl(opaque, addr & ~3)) >> - (8 * (addr & 3))) & 0xff; + E1000State *s = opaque; + + (void)s; + return 0; } -static uint32_t -e1000_mmio_readw(void *opaque, target_phys_addr_t addr) +static void e1000_io_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { - return ((e1000_mmio_readl(opaque, addr & ~3)) >> - (8 * (addr & 3))) & 0xffff; + E1000State *s = opaque; + + (void)s; } +static const MemoryRegionOps e1000_io_ops = { + .read = e1000_io_read, + .write = e1000_io_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + static bool is_version_1(void *opaque, int version_id) { return version_id == 1; @@ -1083,36 +1080,22 @@ static const uint32_t mac_reg_init[] = { /* PCI interface */ -static CPUWriteMemoryFunc * const e1000_mmio_write[] = { - e1000_mmio_writeb, e1000_mmio_writew, e1000_mmio_writel -}; - -static CPUReadMemoryFunc * const e1000_mmio_read[] = { - e1000_mmio_readb, e1000_mmio_readw, e1000_mmio_readl -}; - static void -e1000_mmio_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +e1000_mmio_setup(E1000State *d) { - E1000State *d = DO_UPCAST(E1000State, dev, pci_dev); int i; const uint32_t excluded_regs[] = { E1000_MDIC, E1000_ICR, E1000_ICS, E1000_IMS, E1000_IMC, E1000_TCTL, E1000_TDT, PNPMMIO_SIZE }; - - DBGOUT(MMIO, "e1000_mmio_map addr=0x%08"FMT_PCIBUS" 0x%08"FMT_PCIBUS"\n", - addr, size); - - cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index); - qemu_register_coalesced_mmio(addr, excluded_regs[0]); - + memory_region_init_io(&d->mmio, &e1000_mmio_ops, d, "e1000-mmio", + PNPMMIO_SIZE); + memory_region_add_coalescing(&d->mmio, 0, excluded_regs[0]); for (i = 0; excluded_regs[i] != PNPMMIO_SIZE; i++) - qemu_register_coalesced_mmio(addr + excluded_regs[i] + 4, - excluded_regs[i + 1] - - excluded_regs[i] - 4); + memory_region_add_coalescing(&d->mmio, excluded_regs[i] + 4, + excluded_regs[i+1] - excluded_regs[i] - 4); + memory_region_init_io(&d->io, &e1000_io_ops, d, "e1000-io", IOPORT_SIZE); } static void @@ -1128,7 +1111,8 @@ pci_e1000_uninit(PCIDevice *dev) { E1000State *d = DO_UPCAST(E1000State, dev, dev); - cpu_unregister_io_memory(d->mmio_index); + memory_region_destroy(&d->mmio); + memory_region_destroy(&d->io); qemu_del_vlan_client(&d->nic->nc); return 0; } @@ -1172,14 +1156,11 @@ static int pci_e1000_init(PCIDevice *pci_dev) /* TODO: RST# value should be 0 if programmable, PCI spec 6.2.4 */ pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0 - d->mmio_index = cpu_register_io_memory(e1000_mmio_read, - e1000_mmio_write, d, DEVICE_LITTLE_ENDIAN); + e1000_mmio_setup(d); - pci_register_bar(&d->dev, 0, PNPMMIO_SIZE, - PCI_BASE_ADDRESS_SPACE_MEMORY, e1000_mmio_map); + pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio); - pci_register_bar(&d->dev, 1, IOPORT_SIZE, - PCI_BASE_ADDRESS_SPACE_IO, ioport_map); + pci_register_bar(&d->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->io); memmove(d->eeprom_data, e1000_eeprom_template, sizeof e1000_eeprom_template); diff --git a/hw/eepro100.c b/hw/eepro100.c index 9b6f4a5cd8..a636d309be 100644 --- a/hw/eepro100.c +++ b/hw/eepro100.c @@ -228,13 +228,14 @@ typedef struct { PCIDevice dev; /* Hash register (multicast mask array, multiple individual addresses). */ uint8_t mult[8]; - int mmio_index; + MemoryRegion mmio_bar; + MemoryRegion io_bar; + MemoryRegion flash_bar; NICState *nic; NICConf conf; uint8_t scb_stat; /* SCB stat/ack byte */ uint8_t int_stat; /* PCI interrupt status */ /* region must not be saved by nic_save. */ - uint32_t region1; /* PCI region 1 address */ uint16_t mdimem[32]; eeprom_t *eeprom; uint32_t device; /* device variant */ @@ -1584,147 +1585,36 @@ static void eepro100_write4(EEPRO100State * s, uint32_t addr, uint32_t val) } } -/***************************************************************************** - * - * Port mapped I/O. - * - ****************************************************************************/ - -static uint32_t ioport_read1(void *opaque, uint32_t addr) -{ - EEPRO100State *s = opaque; -#if 0 - logout("addr=%s\n", regname(addr)); -#endif - return eepro100_read1(s, addr - s->region1); -} - -static uint32_t ioport_read2(void *opaque, uint32_t addr) -{ - EEPRO100State *s = opaque; - return eepro100_read2(s, addr - s->region1); -} - -static uint32_t ioport_read4(void *opaque, uint32_t addr) -{ - EEPRO100State *s = opaque; - return eepro100_read4(s, addr - s->region1); -} - -static void ioport_write1(void *opaque, uint32_t addr, uint32_t val) -{ - EEPRO100State *s = opaque; -#if 0 - logout("addr=%s val=0x%02x\n", regname(addr), val); -#endif - eepro100_write1(s, addr - s->region1, val); -} - -static void ioport_write2(void *opaque, uint32_t addr, uint32_t val) -{ - EEPRO100State *s = opaque; - eepro100_write2(s, addr - s->region1, val); -} - -static void ioport_write4(void *opaque, uint32_t addr, uint32_t val) -{ - EEPRO100State *s = opaque; - eepro100_write4(s, addr - s->region1, val); -} - -/***********************************************************/ -/* PCI EEPRO100 definitions */ - -static void pci_map(PCIDevice * pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); - - TRACE(OTHER, logout("region %d, addr=0x%08"FMT_PCIBUS", " - "size=0x%08"FMT_PCIBUS", type=%d\n", - region_num, addr, size, type)); - - assert(region_num == 1); - register_ioport_write(addr, size, 1, ioport_write1, s); - register_ioport_read(addr, size, 1, ioport_read1, s); - register_ioport_write(addr, size, 2, ioport_write2, s); - register_ioport_read(addr, size, 2, ioport_read2, s); - register_ioport_write(addr, size, 4, ioport_write4, s); - register_ioport_read(addr, size, 4, ioport_read4, s); - - s->region1 = addr; -} - -/***************************************************************************** - * - * Memory mapped I/O. - * - ****************************************************************************/ - -static void pci_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - EEPRO100State *s = opaque; -#if 0 - logout("addr=%s val=0x%02x\n", regname(addr), val); -#endif - eepro100_write1(s, addr, val); -} - -static void pci_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val) +static uint64_t eepro100_read(void *opaque, target_phys_addr_t addr, + unsigned size) { EEPRO100State *s = opaque; -#if 0 - logout("addr=%s val=0x%02x\n", regname(addr), val); -#endif - eepro100_write2(s, addr, val); -} -static void pci_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - EEPRO100State *s = opaque; -#if 0 - logout("addr=%s val=0x%02x\n", regname(addr), val); -#endif - eepro100_write4(s, addr, val); -} - -static uint32_t pci_mmio_readb(void *opaque, target_phys_addr_t addr) -{ - EEPRO100State *s = opaque; -#if 0 - logout("addr=%s\n", regname(addr)); -#endif - return eepro100_read1(s, addr); + switch (size) { + case 1: return eepro100_read1(s, addr); + case 2: return eepro100_read2(s, addr); + case 4: return eepro100_read4(s, addr); + default: abort(); + } } -static uint32_t pci_mmio_readw(void *opaque, target_phys_addr_t addr) +static void eepro100_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) { EEPRO100State *s = opaque; -#if 0 - logout("addr=%s\n", regname(addr)); -#endif - return eepro100_read2(s, addr); -} -static uint32_t pci_mmio_readl(void *opaque, target_phys_addr_t addr) -{ - EEPRO100State *s = opaque; -#if 0 - logout("addr=%s\n", regname(addr)); -#endif - return eepro100_read4(s, addr); + switch (size) { + case 1: return eepro100_write1(s, addr, data); + case 2: return eepro100_write2(s, addr, data); + case 4: return eepro100_write4(s, addr, data); + default: abort(); + } } -static CPUWriteMemoryFunc * const pci_mmio_write[] = { - pci_mmio_writeb, - pci_mmio_writew, - pci_mmio_writel -}; - -static CPUReadMemoryFunc * const pci_mmio_read[] = { - pci_mmio_readb, - pci_mmio_readw, - pci_mmio_readl +static const MemoryRegionOps eepro100_ops = { + .read = eepro100_read, + .write = eepro100_write, + .endianness = DEVICE_LITTLE_ENDIAN, }; static int nic_can_receive(VLANClientState *nc) @@ -1953,7 +1843,9 @@ static int pci_nic_uninit(PCIDevice *pci_dev) { EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); - cpu_unregister_io_memory(s->mmio_index); + memory_region_destroy(&s->mmio_bar); + memory_region_destroy(&s->io_bar); + memory_region_destroy(&s->flash_bar); vmstate_unregister(&pci_dev->qdev, s->vmstate, s); eeprom93xx_free(&pci_dev->qdev, s->eeprom); qemu_del_vlan_client(&s->nic->nc); @@ -1985,20 +1877,19 @@ static int e100_nic_init(PCIDevice *pci_dev) s->eeprom = eeprom93xx_new(&pci_dev->qdev, EEPROM_SIZE); /* Handler for memory-mapped I/O */ - s->mmio_index = - cpu_register_io_memory(pci_mmio_read, pci_mmio_write, s, - DEVICE_LITTLE_ENDIAN); - - pci_register_bar_simple(&s->dev, 0, PCI_MEM_SIZE, - PCI_BASE_ADDRESS_MEM_PREFETCH, s->mmio_index); - - pci_register_bar(&s->dev, 1, PCI_IO_SIZE, PCI_BASE_ADDRESS_SPACE_IO, - pci_map); - pci_register_bar_simple(&s->dev, 2, PCI_FLASH_SIZE, 0, s->mmio_index); + memory_region_init_io(&s->mmio_bar, &eepro100_ops, s, "eepro100-mmio", + PCI_MEM_SIZE); + pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->mmio_bar); + memory_region_init_io(&s->io_bar, &eepro100_ops, s, "eepro100-io", + PCI_IO_SIZE); + pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar); + /* FIXME: flash aliases to mmio?! */ + memory_region_init_io(&s->flash_bar, &eepro100_ops, s, "eepro100-flash", + PCI_FLASH_SIZE); + pci_register_bar(&s->dev, 2, 0, &s->flash_bar); qemu_macaddr_default_if_unset(&s->conf.macaddr); logout("macaddr: %s\n", nic_dump(&s->conf.macaddr.a[0], 6)); - assert(s->region1 == 0); nic_reset(s); diff --git a/hw/es1370.c b/hw/es1370.c index 1ed62b7da3..a9387d15cc 100644 --- a/hw/es1370.c +++ b/hw/es1370.c @@ -268,6 +268,7 @@ struct chan { typedef struct ES1370State { PCIDevice dev; QEMUSoundCard card; + MemoryRegion io; struct chan chan[NB_CHANNELS]; SWVoiceOut *dac_voice[2]; SWVoiceIn *adc_voice; @@ -775,7 +776,6 @@ IO_READ_PROTO (es1370_readl) return val; } - static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, int max, int *irq) { @@ -906,23 +906,20 @@ static void es1370_adc_callback (void *opaque, int avail) es1370_run_channel (s, ADC_CHANNEL, avail); } -static void es1370_map (PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - ES1370State *s = DO_UPCAST (ES1370State, dev, pci_dev); - - (void) region_num; - (void) size; - (void) type; - - register_ioport_write (addr, 0x40 * 4, 1, es1370_writeb, s); - register_ioport_write (addr, 0x40 * 2, 2, es1370_writew, s); - register_ioport_write (addr, 0x40, 4, es1370_writel, s); +static const MemoryRegionPortio es1370_portio[] = { + { 0, 0x40 * 4, 1, .write = es1370_writeb, }, + { 0, 0x40 * 2, 2, .write = es1370_writew, }, + { 0, 0x40, 4, .write = es1370_writel, }, + { 0, 0x40 * 4, 1, .read = es1370_readb, }, + { 0, 0x40 * 2, 2, .read = es1370_readw, }, + { 0, 0x40, 4, .read = es1370_readl, }, + PORTIO_END_OF_LIST() +}; - register_ioport_read (addr, 0x40 * 4, 1, es1370_readb, s); - register_ioport_read (addr, 0x40 * 2, 2, es1370_readw, s); - register_ioport_read (addr, 0x40, 4, es1370_readl, s); -} +static const MemoryRegionOps es1370_io_ops = { + .old_portio = es1370_portio, + .endianness = DEVICE_LITTLE_ENDIAN, +}; static const VMStateDescription vmstate_es1370_channel = { .name = "es1370_channel", @@ -1011,7 +1008,8 @@ static int es1370_initfn (PCIDevice *dev) c[PCI_MIN_GNT] = 0x0c; c[PCI_MAX_LAT] = 0x80; - pci_register_bar (&s->dev, 0, 256, PCI_BASE_ADDRESS_SPACE_IO, es1370_map); + memory_region_init_io (&s->io, &es1370_io_ops, s, "es1370", 256); + pci_register_bar (&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io); qemu_register_reset (es1370_on_reset, s); AUD_register_card ("es1370", &s->card); @@ -1019,6 +1017,14 @@ static int es1370_initfn (PCIDevice *dev) return 0; } +static int es1370_exitfn(PCIDevice *dev) +{ + ES1370State *s = DO_UPCAST (ES1370State, dev, dev); + + memory_region_destroy (&s->io); + return 0; +} + int es1370_init (PCIBus *bus) { pci_create_simple (bus, -1, "ES1370"); @@ -1031,6 +1037,7 @@ static PCIDeviceInfo es1370_info = { .qdev.size = sizeof (ES1370State), .qdev.vmsd = &vmstate_es1370, .init = es1370_initfn, + .exit = es1370_exitfn, .vendor_id = PCI_VENDOR_ID_ENSONIQ, .device_id = PCI_DEVICE_ID_ENSONIQ_ES1370, .class_id = PCI_CLASS_MULTIMEDIA_AUDIO, @@ -126,7 +126,7 @@ struct SerialState { SysBusDevice busdev; struct ChannelState chn[2]; uint32_t it_shift; - int mmio_index; + MemoryRegion mmio; uint32_t disabled; uint32_t frequency; }; @@ -490,7 +490,8 @@ static void escc_update_parameters(ChannelState *s) qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); } -static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) +static void escc_mem_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { SerialState *serial = opaque; ChannelState *s; @@ -592,7 +593,8 @@ static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) } } -static uint32_t escc_mem_readb(void *opaque, target_phys_addr_t addr) +static uint64_t escc_mem_read(void *opaque, target_phys_addr_t addr, + unsigned size) { SerialState *serial = opaque; ChannelState *s; @@ -627,6 +629,16 @@ static uint32_t escc_mem_readb(void *opaque, target_phys_addr_t addr) return 0; } +static const MemoryRegionOps escc_mem_ops = { + .read = escc_mem_read, + .write = escc_mem_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; + static int serial_can_receive(void *opaque) { ChannelState *s = opaque; @@ -668,18 +680,6 @@ static void serial_event(void *opaque, int event) serial_receive_break(s); } -static CPUReadMemoryFunc * const escc_mem_read[3] = { - escc_mem_readb, - NULL, - NULL, -}; - -static CPUWriteMemoryFunc * const escc_mem_write[3] = { - escc_mem_writeb, - NULL, - NULL, -}; - static const VMStateDescription vmstate_escc_chn = { .name ="escc_chn", .version_id = 2, @@ -712,7 +712,7 @@ static const VMStateDescription vmstate_escc = { } }; -int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB, +MemoryRegion *escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB, CharDriverState *chrA, CharDriverState *chrB, int clock, int it_shift) { @@ -737,7 +737,7 @@ int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB, } d = FROM_SYSBUS(SerialState, s); - return d->mmio_index; + return &d->mmio; } static const uint8_t keycodes[128] = { @@ -901,7 +901,6 @@ void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq, static int escc_init1(SysBusDevice *dev) { SerialState *s = FROM_SYSBUS(SerialState, dev); - int io; unsigned int i; s->chn[0].disabled = s->disabled; @@ -918,10 +917,9 @@ static int escc_init1(SysBusDevice *dev) s->chn[0].otherchn = &s->chn[1]; s->chn[1].otherchn = &s->chn[0]; - io = cpu_register_io_memory(escc_mem_read, escc_mem_write, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, ESCC_SIZE << s->it_shift, io); - s->mmio_index = io; + memory_region_init_io(&s->mmio, &escc_mem_ops, s, "escc", + ESCC_SIZE << s->it_shift); + sysbus_init_mmio_region(dev, &s->mmio); if (s->chn[0].type == mouse) { qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, @@ -1,6 +1,6 @@ /* escc.c */ #define ESCC_SIZE 4 -int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB, +MemoryRegion *escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB, CharDriverState *chrA, CharDriverState *chrB, int clock, int it_shift); diff --git a/hw/etraxfs.c b/hw/etraxfs.c deleted file mode 100644 index b84d74a11e..0000000000 --- a/hw/etraxfs.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * QEMU ETRAX System Emulator - * - * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "sysbus.h" -#include "boards.h" -#include "net.h" -#include "flash.h" -#include "etraxfs.h" -#include "loader.h" -#include "elf.h" -#include "cris-boot.h" -#include "blockdev.h" - -#define FLASH_SIZE 0x2000000 -#define INTMEM_SIZE (128 * 1024) - -static struct cris_load_info li; - -static void flash_cpu_reset(void *opaque) -{ - CPUState *env = opaque; - cpu_reset(env); -} - -static -void bareetraxfs_init (ram_addr_t ram_size, - const char *boot_device, - const char *kernel_filename, const char *kernel_cmdline, - const char *initrd_filename, const char *cpu_model) -{ - DeviceState *dev; - SysBusDevice *s; - CPUState *env; - qemu_irq irq[30], nmi[2], *cpu_irq; - void *etraxfs_dmac; - struct etraxfs_dma_client *eth[2] = {NULL, NULL}; - DriveInfo *dinfo; - int i; - ram_addr_t phys_ram; - ram_addr_t phys_flash; - ram_addr_t phys_intmem; - - /* init CPUs */ - if (cpu_model == NULL) { - cpu_model = "crisv32"; - } - env = cpu_init(cpu_model); - - /* allocate RAM */ - phys_ram = qemu_ram_alloc(NULL, "etraxfs.ram", ram_size); - cpu_register_physical_memory(0x40000000, ram_size, phys_ram | IO_MEM_RAM); - - /* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the - internal memory. */ - phys_intmem = qemu_ram_alloc(NULL, "etraxfs.chipram", INTMEM_SIZE); - cpu_register_physical_memory(0x38000000, INTMEM_SIZE, - phys_intmem | IO_MEM_RAM); - - - phys_flash = qemu_ram_alloc(NULL, "etraxfs.flash", FLASH_SIZE); - dinfo = drive_get(IF_PFLASH, 0, 0); - pflash_cfi02_register(0x0, phys_flash, - dinfo ? dinfo->bdrv : NULL, (64 * 1024), - FLASH_SIZE >> 16, - 1, 2, 0x0000, 0x0000, 0x0000, 0x0000, - 0x555, 0x2aa, 0); - cpu_irq = cris_pic_init_cpu(env); - dev = qdev_create(NULL, "etraxfs,pic"); - /* FIXME: Is there a proper way to signal vectors to the CPU core? */ - qdev_prop_set_ptr(dev, "interrupt_vector", &env->interrupt_vector); - qdev_init_nofail(dev); - s = sysbus_from_qdev(dev); - sysbus_mmio_map(s, 0, 0x3001c000); - sysbus_connect_irq(s, 0, cpu_irq[0]); - sysbus_connect_irq(s, 1, cpu_irq[1]); - for (i = 0; i < 30; i++) { - irq[i] = qdev_get_gpio_in(dev, i); - } - nmi[0] = qdev_get_gpio_in(dev, 30); - nmi[1] = qdev_get_gpio_in(dev, 31); - - etraxfs_dmac = etraxfs_dmac_init(0x30000000, 10); - for (i = 0; i < 10; i++) { - /* On ETRAX, odd numbered channels are inputs. */ - etraxfs_dmac_connect(etraxfs_dmac, i, irq + 7 + i, i & 1); - } - - /* Add the two ethernet blocks. */ - eth[0] = etraxfs_eth_init(&nd_table[0], 0x30034000, 1); - if (nb_nics > 1) - eth[1] = etraxfs_eth_init(&nd_table[1], 0x30036000, 2); - - /* The DMA Connector block is missing, hardwire things for now. */ - etraxfs_dmac_connect_client(etraxfs_dmac, 0, eth[0]); - etraxfs_dmac_connect_client(etraxfs_dmac, 1, eth[0] + 1); - if (eth[1]) { - etraxfs_dmac_connect_client(etraxfs_dmac, 6, eth[1]); - etraxfs_dmac_connect_client(etraxfs_dmac, 7, eth[1] + 1); - } - - /* 2 timers. */ - sysbus_create_varargs("etraxfs,timer", 0x3001e000, irq[0x1b], nmi[1], NULL); - sysbus_create_varargs("etraxfs,timer", 0x3005e000, irq[0x1b], nmi[1], NULL); - - for (i = 0; i < 4; i++) { - sysbus_create_simple("etraxfs,serial", 0x30026000 + i * 0x2000, - irq[0x14 + i]); - } - - if (kernel_filename) { - li.image_filename = kernel_filename; - li.cmdline = kernel_cmdline; - cris_load_image(env, &li); - } else { - if (!dinfo) { - fprintf(stderr, - "Provide a kernel image or a flash image to boot from.\n"); - exit(1); - } - - /* Nothing more to do for flash images, those boot from addr 0. */ - qemu_register_reset(flash_cpu_reset, env); - } -} - -static QEMUMachine bareetraxfs_machine = { - .name = "bareetraxfs", - .desc = "Bare ETRAX FS board", - .init = bareetraxfs_init, - .is_default = 1, -}; - -static void bareetraxfs_machine_init(void) -{ - qemu_register_machine(&bareetraxfs_machine); -} - -machine_init(bareetraxfs_machine_init); diff --git a/hw/etraxfs.h b/hw/etraxfs.h index 01fb9d3e82..1554b0b8e8 100644 --- a/hw/etraxfs.h +++ b/hw/etraxfs.h @@ -25,4 +25,21 @@ #include "etraxfs_dma.h" qemu_irq *cris_pic_init_cpu(CPUState *env); -void *etraxfs_eth_init(NICInfo *nd, target_phys_addr_t base, int phyaddr); + +/* Instantiate an ETRAXFS Ethernet MAC. */ +static inline DeviceState * +etraxfs_eth_init(NICInfo *nd, target_phys_addr_t base, int phyaddr, + void *dma_out, void *dma_in) +{ + DeviceState *dev; + qemu_check_nic_model(nd, "fseth"); + + dev = qdev_create(NULL, "etraxfs-eth"); + qdev_set_nic_properties(dev, nd); + qdev_prop_set_uint32(dev, "phyaddr", phyaddr); + qdev_prop_set_ptr(dev, "dma_out", dma_out); + qdev_prop_set_ptr(dev, "dma_in", dma_in); + qdev_init_nofail(dev); + sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); + return dev; +} diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c index dff5f55f33..92d4ecac8f 100644 --- a/hw/etraxfs_eth.c +++ b/hw/etraxfs_eth.c @@ -23,7 +23,7 @@ */ #include <stdio.h> -#include "hw.h" +#include "sysbus.h" #include "net.h" #include "etraxfs.h" @@ -319,6 +319,7 @@ static void mdio_cycle(struct qemu_mdio *bus) struct fs_eth { + SysBusDevice busdev; NICState *nic; NICConf conf; int ethregs; @@ -327,8 +328,14 @@ struct fs_eth uint8_t macaddr[2][6]; uint32_t regs[FS_ETH_MAX_REGS]; - struct etraxfs_dma_client *dma_out; - struct etraxfs_dma_client *dma_in; + union { + void *vdma_out; + struct etraxfs_dma_client *dma_out; + }; + union { + void *vdma_in; + struct etraxfs_dma_client *dma_in; + }; /* MDIO bus. */ struct qemu_mdio mdio_bus; @@ -562,7 +569,11 @@ static void eth_cleanup(VLANClientState *nc) cpu_unregister_io_memory(eth->ethregs); - qemu_free(eth->dma_out); + /* Disconnect the client. */ + eth->dma_out->client.push = NULL; + eth->dma_out->client.opaque = NULL; + eth->dma_in->client.opaque = NULL; + eth->dma_in->client.pull = NULL; qemu_free(eth); } @@ -575,39 +586,50 @@ static NetClientInfo net_etraxfs_info = { .link_status_changed = eth_set_link, }; -void *etraxfs_eth_init(NICInfo *nd, target_phys_addr_t base, int phyaddr) +static int fs_eth_init(SysBusDevice *dev) { - struct etraxfs_dma_client *dma = NULL; - struct fs_eth *eth = NULL; + struct fs_eth *s = FROM_SYSBUS(typeof(*s), dev); + int eth_regs; - qemu_check_nic_model(nd, "fseth"); - - dma = qemu_mallocz(sizeof *dma * 2); - eth = qemu_mallocz(sizeof *eth); - - dma[0].client.push = eth_tx_push; - dma[0].client.opaque = eth; - dma[1].client.opaque = eth; - dma[1].client.pull = NULL; + if (!s->dma_out || !s->dma_in) { + hw_error("Unconnected ETRAX-FS Ethernet MAC.\n"); + } - eth->dma_out = dma; - eth->dma_in = dma + 1; + s->dma_out->client.push = eth_tx_push; + s->dma_out->client.opaque = s; + s->dma_in->client.opaque = s; + s->dma_in->client.pull = NULL; - /* Connect the phy. */ - eth->phyaddr = phyaddr & 0x1f; - tdk_init(ð->phy); - mdio_attach(ð->mdio_bus, ð->phy, eth->phyaddr); + eth_regs = cpu_register_io_memory(eth_read, eth_write, s, + DEVICE_LITTLE_ENDIAN); + sysbus_init_mmio(dev, 0x5c, eth_regs); - eth->ethregs = cpu_register_io_memory(eth_read, eth_write, eth, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory (base, 0x5c, eth->ethregs); + qemu_macaddr_default_if_unset(&s->conf.macaddr); + s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf, + dev->qdev.info->name, dev->qdev.id, s); + qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); - eth->conf.macaddr = nd->macaddr; - eth->conf.vlan = nd->vlan; - eth->conf.peer = nd->netdev; + tdk_init(&s->phy); + mdio_attach(&s->mdio_bus, &s->phy, s->phyaddr); + return 0; +} - eth->nic = qemu_new_nic(&net_etraxfs_info, ð->conf, - nd->model, nd->name, eth); +static SysBusDeviceInfo etraxfs_eth_info = { + .init = fs_eth_init, + .qdev.name = "etraxfs-eth", + .qdev.size = sizeof(struct fs_eth), + .qdev.props = (Property[]) { + DEFINE_PROP_UINT32("phyaddr", struct fs_eth, phyaddr, 1), + DEFINE_PROP_PTR("dma_out", struct fs_eth, vdma_out), + DEFINE_PROP_PTR("dma_in", struct fs_eth, vdma_in), + DEFINE_NIC_PROPERTIES(struct fs_eth, conf), + DEFINE_PROP_END_OF_LIST(), + } +}; - return dma; +static void etraxfs_eth_register(void) +{ + sysbus_register_withprop(&etraxfs_eth_info); } + +device_init(etraxfs_eth_register) diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c index b917d4db11..28b86ea2d4 100644 --- a/hw/etraxfs_ser.c +++ b/hw/etraxfs_ser.c @@ -24,6 +24,7 @@ #include "sysbus.h" #include "qemu-char.h" +#include "qemu-log.h" #define D(x) @@ -100,7 +101,7 @@ static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) break; default: r = s->regs[addr]; - D(printf ("%s " TARGET_FMT_plx "=%x\n", __func__, addr, r)); + D(qemu_log("%s " TARGET_FMT_plx "=%x\n", __func__, addr, r)); break; } return r; @@ -113,7 +114,7 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) unsigned char ch = value; D(CPUState *env = s->env); - D(printf ("%s " TARGET_FMT_plx "=%x\n", __func__, addr, value)); + D(qemu_log("%s " TARGET_FMT_plx "=%x\n", __func__, addr, value)); addr >>= 2; switch (addr) { @@ -127,7 +128,8 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) if (s->pending_tx) { value &= ~1; s->pending_tx = 0; - D(printf("fixedup value=%x r_intr=%x\n", value, s->regs[R_INTR])); + D(qemu_log("fixedup value=%x r_intr=%x\n", + value, s->regs[R_INTR])); } s->regs[addr] = value; s->regs[R_INTR] &= ~value; @@ -157,7 +159,7 @@ static void serial_receive(void *opaque, const uint8_t *buf, int size) /* Got a byte. */ if (s->rx_fifo_len >= 16) { - printf("WARNING: UART dropped char.\n"); + qemu_log("WARNING: UART dropped char.\n"); return; } diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c index da67cf9b38..9a823e1c06 100644 --- a/hw/grackle_pci.c +++ b/hw/grackle_pci.c @@ -62,7 +62,8 @@ static void pci_grackle_reset(void *opaque) } PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic, - MemoryRegion *address_space) + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io) { DeviceState *dev; SysBusDevice *s; @@ -75,7 +76,10 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic, d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci", pci_grackle_set_irq, pci_grackle_map_irq, - pic, address_space, 0, 4); + pic, + address_space_mem, + address_space_io, + 0, 4); pci_create_simple(d->host_state.bus, 0, "grackle"); diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c index 65e63ddab8..d5415580e4 100644 --- a/hw/gt64xxx.c +++ b/hw/gt64xxx.c @@ -1093,7 +1093,9 @@ PCIBus *gt64120_register(qemu_irq *pic) d = FROM_SYSBUS(GT64120State, s); d->pci.bus = pci_register_bus(&d->busdev.qdev, "pci", gt64120_pci_set_irq, gt64120_pci_map_irq, - pic, get_system_memory(), + pic, + get_system_memory(), + get_system_io(), PCI_DEVFN(18, 0), 4); d->ISD_handle = cpu_register_io_memory(gt64120_read, gt64120_write, d, DEVICE_NATIVE_ENDIAN); diff --git a/hw/heathrow_pic.c b/hw/heathrow_pic.c index 5fd71a0f71..3ba0b0e0fb 100644 --- a/hw/heathrow_pic.c +++ b/hw/heathrow_pic.c @@ -43,6 +43,7 @@ typedef struct HeathrowPIC { } HeathrowPIC; typedef struct HeathrowPICS { + MemoryRegion mem; HeathrowPIC pics[2]; qemu_irq *irqs; } HeathrowPICS; @@ -62,7 +63,8 @@ static void heathrow_pic_update(HeathrowPICS *s) } } -static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) +static void pic_write(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) { HeathrowPICS *s = opaque; HeathrowPIC *pic; @@ -89,7 +91,8 @@ static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) } } -static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) +static uint64_t pic_read(void *opaque, target_phys_addr_t addr, + unsigned size) { HeathrowPICS *s = opaque; HeathrowPIC *pic; @@ -120,19 +123,12 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) return value; } -static CPUWriteMemoryFunc * const pic_write[] = { - &pic_writel, - &pic_writel, - &pic_writel, +static const MemoryRegionOps heathrow_pic_ops = { + .read = pic_read, + .write = pic_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUReadMemoryFunc * const pic_read[] = { - &pic_readl, - &pic_readl, - &pic_readl, -}; - - static void heathrow_pic_set_irq(void *opaque, int num, int level) { HeathrowPICS *s = opaque; @@ -201,7 +197,7 @@ static void heathrow_pic_reset(void *opaque) s->pics[1].level_triggered = 0x1ff00000; } -qemu_irq *heathrow_pic_init(int *pmem_index, +qemu_irq *heathrow_pic_init(MemoryRegion **pmem, int nb_cpus, qemu_irq **irqs) { HeathrowPICS *s; @@ -209,8 +205,9 @@ qemu_irq *heathrow_pic_init(int *pmem_index, s = qemu_mallocz(sizeof(HeathrowPICS)); /* only 1 CPU */ s->irqs = irqs[0]; - *pmem_index = cpu_register_io_memory(pic_read, pic_write, s, - DEVICE_LITTLE_ENDIAN); + memory_region_init_io(&s->mem, &heathrow_pic_ops, s, + "heathrow-pic", 0x1000); + *pmem = &s->mem; vmstate_register(NULL, -1, &vmstate_heathrow_pic, s); qemu_register_reset(heathrow_pic_reset, s); @@ -218,16 +218,21 @@ static inline int int_clamp(int val, int vmin, int vmax) } } +void hid_pointer_activate(HIDState *hs) +{ + if (!hs->ptr.mouse_grabbed) { + qemu_activate_mouse_event_handler(hs->ptr.eh_entry); + hs->ptr.mouse_grabbed = 1; + } +} + int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len) { int dx, dy, dz, b, l; int index; HIDPointerEvent *e; - if (!hs->ptr.mouse_grabbed) { - qemu_activate_mouse_event_handler(hs->ptr.eh_entry); - hs->ptr.mouse_grabbed = 1; - } + hid_pointer_activate(hs); /* When the buffer is empty, return the last event. Relative movements will all be zero. */ @@ -359,7 +364,6 @@ void hid_reset(HIDState *hs) { switch (hs->kind) { case HID_KEYBOARD: - qemu_add_kbd_event_handler(hid_keyboard_event, hs); memset(hs->kbd.keycodes, 0, sizeof(hs->kbd.keycodes)); memset(hs->kbd.key, 0, sizeof(hs->kbd.key)); hs->kbd.keys = 0; @@ -393,7 +397,9 @@ void hid_init(HIDState *hs, int kind, HIDEventFunc event) hs->kind = kind; hs->event = event; - if (hs->kind == HID_MOUSE) { + if (hs->kind == HID_KEYBOARD) { + qemu_add_kbd_event_handler(hid_keyboard_event, hs); + } else if (hs->kind == HID_MOUSE) { hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event, hs, 0, "QEMU HID Mouse"); } else if (hs->kind == HID_TABLET) { @@ -401,3 +407,61 @@ void hid_init(HIDState *hs, int kind, HIDEventFunc event) 1, "QEMU HID Tablet"); } } + +static int hid_post_load(void *opaque, int version_id) +{ + HIDState *s = opaque; + + if (s->idle) { + hid_set_next_idle(s, qemu_get_clock_ns(vm_clock)); + } + return 0; +} + +static const VMStateDescription vmstate_hid_ptr_queue = { + .name = "HIDPointerEventQueue", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_INT32(xdx, HIDPointerEvent), + VMSTATE_INT32(ydy, HIDPointerEvent), + VMSTATE_INT32(dz, HIDPointerEvent), + VMSTATE_INT32(buttons_state, HIDPointerEvent), + VMSTATE_END_OF_LIST() + } +}; + +const VMStateDescription vmstate_hid_ptr_device = { + .name = "HIDPointerDevice", + .version_id = 1, + .minimum_version_id = 1, + .post_load = hid_post_load, + .fields = (VMStateField[]) { + VMSTATE_STRUCT_ARRAY(ptr.queue, HIDState, QUEUE_LENGTH, 0, + vmstate_hid_ptr_queue, HIDPointerEvent), + VMSTATE_UINT32(head, HIDState), + VMSTATE_UINT32(n, HIDState), + VMSTATE_INT32(protocol, HIDState), + VMSTATE_UINT8(idle, HIDState), + VMSTATE_END_OF_LIST(), + } +}; + +const VMStateDescription vmstate_hid_keyboard_device = { + .name = "HIDKeyboardDevice", + .version_id = 1, + .minimum_version_id = 1, + .post_load = hid_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(kbd.keycodes, HIDState, QUEUE_LENGTH), + VMSTATE_UINT32(head, HIDState), + VMSTATE_UINT32(n, HIDState), + VMSTATE_UINT16(kbd.modifiers, HIDState), + VMSTATE_UINT8(kbd.leds, HIDState), + VMSTATE_UINT8_ARRAY(kbd.key, HIDState, 16), + VMSTATE_INT32(kbd.keys, HIDState), + VMSTATE_INT32(protocol, HIDState), + VMSTATE_UINT8(idle, HIDState), + VMSTATE_END_OF_LIST(), + } +}; @@ -51,6 +51,7 @@ void hid_free(HIDState *hs); bool hid_has_events(HIDState *hs); void hid_set_next_idle(HIDState *hs, int64_t curtime); +void hid_pointer_activate(HIDState *hs); int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len); int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len); int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len); @@ -701,6 +701,26 @@ extern const VMStateDescription vmstate_ptimer; .offset = vmstate_offset_pointer(_state, _field, ptimer_state), \ } +extern const VMStateDescription vmstate_hid_keyboard_device; + +#define VMSTATE_HID_KEYBOARD_DEVICE(_field, _state) { \ + .name = (stringify(_field)), \ + .size = sizeof(HIDState), \ + .vmsd = &vmstate_hid_keyboard_device, \ + .flags = VMS_STRUCT, \ + .offset = vmstate_offset_value(_state, _field, HIDState), \ +} + +extern const VMStateDescription vmstate_hid_ptr_device; + +#define VMSTATE_HID_POINTER_DEVICE(_field, _state) { \ + .name = (stringify(_field)), \ + .size = sizeof(HIDState), \ + .vmsd = &vmstate_hid_ptr_device, \ + .flags = VMS_STRUCT, \ + .offset = vmstate_offset_value(_state, _field, HIDState), \ +} + /* _f : field name _f_n : num of elements field_name _n : num of elements @@ -19,7 +19,7 @@ PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); /* ide-macio.c */ -int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq, +MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq, void *dbdma, int channel, qemu_irq dma_irq); /* ide-mmio.c */ diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 1f008a3dda..e207ca0894 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -276,12 +276,12 @@ static void ahci_port_write(AHCIState *s, int port, int offset, uint32_t val) } } -static uint32_t ahci_mem_readl(void *ptr, target_phys_addr_t addr) +static uint64_t ahci_mem_read(void *opaque, target_phys_addr_t addr, + unsigned size) { - AHCIState *s = ptr; + AHCIState *s = opaque; uint32_t val = 0; - addr = addr & 0xfff; if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) { switch (addr) { case HOST_CAP: @@ -314,10 +314,10 @@ static uint32_t ahci_mem_readl(void *ptr, target_phys_addr_t addr) -static void ahci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) +static void ahci_mem_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { - AHCIState *s = ptr; - addr = addr & 0xfff; + AHCIState *s = opaque; /* Only aligned reads are allowed on AHCI */ if (addr & 3) { @@ -364,16 +364,10 @@ static void ahci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) } -static CPUReadMemoryFunc * const ahci_readfn[3]={ - ahci_mem_readl, - ahci_mem_readl, - ahci_mem_readl -}; - -static CPUWriteMemoryFunc * const ahci_writefn[3]={ - ahci_mem_writel, - ahci_mem_writel, - ahci_mem_writel +static MemoryRegionOps ahci_mem_ops = { + .read = ahci_mem_read, + .write = ahci_mem_write, + .endianness = DEVICE_LITTLE_ENDIAN, }; static void ahci_reg_init(AHCIState *s) @@ -1131,8 +1125,8 @@ void ahci_init(AHCIState *s, DeviceState *qdev, int ports) s->ports = ports; s->dev = qemu_mallocz(sizeof(AHCIDevice) * ports); ahci_reg_init(s); - s->mem = cpu_register_io_memory(ahci_readfn, ahci_writefn, s, - DEVICE_LITTLE_ENDIAN); + /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */ + memory_region_init_io(&s->mem, &ahci_mem_ops, s, "ahci", 0x1000); irqs = qemu_allocate_irqs(ahci_irq_set, s, s->ports); for (i = 0; i < s->ports; i++) { @@ -1151,6 +1145,7 @@ void ahci_init(AHCIState *s, DeviceState *qdev, int ports) void ahci_uninit(AHCIState *s) { + memory_region_destroy(&s->mem); qemu_free(s->dev); } diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h index dc86951ebf..e456193b2b 100644 --- a/hw/ide/ahci.h +++ b/hw/ide/ahci.h @@ -289,7 +289,7 @@ struct AHCIDevice { typedef struct AHCIState { AHCIDevice *dev; AHCIControlRegs control_regs; - int mem; + MemoryRegion mem; int ports; qemu_irq irq; } AHCIState; diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index 56302b5060..4d91e2c642 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -44,35 +44,95 @@ static void cmd646_update_irq(PCIIDEState *d); -static void ide_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static uint64_t cmd646_cmd_read(void *opaque, target_phys_addr_t addr, + unsigned size) { - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); - IDEBus *bus; - - if (region_num <= 3) { - bus = &d->bus[(region_num >> 1)]; - if (region_num & 1) { - register_ioport_read(addr + 2, 1, 1, ide_status_read, bus); - register_ioport_write(addr + 2, 1, 1, ide_cmd_write, bus); + CMD646BAR *cmd646bar = opaque; + + if (addr != 2 || size != 1) { + return ((uint64_t)1 << (size * 8)) - 1; + } + return ide_status_read(cmd646bar->bus, addr + 2); +} + +static void cmd646_cmd_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) +{ + CMD646BAR *cmd646bar = opaque; + + if (addr != 2 || size != 1) { + return; + } + ide_cmd_write(cmd646bar->bus, addr + 2, data); +} + +static MemoryRegionOps cmd646_cmd_ops = { + .read = cmd646_cmd_read, + .write = cmd646_cmd_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static uint64_t cmd646_data_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + CMD646BAR *cmd646bar = opaque; + + if (size == 1) { + return ide_ioport_read(cmd646bar->bus, addr); + } else if (addr == 0) { + if (size == 2) { + return ide_data_readw(cmd646bar->bus, addr); } else { - register_ioport_write(addr, 8, 1, ide_ioport_write, bus); - register_ioport_read(addr, 8, 1, ide_ioport_read, bus); - - /* data ports */ - register_ioport_write(addr, 2, 2, ide_data_writew, bus); - register_ioport_read(addr, 2, 2, ide_data_readw, bus); - register_ioport_write(addr, 4, 4, ide_data_writel, bus); - register_ioport_read(addr, 4, 4, ide_data_readl, bus); + return ide_data_readl(cmd646bar->bus, addr); } } + return ((uint64_t)1 << (size * 8)) - 1; } -static uint32_t bmdma_readb_common(PCIIDEState *pci_dev, BMDMAState *bm, - uint32_t addr) +static void cmd646_data_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) { + CMD646BAR *cmd646bar = opaque; + + if (size == 1) { + return ide_ioport_write(cmd646bar->bus, addr, data); + } else if (addr == 0) { + if (size == 2) { + return ide_data_writew(cmd646bar->bus, addr, data); + } else { + return ide_data_writel(cmd646bar->bus, addr, data); + } + } +} + +static MemoryRegionOps cmd646_data_ops = { + .read = cmd646_data_read, + .write = cmd646_data_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void setup_cmd646_bar(PCIIDEState *d, int bus_num) +{ + IDEBus *bus = &d->bus[bus_num]; + CMD646BAR *bar = &d->cmd646_bar[bus_num]; + + bar->bus = bus; + bar->pci_dev = d; + memory_region_init_io(&bar->cmd, &cmd646_cmd_ops, bar, "cmd646-cmd", 4); + memory_region_init_io(&bar->data, &cmd646_data_ops, bar, "cmd646-data", 8); +} + +static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + BMDMAState *bm = opaque; + PCIIDEState *pci_dev = bm->pci_dev; uint32_t val; + if (size != 1) { + return ((uint64_t)1 << (size * 8)) - 1; + } + switch(addr & 3) { case 0: val = bm->cmd; @@ -100,31 +160,22 @@ static uint32_t bmdma_readb_common(PCIIDEState *pci_dev, BMDMAState *bm, return val; } -static uint32_t bmdma_readb_0(void *opaque, uint32_t addr) +static void bmdma_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { - PCIIDEState *pci_dev = opaque; - BMDMAState *bm = &pci_dev->bmdma[0]; - - return bmdma_readb_common(pci_dev, bm, addr); -} + BMDMAState *bm = opaque; + PCIIDEState *pci_dev = bm->pci_dev; -static uint32_t bmdma_readb_1(void *opaque, uint32_t addr) -{ - PCIIDEState *pci_dev = opaque; - BMDMAState *bm = &pci_dev->bmdma[1]; - - return bmdma_readb_common(pci_dev, bm, addr); -} + if (size != 1) { + return; + } -static void bmdma_writeb_common(PCIIDEState *pci_dev, BMDMAState *bm, - uint32_t addr, uint32_t val) -{ #ifdef DEBUG_IDE printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val); #endif switch(addr & 3) { case 0: - bmdma_cmd_writeb(bm, addr, val); + bmdma_cmd_writeb(bm, val); break; case 1: pci_dev->dev.config[MRDMODE] = @@ -143,42 +194,25 @@ static void bmdma_writeb_common(PCIIDEState *pci_dev, BMDMAState *bm, } } -static void bmdma_writeb_0(void *opaque, uint32_t addr, uint32_t val) -{ - PCIIDEState *pci_dev = opaque; - BMDMAState *bm = &pci_dev->bmdma[0]; - - bmdma_writeb_common(pci_dev, bm, addr, val); -} - -static void bmdma_writeb_1(void *opaque, uint32_t addr, uint32_t val) -{ - PCIIDEState *pci_dev = opaque; - BMDMAState *bm = &pci_dev->bmdma[1]; - - bmdma_writeb_common(pci_dev, bm, addr, val); -} +static MemoryRegionOps cmd646_bmdma_ops = { + .read = bmdma_read, + .write = bmdma_write, +}; -static void bmdma_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static void bmdma_setup_bar(PCIIDEState *d) { - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); + BMDMAState *bm; int i; + memory_region_init(&d->bmdma_bar, "cmd646-bmdma", 16); for(i = 0;i < 2; i++) { - BMDMAState *bm = &d->bmdma[i]; - - if (i == 0) { - register_ioport_write(addr, 4, 1, bmdma_writeb_0, d); - register_ioport_read(addr, 4, 1, bmdma_readb_0, d); - } else { - register_ioport_write(addr, 4, 1, bmdma_writeb_1, d); - register_ioport_read(addr, 4, 1, bmdma_readb_1, d); - } - - iorange_init(&bm->addr_ioport, &bmdma_addr_ioport_ops, addr + 4, 4); - ioport_register(&bm->addr_ioport); - addr += 8; + bm = &d->bmdma[i]; + memory_region_init_io(&bm->extra_io, &cmd646_bmdma_ops, bm, + "cmd646-bmdma-bus", 4); + memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io); + memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm, + "cmd646-bmdma-ioport", 4); + memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport); } } @@ -234,11 +268,14 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev) pci_conf[0x51] |= 0x08; /* enable IDE1 */ } - pci_register_bar(dev, 0, 0x8, PCI_BASE_ADDRESS_SPACE_IO, ide_map); - pci_register_bar(dev, 1, 0x4, PCI_BASE_ADDRESS_SPACE_IO, ide_map); - pci_register_bar(dev, 2, 0x8, PCI_BASE_ADDRESS_SPACE_IO, ide_map); - pci_register_bar(dev, 3, 0x4, PCI_BASE_ADDRESS_SPACE_IO, ide_map); - pci_register_bar(dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO, bmdma_map); + setup_cmd646_bar(d, 0); + setup_cmd646_bar(d, 1); + pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].data); + pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].cmd); + pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[1].data); + pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[1].cmd); + bmdma_setup_bar(d); + pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); /* TODO: RST# value should be 0 */ pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1 @@ -248,7 +285,7 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev) ide_bus_new(&d->bus[i], &d->dev.qdev, i); ide_init2(&d->bus[i], irq[i]); - bmdma_init(&d->bus[i], &d->bmdma[i]); + bmdma_init(&d->bus[i], &d->bmdma[i], d); d->bmdma[i].bus = &d->bus[i]; qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb, &d->bmdma[i].dma); @@ -259,6 +296,24 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev) return 0; } +static int pci_cmd646_ide_exitfn(PCIDevice *dev) +{ + PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); + unsigned i; + + for (i = 0; i < 2; ++i) { + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io); + memory_region_destroy(&d->bmdma[i].extra_io); + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport); + memory_region_destroy(&d->bmdma[i].addr_ioport); + memory_region_destroy(&d->cmd646_bar[i].cmd); + memory_region_destroy(&d->cmd646_bar[i].data); + } + memory_region_destroy(&d->bmdma_bar); + + return 0; +} + void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table, int secondary_ide_enabled) { @@ -276,6 +331,7 @@ static PCIDeviceInfo cmd646_ide_info[] = { .qdev.name = "cmd646-ide", .qdev.size = sizeof(PCIIDEState), .init = pci_cmd646_ide_initfn, + .exit = pci_cmd646_ide_exitfn, .vendor_id = PCI_VENDOR_ID_CMD, .device_id = PCI_DEVICE_ID_CMD_646, .revision = 0x07, // IDE controller revision diff --git a/hw/ide/ich.c b/hw/ide/ich.c index d241ea8005..5278bc4d6c 100644 --- a/hw/ide/ich.c +++ b/hw/ide/ich.c @@ -98,8 +98,7 @@ static int pci_ich9_ahci_init(PCIDevice *dev) msi_init(dev, 0x50, 1, true, false); d->ahci.irq = d->card.irq[0]; - /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */ - pci_register_bar_simple(&d->card, 5, 0x1000, 0, d->ahci.mem); + pci_register_bar(&d->card, 5, 0, &d->ahci.mem); return 0; } diff --git a/hw/ide/macio.c b/hw/ide/macio.c index 7daeb31ec3..7ee35e9bd9 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -35,6 +35,7 @@ /* MacIO based PowerPC IDE */ typedef struct MACIOIDEState { + MemoryRegion mem; IDEBus bus; BlockDriverAIOCB *aiocb; } MACIOIDEState; @@ -281,16 +282,20 @@ static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr) return retval; } -static CPUWriteMemoryFunc * const pmac_ide_write[] = { - pmac_ide_writeb, - pmac_ide_writew, - pmac_ide_writel, -}; - -static CPUReadMemoryFunc * const pmac_ide_read[] = { - pmac_ide_readb, - pmac_ide_readw, - pmac_ide_readl, +static MemoryRegionOps pmac_ide_ops = { + .old_mmio = { + .write = { + pmac_ide_writeb, + pmac_ide_writew, + pmac_ide_writel, + }, + .read = { + pmac_ide_readb, + pmac_ide_readw, + pmac_ide_readl, + }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; static const VMStateDescription vmstate_pmac = { @@ -315,11 +320,10 @@ static void pmac_ide_reset(void *opaque) /* hd_table must contain 4 block drivers */ /* PowerMac uses memory mapped registers, not I/O. Return the memory I/O index to access the ide. */ -int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq, - void *dbdma, int channel, qemu_irq dma_irq) +MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq, + void *dbdma, int channel, qemu_irq dma_irq) { MACIOIDEState *d; - int pmac_ide_memory; d = qemu_mallocz(sizeof(MACIOIDEState)); ide_init2_with_non_qdev_drives(&d->bus, hd_table[0], hd_table[1], irq); @@ -327,11 +331,9 @@ int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq, if (dbdma) DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, pmac_ide_flush, d); - pmac_ide_memory = cpu_register_io_memory(pmac_ide_read, - pmac_ide_write, d, - DEVICE_NATIVE_ENDIAN); + memory_region_init_io(&d->mem, &pmac_ide_ops, d, "pmac-ide", 0x1000); vmstate_register(NULL, 0, &vmstate_pmac, d); qemu_register_reset(pmac_ide_reset, d); - return pmac_ide_memory; + return &d->mem; } diff --git a/hw/ide/pci.c b/hw/ide/pci.c index 9f3050a15e..d1a14d7cc1 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -287,9 +287,8 @@ static void bmdma_irq(void *opaque, int n, int level) qemu_set_irq(bm->irq, level); } -void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) +void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val) { - BMDMAState *bm = opaque; #ifdef DEBUG_IDE printf("%s: 0x%08x\n", __func__, val); #endif @@ -328,22 +327,24 @@ void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) bm->cmd = val & 0x09; } -static void bmdma_addr_read(IORange *ioport, uint64_t addr, - unsigned width, uint64_t *data) +static uint64_t bmdma_addr_read(void *opaque, target_phys_addr_t addr, + unsigned width) { - BMDMAState *bm = container_of(ioport, BMDMAState, addr_ioport); + BMDMAState *bm = opaque; uint32_t mask = (1ULL << (width * 8)) - 1; + uint64_t data; - *data = (bm->addr >> (addr * 8)) & mask; + data = (bm->addr >> (addr * 8)) & mask; #ifdef DEBUG_IDE printf("%s: 0x%08x\n", __func__, (unsigned)*data); #endif + return data; } -static void bmdma_addr_write(IORange *ioport, uint64_t addr, - unsigned width, uint64_t data) +static void bmdma_addr_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned width) { - BMDMAState *bm = container_of(ioport, BMDMAState, addr_ioport); + BMDMAState *bm = opaque; int shift = addr * 8; uint32_t mask = (1ULL << (width * 8)) - 1; @@ -354,9 +355,10 @@ static void bmdma_addr_write(IORange *ioport, uint64_t addr, bm->addr |= ((data & mask) << shift) & ~3; } -const IORangeOps bmdma_addr_ioport_ops = { +MemoryRegionOps bmdma_addr_ioport_ops = { .read = bmdma_addr_read, .write = bmdma_addr_write, + .endianness = DEVICE_LITTLE_ENDIAN, }; static bool ide_bmdma_current_needed(void *opaque) @@ -514,7 +516,7 @@ static const struct IDEDMAOps bmdma_ops = { .reset = bmdma_reset, }; -void bmdma_init(IDEBus *bus, BMDMAState *bm) +void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d) { qemu_irq *irq; @@ -527,4 +529,5 @@ void bmdma_init(IDEBus *bus, BMDMAState *bm) bm->irq = bus->irq; irq = qemu_allocate_irqs(bmdma_irq, bm, 1); bus->irq = *irq; + bm->pci_dev = d; } diff --git a/hw/ide/pci.h b/hw/ide/pci.h index b4f3691a5c..a694e546d7 100644 --- a/hw/ide/pci.h +++ b/hw/ide/pci.h @@ -19,20 +19,31 @@ typedef struct BMDMAState { BlockDriverCompletionFunc *dma_cb; int64_t sector_num; uint32_t nsector; - IORange addr_ioport; + MemoryRegion addr_ioport; + MemoryRegion extra_io; QEMUBH *bh; qemu_irq irq; /* Bit 0-2 and 7: BM status register * Bit 3-6: bus->error_status */ uint8_t migration_compat_status; + struct PCIIDEState *pci_dev; } BMDMAState; +typedef struct CMD646BAR { + MemoryRegion cmd; + MemoryRegion data; + IDEBus *bus; + struct PCIIDEState *pci_dev; +} CMD646BAR; + typedef struct PCIIDEState { PCIDevice dev; IDEBus bus[2]; BMDMAState bmdma[2]; uint32_t secondary; /* used only for cmd646 */ + MemoryRegion bmdma_bar; + CMD646BAR cmd646_bar[2]; /* used only for cmd646 */ } PCIIDEState; @@ -43,9 +54,9 @@ static inline IDEState *bmdma_active_if(BMDMAState *bmdma) } -void bmdma_init(IDEBus *bus, BMDMAState *bm); -void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val); -extern const IORangeOps bmdma_addr_ioport_ops; +void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d); +void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val); +extern MemoryRegionOps bmdma_addr_ioport_ops; void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table); extern const VMStateDescription vmstate_ide_pci; diff --git a/hw/ide/piix.c b/hw/ide/piix.c index f527dbd57e..8525336075 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -33,11 +33,15 @@ #include <hw/ide/pci.h> -static uint32_t bmdma_readb(void *opaque, uint32_t addr) +static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, unsigned size) { BMDMAState *bm = opaque; uint32_t val; + if (size != 1) { + return ((uint64_t)1 << (size * 8)) - 1; + } + switch(addr & 3) { case 0: val = bm->cmd; @@ -55,36 +59,46 @@ static uint32_t bmdma_readb(void *opaque, uint32_t addr) return val; } -static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val) +static void bmdma_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { BMDMAState *bm = opaque; + + if (size != 1) { + return; + } + #ifdef DEBUG_IDE printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val); #endif switch(addr & 3) { + case 0: + return bmdma_cmd_writeb(bm, val); case 2: bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06); break; } } -static void bmdma_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static MemoryRegionOps piix_bmdma_ops = { + .read = bmdma_read, + .write = bmdma_write, +}; + +static void bmdma_setup_bar(PCIIDEState *d) { - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); int i; + memory_region_init(&d->bmdma_bar, "piix-bmdma-container", 16); for(i = 0;i < 2; i++) { BMDMAState *bm = &d->bmdma[i]; - register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); - - register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm); - register_ioport_read(addr, 4, 1, bmdma_readb, bm); - - iorange_init(&bm->addr_ioport, &bmdma_addr_ioport_ops, addr + 4, 4); - ioport_register(&bm->addr_ioport); - addr += 8; + memory_region_init_io(&bm->extra_io, &piix_bmdma_ops, bm, + "piix-bmdma", 4); + memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io); + memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm, + "bmdma", 4); + memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport); } } @@ -124,7 +138,7 @@ static void pci_piix_init_ports(PCIIDEState *d) { ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2); ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq)); - bmdma_init(&d->bus[i], &d->bmdma[i]); + bmdma_init(&d->bus[i], &d->bmdma[i], d); d->bmdma[i].bus = &d->bus[i]; qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb, &d->bmdma[i].dma); @@ -140,7 +154,8 @@ static int pci_piix_ide_initfn(PCIDevice *dev) qemu_register_reset(piix3_reset, d); - pci_register_bar(&d->dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO, bmdma_map); + bmdma_setup_bar(d); + pci_register_bar(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); vmstate_register(&d->dev.qdev, 0, &vmstate_ide_pci, d); @@ -185,6 +200,22 @@ PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) return dev; } +static int pci_piix_ide_exitfn(PCIDevice *dev) +{ + PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); + unsigned i; + + for (i = 0; i < 2; ++i) { + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io); + memory_region_destroy(&d->bmdma[i].extra_io); + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport); + memory_region_destroy(&d->bmdma[i].addr_ioport); + } + memory_region_destroy(&d->bmdma_bar); + + return 0; +} + /* hd_table must contain 4 block drivers */ /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */ PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) @@ -214,6 +245,7 @@ static PCIDeviceInfo piix_ide_info[] = { .qdev.no_user = 1, .no_hotplug = 1, .init = pci_piix_ide_initfn, + .exit = pci_piix_ide_exitfn, .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = PCI_DEVICE_ID_INTEL_82371SB_1, .class_id = PCI_CLASS_STORAGE_IDE, @@ -231,6 +263,7 @@ static PCIDeviceInfo piix_ide_info[] = { .qdev.no_user = 1, .no_hotplug = 1, .init = pci_piix_ide_initfn, + .exit = pci_piix_ide_exitfn, .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = PCI_DEVICE_ID_INTEL_82371AB, .class_id = PCI_CLASS_STORAGE_IDE, diff --git a/hw/ide/via.c b/hw/ide/via.c index 3474c37ff7..c0b9d43827 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -34,11 +34,16 @@ #include <hw/ide/pci.h> -static uint32_t bmdma_readb(void *opaque, uint32_t addr) +static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, + unsigned size) { BMDMAState *bm = opaque; uint32_t val; + if (size != 1) { + return ((uint64_t)1 << (size * 8)) - 1; + } + switch (addr & 3) { case 0: val = bm->cmd; @@ -56,13 +61,21 @@ static uint32_t bmdma_readb(void *opaque, uint32_t addr) return val; } -static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val) +static void bmdma_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { BMDMAState *bm = opaque; + + if (size != 1) { + return; + } + #ifdef DEBUG_IDE printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val); #endif switch (addr & 3) { + case 0: + return bmdma_cmd_writeb(bm, val); case 2: bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06); break; @@ -70,23 +83,25 @@ static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val) } } -static void bmdma_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static MemoryRegionOps via_bmdma_ops = { + .read = bmdma_read, + .write = bmdma_write, +}; + +static void bmdma_setup_bar(PCIIDEState *d) { - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); int i; + memory_region_init(&d->bmdma_bar, "via-bmdma-container", 16); for(i = 0;i < 2; i++) { BMDMAState *bm = &d->bmdma[i]; - register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); - - register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm); - register_ioport_read(addr, 4, 1, bmdma_readb, bm); - - iorange_init(&bm->addr_ioport, &bmdma_addr_ioport_ops, addr + 4, 4); - ioport_register(&bm->addr_ioport); - addr += 8; + memory_region_init_io(&bm->extra_io, &via_bmdma_ops, bm, + "via-bmdma", 4); + memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io); + memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm, + "bmdma", 4); + memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport); } } @@ -147,7 +162,7 @@ static void vt82c686b_init_ports(PCIIDEState *d) { ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2); ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq)); - bmdma_init(&d->bus[i], &d->bmdma[i]); + bmdma_init(&d->bus[i], &d->bmdma[i], d); d->bmdma[i].bus = &d->bus[i]; qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb, &d->bmdma[i].dma); @@ -164,8 +179,8 @@ static int vt82c686b_ide_initfn(PCIDevice *dev) pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); qemu_register_reset(via_reset, d); - pci_register_bar(&d->dev, 4, 0x10, - PCI_BASE_ADDRESS_SPACE_IO, bmdma_map); + bmdma_setup_bar(d); + pci_register_bar(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); vmstate_register(&dev->qdev, 0, &vmstate_ide_pci, d); @@ -174,6 +189,22 @@ static int vt82c686b_ide_initfn(PCIDevice *dev) return 0; } +static int vt82c686b_ide_exitfn(PCIDevice *dev) +{ + PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); + unsigned i; + + for (i = 0; i < 2; ++i) { + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io); + memory_region_destroy(&d->bmdma[i].extra_io); + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport); + memory_region_destroy(&d->bmdma[i].addr_ioport); + } + memory_region_destroy(&d->bmdma_bar); + + return 0; +} + void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) { PCIDevice *dev; @@ -187,6 +218,7 @@ static PCIDeviceInfo via_ide_info = { .qdev.size = sizeof(PCIIDEState), .qdev.no_user = 1, .init = vt82c686b_ide_initfn, + .exit = vt82c686b_ide_exitfn, .vendor_id = PCI_VENDOR_ID_VIA, .device_id = PCI_DEVICE_ID_VIA_IDE, .revision = 0x06, diff --git a/hw/intel-hda.c b/hw/intel-hda.c index 5a2bc3aaa9..fa56a92215 100644 --- a/hw/intel-hda.c +++ b/hw/intel-hda.c @@ -177,7 +177,7 @@ struct IntelHDAState { IntelHDAStream st[8]; /* state */ - int mmio_addr; + MemoryRegion mmio; uint32_t rirb_count; int64_t wall_base_ns; @@ -1084,16 +1084,20 @@ static uint32_t intel_hda_mmio_readl(void *opaque, target_phys_addr_t addr) return intel_hda_reg_read(d, reg, 0xffffffff); } -static CPUReadMemoryFunc * const intel_hda_mmio_read[3] = { - intel_hda_mmio_readb, - intel_hda_mmio_readw, - intel_hda_mmio_readl, -}; - -static CPUWriteMemoryFunc * const intel_hda_mmio_write[3] = { - intel_hda_mmio_writeb, - intel_hda_mmio_writew, - intel_hda_mmio_writel, +static const MemoryRegionOps intel_hda_mmio_ops = { + .old_mmio = { + .read = { + intel_hda_mmio_readb, + intel_hda_mmio_readw, + intel_hda_mmio_readl, + }, + .write = { + intel_hda_mmio_writeb, + intel_hda_mmio_writew, + intel_hda_mmio_writel, + }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; /* --------------------------------------------------------------------- */ @@ -1130,10 +1134,9 @@ static int intel_hda_init(PCIDevice *pci) /* HDCTL off 0x40 bit 0 selects signaling mode (1-HDA, 0 - Ac97) 18.1.19 */ conf[0x40] = 0x01; - d->mmio_addr = cpu_register_io_memory(intel_hda_mmio_read, - intel_hda_mmio_write, d, - DEVICE_NATIVE_ENDIAN); - pci_register_bar_simple(&d->pci, 0, 0x4000, 0, d->mmio_addr); + memory_region_init_io(&d->mmio, &intel_hda_mmio_ops, d, + "intel-hda", 0x4000); + pci_register_bar(&d->pci, 0, 0, &d->mmio); if (d->msi) { msi_init(&d->pci, 0x50, 1, true, false); } @@ -1149,7 +1152,7 @@ static int intel_hda_exit(PCIDevice *pci) IntelHDAState *d = DO_UPCAST(IntelHDAState, pci, pci); msi_uninit(&d->pci); - cpu_unregister_io_memory(d->mmio_addr); + memory_region_destroy(&d->mmio); return 0; } @@ -4,6 +4,7 @@ /* ISA bus */ #include "ioport.h" +#include "memory.h" #include "qdev.h" typedef struct ISABus ISABus; @@ -37,6 +38,7 @@ ISADevice *isa_create_simple(const char *name); extern target_phys_addr_t isa_mem_base; +void isa_mmio_setup(MemoryRegion *mr, target_phys_addr_t size); void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size); /* dma.c */ diff --git a/hw/isa_mmio.c b/hw/isa_mmio.c index ca957fb010..3d2af1a63c 100644 --- a/hw/isa_mmio.c +++ b/hw/isa_mmio.c @@ -24,6 +24,7 @@ #include "hw.h" #include "isa.h" +#include "exec-memory.h" static void isa_mmio_writeb (void *opaque, target_phys_addr_t addr, uint32_t val) @@ -58,25 +59,23 @@ static uint32_t isa_mmio_readl(void *opaque, target_phys_addr_t addr) return cpu_inl(addr & IOPORTS_MASK); } -static CPUWriteMemoryFunc * const isa_mmio_write[] = { - &isa_mmio_writeb, - &isa_mmio_writew, - &isa_mmio_writel, +static const MemoryRegionOps isa_mmio_ops = { + .old_mmio = { + .write = { isa_mmio_writeb, isa_mmio_writew, isa_mmio_writel }, + .read = { isa_mmio_readb, isa_mmio_readw, isa_mmio_readl, }, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; -static CPUReadMemoryFunc * const isa_mmio_read[] = { - &isa_mmio_readb, - &isa_mmio_readw, - &isa_mmio_readl, -}; +void isa_mmio_setup(MemoryRegion *mr, target_phys_addr_t size) +{ + memory_region_init_io(mr, &isa_mmio_ops, NULL, "isa-mmio", size); +} void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size) { - int isa_mmio_iomemtype; + MemoryRegion *mr = qemu_malloc(sizeof(*mr)); - isa_mmio_iomemtype = cpu_register_io_memory(isa_mmio_read, - isa_mmio_write, - NULL, - DEVICE_LITTLE_ENDIAN); - cpu_register_physical_memory(base, size, isa_mmio_iomemtype); + isa_mmio_setup(mr, size); + memory_region_add_subregion(get_system_memory(), base, mr); } diff --git a/hw/ivshmem.c b/hw/ivshmem.c index 3055dd2a50..42a5877032 100644 --- a/hw/ivshmem.c +++ b/hw/ivshmem.c @@ -56,11 +56,16 @@ typedef struct IVShmemState { CharDriverState **eventfd_chr; CharDriverState *server_chr; - int ivshmem_mmio_io_addr; + MemoryRegion ivshmem_mmio; pcibus_t mmio_addr; - pcibus_t shm_pci_addr; - uint64_t ivshmem_offset; + /* We might need to register the BAR before we actually have the memory. + * So prepare a container MemoryRegion for the BAR immediately and + * add a subregion when we have the memory. + */ + MemoryRegion bar; + MemoryRegion ivshmem; + MemoryRegion msix_bar; uint64_t ivshmem_size; /* size of shared memory region */ int shm_fd; /* shared memory file descriptor */ @@ -96,23 +101,6 @@ static inline bool is_power_of_two(uint64_t x) { return (x & (x - 1)) == 0; } -static void ivshmem_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - IVShmemState *s = DO_UPCAST(IVShmemState, dev, pci_dev); - - s->shm_pci_addr = addr; - - if (s->ivshmem_offset > 0) { - cpu_register_physical_memory(s->shm_pci_addr, s->ivshmem_size, - s->ivshmem_offset); - } - - IVSHMEM_DPRINTF("guest pci addr = %" FMT_PCIBUS ", guest h/w addr = %" - PRIu64 ", size = %" FMT_PCIBUS "\n", addr, s->ivshmem_offset, size); - -} - /* accessing registers - based on rtl8139 */ static void ivshmem_update_irq(IVShmemState *s, int val) { @@ -168,15 +156,8 @@ static uint32_t ivshmem_IntrStatus_read(IVShmemState *s) return ret; } -static void ivshmem_io_writew(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - - IVSHMEM_DPRINTF("We shouldn't be writing words\n"); -} - -static void ivshmem_io_writel(void *opaque, target_phys_addr_t addr, - uint32_t val) +static void ivshmem_io_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { IVShmemState *s = opaque; @@ -219,20 +200,8 @@ static void ivshmem_io_writel(void *opaque, target_phys_addr_t addr, } } -static void ivshmem_io_writeb(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - IVSHMEM_DPRINTF("We shouldn't be writing bytes\n"); -} - -static uint32_t ivshmem_io_readw(void *opaque, target_phys_addr_t addr) -{ - - IVSHMEM_DPRINTF("We shouldn't be reading words\n"); - return 0; -} - -static uint32_t ivshmem_io_readl(void *opaque, target_phys_addr_t addr) +static uint64_t ivshmem_io_read(void *opaque, target_phys_addr_t addr, + unsigned size) { IVShmemState *s = opaque; @@ -265,23 +234,14 @@ static uint32_t ivshmem_io_readl(void *opaque, target_phys_addr_t addr) return ret; } -static uint32_t ivshmem_io_readb(void *opaque, target_phys_addr_t addr) -{ - IVSHMEM_DPRINTF("We shouldn't be reading bytes\n"); - - return 0; -} - -static CPUReadMemoryFunc * const ivshmem_mmio_read[3] = { - ivshmem_io_readb, - ivshmem_io_readw, - ivshmem_io_readl, -}; - -static CPUWriteMemoryFunc * const ivshmem_mmio_write[3] = { - ivshmem_io_writeb, - ivshmem_io_writew, - ivshmem_io_writel, +static const MemoryRegionOps ivshmem_mmio_ops = { + .read = ivshmem_io_read, + .write = ivshmem_io_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, }; static void ivshmem_receive(void *opaque, const uint8_t *buf, int size) @@ -371,12 +331,12 @@ static void create_shared_memory_BAR(IVShmemState *s, int fd) { ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - s->ivshmem_offset = qemu_ram_alloc_from_ptr(&s->dev.qdev, "ivshmem.bar2", - s->ivshmem_size, ptr); + memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev, "ivshmem.bar2", + s->ivshmem_size, ptr); + memory_region_add_subregion(&s->bar, 0, &s->ivshmem); /* region for shared memory */ - pci_register_bar(&s->dev, 2, s->ivshmem_size, - PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map); + pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar); } static void close_guest_eventfds(IVShmemState *s, int posn) @@ -401,8 +361,12 @@ static void setup_ioeventfds(IVShmemState *s) { for (i = 0; i <= s->max_peer; i++) { for (j = 0; j < s->peers[i].nb_eventfds; j++) { - kvm_set_ioeventfd_mmio_long(s->peers[i].eventfds[j], - s->mmio_addr + DOORBELL, (i << 16) | j, 1); + memory_region_add_eventfd(&s->ivshmem_mmio, + DOORBELL, + 4, + true, + (i << 16) | j, + s->peers[i].eventfds[j]); } } } @@ -483,18 +447,13 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags) /* mmap the region and map into the BAR2 */ map_ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, incoming_fd, 0); - s->ivshmem_offset = qemu_ram_alloc_from_ptr(&s->dev.qdev, - "ivshmem.bar2", s->ivshmem_size, map_ptr); + memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev, + "ivshmem.bar2", s->ivshmem_size, map_ptr); - IVSHMEM_DPRINTF("guest pci addr = %" FMT_PCIBUS ", guest h/w addr = %" - PRIu64 ", size = %" PRIu64 "\n", s->shm_pci_addr, + IVSHMEM_DPRINTF("guest h/w addr = %" PRIu64 ", size = %" PRIu64 "\n", s->ivshmem_offset, s->ivshmem_size); - if (s->shm_pci_addr > 0) { - /* map memory into BAR2 */ - cpu_register_physical_memory(s->shm_pci_addr, s->ivshmem_size, - s->ivshmem_offset); - } + memory_region_add_subregion(&s->bar, 0, &s->ivshmem); /* only store the fd if it is successfully mapped */ s->shm_fd = incoming_fd; @@ -549,20 +508,6 @@ static void ivshmem_reset(DeviceState *d) return; } -static void ivshmem_mmio_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - IVShmemState *s = DO_UPCAST(IVShmemState, dev, pci_dev); - - s->mmio_addr = addr; - cpu_register_physical_memory(addr + 0, IVSHMEM_REG_BAR_SIZE, - s->ivshmem_mmio_io_addr); - - if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) { - setup_ioeventfds(s); - } -} - static uint64_t ivshmem_get_size(IVShmemState * s) { uint64_t value; @@ -596,11 +541,10 @@ static void ivshmem_setup_msi(IVShmemState * s) { /* allocate the MSI-X vectors */ - if (!msix_init(&s->dev, s->vectors, 1, 0)) { - pci_register_bar(&s->dev, 1, - msix_bar_size(&s->dev), - PCI_BASE_ADDRESS_SPACE_MEMORY, - msix_mmio_map); + memory_region_init(&s->msix_bar, "ivshmem-msix", 4096); + if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) { + pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, + &s->msix_bar); IVSHMEM_DPRINTF("msix initialized (%d vectors)\n", s->vectors); } else { IVSHMEM_DPRINTF("msix initialization failed\n"); @@ -710,15 +654,20 @@ static int pci_ivshmem_init(PCIDevice *dev) pci_config_set_interrupt_pin(pci_conf, 1); - s->shm_pci_addr = 0; - s->ivshmem_offset = 0; s->shm_fd = 0; - s->ivshmem_mmio_io_addr = cpu_register_io_memory(ivshmem_mmio_read, - ivshmem_mmio_write, s, DEVICE_NATIVE_ENDIAN); + memory_region_init_io(&s->ivshmem_mmio, &ivshmem_mmio_ops, s, + "ivshmem-mmio", IVSHMEM_REG_BAR_SIZE); + + if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) { + setup_ioeventfds(s); + } + /* region for registers*/ - pci_register_bar(&s->dev, 0, IVSHMEM_REG_BAR_SIZE, - PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_mmio_map); + pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, + &s->ivshmem_mmio); + + memory_region_init(&s->bar, "ivshmem-bar2-container", s->ivshmem_size); if ((s->server_chr != NULL) && (strncmp(s->server_chr->filename, "unix:", 5) == 0)) { @@ -744,8 +693,8 @@ static int pci_ivshmem_init(PCIDevice *dev) /* allocate/initialize space for interrupt handling */ s->peers = qemu_mallocz(s->nb_peers * sizeof(Peer)); - pci_register_bar(&s->dev, 2, s->ivshmem_size, - PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map); + pci_register_bar(&s->dev, 2, + PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ivshmem); s->eventfd_chr = qemu_mallocz(s->vectors * sizeof(CharDriverState *)); @@ -792,7 +741,10 @@ static int pci_ivshmem_uninit(PCIDevice *dev) { IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev); - cpu_unregister_io_memory(s->ivshmem_mmio_io_addr); + memory_region_destroy(&s->ivshmem_mmio); + memory_region_del_subregion(&s->bar, &s->ivshmem); + memory_region_destroy(&s->ivshmem); + memory_region_destroy(&s->bar); unregister_savevm(&dev->qdev, "ivshmem", s); return 0; diff --git a/hw/kvmclock.c b/hw/kvmclock.c index 692ad182f0..b73aec409c 100644 --- a/hw/kvmclock.c +++ b/hw/kvmclock.c @@ -101,11 +101,8 @@ static SysBusDeviceInfo kvmclock_info = { void kvmclock_create(void) { if (kvm_enabled() && - first_cpu->cpuid_kvm_features & ((1ULL << KVM_FEATURE_CLOCKSOURCE) -#ifdef KVM_FEATURE_CLOCKSOURCE2 - || (1ULL << KVM_FEATURE_CLOCKSOURCE2) -#endif - )) { + first_cpu->cpuid_kvm_features & ((1ULL << KVM_FEATURE_CLOCKSOURCE) | + (1ULL << KVM_FEATURE_CLOCKSOURCE2))) { sysbus_create_simple("kvmclock", -1, NULL); } } diff --git a/hw/lance.c b/hw/lance.c index ddb1cbb7a4..d83e7f57a9 100644 --- a/hw/lance.c +++ b/hw/lance.c @@ -55,8 +55,8 @@ static void parent_lance_reset(void *opaque, int irq, int level) pcnet_h_reset(&d->state); } -static void lance_mem_writew(void *opaque, target_phys_addr_t addr, - uint32_t val) +static void lance_mem_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { SysBusPCNetState *d = opaque; @@ -64,7 +64,8 @@ static void lance_mem_writew(void *opaque, target_phys_addr_t addr, pcnet_ioport_writew(&d->state, addr, val & 0xffff); } -static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr) +static uint64_t lance_mem_read(void *opaque, target_phys_addr_t addr, + unsigned size) { SysBusPCNetState *d = opaque; uint32_t val; @@ -74,16 +75,14 @@ static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr) return val & 0xffff; } -static CPUReadMemoryFunc * const lance_mem_read[3] = { - NULL, - lance_mem_readw, - NULL, -}; - -static CPUWriteMemoryFunc * const lance_mem_write[3] = { - NULL, - lance_mem_writew, - NULL, +static const MemoryRegionOps lance_mem_ops = { + .read = lance_mem_read, + .write = lance_mem_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 2, + .max_access_size = 2, + }, }; static void lance_cleanup(VLANClientState *nc) @@ -117,13 +116,11 @@ static int lance_init(SysBusDevice *dev) SysBusPCNetState *d = FROM_SYSBUS(SysBusPCNetState, dev); PCNetState *s = &d->state; - s->mmio_index = - cpu_register_io_memory(lance_mem_read, lance_mem_write, d, - DEVICE_NATIVE_ENDIAN); + memory_region_init_io(&s->mmio, &lance_mem_ops, d, "lance-mmio", 4); qdev_init_gpio_in(&dev->qdev, parent_lance_reset, 1); - sysbus_init_mmio(dev, 4, s->mmio_index); + sysbus_init_mmio_region(dev, &s->mmio); sysbus_init_irq(dev, &s->irq); diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index e9904c49d9..d067a0227e 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -185,9 +185,9 @@ typedef struct lsi_request { typedef struct { PCIDevice dev; - int mmio_io_addr; - int ram_io_addr; - uint32_t script_ram_base; + MemoryRegion mmio_io; + MemoryRegion ram_io; + MemoryRegion io_io; int carry; /* ??? Should this be an a visible register somewhere? */ int status; @@ -391,10 +391,9 @@ static inline uint32_t read_dword(LSIState *s, uint32_t addr) { uint32_t buf; - /* Optimize reading from SCRIPTS RAM. */ - if ((addr & 0xffffe000) == s->script_ram_base) { - return s->script_ram[(addr & 0x1fff) >> 2]; - } + /* XXX: an optimization here used to fast-path the read from scripts + * memory. But that bypasses any iommu. + */ cpu_physical_memory_read(addr, (uint8_t *)&buf, 4); return cpu_to_le32(buf); } @@ -1899,232 +1898,90 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val) #undef CASE_SET_REG32 } -static void lsi_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) +static void lsi_mmio_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { LSIState *s = opaque; lsi_reg_writeb(s, addr & 0xff, val); } -static void lsi_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - LSIState *s = opaque; - - addr &= 0xff; - lsi_reg_writeb(s, addr, val & 0xff); - lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff); -} - -static void lsi_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - LSIState *s = opaque; - - addr &= 0xff; - lsi_reg_writeb(s, addr, val & 0xff); - lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff); - lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff); - lsi_reg_writeb(s, addr + 3, (val >> 24) & 0xff); -} - -static uint32_t lsi_mmio_readb(void *opaque, target_phys_addr_t addr) +static uint64_t lsi_mmio_read(void *opaque, target_phys_addr_t addr, + unsigned size) { LSIState *s = opaque; return lsi_reg_readb(s, addr & 0xff); } -static uint32_t lsi_mmio_readw(void *opaque, target_phys_addr_t addr) -{ - LSIState *s = opaque; - uint32_t val; - - addr &= 0xff; - val = lsi_reg_readb(s, addr); - val |= lsi_reg_readb(s, addr + 1) << 8; - return val; -} - -static uint32_t lsi_mmio_readl(void *opaque, target_phys_addr_t addr) -{ - LSIState *s = opaque; - uint32_t val; - addr &= 0xff; - val = lsi_reg_readb(s, addr); - val |= lsi_reg_readb(s, addr + 1) << 8; - val |= lsi_reg_readb(s, addr + 2) << 16; - val |= lsi_reg_readb(s, addr + 3) << 24; - return val; -} - -static CPUReadMemoryFunc * const lsi_mmio_readfn[3] = { - lsi_mmio_readb, - lsi_mmio_readw, - lsi_mmio_readl, -}; - -static CPUWriteMemoryFunc * const lsi_mmio_writefn[3] = { - lsi_mmio_writeb, - lsi_mmio_writew, - lsi_mmio_writel, +static const MemoryRegionOps lsi_mmio_ops = { + .read = lsi_mmio_read, + .write = lsi_mmio_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, }; -static void lsi_ram_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) +static void lsi_ram_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { LSIState *s = opaque; uint32_t newval; + uint32_t mask; int shift; - addr &= 0x1fff; newval = s->script_ram[addr >> 2]; shift = (addr & 3) * 8; - newval &= ~(0xff << shift); + mask = ((uint64_t)1 << (size * 8)) - 1; + newval &= ~(mask << shift); newval |= val << shift; s->script_ram[addr >> 2] = newval; } -static void lsi_ram_writew(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - LSIState *s = opaque; - uint32_t newval; - - addr &= 0x1fff; - newval = s->script_ram[addr >> 2]; - if (addr & 2) { - newval = (newval & 0xffff) | (val << 16); - } else { - newval = (newval & 0xffff0000) | val; - } - s->script_ram[addr >> 2] = newval; -} - - -static void lsi_ram_writel(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - LSIState *s = opaque; - - addr &= 0x1fff; - s->script_ram[addr >> 2] = val; -} - -static uint32_t lsi_ram_readb(void *opaque, target_phys_addr_t addr) +static uint64_t lsi_ram_read(void *opaque, target_phys_addr_t addr, + unsigned size) { LSIState *s = opaque; uint32_t val; + uint32_t mask; - addr &= 0x1fff; val = s->script_ram[addr >> 2]; + mask = ((uint64_t)1 << (size * 8)) - 1; val >>= (addr & 3) * 8; - return val & 0xff; -} - -static uint32_t lsi_ram_readw(void *opaque, target_phys_addr_t addr) -{ - LSIState *s = opaque; - uint32_t val; - - addr &= 0x1fff; - val = s->script_ram[addr >> 2]; - if (addr & 2) - val >>= 16; - return val; -} - -static uint32_t lsi_ram_readl(void *opaque, target_phys_addr_t addr) -{ - LSIState *s = opaque; - - addr &= 0x1fff; - return s->script_ram[addr >> 2]; + return val & mask; } -static CPUReadMemoryFunc * const lsi_ram_readfn[3] = { - lsi_ram_readb, - lsi_ram_readw, - lsi_ram_readl, +static const MemoryRegionOps lsi_ram_ops = { + .read = lsi_ram_read, + .write = lsi_ram_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const lsi_ram_writefn[3] = { - lsi_ram_writeb, - lsi_ram_writew, - lsi_ram_writel, -}; - -static uint32_t lsi_io_readb(void *opaque, uint32_t addr) +static uint64_t lsi_io_read(void *opaque, target_phys_addr_t addr, + unsigned size) { LSIState *s = opaque; return lsi_reg_readb(s, addr & 0xff); } -static uint32_t lsi_io_readw(void *opaque, uint32_t addr) -{ - LSIState *s = opaque; - uint32_t val; - addr &= 0xff; - val = lsi_reg_readb(s, addr); - val |= lsi_reg_readb(s, addr + 1) << 8; - return val; -} - -static uint32_t lsi_io_readl(void *opaque, uint32_t addr) -{ - LSIState *s = opaque; - uint32_t val; - addr &= 0xff; - val = lsi_reg_readb(s, addr); - val |= lsi_reg_readb(s, addr + 1) << 8; - val |= lsi_reg_readb(s, addr + 2) << 16; - val |= lsi_reg_readb(s, addr + 3) << 24; - return val; -} - -static void lsi_io_writeb(void *opaque, uint32_t addr, uint32_t val) +static void lsi_io_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { LSIState *s = opaque; lsi_reg_writeb(s, addr & 0xff, val); } -static void lsi_io_writew(void *opaque, uint32_t addr, uint32_t val) -{ - LSIState *s = opaque; - addr &= 0xff; - lsi_reg_writeb(s, addr, val & 0xff); - lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff); -} - -static void lsi_io_writel(void *opaque, uint32_t addr, uint32_t val) -{ - LSIState *s = opaque; - addr &= 0xff; - lsi_reg_writeb(s, addr, val & 0xff); - lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff); - lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff); - lsi_reg_writeb(s, addr + 3, (val >> 24) & 0xff); -} - -static void lsi_io_mapfunc(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - LSIState *s = DO_UPCAST(LSIState, dev, pci_dev); - - DPRINTF("Mapping IO at %08"FMT_PCIBUS"\n", addr); - - register_ioport_write(addr, 256, 1, lsi_io_writeb, s); - register_ioport_read(addr, 256, 1, lsi_io_readb, s); - register_ioport_write(addr, 256, 2, lsi_io_writew, s); - register_ioport_read(addr, 256, 2, lsi_io_readw, s); - register_ioport_write(addr, 256, 4, lsi_io_writel, s); - register_ioport_read(addr, 256, 4, lsi_io_readl, s); -} - -static void lsi_ram_mapfunc(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - LSIState *s = DO_UPCAST(LSIState, dev, pci_dev); - - DPRINTF("Mapping ram at %08"FMT_PCIBUS"\n", addr); - s->script_ram_base = addr; - cpu_register_physical_memory(addr + 0, 0x2000, s->ram_io_addr); -} +static const MemoryRegionOps lsi_io_ops = { + .read = lsi_io_read, + .write = lsi_io_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; static void lsi_scsi_reset(DeviceState *dev) { @@ -2231,8 +2088,9 @@ static int lsi_scsi_uninit(PCIDevice *d) { LSIState *s = DO_UPCAST(LSIState, dev, d); - cpu_unregister_io_memory(s->mmio_io_addr); - cpu_unregister_io_memory(s->ram_io_addr); + memory_region_destroy(&s->mmio_io); + memory_region_destroy(&s->ram_io); + memory_region_destroy(&s->io_io); return 0; } @@ -2256,18 +2114,13 @@ static int lsi_scsi_init(PCIDevice *dev) /* Interrupt pin 1 */ pci_conf[PCI_INTERRUPT_PIN] = 0x01; - s->mmio_io_addr = cpu_register_io_memory(lsi_mmio_readfn, - lsi_mmio_writefn, s, - DEVICE_NATIVE_ENDIAN); - s->ram_io_addr = cpu_register_io_memory(lsi_ram_readfn, - lsi_ram_writefn, s, - DEVICE_NATIVE_ENDIAN); - - pci_register_bar(&s->dev, 0, 256, - PCI_BASE_ADDRESS_SPACE_IO, lsi_io_mapfunc); - pci_register_bar_simple(&s->dev, 1, 0x400, 0, s->mmio_io_addr); - pci_register_bar(&s->dev, 2, 0x2000, - PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_ram_mapfunc); + memory_region_init_io(&s->mmio_io, &lsi_mmio_ops, s, "lsi-mmio", 0x400); + memory_region_init_io(&s->ram_io, &lsi_ram_ops, s, "lsi-ram", 0x2000); + memory_region_init_io(&s->io_io, &lsi_io_ops, s, "lsi-io", 256); + + pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_io); + pci_register_bar(&s->dev, 1, 0, &s->mmio_io); + pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ram_io); QTAILQ_INIT(&s->queue); scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, &lsi_scsi_ops); diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c index ed4458e3bb..350d901edc 100644 --- a/hw/mac_dbdma.c +++ b/hw/mac_dbdma.c @@ -166,6 +166,7 @@ typedef struct DBDMA_channel { } DBDMA_channel; typedef struct { + MemoryRegion mem; DBDMA_channel channels[DBDMA_CHANNELS]; } DBDMAState; @@ -703,8 +704,8 @@ dbdma_control_write(DBDMA_channel *ch) ch->flush(&ch->io); } -static void dbdma_writel (void *opaque, - target_phys_addr_t addr, uint32_t value) +static void dbdma_write(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) { int channel = addr >> DBDMA_CHANNEL_SHIFT; DBDMAState *s = opaque; @@ -753,7 +754,8 @@ static void dbdma_writel (void *opaque, } } -static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr) +static uint64_t dbdma_read(void *opaque, target_phys_addr_t addr, + unsigned size) { uint32_t value; int channel = addr >> DBDMA_CHANNEL_SHIFT; @@ -798,16 +800,14 @@ static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr) return value; } -static CPUWriteMemoryFunc * const dbdma_write[] = { - NULL, - NULL, - dbdma_writel, -}; - -static CPUReadMemoryFunc * const dbdma_read[] = { - NULL, - NULL, - dbdma_readl, +static const MemoryRegionOps dbdma_ops = { + .read = dbdma_read, + .write = dbdma_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, }; static const VMStateDescription vmstate_dbdma_channel = { @@ -842,14 +842,14 @@ static void dbdma_reset(void *opaque) memset(s->channels[i].regs, 0, DBDMA_SIZE); } -void* DBDMA_init (int *dbdma_mem_index) +void* DBDMA_init (MemoryRegion **dbdma_mem) { DBDMAState *s; s = qemu_mallocz(sizeof(DBDMAState)); - *dbdma_mem_index = cpu_register_io_memory(dbdma_read, dbdma_write, s, - DEVICE_LITTLE_ENDIAN); + memory_region_init_io(&s->mem, &dbdma_ops, s, "dbdma", 0x1000); + *dbdma_mem = &s->mem; vmstate_register(NULL, -1, &vmstate_dbdma, s); qemu_register_reset(dbdma_reset, s); diff --git a/hw/mac_dbdma.h b/hw/mac_dbdma.h index d236c5b3f2..933e17c5b9 100644 --- a/hw/mac_dbdma.h +++ b/hw/mac_dbdma.h @@ -20,6 +20,8 @@ * THE SOFTWARE. */ +#include "memory.h" + typedef struct DBDMA_io DBDMA_io; typedef void (*DBDMA_flush)(DBDMA_io *io); @@ -40,4 +42,4 @@ void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, DBDMA_rw rw, DBDMA_flush flush, void *opaque); void DBDMA_schedule(void); -void* DBDMA_init (int *dbdma_mem_index); +void* DBDMA_init (MemoryRegion **dbdma_mem); diff --git a/hw/mac_nvram.c b/hw/mac_nvram.c index 61e53d28b4..ced1e585da 100644 --- a/hw/mac_nvram.c +++ b/hw/mac_nvram.c @@ -39,7 +39,7 @@ struct MacIONVRAMState { uint32_t size; - int mem_index; + MemoryRegion mem; unsigned int it_shift; uint8_t *data; }; @@ -71,8 +71,8 @@ void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val) } /* macio style NVRAM device */ -static void macio_nvram_writeb (void *opaque, - target_phys_addr_t addr, uint32_t value) +static void macio_nvram_writeb(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) { MacIONVRAMState *s = opaque; @@ -81,7 +81,8 @@ static void macio_nvram_writeb (void *opaque, NVR_DPRINTF("writeb addr %04x val %x\n", (int)addr, value); } -static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr) +static uint64_t macio_nvram_readb(void *opaque, target_phys_addr_t addr, + unsigned size) { MacIONVRAMState *s = opaque; uint32_t value; @@ -93,16 +94,10 @@ static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr) return value; } -static CPUWriteMemoryFunc * const nvram_write[] = { - &macio_nvram_writeb, - &macio_nvram_writeb, - &macio_nvram_writeb, -}; - -static CPUReadMemoryFunc * const nvram_read[] = { - &macio_nvram_readb, - &macio_nvram_readb, - &macio_nvram_readb, +static const MemoryRegionOps macio_nvram_ops = { + .read = macio_nvram_readb, + .write = macio_nvram_writeb, + .endianness = DEVICE_NATIVE_ENDIAN, }; static const VMStateDescription vmstate_macio_nvram = { @@ -121,7 +116,7 @@ static void macio_nvram_reset(void *opaque) { } -MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size, +MacIONVRAMState *macio_nvram_init (target_phys_addr_t size, unsigned int it_shift) { MacIONVRAMState *s; @@ -131,22 +126,18 @@ MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size, s->size = size; s->it_shift = it_shift; - s->mem_index = cpu_register_io_memory(nvram_read, nvram_write, s, - DEVICE_NATIVE_ENDIAN); - *mem_index = s->mem_index; + memory_region_init_io(&s->mem, &macio_nvram_ops, s, "macio-nvram", + size << it_shift); vmstate_register(NULL, -1, &vmstate_macio_nvram, s); qemu_register_reset(macio_nvram_reset, s); return s; } -void macio_nvram_map (void *opaque, target_phys_addr_t mem_base) +void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar, + target_phys_addr_t mem_base) { - MacIONVRAMState *s; - - s = opaque; - cpu_register_physical_memory(mem_base, s->size << s->it_shift, - s->mem_index); + memory_region_add_subregion(bar, mem_base, &s->mem); } /* Set up a system OpenBIOS NVRAM partition */ diff --git a/hw/macio.c b/hw/macio.c index 789ca5529d..cc6ae40050 100644 --- a/hw/macio.c +++ b/hw/macio.c @@ -30,58 +30,55 @@ typedef struct macio_state_t macio_state_t; struct macio_state_t { int is_oldworld; - int pic_mem_index; - int dbdma_mem_index; - int cuda_mem_index; - int escc_mem_index; + MemoryRegion bar; + MemoryRegion *pic_mem; + MemoryRegion *dbdma_mem; + MemoryRegion *cuda_mem; + MemoryRegion *escc_mem; void *nvram; int nb_ide; - int ide_mem_index[4]; + MemoryRegion *ide_mem[4]; }; -static void macio_map (PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static void macio_bar_setup(macio_state_t *macio_state) { - macio_state_t *macio_state; int i; + MemoryRegion *bar = &macio_state->bar; - macio_state = (macio_state_t *)(pci_dev + 1); - if (macio_state->pic_mem_index >= 0) { + memory_region_init(bar, "macio", 0x80000); + if (macio_state->pic_mem) { if (macio_state->is_oldworld) { /* Heathrow PIC */ - cpu_register_physical_memory(addr + 0x00000, 0x1000, - macio_state->pic_mem_index); + memory_region_add_subregion(bar, 0x00000, macio_state->pic_mem); } else { /* OpenPIC */ - cpu_register_physical_memory(addr + 0x40000, 0x40000, - macio_state->pic_mem_index); + memory_region_add_subregion(bar, 0x40000, macio_state->pic_mem); } } - if (macio_state->dbdma_mem_index >= 0) { - cpu_register_physical_memory(addr + 0x08000, 0x1000, - macio_state->dbdma_mem_index); + if (macio_state->dbdma_mem) { + memory_region_add_subregion(bar, 0x08000, macio_state->dbdma_mem); } - if (macio_state->escc_mem_index >= 0) { - cpu_register_physical_memory(addr + 0x13000, ESCC_SIZE << 4, - macio_state->escc_mem_index); + if (macio_state->escc_mem) { + memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem); } - if (macio_state->cuda_mem_index >= 0) { - cpu_register_physical_memory(addr + 0x16000, 0x2000, - macio_state->cuda_mem_index); + if (macio_state->cuda_mem) { + memory_region_add_subregion(bar, 0x16000, macio_state->cuda_mem); } for (i = 0; i < macio_state->nb_ide; i++) { - if (macio_state->ide_mem_index[i] >= 0) { - cpu_register_physical_memory(addr + 0x1f000 + (i * 0x1000), 0x1000, - macio_state->ide_mem_index[i]); + if (macio_state->ide_mem[i]) { + memory_region_add_subregion(bar, 0x1f000 + (i * 0x1000), + macio_state->ide_mem[i]); } } if (macio_state->nvram != NULL) - macio_nvram_map(macio_state->nvram, addr + 0x60000); + macio_nvram_setup_bar(macio_state->nvram, bar, 0x60000); } -void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index, - int dbdma_mem_index, int cuda_mem_index, void *nvram, - int nb_ide, int *ide_mem_index, int escc_mem_index) +void macio_init (PCIBus *bus, int device_id, int is_oldworld, + MemoryRegion *pic_mem, MemoryRegion *dbdma_mem, + MemoryRegion *cuda_mem, void *nvram, + int nb_ide, MemoryRegion **ide_mem, + MemoryRegion *escc_mem) { PCIDevice *d; macio_state_t *macio_state; @@ -92,18 +89,18 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index, -1, NULL, NULL); macio_state = (macio_state_t *)(d + 1); macio_state->is_oldworld = is_oldworld; - macio_state->pic_mem_index = pic_mem_index; - macio_state->dbdma_mem_index = dbdma_mem_index; - macio_state->cuda_mem_index = cuda_mem_index; - macio_state->escc_mem_index = escc_mem_index; + macio_state->pic_mem = pic_mem; + macio_state->dbdma_mem = dbdma_mem; + macio_state->cuda_mem = cuda_mem; + macio_state->escc_mem = escc_mem; macio_state->nvram = nvram; if (nb_ide > 4) nb_ide = 4; macio_state->nb_ide = nb_ide; for (i = 0; i < nb_ide; i++) - macio_state->ide_mem_index[i] = ide_mem_index[i]; + macio_state->ide_mem[i] = ide_mem[i]; for (; i < 4; i++) - macio_state->ide_mem_index[i] = -1; + macio_state->ide_mem[i] = NULL; /* Note: this code is strongly inspirated from the corresponding code in PearPC */ @@ -113,6 +110,6 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index, d->config[0x3d] = 0x01; // interrupt on pin 1 - pci_register_bar(d, 0, 0x80000, - PCI_BASE_ADDRESS_SPACE_MEMORY, macio_map); + macio_bar_setup(macio_state); + pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &macio_state->bar); } diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c index 75c85aeb6f..fe4eedb2cb 100644 --- a/hw/milkymist-softusb.c +++ b/hw/milkymist-softusb.c @@ -25,7 +25,7 @@ #include "sysbus.h" #include "trace.h" #include "console.h" -#include "usb.h" +#include "hid.h" #include "qemu-error.h" enum { @@ -46,9 +46,8 @@ enum { struct MilkymistSoftUsbState { SysBusDevice busdev; - USBBus usbbus; - USBPort usbport[2]; - USBDevice *usbdev; + HIDState hid_kbd; + HIDState hid_mouse; qemu_irq irq; @@ -62,13 +61,10 @@ struct MilkymistSoftUsbState { uint32_t regs[R_MAX]; /* mouse state */ - int mouse_dx; - int mouse_dy; - int mouse_dz; - uint8_t mouse_buttons_state; + uint8_t mouse_hid_buffer[4]; /* keyboard state */ - uint8_t kbd_usb_buffer[8]; + uint8_t kbd_hid_buffer[8]; }; typedef struct MilkymistSoftUsbState MilkymistSoftUsbState; @@ -177,16 +173,10 @@ static inline void softusb_write_pmem(MilkymistSoftUsbState *s, static void softusb_mouse_changed(MilkymistSoftUsbState *s) { uint8_t m; - uint8_t buf[4]; - - buf[0] = s->mouse_buttons_state; - buf[1] = s->mouse_dx; - buf[2] = s->mouse_dy; - buf[3] = s->mouse_dz; softusb_read_dmem(s, COMLOC_MEVT_PRODUCE, &m, 1); trace_milkymist_softusb_mevt(m); - softusb_write_dmem(s, COMLOC_MEVT_BASE + 4 * m, buf, 4); + softusb_write_dmem(s, COMLOC_MEVT_BASE + 4 * m, s->mouse_hid_buffer, 4); m = (m + 1) & 0xf; softusb_write_dmem(s, COMLOC_MEVT_PRODUCE, &m, 1); @@ -200,7 +190,7 @@ static void softusb_kbd_changed(MilkymistSoftUsbState *s) softusb_read_dmem(s, COMLOC_KEVT_PRODUCE, &m, 1); trace_milkymist_softusb_kevt(m); - softusb_write_dmem(s, COMLOC_KEVT_BASE + 8 * m, s->kbd_usb_buffer, 8); + softusb_write_dmem(s, COMLOC_KEVT_BASE + 8 * m, s->kbd_hid_buffer, 8); m = (m + 1) & 0x7; softusb_write_dmem(s, COMLOC_KEVT_PRODUCE, &m, 1); @@ -208,62 +198,42 @@ static void softusb_kbd_changed(MilkymistSoftUsbState *s) qemu_irq_pulse(s->irq); } -static void softusb_mouse_event(void *opaque, - int dx, int dy, int dz, int buttons_state) +static void softusb_kbd_hid_datain(HIDState *hs) { - MilkymistSoftUsbState *s = opaque; + MilkymistSoftUsbState *s = container_of(hs, MilkymistSoftUsbState, hid_kbd); + int len; /* if device is in reset, do nothing */ if (s->regs[R_CTRL] & CTRL_RESET) { return; } - trace_milkymist_softusb_mouse_event(dx, dy, dz, buttons_state); + len = hid_keyboard_poll(hs, s->kbd_hid_buffer, sizeof(s->kbd_hid_buffer)); - s->mouse_dx = dx; - s->mouse_dy = dy; - s->mouse_dz = dz; - s->mouse_buttons_state = buttons_state; - - softusb_mouse_changed(s); + if (len == 8) { + softusb_kbd_changed(s); + } } -static void softusb_usbdev_datain(void *opaque) +static void softusb_mouse_hid_datain(HIDState *hs) { - MilkymistSoftUsbState *s = opaque; - - USBPacket p; - - usb_packet_init(&p); - usb_packet_setup(&p, USB_TOKEN_IN, 0, 1); - usb_packet_addbuf(&p, s->kbd_usb_buffer, sizeof(s->kbd_usb_buffer)); - s->usbdev->info->handle_data(s->usbdev, &p); - usb_packet_cleanup(&p); - - softusb_kbd_changed(s); -} + MilkymistSoftUsbState *s = + container_of(hs, MilkymistSoftUsbState, hid_mouse); + int len; -static void softusb_attach(USBPort *port) -{ -} + /* if device is in reset, do nothing */ + if (s->regs[R_CTRL] & CTRL_RESET) { + return; + } -static void softusb_detach(USBPort *port) -{ -} + len = hid_pointer_poll(hs, s->mouse_hid_buffer, + sizeof(s->mouse_hid_buffer)); -static void softusb_child_detach(USBPort *port, USBDevice *child) -{ + if (len == 4) { + softusb_mouse_changed(s); + } } -static USBPortOps softusb_ops = { - .attach = softusb_attach, - .detach = softusb_detach, - .child_detach = softusb_child_detach, -}; - -static USBBusOps softusb_bus_ops = { -}; - static void milkymist_softusb_reset(DeviceState *d) { MilkymistSoftUsbState *s = @@ -273,11 +243,11 @@ static void milkymist_softusb_reset(DeviceState *d) for (i = 0; i < R_MAX; i++) { s->regs[i] = 0; } - s->mouse_dx = 0; - s->mouse_dy = 0; - s->mouse_dz = 0; - s->mouse_buttons_state = 0; - memset(s->kbd_usb_buffer, 0, sizeof(s->kbd_usb_buffer)); + memset(s->kbd_hid_buffer, 0, sizeof(s->kbd_hid_buffer)); + memset(s->mouse_hid_buffer, 0, sizeof(s->mouse_hid_buffer)); + + hid_reset(&s->hid_kbd); + hid_reset(&s->hid_mouse); /* defaults */ s->regs[R_CTRL] = CTRL_RESET; @@ -304,23 +274,8 @@ static int milkymist_softusb_init(SysBusDevice *dev) cpu_register_physical_memory(s->dmem_base, s->dmem_size, dmem_ram | IO_MEM_RAM); - qemu_add_mouse_event_handler(softusb_mouse_event, s, 0, "Milkymist Mouse"); - - /* create our usb bus */ - usb_bus_new(&s->usbbus, &softusb_bus_ops, NULL); - - /* our two ports */ - /* FIXME: claim to support full speed devices. qemu mouse and keyboard - * report themselves as full speed devices. */ - usb_register_port(&s->usbbus, &s->usbport[0], NULL, 0, &softusb_ops, - USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); - usb_register_port(&s->usbbus, &s->usbport[1], NULL, 1, &softusb_ops, - USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); - - /* and finally create an usb keyboard */ - s->usbdev = usb_create_simple(&s->usbbus, "usb-kbd"); - usb_hid_datain_cb(s->usbdev, s, softusb_usbdev_datain); - s->usbdev->info->handle_reset(s->usbdev); + hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain); + hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain); return 0; } @@ -332,11 +287,10 @@ static const VMStateDescription vmstate_milkymist_softusb = { .minimum_version_id_old = 1, .fields = (VMStateField[]) { VMSTATE_UINT32_ARRAY(regs, MilkymistSoftUsbState, R_MAX), - VMSTATE_INT32(mouse_dx, MilkymistSoftUsbState), - VMSTATE_INT32(mouse_dy, MilkymistSoftUsbState), - VMSTATE_INT32(mouse_dz, MilkymistSoftUsbState), - VMSTATE_UINT8(mouse_buttons_state, MilkymistSoftUsbState), - VMSTATE_BUFFER(kbd_usb_buffer, MilkymistSoftUsbState), + VMSTATE_HID_KEYBOARD_DEVICE(hid_kbd, MilkymistSoftUsbState), + VMSTATE_HID_POINTER_DEVICE(hid_mouse, MilkymistSoftUsbState), + VMSTATE_BUFFER(kbd_hid_buffer, MilkymistSoftUsbState), + VMSTATE_BUFFER(mouse_hid_buffer, MilkymistSoftUsbState), VMSTATE_END_OF_LIST() } }; @@ -82,7 +82,8 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries, return 0; } -static uint32_t msix_mmio_readl(void *opaque, target_phys_addr_t addr) +static uint64_t msix_mmio_read(void *opaque, target_phys_addr_t addr, + unsigned size) { PCIDevice *dev = opaque; unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3; @@ -91,12 +92,6 @@ static uint32_t msix_mmio_readl(void *opaque, target_phys_addr_t addr) return pci_get_long(page + offset); } -static uint32_t msix_mmio_read_unallowed(void *opaque, target_phys_addr_t addr) -{ - fprintf(stderr, "MSI-X: only dword read is allowed!\n"); - return 0; -} - static uint8_t msix_pending_mask(int vector) { return 1 << (vector % 8); @@ -169,8 +164,8 @@ void msix_write_config(PCIDevice *dev, uint32_t addr, } } -static void msix_mmio_writel(void *opaque, target_phys_addr_t addr, - uint32_t val) +static void msix_mmio_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { PCIDevice *dev = opaque; unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3; @@ -179,37 +174,25 @@ static void msix_mmio_writel(void *opaque, target_phys_addr_t addr, msix_handle_mask_update(dev, vector); } -static void msix_mmio_write_unallowed(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - fprintf(stderr, "MSI-X: only dword write is allowed!\n"); -} - -static CPUWriteMemoryFunc * const msix_mmio_write[] = { - msix_mmio_write_unallowed, msix_mmio_write_unallowed, msix_mmio_writel -}; - -static CPUReadMemoryFunc * const msix_mmio_read[] = { - msix_mmio_read_unallowed, msix_mmio_read_unallowed, msix_mmio_readl +static const MemoryRegionOps msix_mmio_ops = { + .read = msix_mmio_read, + .write = msix_mmio_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, }; -/* Should be called from device's map method. */ -void msix_mmio_map(PCIDevice *d, int region_num, - pcibus_t addr, pcibus_t size, int type) +static void msix_mmio_setup(PCIDevice *d, MemoryRegion *bar) { uint8_t *config = d->config + d->msix_cap; uint32_t table = pci_get_long(config + PCI_MSIX_TABLE); uint32_t offset = table & ~(MSIX_PAGE_SIZE - 1); /* TODO: for assigned devices, we'll want to make it possible to map * pending bits separately in case they are in a separate bar. */ - int table_bir = table & PCI_MSIX_FLAGS_BIRMASK; - if (table_bir != region_num) - return; - if (size <= offset) - return; - cpu_register_physical_memory(addr + offset, size - offset, - d->msix_mmio_index); + memory_region_add_subregion(bar, offset, &d->msix_mmio); } static void msix_mask_all(struct PCIDevice *dev, unsigned nentries) @@ -225,6 +208,7 @@ static void msix_mask_all(struct PCIDevice *dev, unsigned nentries) /* Initialize the MSI-X structures. Note: if MSI-X is supported, BAR size is * modified, it should be retrieved with msix_bar_size. */ int msix_init(struct PCIDevice *dev, unsigned short nentries, + MemoryRegion *bar, unsigned bar_nr, unsigned bar_size) { int ret; @@ -241,13 +225,8 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries, dev->msix_table_page = qemu_mallocz(MSIX_PAGE_SIZE); msix_mask_all(dev, nentries); - dev->msix_mmio_index = cpu_register_io_memory(msix_mmio_read, - msix_mmio_write, dev, - DEVICE_NATIVE_ENDIAN); - if (dev->msix_mmio_index == -1) { - ret = -EBUSY; - goto err_index; - } + memory_region_init_io(&dev->msix_mmio, &msix_mmio_ops, dev, + "msix", MSIX_PAGE_SIZE); dev->msix_entries_nr = nentries; ret = msix_add_config(dev, nentries, bar_nr, bar_size); @@ -255,12 +234,12 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries, goto err_config; dev->cap_present |= QEMU_PCI_CAP_MSIX; + msix_mmio_setup(dev, bar); return 0; err_config: dev->msix_entries_nr = 0; - cpu_unregister_io_memory(dev->msix_mmio_index); -err_index: + memory_region_destroy(&dev->msix_mmio); qemu_free(dev->msix_table_page); dev->msix_table_page = NULL; qemu_free(dev->msix_entry_used); @@ -279,7 +258,7 @@ static void msix_free_irq_entries(PCIDevice *dev) } /* Clean up resources for the device. */ -int msix_uninit(PCIDevice *dev) +int msix_uninit(PCIDevice *dev, MemoryRegion *bar) { if (!(dev->cap_present & QEMU_PCI_CAP_MSIX)) return 0; @@ -287,7 +266,8 @@ int msix_uninit(PCIDevice *dev) dev->msix_cap = 0; msix_free_irq_entries(dev); dev->msix_entries_nr = 0; - cpu_unregister_io_memory(dev->msix_mmio_index); + memory_region_del_subregion(bar, &dev->msix_mmio); + memory_region_destroy(&dev->msix_mmio); qemu_free(dev->msix_table_page); dev->msix_table_page = NULL; qemu_free(dev->msix_entry_used); @@ -5,15 +5,13 @@ #include "pci.h" int msix_init(PCIDevice *pdev, unsigned short nentries, + MemoryRegion *bar, unsigned bar_nr, unsigned bar_size); void msix_write_config(PCIDevice *pci_dev, uint32_t address, uint32_t val, int len); -void msix_mmio_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type); - -int msix_uninit(PCIDevice *d); +int msix_uninit(PCIDevice *d, MemoryRegion *bar); void msix_save(PCIDevice *dev, QEMUFile *f); void msix_load(PCIDevice *dev, QEMUFile *f); diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c index e41dbbaa79..756ed5ca46 100644 --- a/hw/ne2000-isa.c +++ b/hw/ne2000-isa.c @@ -27,6 +27,7 @@ #include "qdev.h" #include "net.h" #include "ne2000.h" +#include "exec-memory.h" typedef struct ISANE2000State { ISADevice dev; @@ -66,19 +67,11 @@ static int isa_ne2000_initfn(ISADevice *dev) ISANE2000State *isa = DO_UPCAST(ISANE2000State, dev, dev); NE2000State *s = &isa->ne2000; - register_ioport_write(isa->iobase, 16, 1, ne2000_ioport_write, s); - register_ioport_read(isa->iobase, 16, 1, ne2000_ioport_read, s); + ne2000_setup_io(s, 0x20); isa_init_ioport_range(dev, isa->iobase, 16); - - register_ioport_write(isa->iobase + 0x10, 1, 1, ne2000_asic_ioport_write, s); - register_ioport_read(isa->iobase + 0x10, 1, 1, ne2000_asic_ioport_read, s); - register_ioport_write(isa->iobase + 0x10, 2, 2, ne2000_asic_ioport_write, s); - register_ioport_read(isa->iobase + 0x10, 2, 2, ne2000_asic_ioport_read, s); isa_init_ioport_range(dev, isa->iobase + 0x10, 2); - - register_ioport_write(isa->iobase + 0x1f, 1, 1, ne2000_reset_ioport_write, s); - register_ioport_read(isa->iobase + 0x1f, 1, 1, ne2000_reset_ioport_read, s); isa_init_ioport(dev, isa->iobase + 0x1f); + memory_region_add_subregion(get_system_io(), isa->iobase, &s->io); isa_init_irq(dev, &s->irq, isa->isairq); diff --git a/hw/ne2000.c b/hw/ne2000.c index f8acaaeeb6..a035a85244 100644 --- a/hw/ne2000.c +++ b/hw/ne2000.c @@ -297,7 +297,7 @@ ssize_t ne2000_receive(VLANClientState *nc, const uint8_t *buf, size_t size_) return size_; } -void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) +static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) { NE2000State *s = opaque; int offset, page, index; @@ -394,7 +394,7 @@ void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) } } -uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) +static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) { NE2000State *s = opaque; int offset, page, ret; @@ -544,7 +544,7 @@ static inline void ne2000_dma_update(NE2000State *s, int len) } } -void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) +static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) { NE2000State *s = opaque; @@ -564,7 +564,7 @@ void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) } } -uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr) +static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr) { NE2000State *s = opaque; int ret; @@ -612,12 +612,12 @@ static uint32_t ne2000_asic_ioport_readl(void *opaque, uint32_t addr) return ret; } -void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val) +static void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val) { /* nothing to do (end of reset pulse) */ } -uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr) +static uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr) { NE2000State *s = opaque; ne2000_reset(s); @@ -676,27 +676,55 @@ static const VMStateDescription vmstate_pci_ne2000 = { } }; -/***********************************************************/ -/* PCI NE2000 definitions */ +static uint64_t ne2000_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + NE2000State *s = opaque; -static void ne2000_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) + if (addr < 0x10 && size == 1) { + return ne2000_ioport_read(s, addr); + } else if (addr == 0x10) { + if (size <= 2) { + return ne2000_asic_ioport_read(s, addr); + } else { + return ne2000_asic_ioport_readl(s, addr); + } + } else if (addr == 0x1f && size == 1) { + return ne2000_reset_ioport_read(s, addr); + } + return ((uint64_t)1 << (size * 8)) - 1; +} + +static void ne2000_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) { - PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev); - NE2000State *s = &d->ne2000; + NE2000State *s = opaque; + + if (addr < 0x10 && size == 1) { + return ne2000_ioport_write(s, addr, data); + } else if (addr == 0x10) { + if (size <= 2) { + return ne2000_asic_ioport_write(s, addr, data); + } else { + return ne2000_asic_ioport_writel(s, addr, data); + } + } else if (addr == 0x1f && size == 1) { + return ne2000_reset_ioport_write(s, addr, data); + } +} - register_ioport_write(addr, 16, 1, ne2000_ioport_write, s); - register_ioport_read(addr, 16, 1, ne2000_ioport_read, s); +static const MemoryRegionOps ne2000_ops = { + .read = ne2000_read, + .write = ne2000_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; - register_ioport_write(addr + 0x10, 1, 1, ne2000_asic_ioport_write, s); - register_ioport_read(addr + 0x10, 1, 1, ne2000_asic_ioport_read, s); - register_ioport_write(addr + 0x10, 2, 2, ne2000_asic_ioport_write, s); - register_ioport_read(addr + 0x10, 2, 2, ne2000_asic_ioport_read, s); - register_ioport_write(addr + 0x10, 4, 4, ne2000_asic_ioport_writel, s); - register_ioport_read(addr + 0x10, 4, 4, ne2000_asic_ioport_readl, s); +/***********************************************************/ +/* PCI NE2000 definitions */ - register_ioport_write(addr + 0x1f, 1, 1, ne2000_reset_ioport_write, s); - register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s); +void ne2000_setup_io(NE2000State *s, unsigned size) +{ + memory_region_init_io(&s->io, &ne2000_ops, s, "ne2000", size); } static void ne2000_cleanup(VLANClientState *nc) @@ -724,9 +752,9 @@ static int pci_ne2000_init(PCIDevice *pci_dev) /* TODO: RST# value should be 0. PCI spec 6.2.4 */ pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0 - pci_register_bar(&d->dev, 0, 0x100, - PCI_BASE_ADDRESS_SPACE_IO, ne2000_map); s = &d->ne2000; + ne2000_setup_io(s, 0x100); + pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io); s->irq = d->dev.irq[0]; qemu_macaddr_default_if_unset(&s->c.macaddr); @@ -754,6 +782,7 @@ static int pci_ne2000_exit(PCIDevice *pci_dev) PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev); NE2000State *s = &d->ne2000; + memory_region_destroy(&s->io); qemu_del_vlan_client(&s->nic->nc); return 0; } diff --git a/hw/ne2000.h b/hw/ne2000.h index 54fdfca133..5fee052194 100644 --- a/hw/ne2000.h +++ b/hw/ne2000.h @@ -4,6 +4,7 @@ #define NE2000_MEM_SIZE NE2000_PMEM_END typedef struct NE2000State { + MemoryRegion io; uint8_t cmd; uint32_t start; uint32_t stop; @@ -27,12 +28,7 @@ typedef struct NE2000State { uint8_t mem[NE2000_MEM_SIZE]; } NE2000State; -void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val); -uint32_t ne2000_ioport_read(void *opaque, uint32_t addr); -void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val); -uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr); -void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val); -uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr); +void ne2000_setup_io(NE2000State *s, unsigned size); extern const VMStateDescription vmstate_ne2000; void ne2000_reset(NE2000State *s); int ne2000_can_receive(VLANClientState *vc); diff --git a/hw/openpic.c b/hw/openpic.c index 6d2cf994ba..ccd4a14f81 100644 --- a/hw/openpic.c +++ b/hw/openpic.c @@ -205,7 +205,7 @@ typedef struct IRQ_dst_t { typedef struct openpic_t { PCIDevice pci_dev; - int mem_index; + MemoryRegion mem; /* Global registers */ uint32_t frep; /* Feature reporting register */ uint32_t glbc; /* Global configuration register */ @@ -984,47 +984,34 @@ static uint32_t openpic_readl (void *opaque,target_phys_addr_t addr) return retval; } -static CPUWriteMemoryFunc * const openpic_write[] = { - &openpic_buggy_write, - &openpic_buggy_write, - &openpic_writel, -}; +static uint64_t openpic_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + openpic_t *opp = opaque; -static CPUReadMemoryFunc * const openpic_read[] = { - &openpic_buggy_read, - &openpic_buggy_read, - &openpic_readl, -}; + switch (size) { + case 4: return openpic_readl(opp, addr); + default: return openpic_buggy_read(opp, addr); + } +} -static void openpic_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static void openpic_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) { - openpic_t *opp; + openpic_t *opp = opaque; - DPRINTF("Map OpenPIC\n"); - opp = (openpic_t *)pci_dev; - /* Global registers */ - DPRINTF("Register OPENPIC gbl %08x => %08x\n", - addr + 0x1000, addr + 0x1000 + 0x100); - /* Timer registers */ - DPRINTF("Register OPENPIC timer %08x => %08x\n", - addr + 0x1100, addr + 0x1100 + 0x40 * MAX_TMR); - /* Interrupt source registers */ - DPRINTF("Register OPENPIC src %08x => %08x\n", - addr + 0x10000, addr + 0x10000 + 0x20 * (OPENPIC_EXT_IRQ + 2)); - /* Per CPU registers */ - DPRINTF("Register OPENPIC dst %08x => %08x\n", - addr + 0x20000, addr + 0x20000 + 0x1000 * MAX_CPU); - cpu_register_physical_memory(addr, 0x40000, opp->mem_index); -#if 0 // Don't implement ISU for now - opp_io_memory = cpu_register_io_memory(openpic_src_read, - openpic_src_write, NULL - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2), - opp_io_memory); -#endif + switch (size) { + case 4: return openpic_writel(opp, addr, data); + default: return openpic_buggy_write(opp, addr, data); + } } +static const MemoryRegionOps openpic_ops = { + .read = openpic_read, + .write = openpic_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + static void openpic_save_IRQ_queue(QEMUFile* f, IRQ_queue_t *q) { unsigned int i; @@ -1161,7 +1148,7 @@ static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src) qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]); } -qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus, +qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus, qemu_irq **irqs, qemu_irq irq_out) { openpic_t *opp; @@ -1180,14 +1167,22 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus, pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER); // FIXME? pci_conf[0x3d] = 0x00; // no interrupt pin + memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000); +#if 0 // Don't implement ISU for now + opp_io_memory = cpu_register_io_memory(openpic_src_read, + openpic_src_write, NULL + DEVICE_NATIVE_ENDIAN); + cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2), + opp_io_memory); +#endif + /* Register I/O spaces */ - pci_register_bar(&opp->pci_dev, 0, 0x40000, - PCI_BASE_ADDRESS_SPACE_MEMORY, &openpic_map); + pci_register_bar(&opp->pci_dev, 0, + PCI_BASE_ADDRESS_SPACE_MEMORY, &opp->mem); } else { opp = qemu_mallocz(sizeof(openpic_t)); + memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000); } - opp->mem_index = cpu_register_io_memory(openpic_read, openpic_write, opp, - DEVICE_LITTLE_ENDIAN); // isu_base &= 0xFFFC0000; opp->nb_cpus = nb_cpus; @@ -1223,8 +1218,8 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus, opp->irq_raise = openpic_irq_raise; opp->reset = openpic_reset; - if (pmem_index) - *pmem_index = opp->mem_index; + if (pmem) + *pmem = &opp->mem; return qemu_allocate_irqs(openpic_set_irq, opp, opp->max_irq); } diff --git a/hw/openpic.h b/hw/openpic.h index 0957c1ff00..75de3616ad 100644 --- a/hw/openpic.h +++ b/hw/openpic.h @@ -11,7 +11,7 @@ enum { OPENPIC_OUTPUT_NB, }; -qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus, +qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus, qemu_irq **irqs, qemu_irq irq_out); qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus, qemu_irq **irqs, qemu_irq irq_out); @@ -179,7 +179,9 @@ struct PCII440FXState; typedef struct PCII440FXState PCII440FXState; PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, - qemu_irq *pic, MemoryRegion *address_space, + qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, ram_addr_t ram_size); void i440fx_init_memory_mappings(PCII440FXState *d); diff --git a/hw/pc_piix.c b/hw/pc_piix.c index c0a2abe4bc..7dd5008dce 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -69,6 +69,7 @@ static void ioapic_init(IsaIrqState *isa_irq_state) /* PC hardware initialisation */ static void pc_init1(MemoryRegion *system_memory, + MemoryRegion *system_io, ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, @@ -129,7 +130,7 @@ static void pc_init1(MemoryRegion *system_memory, if (pci_enabled) { pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, - system_memory, ram_size); + system_memory, system_io, ram_size); } else { pci_bus = NULL; i440fx_state = NULL; @@ -218,6 +219,7 @@ static void pc_init_pci(ram_addr_t ram_size, const char *cpu_model) { pc_init1(get_system_memory(), + get_system_io(), ram_size, boot_device, kernel_filename, kernel_cmdline, initrd_filename, cpu_model, 1, 1); @@ -231,6 +233,7 @@ static void pc_init_pci_no_kvmclock(ram_addr_t ram_size, const char *cpu_model) { pc_init1(get_system_memory(), + get_system_io(), ram_size, boot_device, kernel_filename, kernel_cmdline, initrd_filename, cpu_model, 1, 0); @@ -246,6 +249,7 @@ static void pc_init_isa(ram_addr_t ram_size, if (cpu_model == NULL) cpu_model = "486"; pc_init1(get_system_memory(), + get_system_io(), ram_size, boot_device, kernel_filename, kernel_cmdline, initrd_filename, cpu_model, 0, 1); @@ -264,13 +264,15 @@ int pci_find_domain(const PCIBus *bus) void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent, const char *name, - MemoryRegion *address_space, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, uint8_t devfn_min) { qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name); assert(PCI_FUNC(devfn_min) == 0); bus->devfn_min = devfn_min; - bus->address_space = address_space; + bus->address_space_mem = address_space_mem; + bus->address_space_io = address_space_io; /* host bridge */ QLIST_INIT(&bus->child); @@ -280,13 +282,16 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent, } PCIBus *pci_bus_new(DeviceState *parent, const char *name, - MemoryRegion *address_space, uint8_t devfn_min) + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, + uint8_t devfn_min) { PCIBus *bus; bus = qemu_mallocz(sizeof(*bus)); bus->qbus.qdev_allocated = 1; - pci_bus_new_inplace(bus, parent, name, address_space, devfn_min); + pci_bus_new_inplace(bus, parent, name, address_space_mem, + address_space_io, devfn_min); return bus; } @@ -315,12 +320,14 @@ void pci_bus_set_mem_base(PCIBus *bus, target_phys_addr_t base) PCIBus *pci_register_bus(DeviceState *parent, const char *name, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, void *irq_opaque, - MemoryRegion *address_space, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, uint8_t devfn_min, int nirq) { PCIBus *bus; - bus = pci_bus_new(parent, name, address_space, devfn_min); + bus = pci_bus_new(parent, name, address_space_mem, + address_space_io, devfn_min); pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq); return bus; } @@ -841,19 +848,7 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev) r = &pci_dev->io_regions[i]; if (!r->size || r->addr == PCI_BAR_UNMAPPED) continue; - if (r->type == PCI_BASE_ADDRESS_SPACE_IO) { - isa_unassign_ioport(r->addr, r->filtered_size); - } else { - if (r->memory) { - memory_region_del_subregion(pci_dev->bus->address_space, - r->memory); - } else { - cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus, - r->addr), - r->filtered_size, - IO_MEM_UNASSIGNED); - } - } + memory_region_del_subregion(r->address_space, r->memory); } } @@ -876,12 +871,12 @@ static int pci_unregister_device(DeviceState *dev) } void pci_register_bar(PCIDevice *pci_dev, int region_num, - pcibus_t size, uint8_t type, - PCIMapIORegionFunc *map_func) + uint8_t type, MemoryRegion *memory) { PCIIORegion *r; uint32_t addr; uint64_t wmask; + pcibus_t size = memory_region_size(memory); assert(region_num >= 0); assert(region_num < PCI_NUM_REGIONS); @@ -896,8 +891,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, r->size = size; r->filtered_size = size; r->type = type; - r->map_func = map_func; - r->ram_addr = IO_MEM_UNASSIGNED; r->memory = NULL; wmask = ~(size - 1); @@ -915,41 +908,16 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff); pci_set_long(pci_dev->cmask + addr, 0xffffffff); } + pci_dev->io_regions[region_num].memory = memory; + pci_dev->io_regions[region_num].address_space + = type & PCI_BASE_ADDRESS_SPACE_IO + ? pci_dev->bus->address_space_io + : pci_dev->bus->address_space_mem; } -static void pci_simple_bar_mapfunc(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - cpu_register_physical_memory(addr, size, - pci_dev->io_regions[region_num].ram_addr); -} - -static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, - int type) -{ - memory_region_add_subregion_overlap(pci_dev->bus->address_space, - addr, - pci_dev->io_regions[region_num].memory, - 1); -} - -void pci_register_bar_simple(PCIDevice *pci_dev, int region_num, - pcibus_t size, uint8_t attr, ram_addr_t ram_addr) -{ - pci_register_bar(pci_dev, region_num, size, - PCI_BASE_ADDRESS_SPACE_MEMORY | attr, - pci_simple_bar_mapfunc); - pci_dev->io_regions[region_num].ram_addr = ram_addr; -} - -void pci_register_bar_region(PCIDevice *pci_dev, int region_num, - uint8_t attr, MemoryRegion *memory) +pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num) { - pci_register_bar(pci_dev, region_num, memory_region_size(memory), - PCI_BASE_ADDRESS_SPACE_MEMORY | attr, - pci_simple_bar_mapfunc_region); - pci_dev->io_regions[region_num].memory = memory; + return pci_dev->io_regions[region_num].addr; } static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size, @@ -1079,28 +1047,7 @@ static void pci_update_mappings(PCIDevice *d) /* now do the real mapping */ if (r->addr != PCI_BAR_UNMAPPED) { - if (r->type & PCI_BASE_ADDRESS_SPACE_IO) { - int class; - /* NOTE: specific hack for IDE in PC case: - only one byte must be mapped. */ - class = pci_get_word(d->config + PCI_CLASS_DEVICE); - if (class == 0x0101 && r->size == 4) { - isa_unassign_ioport(r->addr + 2, 1); - } else { - isa_unassign_ioport(r->addr, r->filtered_size); - } - } else { - if (r->memory) { - memory_region_del_subregion(d->bus->address_space, - r->memory); - } else { - cpu_register_physical_memory(pci_to_cpu_addr(d->bus, - r->addr), - r->filtered_size, - IO_MEM_UNASSIGNED); - qemu_unregister_coalesced_mmio(r->addr, r->filtered_size); - } - } + memory_region_del_subregion(r->address_space, r->memory); } r->addr = new_addr; r->filtered_size = filtered_size; @@ -1113,10 +1060,16 @@ static void pci_update_mappings(PCIDevice *d) * addr & (size - 1) != 0. */ if (r->type & PCI_BASE_ADDRESS_SPACE_IO) { - r->map_func(d, i, r->addr, r->filtered_size, r->type); + memory_region_add_subregion_overlap(r->address_space, + r->addr, + r->memory, + 1); } else { - r->map_func(d, i, pci_to_cpu_addr(d->bus, r->addr), - r->filtered_size, r->type); + memory_region_add_subregion_overlap(r->address_space, + pci_to_cpu_addr(d->bus, + r->addr), + r->memory, + 1); } } } @@ -1858,11 +1811,6 @@ static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id, return next; } -static void pci_map_option_rom(PCIDevice *pdev, int region_num, pcibus_t addr, pcibus_t size, int type) -{ - cpu_register_physical_memory(addr, size, pdev->rom_offset); -} - /* Patch the PCI vendor and device ids in a PCI rom image if necessary. This is needed for an option rom which is used for more than one device. */ static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, int size) @@ -1966,9 +1914,9 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom) snprintf(name, sizeof(name), "%s.rom", pdev->qdev.info->vmsd->name); else snprintf(name, sizeof(name), "%s.rom", pdev->qdev.info->name); - pdev->rom_offset = qemu_ram_alloc(&pdev->qdev, name, size); - - ptr = qemu_get_ram_ptr(pdev->rom_offset); + pdev->has_rom = true; + memory_region_init_ram(&pdev->rom, &pdev->qdev, name, size); + ptr = memory_region_get_ram_ptr(&pdev->rom); load_image(path, ptr); qemu_free(path); @@ -1979,19 +1927,18 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom) qemu_put_ram_ptr(ptr); - pci_register_bar(pdev, PCI_ROM_SLOT, size, - 0, pci_map_option_rom); + pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom); return 0; } static void pci_del_option_rom(PCIDevice *pdev) { - if (!pdev->rom_offset) + if (!pdev->has_rom) return; - qemu_ram_free(pdev->rom_offset); - pdev->rom_offset = 0; + memory_region_destroy(&pdev->rom); + pdev->has_rom = false; } /* @@ -92,9 +92,8 @@ typedef struct PCIIORegion { pcibus_t size; pcibus_t filtered_size; uint8_t type; - PCIMapIORegionFunc *map_func; - ram_addr_t ram_addr; MemoryRegion *memory; + MemoryRegion *address_space; } PCIIORegion; #define PCI_ROM_SLOT 6 @@ -175,7 +174,7 @@ struct PCIDevice { /* Space to store MSIX table */ uint8_t *msix_table_page; /* MMIO index used to map MSIX table and pending bit entries. */ - int msix_mmio_index; + MemoryRegion msix_mmio; /* Reference-count for entries actually in use by driver. */ unsigned *msix_entry_used; /* Region including the MSI-X table */ @@ -191,7 +190,8 @@ struct PCIDevice { /* Location of option rom */ char *romfile; - ram_addr_t rom_offset; + bool has_rom; + MemoryRegion rom; uint32_t rom_bar; }; @@ -201,12 +201,8 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name, PCIConfigWriteFunc *config_write); void pci_register_bar(PCIDevice *pci_dev, int region_num, - pcibus_t size, uint8_t type, - PCIMapIORegionFunc *map_func); -void pci_register_bar_simple(PCIDevice *pci_dev, int region_num, - pcibus_t size, uint8_t attr, ram_addr_t ram_addr); -void pci_register_bar_region(PCIDevice *pci_dev, int region_num, - uint8_t attr, MemoryRegion *memory); + uint8_t attr, MemoryRegion *memory); +pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num); int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t offset, uint8_t size); @@ -238,10 +234,13 @@ typedef int (*pci_hotplug_fn)(DeviceState *qdev, PCIDevice *pci_dev, PCIHotplugState state); void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent, const char *name, - MemoryRegion *address_space, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, uint8_t devfn_min); PCIBus *pci_bus_new(DeviceState *parent, const char *name, - MemoryRegion *address_space, uint8_t devfn_min); + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, + uint8_t devfn_min); void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, void *irq_opaque, int nirq); int pci_bus_get_irq_level(PCIBus *bus, int irq_num); @@ -249,7 +248,8 @@ void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *dev); PCIBus *pci_register_bus(DeviceState *parent, const char *name, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, void *irq_opaque, - MemoryRegion *address_space, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, uint8_t devfn_min, int nirq); void pci_device_reset(PCIDevice *dev); void pci_bus_reset(PCIBus *bus); diff --git a/hw/pci_internals.h b/hw/pci_internals.h index c3a463a703..c7fd23dc54 100644 --- a/hw/pci_internals.h +++ b/hw/pci_internals.h @@ -25,7 +25,8 @@ struct PCIBus { PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX]; PCIDevice *parent_dev; target_phys_addr_t mem_base; - MemoryRegion *address_space; + MemoryRegion *address_space_mem; + MemoryRegion *address_space_io; QLIST_HEAD(, PCIBus) child; /* this will be replaced by qdev later */ QLIST_ENTRY(PCIBus) sibling;/* this will be replaced by qdev later */ diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c index 216cf81492..13d9380b00 100644 --- a/hw/pcnet-pci.c +++ b/hw/pcnet-pci.c @@ -46,6 +46,7 @@ typedef struct { PCIDevice pci_dev; PCNetState state; + MemoryRegion io_bar; } PCIPCNetState; static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val) @@ -69,25 +70,41 @@ static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr) return val; } -static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static uint64_t pcnet_ioport_read(void *opaque, target_phys_addr_t addr, + unsigned size) { - PCNetState *d = &DO_UPCAST(PCIPCNetState, pci_dev, pci_dev)->state; + PCNetState *d = opaque; -#ifdef PCNET_DEBUG_IO - printf("pcnet_ioport_map addr=0x%04"FMT_PCIBUS" size=0x%04"FMT_PCIBUS"\n", - addr, size); -#endif + if (addr < 16 && size == 1) { + return pcnet_aprom_readb(d, addr); + } else if (addr >= 0x10 && addr < 0x20 && size == 2) { + return pcnet_ioport_readw(d, addr); + } else if (addr >= 0x10 && addr < 0x20 && size == 4) { + return pcnet_ioport_readl(d, addr); + } + return ((uint64_t)1 << (size * 8)) - 1; +} - register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d); - register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d); +static void pcnet_ioport_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) +{ + PCNetState *d = opaque; - register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d); - register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d); - register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d); - register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d); + if (addr < 16 && size == 1) { + return pcnet_aprom_writeb(d, addr, data); + } else if (addr >= 0x10 && addr < 0x20 && size == 2) { + return pcnet_ioport_writew(d, addr, data); + } else if (addr >= 0x10 && addr < 0x20 && size == 4) { + return pcnet_ioport_writel(d, addr, data); + } } +static const MemoryRegionOps pcnet_io_ops = { + .read = pcnet_ioport_read, + .write = pcnet_ioport_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) { PCNetState *d = opaque; @@ -202,16 +219,12 @@ static const VMStateDescription vmstate_pci_pcnet = { /* PCI interface */ -static CPUWriteMemoryFunc * const pcnet_mmio_write[] = { - &pcnet_mmio_writeb, - &pcnet_mmio_writew, - &pcnet_mmio_writel -}; - -static CPUReadMemoryFunc * const pcnet_mmio_read[] = { - &pcnet_mmio_readb, - &pcnet_mmio_readw, - &pcnet_mmio_readl +static const MemoryRegionOps pcnet_mmio_ops = { + .old_mmio = { + .read = { pcnet_mmio_readb, pcnet_mmio_readw, pcnet_mmio_readl }, + .write = { pcnet_mmio_writeb, pcnet_mmio_writew, pcnet_mmio_writel }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr, @@ -237,7 +250,8 @@ static int pci_pcnet_uninit(PCIDevice *dev) { PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, dev); - cpu_unregister_io_memory(d->state.mmio_index); + memory_region_destroy(&d->state.mmio); + memory_region_destroy(&d->io_bar); qemu_del_timer(d->state.poll_timer); qemu_free_timer(d->state.poll_timer); qemu_del_vlan_client(&d->state.nic->nc); @@ -276,14 +290,14 @@ static int pci_pcnet_init(PCIDevice *pci_dev) pci_conf[PCI_MAX_LAT] = 0xff; /* Handler for memory-mapped I/O */ - s->mmio_index = - cpu_register_io_memory(pcnet_mmio_read, pcnet_mmio_write, &d->state, - DEVICE_NATIVE_ENDIAN); + memory_region_init_io(&d->state.mmio, &pcnet_mmio_ops, d, "pcnet-mmio", + PCNET_PNPMMIO_SIZE); - pci_register_bar(pci_dev, 0, PCNET_IOPORT_SIZE, - PCI_BASE_ADDRESS_SPACE_IO, pcnet_ioport_map); + memory_region_init_io(&d->io_bar, &pcnet_io_ops, d, "pcnet-io", + PCNET_IOPORT_SIZE); + pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->io_bar); - pci_register_bar_simple(pci_dev, 1, PCNET_PNPMMIO_SIZE, 0, s->mmio_index); + pci_register_bar(pci_dev, 1, 0, &s->mmio); s->irq = pci_dev->irq[0]; s->phys_mem_read = pci_physical_memory_read; diff --git a/hw/pcnet.h b/hw/pcnet.h index 534bdf9c2b..7e1c6853dd 100644 --- a/hw/pcnet.h +++ b/hw/pcnet.h @@ -4,6 +4,7 @@ #define PCNET_LOOPTEST_CRC 1 #define PCNET_LOOPTEST_NOCRC 2 +#include "memory.h" typedef struct PCNetState_st PCNetState; @@ -17,7 +18,8 @@ struct PCNetState_st { uint16_t csr[128]; uint16_t bcr[32]; uint64_t timer; - int mmio_index, xmit_pos; + MemoryRegion mmio; + int xmit_pos; uint8_t buffer[4096]; int tx_busy; qemu_irq irq; diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 80d6665350..28a3ee2e9c 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -242,7 +242,8 @@ static PCIBus *i440fx_common_init(const char *device_name, PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *pic, - MemoryRegion *address_space, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, ram_addr_t ram_size) { DeviceState *dev; @@ -253,8 +254,9 @@ static PCIBus *i440fx_common_init(const char *device_name, dev = qdev_create(NULL, "i440FX-pcihost"); s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev)); - s->address_space = address_space; - b = pci_bus_new(&s->busdev.qdev, NULL, s->address_space, 0); + s->address_space = address_space_mem; + b = pci_bus_new(&s->busdev.qdev, NULL, s->address_space, + address_space_io, 0); s->bus = b; qdev_init_nofail(dev); @@ -291,13 +293,15 @@ static PCIBus *i440fx_common_init(const char *device_name, } PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, - qemu_irq *pic, MemoryRegion *address_space, + qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, ram_addr_t ram_size) { PCIBus *b; b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic, - address_space, ram_size); + address_space_mem, address_space_io, ram_size); return b; } diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c index 15c24f6e7a..c7696b07d5 100644 --- a/hw/ppc4xx_pci.c +++ b/hw/ppc4xx_pci.c @@ -348,6 +348,7 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4], ppc4xx_pci_map_irq, pci_irqs, get_system_memory(), + get_system_io(), 0, 4); controller->pci_dev = pci_register_device(controller->pci_state.bus, diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h index 6fad20a745..7351bb6d37 100644 --- a/hw/ppc_mac.h +++ b/hw/ppc_mac.h @@ -42,31 +42,38 @@ #define ESCC_CLOCK 3686400 /* Cuda */ -void cuda_init (int *cuda_mem_index, qemu_irq irq); +void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq); /* MacIO */ -void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index, - int dbdma_mem_index, int cuda_mem_index, void *nvram, - int nb_ide, int *ide_mem_index, int escc_mem_index); +void macio_init (PCIBus *bus, int device_id, int is_oldworld, + MemoryRegion *pic_mem, MemoryRegion *dbdma_mem, + MemoryRegion *cuda_mem, void *nvram, + int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem); /* Heathrow PIC */ -qemu_irq *heathrow_pic_init(int *pmem_index, +qemu_irq *heathrow_pic_init(MemoryRegion **pmem, int nb_cpus, qemu_irq **irqs); /* Grackle PCI */ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic, - MemoryRegion *address_space); + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io); /* UniNorth PCI */ -PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space); -PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space); +PCIBus *pci_pmac_init(qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io); +PCIBus *pci_pmac_u3_init(qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io); /* Mac NVRAM */ typedef struct MacIONVRAMState MacIONVRAMState; -MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size, +MacIONVRAMState *macio_nvram_init (target_phys_addr_t size, unsigned int it_shift); -void macio_nvram_map (void *opaque, target_phys_addr_t mem_base); +void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar, + target_phys_addr_t mem_base); void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len); uint32_t macio_nvram_read (void *opaque, uint32_t addr); void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val); diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c index 2c0fae8ef3..303902290b 100644 --- a/hw/ppc_newworld.c +++ b/hw/ppc_newworld.c @@ -144,10 +144,9 @@ static void ppc_core99_init (ram_addr_t ram_size, long kernel_size, initrd_size; PCIBus *pci_bus; MacIONVRAMState *nvr; - int nvram_mem_index; int bios_size; - int pic_mem_index, dbdma_mem_index, cuda_mem_index, escc_mem_index; - int ide_mem_index[3]; + MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem, *escc_mem; + MemoryRegion *ide_mem[3]; int ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; @@ -315,44 +314,43 @@ static void ppc_core99_init (ram_addr_t ram_size, exit(1); } } - pic = openpic_init(NULL, &pic_mem_index, smp_cpus, openpic_irqs, NULL); + pic = openpic_init(NULL, &pic_mem, smp_cpus, openpic_irqs, NULL); if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) { /* 970 gets a U3 bus */ - pci_bus = pci_pmac_u3_init(pic, get_system_memory()); + pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io()); machine_arch = ARCH_MAC99_U3; } else { - pci_bus = pci_pmac_init(pic, get_system_memory()); + pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io()); machine_arch = ARCH_MAC99; } /* init basic PC hardware */ pci_vga_init(pci_bus); - escc_mem_index = escc_init(0x80013000, pic[0x25], pic[0x24], - serial_hds[0], serial_hds[1], ESCC_CLOCK, 4); + escc_mem = escc_init(0x80013000, pic[0x25], pic[0x24], + serial_hds[0], serial_hds[1], ESCC_CLOCK, 4); for(i = 0; i < nb_nics; i++) pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL); ide_drive_get(hd, MAX_IDE_BUS); - dbdma = DBDMA_init(&dbdma_mem_index); + dbdma = DBDMA_init(&dbdma_mem); /* We only emulate 2 out of 3 IDE controllers for now */ - ide_mem_index[0] = -1; - ide_mem_index[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]); - ide_mem_index[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]); + ide_mem[0] = NULL; + ide_mem[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]); + ide_mem[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]); /* cuda also initialize ADB */ if (machine_arch == ARCH_MAC99_U3) { usb_enabled = 1; } - cuda_init(&cuda_mem_index, pic[0x19]); + cuda_init(&cuda_mem, pic[0x19]); adb_kbd_init(&adb_bus); adb_mouse_init(&adb_bus); - macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem_index, - dbdma_mem_index, cuda_mem_index, NULL, 3, ide_mem_index, - escc_mem_index); + macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem, + dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_mem); if (usb_enabled) { usb_ohci_init_pci(pci_bus, -1); @@ -369,9 +367,9 @@ static void ppc_core99_init (ram_addr_t ram_size, graphic_depth = 15; /* The NewWorld NVRAM is not located in the MacIO device */ - nvr = macio_nvram_init(&nvram_mem_index, 0x2000, 1); + nvr = macio_nvram_init(0x2000, 1); pmac_format_nvram_partition(nvr, 0x2000); - macio_nvram_map(nvr, 0xFFF04000); + macio_nvram_setup_bar(nvr, get_system_memory(), 0xFFF04000); /* No PCI init: the BIOS will do it */ fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2); diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c index 585afd6c4b..41703a7e2c 100644 --- a/hw/ppc_oldworld.c +++ b/hw/ppc_oldworld.c @@ -82,8 +82,8 @@ static void ppc_heathrow_init (ram_addr_t ram_size, PCIBus *pci_bus; MacIONVRAMState *nvr; int bios_size; - int pic_mem_index, nvram_mem_index, dbdma_mem_index, cuda_mem_index; - int escc_mem_index, ide_mem_index[2]; + MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem; + MemoryRegion *escc_mem, *ide_mem[2]; uint16_t ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; @@ -233,11 +233,13 @@ static void ppc_heathrow_init (ram_addr_t ram_size, if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) { hw_error("Only 6xx bus is supported on heathrow machine\n"); } - pic = heathrow_pic_init(&pic_mem_index, 1, heathrow_irqs); - pci_bus = pci_grackle_init(0xfec00000, pic, get_system_memory()); + pic = heathrow_pic_init(&pic_mem, 1, heathrow_irqs); + pci_bus = pci_grackle_init(0xfec00000, pic, + get_system_memory(), + get_system_io()); pci_vga_init(pci_bus); - escc_mem_index = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0], + escc_mem = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0], serial_hds[1], ESCC_CLOCK, 4); for(i = 0; i < nb_nics; i++) @@ -247,9 +249,9 @@ static void ppc_heathrow_init (ram_addr_t ram_size, ide_drive_get(hd, MAX_IDE_BUS); /* First IDE channel is a MAC IDE on the MacIO bus */ - dbdma = DBDMA_init(&dbdma_mem_index); - ide_mem_index[0] = -1; - ide_mem_index[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]); + dbdma = DBDMA_init(&dbdma_mem); + ide_mem[0] = NULL; + ide_mem[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]); /* Second IDE channel is a CMD646 on the PCI bus */ hd[0] = hd[MAX_IDE_DEVS]; @@ -258,17 +260,16 @@ static void ppc_heathrow_init (ram_addr_t ram_size, pci_cmd646_ide_init(pci_bus, hd, 0); /* cuda also initialize ADB */ - cuda_init(&cuda_mem_index, pic[0x12]); + cuda_init(&cuda_mem, pic[0x12]); adb_kbd_init(&adb_bus); adb_mouse_init(&adb_bus); - nvr = macio_nvram_init(&nvram_mem_index, 0x2000, 4); + nvr = macio_nvram_init(0x2000, 4); pmac_format_nvram_partition(nvr, 0x2000); - macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem_index, - dbdma_mem_index, cuda_mem_index, nvr, 2, ide_mem_index, - escc_mem_index); + macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem, + dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_mem); if (usb_enabled) { usb_ohci_init_pci(pci_bus, -1); diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c index 91ebe07dcd..38d8573d14 100644 --- a/hw/ppc_prep.c +++ b/hw/ppc_prep.c @@ -649,7 +649,7 @@ static void ppc_prep_init (ram_addr_t ram_size, hw_error("Only 6xx bus is supported on PREP machine\n"); } i8259 = i8259_init(first_cpu->irq_inputs[PPC6xx_INPUT_INT]); - pci_bus = pci_prep_init(i8259, get_system_memory()); + pci_bus = pci_prep_init(i8259, get_system_memory(), get_system_io()); /* Hmm, prep has no pci-isa bridge ??? */ isa_bus_new(NULL); isa_bus_irqs(i8259); diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c index 134453965b..6a9f97975d 100644 --- a/hw/ppce500_pci.c +++ b/hw/ppce500_pci.c @@ -282,7 +282,8 @@ static int e500_pcihost_initfn(SysBusDevice *dev) PPCE500PCIState *s; PCIBus *b; int i; - MemoryRegion *address_space = get_system_memory(); + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *address_space_io = get_system_io(); h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev)); s = DO_UPCAST(PPCE500PCIState, pci_state, h); @@ -292,8 +293,8 @@ static int e500_pcihost_initfn(SysBusDevice *dev) } b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, mpc85xx_pci_set_irq, - mpc85xx_pci_map_irq, s->irq, address_space, - PCI_DEVFN(0x11, 0), 4); + mpc85xx_pci_map_irq, s->irq, address_space_mem, + address_space_io, PCI_DEVFN(0x11, 0), 4); s->pci_state.bus = b; pci_create_simple(b, 0, "e500-host-bridge"); diff --git a/hw/prep_pci.c b/hw/prep_pci.c index da02f0ea8e..58619ddf74 100644 --- a/hw/prep_pci.c +++ b/hw/prep_pci.c @@ -110,7 +110,9 @@ static void prep_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(pic[(irq_num & 1) ? 11 : 9] , level); } -PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space) +PCIBus *pci_prep_init(qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io) { PREPPCIState *s; PCIDevice *d; @@ -119,7 +121,9 @@ PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space) s = qemu_mallocz(sizeof(PREPPCIState)); s->bus = pci_register_bus(NULL, "pci", prep_set_irq, prep_map_irq, pic, - address_space, 0, 4); + address_space_mem, + address_space_io, + 0, 4); pci_host_conf_register_ioport(0xcf8, s); diff --git a/hw/prep_pci.h b/hw/prep_pci.h index a27368b99b..b6b481a517 100644 --- a/hw/prep_pci.h +++ b/hw/prep_pci.h @@ -4,6 +4,8 @@ #include "qemu-common.h" #include "memory.h" -PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space); +PCIBus *pci_prep_init(qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io); #endif diff --git a/hw/qxl-render.c b/hw/qxl-render.c index 643ff2d841..1b775770ce 100644 --- a/hw/qxl-render.c +++ b/hw/qxl-render.c @@ -86,7 +86,7 @@ void qxl_render_update(PCIQXLDevice *qxl) } qemu_free_displaysurface(vga->ds); - qxl->guest_primary.data = qemu_get_ram_ptr(qxl->vga.vram_offset); + qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram); if (qxl->guest_primary.stride < 0) { /* spice surface is upside down -> need extra buffer to flip */ qxl->guest_primary.stride = -qxl->guest_primary.stride; @@ -263,7 +263,7 @@ static ram_addr_t qxl_rom_size(void) static void init_qxl_rom(PCIQXLDevice *d) { - QXLRom *rom = qemu_get_ram_ptr(d->rom_offset); + QXLRom *rom = memory_region_get_ram_ptr(&d->rom_bar); QXLModes *modes = (QXLModes *)(rom + 1); uint32_t ram_header_size; uint32_t surface0_area_size; @@ -339,39 +339,37 @@ static void init_qxl_ram(PCIQXLDevice *d) } /* can be called from spice server thread context */ -static void qxl_set_dirty(ram_addr_t addr, ram_addr_t end) +static void qxl_set_dirty(MemoryRegion *mr, ram_addr_t addr, ram_addr_t end) { while (addr < end) { - cpu_physical_memory_set_dirty(addr); + memory_region_set_dirty(mr, addr); addr += TARGET_PAGE_SIZE; } } static void qxl_rom_set_dirty(PCIQXLDevice *qxl) { - ram_addr_t addr = qxl->rom_offset; - qxl_set_dirty(addr, addr + qxl->rom_size); + qxl_set_dirty(&qxl->rom_bar, 0, qxl->rom_size); } /* called from spice server thread context only */ static void qxl_ram_set_dirty(PCIQXLDevice *qxl, void *ptr) { - ram_addr_t addr = qxl->vga.vram_offset; void *base = qxl->vga.vram_ptr; intptr_t offset; offset = ptr - base; offset &= ~(TARGET_PAGE_SIZE-1); assert(offset < qxl->vga.vram_size); - qxl_set_dirty(addr + offset, addr + offset + TARGET_PAGE_SIZE); + qxl_set_dirty(&qxl->vga.vram, offset, offset + TARGET_PAGE_SIZE); } /* can be called from spice server thread context */ static void qxl_ring_set_dirty(PCIQXLDevice *qxl) { - ram_addr_t addr = qxl->vga.vram_offset + qxl->shadow_rom.ram_header_offset; - ram_addr_t end = qxl->vga.vram_offset + qxl->vga.vram_size; - qxl_set_dirty(addr, end); + ram_addr_t addr = qxl->shadow_rom.ram_header_offset; + ram_addr_t end = qxl->vga.vram_size; + qxl_set_dirty(&qxl->vga.vram, addr, end); } /* @@ -819,35 +817,19 @@ static void qxl_set_irq(PCIQXLDevice *d) qxl_ring_set_dirty(d); } -static void qxl_write_config(PCIDevice *d, uint32_t address, - uint32_t val, int len) -{ - PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, d); - VGACommonState *vga = &qxl->vga; - - vga_dirty_log_stop(vga); - pci_default_write_config(d, address, val, len); - if (vga->map_addr && qxl->pci.io_regions[0].addr == -1) { - vga->map_addr = 0; - } - vga_dirty_log_start(vga); -} - static void qxl_check_state(PCIQXLDevice *d) { QXLRam *ram = d->ram; - assert(SPICE_RING_IS_EMPTY(&ram->cmd_ring)); - assert(SPICE_RING_IS_EMPTY(&ram->cursor_ring)); + assert(!d->ssd.running || SPICE_RING_IS_EMPTY(&ram->cmd_ring)); + assert(!d->ssd.running || SPICE_RING_IS_EMPTY(&ram->cursor_ring)); } static void qxl_reset_state(PCIQXLDevice *d) { - QXLRam *ram = d->ram; QXLRom *rom = d->rom; - assert(!d->ssd.running || SPICE_RING_IS_EMPTY(&ram->cmd_ring)); - assert(!d->ssd.running || SPICE_RING_IS_EMPTY(&ram->cursor_ring)); + qxl_check_state(d); d->shadow_rom.update_id = cpu_to_le32(0); *rom = d->shadow_rom; qxl_rom_set_dirty(d); @@ -959,10 +941,10 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta, switch (pci_region) { case QXL_RAM_RANGE_INDEX: - virt_start = (intptr_t)qemu_get_ram_ptr(d->vga.vram_offset); + virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vga.vram); break; case QXL_VRAM_RANGE_INDEX: - virt_start = (intptr_t)qemu_get_ram_ptr(d->vram_offset); + virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vram_bar); break; default: /* should not happen */ @@ -1132,10 +1114,11 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm) qxl_rom_set_dirty(d); } -static void ioport_write(void *opaque, uint32_t addr, uint32_t val) +static void ioport_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { PCIQXLDevice *d = opaque; - uint32_t io_port = addr - d->io_base; + uint32_t io_port = addr; qxl_async_io async = QXL_SYNC; #if SPICE_INTERFACE_QXL_MINOR >= 1 uint32_t orig_io_port = io_port; @@ -1204,7 +1187,7 @@ async_common: } d->current_async = orig_io_port; qemu_mutex_unlock(&d->async_lock); - dprint(d, 2, "start async %d (%d)\n", io_port, val); + dprint(d, 2, "start async %d (%"PRId64")\n", io_port, val); break; default: break; @@ -1241,7 +1224,7 @@ async_common: d->oom_running = 0; break; case QXL_IO_SET_MODE: - dprint(d, 1, "QXL_SET_MODE %d\n", val); + dprint(d, 1, "QXL_SET_MODE %d\n", (int)val); qxl_set_mode(d, val, 0); break; case QXL_IO_LOG: @@ -1320,7 +1303,8 @@ async_common: break; } case QXL_IO_FLUSH_SURFACES_ASYNC: - dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC (%d) (%s, s#=%d, res#=%d)\n", + dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC" + " (%"PRId64") (%s, s#=%d, res#=%d)\n", val, qxl_mode_to_string(d->mode), d->guest_surfaces.count, d->num_free_res); qxl_spice_flush_surfaces_async(d); @@ -1348,7 +1332,8 @@ cancel_async: #endif } -static uint32_t ioport_read(void *opaque, uint32_t addr) +static uint64_t ioport_read(void *opaque, target_phys_addr_t addr, + unsigned size) { PCIQXLDevice *d = opaque; @@ -1356,42 +1341,14 @@ static uint32_t ioport_read(void *opaque, uint32_t addr) return 0xff; } -static void qxl_map(PCIDevice *pci, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - static const char *names[] = { - [ QXL_IO_RANGE_INDEX ] = "ioports", - [ QXL_RAM_RANGE_INDEX ] = "devram", - [ QXL_ROM_RANGE_INDEX ] = "rom", - [ QXL_VRAM_RANGE_INDEX ] = "vram", - }; - PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, pci); - - dprint(qxl, 1, "%s: bar %d [%s] addr 0x%lx size 0x%lx\n", __FUNCTION__, - region_num, names[region_num], addr, size); - - switch (region_num) { - case QXL_IO_RANGE_INDEX: - register_ioport_write(addr, size, 1, ioport_write, pci); - register_ioport_read(addr, size, 1, ioport_read, pci); - qxl->io_base = addr; - break; - case QXL_RAM_RANGE_INDEX: - cpu_register_physical_memory(addr, size, qxl->vga.vram_offset | IO_MEM_RAM); - qxl->vga.map_addr = addr; - qxl->vga.map_end = addr + size; - if (qxl->id == 0) { - vga_dirty_log_start(&qxl->vga); - } - break; - case QXL_ROM_RANGE_INDEX: - cpu_register_physical_memory(addr, size, qxl->rom_offset | IO_MEM_ROM); - break; - case QXL_VRAM_RANGE_INDEX: - cpu_register_physical_memory(addr, size, qxl->vram_offset | IO_MEM_RAM); - break; - } -} +static const MemoryRegionOps qxl_io_ops = { + .read = ioport_read, + .write = ioport_write, + .valid = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; static void pipe_read(void *opaque) { @@ -1511,10 +1468,9 @@ static void qxl_vm_change_state_handler(void *opaque, int running, int reason) * to make sure they are saved */ /* FIXME #1: should go out during "live" stage */ /* FIXME #2: we only need to save the areas which are actually used */ - ram_addr_t vram_addr = qxl->vram_offset; - ram_addr_t surface0_addr = qxl->vga.vram_offset + qxl->shadow_rom.draw_area_offset; - qxl_set_dirty(vram_addr, vram_addr + qxl->vram_size); - qxl_set_dirty(surface0_addr, surface0_addr + qxl->shadow_rom.surface0_area_size); + qxl_set_dirty(&qxl->vram_bar, 0, qxl->vram_size); + qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset, + qxl->shadow_rom.surface0_area_size); } } @@ -1580,7 +1536,8 @@ static int qxl_init_common(PCIQXLDevice *qxl) pci_set_byte(&config[PCI_INTERRUPT_PIN], 1); qxl->rom_size = qxl_rom_size(); - qxl->rom_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vrom", qxl->rom_size); + memory_region_init_ram(&qxl->rom_bar, &qxl->pci.qdev, "qxl.vrom", + qxl->rom_size); init_qxl_rom(qxl); init_qxl_ram(qxl); @@ -1591,26 +1548,32 @@ static int qxl_init_common(PCIQXLDevice *qxl) qxl->vram_size = 4096; } qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1); - qxl->vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vram", qxl->vram_size); + memory_region_init_ram(&qxl->vram_bar, &qxl->pci.qdev, "qxl.vram", + qxl->vram_size); io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1); if (qxl->revision == 1) { io_size = 8; } + memory_region_init_io(&qxl->io_bar, &qxl_io_ops, qxl, + "qxl-ioports", io_size); + if (qxl->id == 0) { + vga_dirty_log_start(&qxl->vga); + } + + pci_register_bar(&qxl->pci, QXL_IO_RANGE_INDEX, - io_size, PCI_BASE_ADDRESS_SPACE_IO, qxl_map); + PCI_BASE_ADDRESS_SPACE_IO, &qxl->io_bar); pci_register_bar(&qxl->pci, QXL_ROM_RANGE_INDEX, - qxl->rom_size, PCI_BASE_ADDRESS_SPACE_MEMORY, - qxl_map); + PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->rom_bar); pci_register_bar(&qxl->pci, QXL_RAM_RANGE_INDEX, - qxl->vga.vram_size, PCI_BASE_ADDRESS_SPACE_MEMORY, - qxl_map); + PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vga.vram); - pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX, qxl->vram_size, - PCI_BASE_ADDRESS_SPACE_MEMORY, qxl_map); + pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX, + PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vram_bar); qxl->ssd.qxl.base.sif = &qxl_interface.base; qxl->ssd.qxl.id = qxl->id; @@ -1664,9 +1627,9 @@ static int qxl_init_secondary(PCIDevice *dev) ram_size = 16 * 1024 * 1024; } qxl->vga.vram_size = ram_size; - qxl->vga.vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vgavram", - qxl->vga.vram_size); - qxl->vga.vram_ptr = qemu_get_ram_ptr(qxl->vga.vram_offset); + memory_region_init_ram(&qxl->vga.vram, &qxl->pci.qdev, "qxl.vgavram", + qxl->vga.vram_size); + qxl->vga.vram_ptr = memory_region_get_ram_ptr(&qxl->vga.vram); return qxl_init_common(qxl); } @@ -1829,7 +1792,6 @@ static PCIDeviceInfo qxl_info_primary = { .qdev.vmsd = &qxl_vmstate, .no_hotplug = 1, .init = qxl_init_primary, - .config_write = qxl_write_config, .romfile = "vgabios-qxl.bin", .vendor_id = REDHAT_PCI_VENDOR_ID, .device_id = QXL_DEVICE_ID_STABLE, @@ -79,14 +79,14 @@ typedef struct PCIQXLDevice { QXLRom *rom; QXLModes *modes; uint32_t rom_size; - uint64_t rom_offset; + MemoryRegion rom_bar; /* vram pci bar */ uint32_t vram_size; - uint64_t vram_offset; + MemoryRegion vram_bar; /* io bar */ - uint32_t io_base; + MemoryRegion io_bar; } PCIQXLDevice; #define PANIC_ON(x) if ((x)) { \ diff --git a/hw/rtl8139.c b/hw/rtl8139.c index 5214b8cb7c..c6cafc2513 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -474,7 +474,6 @@ typedef struct RTL8139State { NICState *nic; NICConf conf; - int rtl8139_mmio_io_addr; /* C ring mode */ uint32_t currTxDesc; @@ -506,6 +505,9 @@ typedef struct RTL8139State { QEMUTimer *timer; int64_t TimerExpire; + MemoryRegion bar_io; + MemoryRegion bar_mem; + /* Support migration to/from old versions */ int rtl8139_mmio_io_addr_dummy; } RTL8139State; @@ -3283,7 +3285,7 @@ static void rtl8139_pre_save(void *opaque) rtl8139_set_next_tctr_time(s, current_time); s->TCTR = muldiv64(current_time - s->TCTR_base, PCI_FREQUENCY, get_ticks_per_sec()); - s->rtl8139_mmio_io_addr_dummy = s->rtl8139_mmio_io_addr; + s->rtl8139_mmio_io_addr_dummy = 0; } static const VMStateDescription vmstate_rtl8139 = { @@ -3379,31 +3381,35 @@ static const VMStateDescription vmstate_rtl8139 = { /***********************************************************/ /* PCI RTL8139 definitions */ -static void rtl8139_ioport_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - RTL8139State *s = DO_UPCAST(RTL8139State, dev, pci_dev); - - register_ioport_write(addr, 0x100, 1, rtl8139_ioport_writeb, s); - register_ioport_read( addr, 0x100, 1, rtl8139_ioport_readb, s); - - register_ioport_write(addr, 0x100, 2, rtl8139_ioport_writew, s); - register_ioport_read( addr, 0x100, 2, rtl8139_ioport_readw, s); - - register_ioport_write(addr, 0x100, 4, rtl8139_ioport_writel, s); - register_ioport_read( addr, 0x100, 4, rtl8139_ioport_readl, s); -} +static const MemoryRegionPortio rtl8139_portio[] = { + { 0, 0x100, 1, .read = rtl8139_ioport_readb, }, + { 0, 0x100, 1, .write = rtl8139_ioport_writeb, }, + { 0, 0x100, 2, .read = rtl8139_ioport_readw, }, + { 0, 0x100, 2, .write = rtl8139_ioport_writew, }, + { 0, 0x100, 4, .read = rtl8139_ioport_readl, }, + { 0, 0x100, 4, .write = rtl8139_ioport_writel, }, + PORTIO_END_OF_LIST() +}; -static CPUReadMemoryFunc * const rtl8139_mmio_read[3] = { - rtl8139_mmio_readb, - rtl8139_mmio_readw, - rtl8139_mmio_readl, +static const MemoryRegionOps rtl8139_io_ops = { + .old_portio = rtl8139_portio, + .endianness = DEVICE_LITTLE_ENDIAN, }; -static CPUWriteMemoryFunc * const rtl8139_mmio_write[3] = { - rtl8139_mmio_writeb, - rtl8139_mmio_writew, - rtl8139_mmio_writel, +static const MemoryRegionOps rtl8139_mmio_ops = { + .old_mmio = { + .read = { + rtl8139_mmio_readb, + rtl8139_mmio_readw, + rtl8139_mmio_readl, + }, + .write = { + rtl8139_mmio_writeb, + rtl8139_mmio_writew, + rtl8139_mmio_writel, + }, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; static void rtl8139_timer(void *opaque) @@ -3432,7 +3438,8 @@ static int pci_rtl8139_uninit(PCIDevice *dev) { RTL8139State *s = DO_UPCAST(RTL8139State, dev, dev); - cpu_unregister_io_memory(s->rtl8139_mmio_io_addr); + memory_region_destroy(&s->bar_io); + memory_region_destroy(&s->bar_mem); if (s->cplus_txbuffer) { qemu_free(s->cplus_txbuffer); s->cplus_txbuffer = NULL; @@ -3462,15 +3469,10 @@ static int pci_rtl8139_init(PCIDevice *dev) * list bit in status register, and offset 0xdc seems unused. */ pci_conf[PCI_CAPABILITY_LIST] = 0xdc; - /* I/O handler for memory-mapped I/O */ - s->rtl8139_mmio_io_addr = - cpu_register_io_memory(rtl8139_mmio_read, rtl8139_mmio_write, s, - DEVICE_LITTLE_ENDIAN); - - pci_register_bar(&s->dev, 0, 0x100, - PCI_BASE_ADDRESS_SPACE_IO, rtl8139_ioport_map); - - pci_register_bar_simple(&s->dev, 1, 0x100, 0, s->rtl8139_mmio_io_addr); + memory_region_init_io(&s->bar_io, &rtl8139_io_ops, s, "rtl8139", 0x100); + memory_region_init_io(&s->bar_mem, &rtl8139_mmio_ops, s, "rtl8139", 0x100); + pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->bar_io); + pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar_mem); qemu_macaddr_default_if_unset(&s->conf.macaddr); diff --git a/hw/sh_pci.c b/hw/sh_pci.c index 0ef93a062e..cd8650143c 100644 --- a/hw/sh_pci.c +++ b/hw/sh_pci.c @@ -128,7 +128,9 @@ static int sh_pci_init_device(SysBusDevice *dev) } s->bus = pci_register_bus(&s->busdev.qdev, "pci", sh_pci_set_irq, sh_pci_map_irq, - s->irq, get_system_memory(), + s->irq, + get_system_memory(), + get_system_io(), PCI_DEVFN(0, 0), 4); s->memconfig = cpu_register_io_memory(sh_pci_reg.r, sh_pci_reg.w, s, DEVICE_NATIVE_ENDIAN); diff --git a/hw/sun4u.c b/hw/sun4u.c index d7dcaf007d..7b2d0b17e4 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -91,6 +91,12 @@ struct hwdef { uint64_t console_serial_base; }; +typedef struct EbusState { + PCIDevice pci_dev; + MemoryRegion bar0; + MemoryRegion bar1; +} EbusState; + int DMA_get_channel_mode (int nchan) { return 0; @@ -518,21 +524,6 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit) } } -static void ebus_mmio_mapfunc(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - EBUS_DPRINTF("Mapping region %d registers at %" FMT_PCIBUS "\n", - region_num, addr); - switch (region_num) { - case 0: - isa_mmio_init(addr, 0x1000000); - break; - case 1: - isa_mmio_init(addr, 0x800000); - break; - } -} - static void dummy_isa_irq_handler(void *opaque, int n, int level) { } @@ -549,27 +540,29 @@ pci_ebus_init(PCIBus *bus, int devfn) } static int -pci_ebus_init1(PCIDevice *s) +pci_ebus_init1(PCIDevice *pci_dev) { - isa_bus_new(&s->qdev); + EbusState *s = DO_UPCAST(EbusState, pci_dev, pci_dev); + + isa_bus_new(&pci_dev->qdev); - s->config[0x04] = 0x06; // command = bus master, pci mem - s->config[0x05] = 0x00; - s->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error - s->config[0x07] = 0x03; // status = medium devsel - s->config[0x09] = 0x00; // programming i/f - s->config[0x0D] = 0x0a; // latency_timer + pci_dev->config[0x04] = 0x06; // command = bus master, pci mem + pci_dev->config[0x05] = 0x00; + pci_dev->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error + pci_dev->config[0x07] = 0x03; // status = medium devsel + pci_dev->config[0x09] = 0x00; // programming i/f + pci_dev->config[0x0D] = 0x0a; // latency_timer - pci_register_bar(s, 0, 0x1000000, PCI_BASE_ADDRESS_SPACE_MEMORY, - ebus_mmio_mapfunc); - pci_register_bar(s, 1, 0x800000, PCI_BASE_ADDRESS_SPACE_MEMORY, - ebus_mmio_mapfunc); + isa_mmio_setup(&s->bar0, 0x1000000); + pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar0); + isa_mmio_setup(&s->bar1, 0x800000); + pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar1); return 0; } static PCIDeviceInfo ebus_info = { .qdev.name = "ebus", - .qdev.size = sizeof(PCIDevice), + .qdev.size = sizeof(EbusState), .init = pci_ebus_init1, .vendor_id = PCI_VENDOR_ID_SUN, .device_id = PCI_DEVICE_ID_SUN_EBUS, diff --git a/hw/unin_pci.c b/hw/unin_pci.c index b499523c93..f896f8c76b 100644 --- a/hw/unin_pci.c +++ b/hw/unin_pci.c @@ -201,7 +201,9 @@ static int pci_unin_internal_init_device(SysBusDevice *dev) return 0; } -PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space) +PCIBus *pci_pmac_init(qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io) { DeviceState *dev; SysBusDevice *s; @@ -215,7 +217,9 @@ PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space) d = FROM_SYSBUS(UNINState, s); d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci", pci_unin_set_irq, pci_unin_map_irq, - pic, address_space, + pic, + address_space_mem, + address_space_io, PCI_DEVFN(11, 0), 4); #if 0 @@ -253,7 +257,9 @@ PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space) return d->host_state.bus; } -PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space) +PCIBus *pci_pmac_u3_init(qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io) { DeviceState *dev; SysBusDevice *s; @@ -268,7 +274,9 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space) d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci", pci_unin_set_irq, pci_unin_map_irq, - pic, address_space, + pic, + address_space_mem, + address_space_io, PCI_DEVFN(11, 0), 4); sysbus_mmio_map(s, 0, 0xf0800000); diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c index 2b43895315..c9d0a692ed 100644 --- a/hw/usb-ehci.c +++ b/hw/usb-ehci.c @@ -370,8 +370,7 @@ struct EHCIState { PCIDevice dev; USBBus bus; qemu_irq irq; - target_phys_addr_t mem_base; - int mem; + MemoryRegion mem; int companion_count; /* properties */ @@ -2179,29 +2178,15 @@ static void ehci_frame_timer(void *opaque) qemu_mod_timer(ehci->frame_timer, expire_time); } -static CPUReadMemoryFunc *ehci_readfn[3]={ - ehci_mem_readb, - ehci_mem_readw, - ehci_mem_readl -}; -static CPUWriteMemoryFunc *ehci_writefn[3]={ - ehci_mem_writeb, - ehci_mem_writew, - ehci_mem_writel +static const MemoryRegionOps ehci_mem_ops = { + .old_mmio = { + .read = { ehci_mem_readb, ehci_mem_readw, ehci_mem_readl }, + .write = { ehci_mem_writeb, ehci_mem_writew, ehci_mem_writel }, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; -static void ehci_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - EHCIState *s =(EHCIState *)pci_dev; - - DPRINTF("ehci_map: region %d, addr %08" PRIx64 ", size %" PRId64 ", s->mem %08X\n", - region_num, addr, size, s->mem); - s->mem_base = addr; - cpu_register_physical_memory(addr, size, s->mem); -} - static int usb_ehci_initfn(PCIDevice *dev); static USBPortOps ehci_port_ops = { @@ -2316,11 +2301,8 @@ static int usb_ehci_initfn(PCIDevice *dev) qemu_register_reset(ehci_reset, s); - s->mem = cpu_register_io_memory(ehci_readfn, ehci_writefn, s, - DEVICE_LITTLE_ENDIAN); - - pci_register_bar(&s->dev, 0, MMIO_SIZE, PCI_BASE_ADDRESS_SPACE_MEMORY, - ehci_map); + memory_region_init_io(&s->mem, &ehci_mem_ops, s, "ehci", MMIO_SIZE); + pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem); fprintf(stderr, "*** EHCI support is under development ***\n"); diff --git a/hw/usb-hid.c b/hw/usb-hid.c index e5d57de888..ba79466401 100644 --- a/hw/usb-hid.c +++ b/hw/usb-hid.c @@ -45,8 +45,6 @@ typedef struct USBHIDState { USBDevice dev; HIDState hid; - void *datain_opaque; - void (*datain)(void *); } USBHIDState; enum { @@ -362,10 +360,6 @@ static void usb_hid_changed(HIDState *hs) { USBHIDState *us = container_of(hs, USBHIDState, hid); - if (us->datain) { - us->datain(us->datain_opaque); - } - usb_wakeup(&us->dev); } @@ -454,6 +448,9 @@ static int usb_hid_handle_control(USBDevice *dev, USBPacket *p, case SET_IDLE: hs->idle = (uint8_t) (value >> 8); hid_set_next_idle(hs, qemu_get_clock_ns(vm_clock)); + if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) { + hid_pointer_activate(hs); + } ret = 0; break; default: @@ -530,49 +527,13 @@ static int usb_keyboard_initfn(USBDevice *dev) return usb_hid_initfn(dev, HID_KEYBOARD); } -void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *)) -{ - USBHIDState *s = (USBHIDState *)dev; - - s->datain_opaque = opaque; - s->datain = datain; -} - -static int usb_hid_post_load(void *opaque, int version_id) -{ - USBHIDState *s = opaque; - - if (s->hid.idle) { - hid_set_next_idle(&s->hid, qemu_get_clock_ns(vm_clock)); - } - return 0; -} - -static const VMStateDescription vmstate_usb_ptr_queue = { - .name = "usb-ptr-queue", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField []) { - VMSTATE_INT32(xdx, HIDPointerEvent), - VMSTATE_INT32(ydy, HIDPointerEvent), - VMSTATE_INT32(dz, HIDPointerEvent), - VMSTATE_INT32(buttons_state, HIDPointerEvent), - VMSTATE_END_OF_LIST() - } -}; static const VMStateDescription vmstate_usb_ptr = { .name = "usb-ptr", .version_id = 1, .minimum_version_id = 1, - .post_load = usb_hid_post_load, .fields = (VMStateField []) { VMSTATE_USB_DEVICE(dev, USBHIDState), - VMSTATE_STRUCT_ARRAY(hid.ptr.queue, USBHIDState, QUEUE_LENGTH, 0, - vmstate_usb_ptr_queue, HIDPointerEvent), - VMSTATE_UINT32(hid.head, USBHIDState), - VMSTATE_UINT32(hid.n, USBHIDState), - VMSTATE_INT32(hid.protocol, USBHIDState), - VMSTATE_UINT8(hid.idle, USBHIDState), + VMSTATE_HID_POINTER_DEVICE(hid, USBHIDState), VMSTATE_END_OF_LIST() } }; @@ -581,18 +542,9 @@ static const VMStateDescription vmstate_usb_kbd = { .name = "usb-kbd", .version_id = 1, .minimum_version_id = 1, - .post_load = usb_hid_post_load, .fields = (VMStateField []) { VMSTATE_USB_DEVICE(dev, USBHIDState), - VMSTATE_UINT32_ARRAY(hid.kbd.keycodes, USBHIDState, QUEUE_LENGTH), - VMSTATE_UINT32(hid.head, USBHIDState), - VMSTATE_UINT32(hid.n, USBHIDState), - VMSTATE_UINT16(hid.kbd.modifiers, USBHIDState), - VMSTATE_UINT8(hid.kbd.leds, USBHIDState), - VMSTATE_UINT8_ARRAY(hid.kbd.key, USBHIDState, 16), - VMSTATE_INT32(hid.kbd.keys, USBHIDState), - VMSTATE_INT32(hid.protocol, USBHIDState), - VMSTATE_UINT8(hid.idle, USBHIDState), + VMSTATE_HID_KEYBOARD_DEVICE(hid, USBHIDState), VMSTATE_END_OF_LIST() } }; diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c index d39bcb0c0d..d30db3f92f 100644 --- a/hw/usb-ohci.c +++ b/hw/usb-ohci.c @@ -1790,7 +1790,7 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev) ohci->state.irq = ohci->pci_dev.irq[0]; /* TODO: avoid cast below by using dev */ - pci_register_bar_region(&ohci->pci_dev, 0, 0, &ohci->state.mem); + pci_register_bar(&ohci->pci_dev, 0, 0, &ohci->state.mem); return 0; } diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c index 824e3a5e8b..16088d7dca 100644 --- a/hw/usb-uhci.c +++ b/hw/usb-uhci.c @@ -129,6 +129,7 @@ typedef struct UHCIPort { struct UHCIState { PCIDevice dev; + MemoryRegion io_bar; USBBus bus; /* Note unused when we're a companion controller */ uint16_t cmd; /* cmd register */ uint16_t status; @@ -1096,18 +1097,19 @@ static void uhci_frame_timer(void *opaque) qemu_mod_timer(s->frame_timer, s->expire_time); } -static void uhci_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - UHCIState *s = (UHCIState *)pci_dev; - - register_ioport_write(addr, 32, 2, uhci_ioport_writew, s); - register_ioport_read(addr, 32, 2, uhci_ioport_readw, s); - register_ioport_write(addr, 32, 4, uhci_ioport_writel, s); - register_ioport_read(addr, 32, 4, uhci_ioport_readl, s); - register_ioport_write(addr, 32, 1, uhci_ioport_writeb, s); - register_ioport_read(addr, 32, 1, uhci_ioport_readb, s); -} +static const MemoryRegionPortio uhci_portio[] = { + { 0, 32, 2, .write = uhci_ioport_writew, }, + { 0, 32, 2, .read = uhci_ioport_readw, }, + { 0, 32, 4, .write = uhci_ioport_writel, }, + { 0, 32, 4, .read = uhci_ioport_readl, }, + { 0, 32, 1, .write = uhci_ioport_writeb, }, + { 0, 32, 1, .read = uhci_ioport_readb, }, + PORTIO_END_OF_LIST() +}; + +static const MemoryRegionOps uhci_ioport_ops = { + .old_portio = uhci_portio, +}; static USBPortOps uhci_port_ops = { .attach = uhci_attach, @@ -1154,10 +1156,10 @@ static int usb_uhci_common_initfn(PCIDevice *dev) qemu_register_reset(uhci_reset, s); + memory_region_init_io(&s->io_bar, &uhci_ioport_ops, s, "uhci", 0x20); /* Use region 4 for consistency with real hardware. BSD guests seem to rely on this. */ - pci_register_bar(&s->dev, 4, 0x20, - PCI_BASE_ADDRESS_SPACE_IO, uhci_map); + pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar); return 0; } @@ -1177,6 +1179,14 @@ static int usb_uhci_vt82c686b_initfn(PCIDevice *dev) return usb_uhci_common_initfn(dev); } +static int usb_uhci_exit(PCIDevice *dev) +{ + UHCIState *s = DO_UPCAST(UHCIState, dev, dev); + + memory_region_destroy(&s->io_bar); + return 0; +} + static Property uhci_properties[] = { DEFINE_PROP_STRING("masterbus", UHCIState, masterbus), DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0), @@ -1189,6 +1199,7 @@ static PCIDeviceInfo uhci_info[] = { .qdev.size = sizeof(UHCIState), .qdev.vmsd = &vmstate_uhci, .init = usb_uhci_common_initfn, + .exit = usb_uhci_exit, .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = PCI_DEVICE_ID_INTEL_82371SB_2, .revision = 0x01, @@ -1199,6 +1210,7 @@ static PCIDeviceInfo uhci_info[] = { .qdev.size = sizeof(UHCIState), .qdev.vmsd = &vmstate_uhci, .init = usb_uhci_common_initfn, + .exit = usb_uhci_exit, .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = PCI_DEVICE_ID_INTEL_82371AB_2, .revision = 0x01, @@ -1209,6 +1221,7 @@ static PCIDeviceInfo uhci_info[] = { .qdev.size = sizeof(UHCIState), .qdev.vmsd = &vmstate_uhci, .init = usb_uhci_vt82c686b_initfn, + .exit = usb_uhci_exit, .vendor_id = PCI_VENDOR_ID_VIA, .device_id = PCI_DEVICE_ID_VIA_UHCI, .revision = 0x01, @@ -316,9 +316,6 @@ USBDevice *usb_host_device_open(const char *devname); int usb_host_device_close(const char *devname); void usb_host_info(Monitor *mon); -/* usb-hid.c */ -void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *)); - /* usb-bt.c */ USBDevice *usb_bt_init(HCIInfo *hci); diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index cffe387187..e1d5c0bf5a 100644 --- a/hw/versatile_pci.c +++ b/hw/versatile_pci.c @@ -112,7 +112,7 @@ static int pci_vpb_init(SysBusDevice *dev) } bus = pci_register_bus(&dev->qdev, "pci", pci_vpb_set_irq, pci_vpb_map_irq, s->irq, - get_system_memory(), + get_system_memory(), get_system_io(), PCI_DEVFN(11, 0), 4); /* ??? Register memory space. */ diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c index 4954bb18be..96e6e7dd21 100644 --- a/hw/vga-isa-mm.c +++ b/hw/vga-isa-mm.c @@ -27,6 +27,7 @@ #include "vga_int.h" #include "pixel_ops.h" #include "qemu-timer.h" +#include "exec-memory.h" typedef struct ISAVGAMMState { VGACommonState vga; @@ -79,35 +80,44 @@ static void vga_mm_writel (void *opaque, vga_ioport_write(&s->vga, addr >> s->it_shift, value); } -static CPUReadMemoryFunc * const vga_mm_read_ctrl[] = { - &vga_mm_readb, - &vga_mm_readw, - &vga_mm_readl, -}; - -static CPUWriteMemoryFunc * const vga_mm_write_ctrl[] = { - &vga_mm_writeb, - &vga_mm_writew, - &vga_mm_writel, +static const MemoryRegionOps vga_mm_ctrl_ops = { + .old_mmio = { + .read = { + vga_mm_readb, + vga_mm_readw, + vga_mm_readl, + }, + .write = { + vga_mm_writeb, + vga_mm_writew, + vga_mm_writel, + }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void vga_mm_init(ISAVGAMMState *s, target_phys_addr_t vram_base, target_phys_addr_t ctrl_base, int it_shift) { - int s_ioport_ctrl, vga_io_memory; + MemoryRegion *s_ioport_ctrl, *vga_io_memory; s->it_shift = it_shift; - s_ioport_ctrl = cpu_register_io_memory(vga_mm_read_ctrl, vga_mm_write_ctrl, s, - DEVICE_NATIVE_ENDIAN); - vga_io_memory = cpu_register_io_memory(vga_mem_read, vga_mem_write, s, - DEVICE_NATIVE_ENDIAN); + s_ioport_ctrl = qemu_malloc(sizeof(*s_ioport_ctrl)); + memory_region_init_io(s_ioport_ctrl, &vga_mm_ctrl_ops, s, + "vga-mm-ctrl", 0x100000); + + vga_io_memory = qemu_malloc(sizeof(*vga_io_memory)); + /* XXX: endianness? */ + memory_region_init_io(vga_io_memory, &vga_mem_ops, &s->vga, + "vga-mem", 0x20000); vmstate_register(NULL, 0, &vmstate_vga_common, s); - cpu_register_physical_memory(ctrl_base, 0x100000, s_ioport_ctrl); + memory_region_add_subregion(get_system_memory(), ctrl_base, s_ioport_ctrl); s->vga.bank_offset = 0; - cpu_register_physical_memory(vram_base + 0x000a0000, 0x20000, vga_io_memory); - qemu_register_coalesced_mmio(vram_base + 0x000a0000, 0x20000); + memory_region_add_subregion(get_system_memory(), + vram_base + 0x000a0000, vga_io_memory); + memory_region_set_coalescing(vga_io_memory); } int isa_vga_mm_init(target_phys_addr_t vram_base, diff --git a/hw/vga-isa.c b/hw/vga-isa.c index 245841f18b..fef7f58f28 100644 --- a/hw/vga-isa.c +++ b/hw/vga-isa.c @@ -28,6 +28,7 @@ #include "pixel_ops.h" #include "qemu-timer.h" #include "loader.h" +#include "exec-memory.h" typedef struct ISAVGAState { ISADevice dev; @@ -46,13 +47,14 @@ static int vga_initfn(ISADevice *dev) { ISAVGAState *d = DO_UPCAST(ISAVGAState, dev, dev); VGACommonState *s = &d->state; - int vga_io_memory; + MemoryRegion *vga_io_memory; vga_common_init(s, VGA_RAM_SIZE); vga_io_memory = vga_init_io(s); - cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000, - vga_io_memory); - qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000); + memory_region_add_subregion_overlap(get_system_memory(), + isa_mem_base + 0x000a0000, + vga_io_memory, 1); + memory_region_set_coalescing(vga_io_memory); isa_init_ioport(dev, 0x3c0); isa_init_ioport(dev, 0x3b4); isa_init_ioport(dev, 0x3ba); diff --git a/hw/vga-pci.c b/hw/vga-pci.c index 481f448e3f..c67be0abeb 100644 --- a/hw/vga-pci.c +++ b/hw/vga-pci.c @@ -47,29 +47,6 @@ static const VMStateDescription vmstate_vga_pci = { } }; -static void vga_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - PCIVGAState *d = (PCIVGAState *)pci_dev; - VGACommonState *s = &d->vga; - - cpu_register_physical_memory(addr, s->vram_size, s->vram_offset); - s->map_addr = addr; - s->map_end = addr + s->vram_size; - vga_dirty_log_start(s); -} - -static void pci_vga_write_config(PCIDevice *d, - uint32_t address, uint32_t val, int len) -{ - PCIVGAState *pvs = container_of(d, PCIVGAState, dev); - VGACommonState *s = &pvs->vga; - - pci_default_write_config(d, address, val, len); - if (s->map_addr && pvs->dev.io_regions[0].addr == -1) - s->map_addr = 0; -} - static int pci_vga_initfn(PCIDevice *dev) { PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev); @@ -83,8 +60,7 @@ static int pci_vga_initfn(PCIDevice *dev) s->screen_dump, s->text_update, s); /* XXX: VGA_RAM_SIZE must be a power of two */ - pci_register_bar(&d->dev, 0, VGA_RAM_SIZE, - PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map); + pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram); if (!dev->rom_bar) { /* compatibility with pc-0.13 and older */ @@ -106,7 +82,6 @@ static PCIDeviceInfo vga_info = { .qdev.vmsd = &vmstate_vga_pci, .no_hotplug = 1, .init = pci_vga_initfn, - .config_write = pci_vga_write_config, .romfile = "vgabios-stdvga.bin", /* dummy VGA (same as Bochs ID) */ @@ -28,6 +28,7 @@ #include "vga_int.h" #include "pixel_ops.h" #include "qemu-timer.h" +#include "exec-memory.h" //#define DEBUG_VGA //#define DEBUG_VGA_MEM @@ -707,9 +708,8 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) #endif /* called for accesses between 0xa0000 and 0xc0000 */ -uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr) +uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr) { - VGACommonState *s = opaque; int memory_map_mode, plane; uint32_t ret; @@ -763,28 +763,9 @@ uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr) return ret; } -static uint32_t vga_mem_readw(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - v = vga_mem_readb(opaque, addr); - v |= vga_mem_readb(opaque, addr + 1) << 8; - return v; -} - -static uint32_t vga_mem_readl(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - v = vga_mem_readb(opaque, addr); - v |= vga_mem_readb(opaque, addr + 1) << 8; - v |= vga_mem_readb(opaque, addr + 2) << 16; - v |= vga_mem_readb(opaque, addr + 3) << 24; - return v; -} - /* called for accesses between 0xa0000 and 0xc0000 */ -void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) +void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val) { - VGACommonState *s = opaque; int memory_map_mode, plane, write_mode, b, func_select, mask; uint32_t write_mask, bit_mask, set_mask; @@ -825,7 +806,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr); #endif s->plane_updated |= mask; /* only used to detect font change */ - cpu_physical_memory_set_dirty(s->vram_offset + addr); + memory_region_set_dirty(&s->vram, addr); } } else if (s->gr[5] & 0x10) { /* odd/even mode (aka text mode mapping) */ @@ -838,7 +819,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr); #endif s->plane_updated |= mask; /* only used to detect font change */ - cpu_physical_memory_set_dirty(s->vram_offset + addr); + memory_region_set_dirty(&s->vram, addr); } } else { /* standard VGA latched access */ @@ -912,24 +893,10 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n", addr * 4, write_mask, val); #endif - cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2)); + memory_region_set_dirty(&s->vram, addr << 2); } } -static void vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - vga_mem_writeb(opaque, addr, val & 0xff); - vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - vga_mem_writeb(opaque, addr, val & 0xff); - vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff); - vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff); - vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff); -} - typedef void vga_draw_glyph8_func(uint8_t *d, int linesize, const uint8_t *font_ptr, int h, uint32_t fgcol, uint32_t bgcol); @@ -1553,57 +1520,17 @@ void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2) static void vga_sync_dirty_bitmap(VGACommonState *s) { - if (s->map_addr) - cpu_physical_sync_dirty_bitmap(s->map_addr, s->map_end); - - if (s->lfb_vram_mapped) { - cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa0000, 0xa8000); - cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa8000, 0xb0000); - } - -#ifdef CONFIG_BOCHS_VBE - if (s->vbe_mapped) { - cpu_physical_sync_dirty_bitmap(VBE_DISPI_LFB_PHYSICAL_ADDRESS, - VBE_DISPI_LFB_PHYSICAL_ADDRESS + s->vram_size); - } -#endif - + memory_region_sync_dirty_bitmap(&s->vram); } void vga_dirty_log_start(VGACommonState *s) { - if (s->map_addr) { - cpu_physical_log_start(s->map_addr, s->map_end - s->map_addr); - } - - if (s->lfb_vram_mapped) { - cpu_physical_log_start(isa_mem_base + 0xa0000, 0x8000); - cpu_physical_log_start(isa_mem_base + 0xa8000, 0x8000); - } - -#ifdef CONFIG_BOCHS_VBE - if (s->vbe_mapped) { - cpu_physical_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); - } -#endif + memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA); } void vga_dirty_log_stop(VGACommonState *s) { - if (s->map_addr) { - cpu_physical_log_stop(s->map_addr, s->map_end - s->map_addr); - } - - if (s->lfb_vram_mapped) { - cpu_physical_log_stop(isa_mem_base + 0xa0000, 0x8000); - cpu_physical_log_stop(isa_mem_base + 0xa8000, 0x8000); - } - -#ifdef CONFIG_BOCHS_VBE - if (s->vbe_mapped) { - cpu_physical_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); - } -#endif + memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA); } void vga_dirty_log_restart(VGACommonState *s) @@ -1773,15 +1700,16 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) if (!(s->cr[0x17] & 2)) { addr = (addr & ~0x8000) | ((y1 & 2) << 14); } - page0 = s->vram_offset + (addr & TARGET_PAGE_MASK); - page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK); + page0 = addr & TARGET_PAGE_MASK; + page1 = (addr + bwidth - 1) & TARGET_PAGE_MASK; update = full_update | - cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) | - cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG); + memory_region_get_dirty(&s->vram, page0, DIRTY_MEMORY_VGA) | + memory_region_get_dirty(&s->vram, page1, DIRTY_MEMORY_VGA); if ((page1 - page0) > TARGET_PAGE_SIZE) { /* if wide line, can use another page */ - update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE, - VGA_DIRTY_FLAG); + update |= memory_region_get_dirty(&s->vram, + page0 + TARGET_PAGE_SIZE, + DIRTY_MEMORY_VGA); } /* explicit invalidation for the hardware cursor */ update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1; @@ -1826,8 +1754,10 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) } /* reset modified pages */ if (page_max >= page_min) { - cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE, - VGA_DIRTY_FLAG); + memory_region_reset_dirty(&s->vram, + page_min, + page_max + TARGET_PAGE_SIZE - page_min, + DIRTY_MEMORY_VGA); } memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4); } @@ -1906,11 +1836,6 @@ static void vga_invalidate_display(void *opaque) void vga_common_reset(VGACommonState *s) { - s->lfb_addr = 0; - s->lfb_end = 0; - s->map_addr = 0; - s->map_end = 0; - s->lfb_vram_mapped = 0; s->sr_index = 0; memset(s->sr, '\0', sizeof(s->sr)); s->gr_index = 0; @@ -2141,16 +2066,30 @@ static void vga_update_text(void *opaque, console_ch_t *chardata) dpy_update(s->ds, 0, 0, s->last_width, height); } -CPUReadMemoryFunc * const vga_mem_read[3] = { - vga_mem_readb, - vga_mem_readw, - vga_mem_readl, -}; +static uint64_t vga_mem_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + VGACommonState *s = opaque; + + return vga_mem_readb(s, addr); +} + +static void vga_mem_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) +{ + VGACommonState *s = opaque; + + return vga_mem_writeb(s, addr, data); +} -CPUWriteMemoryFunc * const vga_mem_write[3] = { - vga_mem_writeb, - vga_mem_writew, - vga_mem_writel, +const MemoryRegionOps vga_mem_ops = { + .read = vga_mem_read, + .write = vga_mem_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, }; static int vga_common_post_load(void *opaque, int version_id) @@ -2236,8 +2175,8 @@ void vga_common_init(VGACommonState *s, int vga_ram_size) #else s->is_vbe_vmstate = 0; #endif - s->vram_offset = qemu_ram_alloc(NULL, "vga.vram", vga_ram_size); - s->vram_ptr = qemu_get_ram_ptr(s->vram_offset); + memory_region_init_ram(&s->vram, NULL, "vga.vram", vga_ram_size); + s->vram_ptr = memory_region_get_ram_ptr(&s->vram); s->vram_size = vga_ram_size; s->get_bpp = vga_get_bpp; s->get_offsets = vga_get_offsets; @@ -2257,11 +2196,14 @@ void vga_common_init(VGACommonState *s, int vga_ram_size) s->update_retrace_info = vga_precise_update_retrace_info; break; } + vga_dirty_log_start(s); } /* used by both ISA and PCI */ -int vga_init_io(VGACommonState *s) +MemoryRegion *vga_init_io(VGACommonState *s) { + MemoryRegion *vga_mem; + register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s); register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s); @@ -2292,30 +2234,36 @@ int vga_init_io(VGACommonState *s) #endif #endif /* CONFIG_BOCHS_VBE */ - return cpu_register_io_memory(vga_mem_read, vga_mem_write, s, - DEVICE_LITTLE_ENDIAN); + vga_mem = qemu_malloc(sizeof(*vga_mem)); + memory_region_init_io(vga_mem, &vga_mem_ops, s, + "vga-lowmem", 0x20000); + + return vga_mem; } void vga_init(VGACommonState *s) { - int vga_io_memory; + MemoryRegion *vga_io_memory; qemu_register_reset(vga_reset, s); s->bank_offset = 0; vga_io_memory = vga_init_io(s); - cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000, - vga_io_memory); - qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000); + memory_region_add_subregion_overlap(get_system_memory(), + isa_mem_base + 0x000a0000, + vga_io_memory, + 1); + memory_region_set_coalescing(vga_io_memory); } void vga_init_vbe(VGACommonState *s) { #ifdef CONFIG_BOCHS_VBE /* XXX: use optimized standard vga accesses */ - cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, - VGA_RAM_SIZE, s->vram_offset); + memory_region_add_subregion(get_system_memory(), + VBE_DISPI_LFB_PHYSICAL_ADDRESS, + &s->vram); s->vbe_mapped = 1; #endif } diff --git a/hw/vga_int.h b/hw/vga_int.h index eee91a84f3..100d98c8bf 100644 --- a/hw/vga_int.h +++ b/hw/vga_int.h @@ -23,6 +23,7 @@ */ #include <hw/hw.h> +#include "memory.h" #define MSR_COLOR_EMULATION 0x01 #define MSR_PAGE_SELECT 0x20 @@ -105,11 +106,7 @@ typedef void (* vga_update_retrace_info_fn)(struct VGACommonState *s); typedef struct VGACommonState { uint8_t *vram_ptr; - ram_addr_t vram_offset; - target_phys_addr_t lfb_addr; - target_phys_addr_t lfb_end; - target_phys_addr_t map_addr; - target_phys_addr_t map_end; + MemoryRegion vram; uint32_t vram_size; uint32_t latch; uint32_t lfb_vram_mapped; /* whether 0xa0000 is mapped as ram */ @@ -134,7 +131,7 @@ typedef struct VGACommonState { int dac_8bit; uint8_t palette[768]; int32_t bank_offset; - int vga_io_memory; + MemoryRegion *vga_io_memory; int (*get_bpp)(struct VGACommonState *s); void (*get_offsets)(struct VGACommonState *s, uint32_t *pline_offset, @@ -191,7 +188,7 @@ static inline int c6_to_8(int v) void vga_common_init(VGACommonState *s, int vga_ram_size); void vga_init(VGACommonState *s); -int vga_init_io(VGACommonState *s); +MemoryRegion *vga_init_io(VGACommonState *s); void vga_common_reset(VGACommonState *s); void vga_dirty_log_start(VGACommonState *s); @@ -201,8 +198,8 @@ void vga_dirty_log_restart(VGACommonState *s); extern const VMStateDescription vmstate_vga_common; uint32_t vga_ioport_read(void *opaque, uint32_t addr); void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val); -uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr); -void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val); +uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr); +void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val); void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2); int ppm_save(const char *filename, struct DisplaySurface *ds); @@ -229,5 +226,4 @@ extern const uint8_t gr_mask[16]; #define VGABIOS_FILENAME "vgabios.bin" #define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin" -extern CPUReadMemoryFunc * const vga_mem_read[3]; -extern CPUWriteMemoryFunc * const vga_mem_write[3]; +extern const MemoryRegionOps vga_mem_ops; diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index f3b3293db0..df27c198b0 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -162,7 +162,8 @@ static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy, { VirtQueue *vq = virtio_get_queue(proxy->vdev, n); EventNotifier *notifier = virtio_queue_get_host_notifier(vq); - int r; + int r = 0; + if (assign) { r = event_notifier_init(notifier, 1); if (r < 0) { @@ -170,24 +171,11 @@ static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy, __func__, r); return r; } - r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier), - proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY, - n, assign); - if (r < 0) { - error_report("%s: unable to map ioeventfd: %d", - __func__, r); - event_notifier_cleanup(notifier); - } + memory_region_add_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2, + true, n, event_notifier_get_fd(notifier)); } else { - r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier), - proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY, - n, assign); - if (r < 0) { - error_report("%s: unable to unmap ioeventfd: %d", - __func__, r); - return r; - } - + memory_region_del_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2, + true, n, event_notifier_get_fd(notifier)); /* Handle the race condition where the guest kicked and we deassigned * before we got around to handling the kick. */ @@ -424,7 +412,6 @@ static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr) { VirtIOPCIProxy *proxy = opaque; uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - addr -= proxy->addr; if (addr < config) return virtio_ioport_read(proxy, addr); addr -= config; @@ -435,7 +422,6 @@ static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr) { VirtIOPCIProxy *proxy = opaque; uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - addr -= proxy->addr; if (addr < config) return virtio_ioport_read(proxy, addr); addr -= config; @@ -446,7 +432,6 @@ static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr) { VirtIOPCIProxy *proxy = opaque; uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - addr -= proxy->addr; if (addr < config) return virtio_ioport_read(proxy, addr); addr -= config; @@ -457,7 +442,6 @@ static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val) { VirtIOPCIProxy *proxy = opaque; uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - addr -= proxy->addr; if (addr < config) { virtio_ioport_write(proxy, addr, val); return; @@ -470,7 +454,6 @@ static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val) { VirtIOPCIProxy *proxy = opaque; uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - addr -= proxy->addr; if (addr < config) { virtio_ioport_write(proxy, addr, val); return; @@ -483,7 +466,6 @@ static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val) { VirtIOPCIProxy *proxy = opaque; uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - addr -= proxy->addr; if (addr < config) { virtio_ioport_write(proxy, addr, val); return; @@ -492,25 +474,20 @@ static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val) virtio_config_writel(proxy->vdev, addr, val); } -static void virtio_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - VirtIOPCIProxy *proxy = container_of(pci_dev, VirtIOPCIProxy, pci_dev); - VirtIODevice *vdev = proxy->vdev; - unsigned config_len = VIRTIO_PCI_REGION_SIZE(pci_dev) + vdev->config_len; - - proxy->addr = addr; - - register_ioport_write(addr, config_len, 1, virtio_pci_config_writeb, proxy); - register_ioport_write(addr, config_len, 2, virtio_pci_config_writew, proxy); - register_ioport_write(addr, config_len, 4, virtio_pci_config_writel, proxy); - register_ioport_read(addr, config_len, 1, virtio_pci_config_readb, proxy); - register_ioport_read(addr, config_len, 2, virtio_pci_config_readw, proxy); - register_ioport_read(addr, config_len, 4, virtio_pci_config_readl, proxy); +const MemoryRegionPortio virtio_portio[] = { + { 0, 0x10000, 1, .write = virtio_pci_config_writeb, }, + { 0, 0x10000, 2, .write = virtio_pci_config_writew, }, + { 0, 0x10000, 4, .write = virtio_pci_config_writel, }, + { 0, 0x10000, 1, .read = virtio_pci_config_readb, }, + { 0, 0x10000, 2, .read = virtio_pci_config_readw, }, + { 0, 0x10000, 4, .read = virtio_pci_config_readl, }, + PORTIO_END_OF_LIST() +}; - if (vdev->config_len) - vdev->get_config(vdev, vdev->config); -} +static const MemoryRegionOps virtio_pci_config_ops = { + .old_portio = virtio_portio, + .endianness = DEVICE_LITTLE_ENDIAN, +}; static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, uint32_t val, int len) @@ -664,11 +641,11 @@ void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev) pci_set_word(config + 0x2e, vdev->device_id); config[0x3d] = 1; - if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors, 1, 0)) { - pci_register_bar(&proxy->pci_dev, 1, - msix_bar_size(&proxy->pci_dev), - PCI_BASE_ADDRESS_SPACE_MEMORY, - msix_mmio_map); + memory_region_init(&proxy->msix_bar, "virtio-msix", 4096); + if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors, + &proxy->msix_bar, 1, 0)) { + pci_register_bar(&proxy->pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, + &proxy->msix_bar); } else vdev->nvectors = 0; @@ -678,8 +655,10 @@ void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev) if (size & (size-1)) size = 1 << qemu_fls(size); - pci_register_bar(&proxy->pci_dev, 0, size, PCI_BASE_ADDRESS_SPACE_IO, - virtio_map); + memory_region_init_io(&proxy->bar, &virtio_pci_config_ops, proxy, + "virtio-pci", size); + pci_register_bar(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, + &proxy->bar); if (!kvm_has_many_ioeventfds()) { proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD; @@ -714,7 +693,13 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev) static int virtio_exit_pci(PCIDevice *pci_dev) { - return msix_uninit(pci_dev); + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + int r; + + memory_region_destroy(&proxy->bar); + r = msix_uninit(pci_dev, &proxy->msix_bar); + memory_region_destroy(&proxy->msix_bar); + return r; } static int virtio_blk_exit_pci(PCIDevice *pci_dev) diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h index 1f0de5684d..14c10f7d67 100644 --- a/hw/virtio-pci.h +++ b/hw/virtio-pci.h @@ -21,8 +21,9 @@ typedef struct { PCIDevice pci_dev; VirtIODevice *vdev; + MemoryRegion bar; + MemoryRegion msix_bar; uint32_t flags; - uint32_t addr; uint32_t class_code; uint32_t nvectors; BlockConf block; diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c index 354c221720..d5cfa70cba 100644 --- a/hw/vmware_vga.c +++ b/hw/vmware_vga.c @@ -52,8 +52,6 @@ struct vmsvga_state_s { int on; } cursor; - target_phys_addr_t vram_base; - int index; int scratch_size; uint32_t *scratch; @@ -67,10 +65,9 @@ struct vmsvga_state_s { int syncing; int fb_size; - ram_addr_t fifo_offset; + MemoryRegion fifo_ram; uint8_t *fifo_ptr; unsigned int fifo_size; - target_phys_addr_t fifo_base; union { uint32_t *fifo; @@ -94,6 +91,7 @@ struct vmsvga_state_s { struct pci_vmsvga_state_s { PCIDevice card; struct vmsvga_state_s chip; + MemoryRegion io_bar; }; #define SVGA_MAGIC 0x900000UL @@ -761,8 +759,11 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) case SVGA_REG_BYTES_PER_LINE: return ((s->depth + 7) >> 3) * s->new_width; - case SVGA_REG_FB_START: - return s->vram_base; + case SVGA_REG_FB_START: { + struct pci_vmsvga_state_s *pci_vmsvga + = container_of(s, struct pci_vmsvga_state_s, chip); + return pci_get_bar_addr(&pci_vmsvga->card, 1); + } case SVGA_REG_FB_OFFSET: return 0x0; @@ -788,8 +789,11 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) #endif return caps; - case SVGA_REG_MEM_START: - return s->fifo_base; + case SVGA_REG_MEM_START: { + struct pci_vmsvga_state_s *pci_vmsvga + = container_of(s, struct pci_vmsvga_state_s, chip); + return pci_get_bar_addr(&pci_vmsvga->card, 2); + } case SVGA_REG_MEM_SIZE: return s->fifo_size; @@ -1134,17 +1138,22 @@ static void vmsvga_vram_writel(void *opaque, target_phys_addr_t addr, *(uint32_t *) (s->vram_ptr + addr) = value; } -static CPUReadMemoryFunc * const vmsvga_vram_read[] = { - vmsvga_vram_readb, - vmsvga_vram_readw, - vmsvga_vram_readl, -}; +static const MemoryRegionOps vmsvga_vram_io_ops = { + .old_mmio = { + .read = { + vmsvga_vram_readb, + vmsvga_vram_readw, + vmsvga_vram_readl, + }, + .write = { + vmsvga_vram_writeb, + vmsvga_vram_writew, + vmsvga_vram_writel, + }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, +} -static CPUWriteMemoryFunc * const vmsvga_vram_write[] = { - vmsvga_vram_writeb, - vmsvga_vram_writew, - vmsvga_vram_writel, -}; #endif static int vmsvga_post_load(void *opaque, int version_id) @@ -1210,8 +1219,8 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size) s->fifo_size = SVGA_FIFO_SIZE; - s->fifo_offset = qemu_ram_alloc(NULL, "vmsvga.fifo", s->fifo_size); - s->fifo_ptr = qemu_get_ram_ptr(s->fifo_offset); + memory_region_init_ram(&s->fifo_ram, NULL, "vmsvga.fifo", s->fifo_size); + s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram); vga_common_init(&s->vga, vga_ram_size); vga_init(&s->vga); @@ -1220,80 +1229,76 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size) vmsvga_reset(s); } -static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static uint64_t vmsvga_io_read(void *opaque, target_phys_addr_t addr, + unsigned size) { - struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev; - struct vmsvga_state_s *s = &d->chip; - - register_ioport_read(addr + SVGA_IO_MUL * SVGA_INDEX_PORT, - 1, 4, vmsvga_index_read, s); - register_ioport_write(addr + SVGA_IO_MUL * SVGA_INDEX_PORT, - 1, 4, vmsvga_index_write, s); - register_ioport_read(addr + SVGA_IO_MUL * SVGA_VALUE_PORT, - 1, 4, vmsvga_value_read, s); - register_ioport_write(addr + SVGA_IO_MUL * SVGA_VALUE_PORT, - 1, 4, vmsvga_value_write, s); - register_ioport_read(addr + SVGA_IO_MUL * SVGA_BIOS_PORT, - 1, 4, vmsvga_bios_read, s); - register_ioport_write(addr + SVGA_IO_MUL * SVGA_BIOS_PORT, - 1, 4, vmsvga_bios_write, s); + struct vmsvga_state_s *s = opaque; + + switch (addr) { + case SVGA_IO_MUL * SVGA_INDEX_PORT: return vmsvga_index_read(s, addr); + case SVGA_IO_MUL * SVGA_VALUE_PORT: return vmsvga_value_read(s, addr); + case SVGA_IO_MUL * SVGA_BIOS_PORT: return vmsvga_bios_read(s, addr); + default: return -1u; + } } -static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static void vmsvga_io_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) { - struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev; - struct vmsvga_state_s *s = &d->chip; - ram_addr_t iomemtype; - - s->vram_base = addr; -#ifdef DIRECT_VRAM - iomemtype = cpu_register_io_memory(vmsvga_vram_read, - vmsvga_vram_write, s, DEVICE_NATIVE_ENDIAN); -#else - iomemtype = s->vga.vram_offset | IO_MEM_RAM; -#endif - cpu_register_physical_memory(s->vram_base, s->vga.vram_size, - iomemtype); + struct vmsvga_state_s *s = opaque; - s->vga.map_addr = addr; - s->vga.map_end = addr + s->vga.vram_size; - vga_dirty_log_restart(&s->vga); + switch (addr) { + case SVGA_IO_MUL * SVGA_INDEX_PORT: + return vmsvga_index_write(s, addr, data); + case SVGA_IO_MUL * SVGA_VALUE_PORT: + return vmsvga_value_write(s, addr, data); + case SVGA_IO_MUL * SVGA_BIOS_PORT: + return vmsvga_bios_write(s, addr, data); + } } -static void pci_vmsvga_map_fifo(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev; - struct vmsvga_state_s *s = &d->chip; - ram_addr_t iomemtype; - - s->fifo_base = addr; - iomemtype = s->fifo_offset | IO_MEM_RAM; - cpu_register_physical_memory(s->fifo_base, s->fifo_size, - iomemtype); -} +static const MemoryRegionOps vmsvga_io_ops = { + .read = vmsvga_io_read, + .write = vmsvga_io_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; static int pci_vmsvga_initfn(PCIDevice *dev) { struct pci_vmsvga_state_s *s = DO_UPCAST(struct pci_vmsvga_state_s, card, dev); + MemoryRegion *iomem; + +#ifdef DIRECT_VRAM + DirectMem *directmem = qemu_malloc(sizeof(*directmem)); + + iomem = &directmem->mr; + memory_region_init_io(iomem, &vmsvga_vram_io_ops, &s->chip, "vmsvga", + memory_region_size(&s->chip.vga.vram)); +#else + iomem = &s->chip.vga.vram; +#endif + + vga_dirty_log_restart(&s->chip.vga); s->card.config[PCI_CACHE_LINE_SIZE] = 0x08; /* Cache line size */ s->card.config[PCI_LATENCY_TIMER] = 0x40; /* Latency timer */ s->card.config[PCI_INTERRUPT_LINE] = 0xff; /* End */ - pci_register_bar(&s->card, 0, 0x10, - PCI_BASE_ADDRESS_SPACE_IO, pci_vmsvga_map_ioport); - pci_register_bar(&s->card, 1, VGA_RAM_SIZE, - PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_mem); - - pci_register_bar(&s->card, 2, SVGA_FIFO_SIZE, - PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_fifo); + memory_region_init_io(&s->io_bar, &vmsvga_io_ops, &s->chip, + "vmsvga-io", 0x10); + pci_register_bar(&s->card, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar); vmsvga_init(&s->chip, VGA_RAM_SIZE); + pci_register_bar(&s->card, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, iomem); + pci_register_bar(&s->card, 2, PCI_BASE_ADDRESS_MEM_PREFETCH, + &s->chip.fifo_ram); + if (!dev->rom_bar) { /* compatibility with pc-0.13 and older */ vga_init_vbe(&s->chip.vga); diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c index 53786ce8fa..20d8673186 100644 --- a/hw/wdt_i6300esb.c +++ b/hw/wdt_i6300esb.c @@ -66,6 +66,7 @@ /* Device state. */ struct I6300State { PCIDevice dev; + MemoryRegion io_mem; int reboot_enabled; /* "Reboot" on timer expiry. The real action * performed depends on the -watchdog-action @@ -355,6 +356,22 @@ static void i6300esb_mem_writel(void *vp, target_phys_addr_t addr, uint32_t val) } } +static const MemoryRegionOps i6300esb_ops = { + .old_mmio = { + .read = { + i6300esb_mem_readb, + i6300esb_mem_readw, + i6300esb_mem_readl, + }, + .write = { + i6300esb_mem_writeb, + i6300esb_mem_writew, + i6300esb_mem_writel, + }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + static const VMStateDescription vmstate_i6300esb = { .name = "i6300esb_wdt", .version_id = sizeof(I6300State), @@ -381,31 +398,28 @@ static const VMStateDescription vmstate_i6300esb = { static int i6300esb_init(PCIDevice *dev) { I6300State *d = DO_UPCAST(I6300State, dev, dev); - int io_mem; - static CPUReadMemoryFunc * const mem_read[3] = { - i6300esb_mem_readb, - i6300esb_mem_readw, - i6300esb_mem_readl, - }; - static CPUWriteMemoryFunc * const mem_write[3] = { - i6300esb_mem_writeb, - i6300esb_mem_writew, - i6300esb_mem_writel, - }; i6300esb_debug("I6300State = %p\n", d); d->timer = qemu_new_timer_ns(vm_clock, i6300esb_timer_expired, d); d->previous_reboot_flag = 0; - io_mem = cpu_register_io_memory(mem_read, mem_write, d, - DEVICE_NATIVE_ENDIAN); - pci_register_bar_simple(&d->dev, 0, 0x10, 0, io_mem); + memory_region_init_io(&d->io_mem, &i6300esb_ops, d, "i6300esb", 0x10); + pci_register_bar(&d->dev, 0, 0, &d->io_mem); /* qemu_register_coalesced_mmio (addr, 0x10); ? */ return 0; } +static int i6300esb_exit(PCIDevice *dev) +{ + I6300State *d = DO_UPCAST(I6300State, dev, dev); + + memory_region_destroy(&d->io_mem); + + return 0; +} + static WatchdogTimerModel model = { .wdt_name = "i6300esb", .wdt_description = "Intel 6300ESB", @@ -419,6 +433,7 @@ static PCIDeviceInfo i6300esb_info = { .config_read = i6300esb_config_read, .config_write = i6300esb_config_write, .init = i6300esb_init, + .exit = i6300esb_exit, .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = PCI_DEVICE_ID_INTEL_ESB_9, .class_id = PCI_CLASS_SYSTEM_OTHER, diff --git a/hw/xen_platform.c b/hw/xen_platform.c index fb6be6a464..6e3ba8b507 100644 --- a/hw/xen_platform.c +++ b/hw/xen_platform.c @@ -32,8 +32,8 @@ #include "xen_common.h" #include "net.h" #include "xen_backend.h" -#include "rwhandler.h" #include "trace.h" +#include "exec-memory.h" #include <xenguest.h> @@ -51,6 +51,9 @@ typedef struct PCIXenPlatformState { PCIDevice pci_dev; + MemoryRegion fixed_io; + MemoryRegion bar; + MemoryRegion mmio_bar; uint8_t flags; /* used only for version_id == 2 */ int drivers_blacklisted; uint16_t driver_product_version; @@ -221,21 +224,32 @@ static void platform_fixed_ioport_reset(void *opaque) platform_fixed_ioport_writeb(s, XEN_PLATFORM_IOPORT, 0); } +const MemoryRegionPortio xen_platform_ioport[] = { + { 0, 16, 4, .write = platform_fixed_ioport_writel, }, + { 0, 16, 2, .write = platform_fixed_ioport_writew, }, + { 0, 16, 1, .write = platform_fixed_ioport_writeb, }, + { 0, 16, 2, .read = platform_fixed_ioport_readw, }, + { 0, 16, 1, .read = platform_fixed_ioport_readb, }, + PORTIO_END_OF_LIST() +}; + +static const MemoryRegionOps platform_fixed_io_ops = { + .old_portio = xen_platform_ioport, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + static void platform_fixed_ioport_init(PCIXenPlatformState* s) { - register_ioport_write(XEN_PLATFORM_IOPORT, 16, 4, platform_fixed_ioport_writel, s); - register_ioport_write(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_writew, s); - register_ioport_write(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_writeb, s); - register_ioport_read(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_readw, s); - register_ioport_read(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_readb, s); + memory_region_init_io(&s->fixed_io, &platform_fixed_io_ops, s, + "xen-fixed", 16); + memory_region_add_subregion(get_system_io(), XEN_PLATFORM_IOPORT, + &s->fixed_io); } /* Xen Platform PCI Device */ static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr) { - addr &= 0xff; - if (addr == 0) { return platform_fixed_ioport_readb(opaque, XEN_PLATFORM_IOPORT); } else { @@ -247,9 +261,6 @@ static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val { PCIXenPlatformState *s = opaque; - addr &= 0xff; - val &= 0xff; - switch (addr) { case 0: /* Platform flags */ platform_fixed_ioport_writeb(opaque, XEN_PLATFORM_IOPORT, val); @@ -262,15 +273,23 @@ static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val } } -static void platform_ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, pcibus_t size, int type) -{ - PCIXenPlatformState *d = DO_UPCAST(PCIXenPlatformState, pci_dev, pci_dev); +static MemoryRegionPortio xen_pci_portio[] = { + { 0, 0x100, 1, .read = xen_platform_ioport_readb, }, + { 0, 0x100, 1, .write = xen_platform_ioport_writeb, }, + PORTIO_END_OF_LIST() +}; + +static const MemoryRegionOps xen_pci_io_ops = { + .old_portio = xen_pci_portio, +}; - register_ioport_write(addr, size, 1, xen_platform_ioport_writeb, d); - register_ioport_read(addr, size, 1, xen_platform_ioport_readb, d); +static void platform_ioport_bar_setup(PCIXenPlatformState *d) +{ + memory_region_init_io(&d->bar, &xen_pci_io_ops, d, "xen-pci", 0x100); } -static uint32_t platform_mmio_read(ReadWriteHandler *handler, pcibus_t addr, int len) +static uint64_t platform_mmio_read(void *opaque, target_phys_addr_t addr, + unsigned size) { DPRINTF("Warning: attempted read from physical address " "0x" TARGET_FMT_plx " in xen platform mmio space\n", addr); @@ -278,28 +297,24 @@ static uint32_t platform_mmio_read(ReadWriteHandler *handler, pcibus_t addr, int return 0; } -static void platform_mmio_write(ReadWriteHandler *handler, pcibus_t addr, - uint32_t val, int len) +static void platform_mmio_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { - DPRINTF("Warning: attempted write of 0x%x to physical " + DPRINTF("Warning: attempted write of 0x%"PRIx64" to physical " "address 0x" TARGET_FMT_plx " in xen platform mmio space\n", val, addr); } -static ReadWriteHandler platform_mmio_handler = { +static const MemoryRegionOps platform_mmio_handler = { .read = &platform_mmio_read, .write = &platform_mmio_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static void platform_mmio_map(PCIDevice *d, int region_num, - pcibus_t addr, pcibus_t size, int type) +static void platform_mmio_setup(PCIXenPlatformState *d) { - int mmio_io_addr; - - mmio_io_addr = cpu_register_io_memory_simple(&platform_mmio_handler, - DEVICE_NATIVE_ENDIAN); - - cpu_register_physical_memory(addr, size, mmio_io_addr); + memory_region_init_io(&d->mmio_bar, &platform_mmio_handler, d, + "xen-mmio", 0x1000000); } static int xen_platform_post_load(void *opaque, int version_id) @@ -337,12 +352,13 @@ static int xen_platform_initfn(PCIDevice *dev) pci_conf[PCI_INTERRUPT_PIN] = 1; - pci_register_bar(&d->pci_dev, 0, 0x100, - PCI_BASE_ADDRESS_SPACE_IO, platform_ioport_map); + platform_ioport_bar_setup(d); + pci_register_bar(&d->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->bar); /* reserve 16MB mmio address for share memory*/ - pci_register_bar(&d->pci_dev, 1, 0x1000000, - PCI_BASE_ADDRESS_MEM_PREFETCH, platform_mmio_map); + platform_mmio_setup(d); + pci_register_bar(&d->pci_dev, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, + &d->mmio_bar); platform_fixed_ioport_init(d); |