diff options
143 files changed, 2253 insertions, 2433 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 7cbcd7e..508ea1e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -143,6 +143,16 @@ L: kvm@vger.kernel.org S: Supported F: target-i386/kvm.c +Guest CPU Cores (Xen): +---------------------- + +X86 +M: Stefano Stabellini <stefano.stabellini@eu.citrix.com> +L: xen-devel@lists.xensource.com +S: Supported +F: xen-* +F: */xen* + ARM Machines ------------ Gumstix diff --git a/bsd-user/main.c b/bsd-user/main.c index a63b877..cc7d4a3 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -905,7 +905,8 @@ int main(int argc, char **argv) cpu_model = "any"; #endif } - cpu_exec_init_all(0); + tcg_exec_init(0); + cpu_exec_init_all(); /* NOTE: we need to init the CPU at this stage to get qemu_host_page_size */ env = cpu_init(cpu_model); @@ -220,14 +220,14 @@ done # Using uname is really, really broken. Once we have the right set of checks # we can eliminate it's usage altogether -cc="${cross_prefix}${CC-gcc}" -ar="${cross_prefix}${AR-ar}" -objcopy="${cross_prefix}${OBJCOPY-objcopy}" -ld="${cross_prefix}${LD-ld}" -strip="${cross_prefix}${STRIP-strip}" -windres="${cross_prefix}${WINDRES-windres}" -pkg_config="${cross_prefix}${PKG_CONFIG-pkg-config}" -sdl_config="${cross_prefix}${SDL_CONFIG-sdl-config}" +cc="${CC-${cross_prefix}gcc}" +ar="${AR-${cross_prefix}ar}" +objcopy="${OBJCOPY-${cross_prefix}objcopy}" +ld="${LD-${cross_prefix}ld}" +strip="${STRIP-${cross_prefix}strip}" +windres="${WINDRES-${cross_prefix}windres}" +pkg_config="${PKG_CONFIG-${cross_prefix}pkg-config}" +sdl_config="${SDL_CONFIG-${cross_prefix}sdl-config}" # default flags for all hosts QEMU_CFLAGS="-fno-strict-aliasing $QEMU_CFLAGS" diff --git a/coroutine-ucontext.c b/coroutine-ucontext.c index 41c2379..42dc3e2 100644 --- a/coroutine-ucontext.c +++ b/coroutine-ucontext.c @@ -133,7 +133,7 @@ static Coroutine *coroutine_new(void) CoroutineUContext *co; ucontext_t old_uc, uc; jmp_buf old_env; - union cc_arg arg; + union cc_arg arg = {0}; /* The ucontext functions preserve signal masks which incurs a system call * overhead. setjmp()/longjmp() does not preserve signal masks but only diff --git a/darwin-user/main.c b/darwin-user/main.c index 72307ad..1a881a0 100644 --- a/darwin-user/main.c +++ b/darwin-user/main.c @@ -852,8 +852,8 @@ int main(int argc, char **argv) #error unsupported CPU #endif } - - cpu_exec_init_all(0); + tcg_exec_init(0); + cpu_exec_init_all(); /* NOTE: we need to init the CPU at this stage to get qemu_host_page_size */ env = cpu_init(cpu_model); diff --git a/darwin-user/signal.c b/darwin-user/signal.c index e2adca3..c530227 100644 --- a/darwin-user/signal.c +++ b/darwin-user/signal.c @@ -319,7 +319,6 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, void *set, CPUState *env) { void *frame; - int i, err = 0; fprintf(stderr, "setup_frame %d\n", sig); frame = get_sigframe(ka, env, sizeof(*frame)); diff --git a/exec-memory.h b/exec-memory.h index c439aba..334219f 100644 --- a/exec-memory.h +++ b/exec-memory.h @@ -28,6 +28,11 @@ */ MemoryRegion *get_system_memory(void); +/* Get the root I/O port region. This interface should only be used + * temporarily until a proper bus interface is available. + */ +MemoryRegion *get_system_io(void); + /* Set the root memory region. This region is the system memory map. */ void set_system_memory_map(MemoryRegion *mr); @@ -113,6 +113,7 @@ static int in_migration; RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list) }; static MemoryRegion *system_memory; +static MemoryRegion *system_io; #endif @@ -526,7 +527,8 @@ static void code_gen_alloc(unsigned long tb_size) } } #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \ - || defined(__DragonFly__) || defined(__OpenBSD__) + || defined(__DragonFly__) || defined(__OpenBSD__) \ + || defined(__NetBSD__) { int flags; void *addr = NULL; @@ -570,16 +572,12 @@ static void code_gen_alloc(unsigned long tb_size) /* Must be called before using the QEMU cpus. 'tb_size' is the size (in bytes) allocated to the translation buffer. Zero means default size. */ -void cpu_exec_init_all(unsigned long tb_size) +void tcg_exec_init(unsigned long tb_size) { cpu_gen_init(); code_gen_alloc(tb_size); code_gen_ptr = code_gen_buffer; page_init(); -#if !defined(CONFIG_USER_ONLY) - memory_map_init(); - io_mem_init(); -#endif #if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE) /* There's no guest base to take into account, so go ahead and initialize the prologue now. */ @@ -587,6 +585,19 @@ void cpu_exec_init_all(unsigned long tb_size) #endif } +bool tcg_enabled(void) +{ + return code_gen_buffer != NULL; +} + +void cpu_exec_init_all(void) +{ +#if !defined(CONFIG_USER_ONLY) + memory_map_init(); + io_mem_init(); +#endif +} + #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY) static int cpu_common_post_load(void *opaque, int version_id) @@ -3818,8 +3829,12 @@ static void io_mem_init(void) static void memory_map_init(void) { system_memory = qemu_malloc(sizeof(*system_memory)); - memory_region_init(system_memory, "system", UINT64_MAX); + memory_region_init(system_memory, "system", INT64_MAX); set_system_memory_map(system_memory); + + system_io = qemu_malloc(sizeof(*system_io)); + memory_region_init(system_io, "io", 65536); + set_system_io_map(system_io); } MemoryRegion *get_system_memory(void) @@ -3827,6 +3842,11 @@ MemoryRegion *get_system_memory(void) return system_memory; } +MemoryRegion *get_system_io(void) +{ + return system_io; +} + #endif /* !defined(CONFIG_USER_ONLY) */ /* physical memory access (slow version, mainly for debug) */ @@ -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 8b9939c..1638226 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/bonito.c b/hw/bonito.c index 5f62dda..8708e95 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 f39d1f8..b489309 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, @@ -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); } @@ -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 9b6f4a5..a636d30 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 1ed62b7..a9387d1 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/fw_cfg.c b/hw/fw_cfg.c index a29db90..e4847b7 100644 --- a/hw/fw_cfg.c +++ b/hw/fw_cfg.c @@ -87,6 +87,13 @@ static FILE *probe_splashfile(char *filename, int *file_sizep, int *file_typep) /* check magic ID */ fseek(fp, 0L, SEEK_SET); fop_ret = fread(buf, 1, 2, fp); + if (fop_ret != 2) { + error_report("Could not read header from '%s': %s", + filename, strerror(errno)); + fclose(fp); + fp = NULL; + return fp; + } filehead_value = (buf[0] + (buf[1] << 8)) & 0xffff; if (filehead_value == 0xd8ff) { file_type = JPG_FILE; @@ -181,6 +188,12 @@ static void fw_cfg_bootsplash(FWCfgState *s) boot_splash_filedata_size = file_size; fseek(fp, 0L, SEEK_SET); fop_ret = fread(boot_splash_filedata, 1, file_size, fp); + if (fop_ret != file_size) { + error_report("failed to read data from '%s'.", + boot_splash_filename); + fclose(fp); + return; + } fclose(fp); /* insert data */ if (file_type == JPG_FILE) { diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c index da67cf9..9a823e1 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 65e63dd..d541558 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 5fd71a0..3ba0b0e 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); @@ -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 1f008a3..e207ca0 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 dc86951..e456193 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 56302b5..4d91e2c 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 d241ea8..5278bc4 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 7daeb31..7ee35e9 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 9f3050a..d1a14d7 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 b4f3691..a694e54 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 f527dbd..8525336 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 3474c37..c0b9d43 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 5a2bc3a..fa56a92 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 ca957fb..3d2af1a 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 3055dd2..42a5877 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; @@ -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, s, "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 e9904c4..d067a02 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 ed4458e..350d901 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 d236c5b..933e17c 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 61e53d2..ced1e58 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 */ @@ -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); } @@ -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 e41dbba..756ed5c 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 f8acaae..a035a85 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 54fdfca..5fee052 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 6d2cf99..ccd4a14 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 0957c1f..75de361 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 c0a2abe..7dd5008 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 c3a463a..c7fd23d 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 216cf81..13d9380 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; @@ -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 80d6665..28a3ee2 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 15c24f6..c7696b0 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 6fad20a..7351bb6 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 2c0fae8..3039022 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 585afd6..41703a7 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 91ebe07..38d8573 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 1344539..6a9f979 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 da02f0e..58619dd 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 a27368b..b6b481a 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 @@ -36,6 +36,7 @@ static bool qdev_hot_removed = false; /* This is a nasty hack to allow passing a NULL bus to qdev_create. */ static BusState *main_system_bus; +static void main_system_bus_create(void); DeviceInfo *device_info_list; @@ -328,8 +329,7 @@ static int qdev_reset_one(DeviceState *dev, void *opaque) BusState *sysbus_get_default(void) { if (!main_system_bus) { - main_system_bus = qbus_create(&system_bus_info, NULL, - "main-system-bus"); + main_system_bus_create(); } return main_system_bus; } @@ -784,6 +784,16 @@ BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name) return bus; } +static void main_system_bus_create(void) +{ + /* assign main_system_bus before qbus_create_inplace() + * in order to make "if (bus != main_system_bus)" work */ + main_system_bus = qemu_mallocz(system_bus_info.size); + main_system_bus->qdev_allocated = 1; + qbus_create_inplace(main_system_bus, &system_bus_info, NULL, + "main-system-bus"); +} + void qbus_free(BusState *bus) { DeviceState *dev; diff --git a/hw/qxl-render.c b/hw/qxl-render.c index 643ff2d..1b77577 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,20 +817,6 @@ 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; @@ -959,10 +943,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 +1116,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; @@ -1241,7 +1226,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: @@ -1348,7 +1333,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 +1342,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 +1469,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 +1537,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 +1549,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 +1628,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 +1793,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 5214b8c..c6cafc2 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 0ef93a0..cd86501 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); @@ -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 b499523..f896f8c 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 2b43895..c9d0a69 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-ohci.c b/hw/usb-ohci.c index d39bcb0..d30db3f 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 824e3a5..16088d7 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, diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index cffe387..e1d5c0b 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 4954bb1..96e6e7d 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 245841f..fef7f58 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 481f448..c67be0a 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 eee91a8..100d98c 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 f3b3293..df27c19 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 1f0de56..14c10f7 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 354c221..d5cfa70 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 53786ce..20d8673 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 fb6be6a..6e3ba8b 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); diff --git a/linux-user/main.c b/linux-user/main.c index 6a8f4bd..8e15474 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3117,7 +3117,8 @@ int main(int argc, char **argv, char **envp) cpu_model = "any"; #endif } - cpu_exec_init_all(0); + tcg_exec_init(0); + cpu_exec_init_all(); /* NOTE: we need to init the CPU at this stage to get qemu_host_page_size */ env = cpu_init(cpu_model); @@ -22,12 +22,17 @@ unsigned memory_region_transaction_depth = 0; typedef struct AddrRange AddrRange; +/* + * Note using signed integers limits us to physical addresses at most + * 63 bits wide. They are needed for negative offsetting in aliases + * (large MemoryRegion::alias_offset). + */ struct AddrRange { - uint64_t start; - uint64_t size; + int64_t start; + int64_t size; }; -static AddrRange addrrange_make(uint64_t start, uint64_t size) +static AddrRange addrrange_make(int64_t start, int64_t size) { return (AddrRange) { start, size }; } @@ -37,7 +42,7 @@ static bool addrrange_equal(AddrRange r1, AddrRange r2) return r1.start == r2.start && r1.size == r2.size; } -static uint64_t addrrange_end(AddrRange r) +static int64_t addrrange_end(AddrRange r) { return r.start + r.size; } @@ -56,9 +61,9 @@ static bool addrrange_intersects(AddrRange r1, AddrRange r2) static AddrRange addrrange_intersection(AddrRange r1, AddrRange r2) { - uint64_t start = MAX(r1.start, r2.start); + int64_t start = MAX(r1.start, r2.start); /* off-by-one arithmetic to prevent overflow */ - uint64_t end = MIN(addrrange_end(r1) - 1, addrrange_end(r2) - 1); + int64_t end = MIN(addrrange_end(r1) - 1, addrrange_end(r2) - 1); return addrrange_make(start, end - start + 1); } @@ -245,6 +250,10 @@ static void as_memory_range_add(AddressSpace *as, FlatRange *fr) static void as_memory_range_del(AddressSpace *as, FlatRange *fr) { + if (fr->dirty_log_mask) { + cpu_physical_sync_dirty_bitmap(fr->addr.start, + fr->addr.start + fr->addr.size); + } cpu_register_physical_memory(fr->addr.start, fr->addr.size, IO_MEM_UNASSIGNED); } @@ -407,8 +416,8 @@ static void render_memory_region(FlatView *view, MemoryRegion *subregion; unsigned i; target_phys_addr_t offset_in_region; - uint64_t remain; - uint64_t now; + int64_t remain; + int64_t now; FlatRange fr; AddrRange tmp; @@ -482,7 +491,7 @@ static FlatView generate_memory_topology(MemoryRegion *mr) flatview_init(&view); - render_memory_region(&view, mr, 0, addrrange_make(0, UINT64_MAX)); + render_memory_region(&view, mr, 0, addrrange_make(0, INT64_MAX)); flatview_simplify(&view); return view; @@ -133,7 +133,7 @@ struct MemoryRegionPortio { IOPortWriteFunc *write; }; -#define PORTIO_END { } +#define PORTIO_END_OF_LIST() { } /** * memory_region_init: Initialize a memory region diff --git a/migration.c b/migration.c index 2a15b98..756fa62 100644 --- a/migration.c +++ b/migration.c @@ -292,18 +292,17 @@ int migrate_fd_cleanup(FdMigrationState *s) ret = -1; } s->file = NULL; + } else { + if (s->mon) { + monitor_resume(s->mon); + } } - if (s->fd != -1) + if (s->fd != -1) { close(s->fd); - - /* Don't resume monitor until we've flushed all of the buffers */ - if (s->mon) { - monitor_resume(s->mon); + s->fd = -1; } - s->fd = -1; - return ret; } @@ -330,9 +329,6 @@ ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size) if (ret == -EAGAIN) { qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s); } else if (ret < 0) { - if (s->mon) { - monitor_resume(s->mon); - } s->state = MIG_STATE_ERROR; notifier_list_notify(&migration_state_notifiers, NULL); } @@ -458,6 +454,9 @@ int migrate_fd_close(void *opaque) { FdMigrationState *s = opaque; + if (s->mon) { + monitor_resume(s->mon); + } qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); return s->close(s); } diff --git a/net/socket.c b/net/socket.c index 11fe5f3..5cd0b9a 100644 --- a/net/socket.c +++ b/net/socket.c @@ -154,6 +154,12 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr struct ip_mreq imr; int fd; int val, ret; +#ifdef __OpenBSD__ + unsigned char loop; +#else + int loop; +#endif + if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) { fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n", inet_ntoa(mcastaddr->sin_addr), @@ -197,9 +203,9 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr } /* Force mcast msgs to loopback (eg. several QEMUs in same host */ - val = 1; + loop = 1; ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, - (const char *)&val, sizeof(val)); + (const char *)&loop, sizeof(loop)); if (ret < 0) { perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)"); goto fail; diff --git a/net/tap-bsd.c b/net/tap-bsd.c index 2f3efde..4b6b3a4 100644 --- a/net/tap-bsd.c +++ b/net/tap-bsd.c @@ -28,6 +28,8 @@ #include "qemu-error.h" #ifdef __NetBSD__ +#include <sys/ioctl.h> +#include <net/if.h> #include <net/if_tap.h> #endif @@ -40,8 +42,12 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required) { int fd; +#ifdef TAPGIFNAME + struct ifreq ifr; +#else char *dev; struct stat s; +#endif #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) /* if no ifname is given, always start the search from tap0/tun0. */ @@ -77,14 +83,30 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required #else TFR(fd = open("/dev/tap", O_RDWR)); if (fd < 0) { - fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n"); + fprintf(stderr, + "warning: could not open /dev/tap: no virtual network emulation: %s\n", + strerror(errno)); return -1; } #endif - fstat(fd, &s); +#ifdef TAPGIFNAME + if (ioctl(fd, TAPGIFNAME, (void *)&ifr) < 0) { + fprintf(stderr, "warning: could not get tap name: %s\n", + strerror(errno)); + return -1; + } + pstrcpy(ifname, ifname_size, ifr.ifr_name); +#else + if (fstat(fd, &s) < 0) { + fprintf(stderr, + "warning: could not stat /dev/tap: no virtual network emulation: %s\n", + strerror(errno)); + return -1; + } dev = devname(s.st_rdev, S_IFCHR); pstrcpy(ifname, ifname_size, dev); +#endif if (*vnet_hdr) { /* BSD doesn't have IFF_VNET_HDR */ diff --git a/qemu-common.h b/qemu-common.h index 389f4d2..74d5c4b 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -272,7 +272,10 @@ typedef struct QEMUSGList QEMUSGList; typedef uint64_t pcibus_t; -void cpu_exec_init_all(unsigned long tb_size); +void tcg_exec_init(unsigned long tb_size); +bool tcg_enabled(void); + +void cpu_exec_init_all(void); /* CPU save/load. */ void cpu_save(QEMUFile *f, void *opaque); diff --git a/qemu-doc.texi b/qemu-doc.texi index 47e1991..31199f6 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -288,6 +288,14 @@ then the modifier is Ctrl-Alt-Shift (instead of Ctrl-Alt) and if you use @kindex Ctrl-Alt-f Toggle full screen +@item Ctrl-Alt-+ +@kindex Ctrl-Alt-+ +Enlarge the screen + +@item Ctrl-Alt-- +@kindex Ctrl-Alt-- +Shrink the screen + @item Ctrl-Alt-u @kindex Ctrl-Alt-u Restore the screen's un-scaled dimensions diff --git a/slirp/arp_table.c b/slirp/arp_table.c index 820dee2..5d7b8ac 100644 --- a/slirp/arp_table.c +++ b/slirp/arp_table.c @@ -24,9 +24,9 @@ #include "slirp.h" -void arp_table_add(Slirp *slirp, int ip_addr, uint8_t ethaddr[ETH_ALEN]) +void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN]) { - const in_addr_t broadcast_addr = + const uint32_t broadcast_addr = ~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr; ArpTable *arptbl = &slirp->arp_table; int i; @@ -60,29 +60,29 @@ void arp_table_add(Slirp *slirp, int ip_addr, uint8_t ethaddr[ETH_ALEN]) arptbl->next_victim = (arptbl->next_victim + 1) % ARP_TABLE_SIZE; } -bool arp_table_search(Slirp *slirp, int in_ip_addr, +bool arp_table_search(Slirp *slirp, uint32_t ip_addr, uint8_t out_ethaddr[ETH_ALEN]) { - const in_addr_t broadcast_addr = + const uint32_t broadcast_addr = ~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr; ArpTable *arptbl = &slirp->arp_table; int i; DEBUG_CALL("arp_table_search"); - DEBUG_ARG("ip = 0x%x", in_ip_addr); + DEBUG_ARG("ip = 0x%x", ip_addr); /* Check 0.0.0.0/8 invalid source-only addresses */ - assert((in_ip_addr & htonl(~(0xf << 28))) != 0); + assert((ip_addr & htonl(~(0xf << 28))) != 0); /* If broadcast address */ - if (in_ip_addr == 0xffffffff || in_ip_addr == broadcast_addr) { + if (ip_addr == 0xffffffff || ip_addr == broadcast_addr) { /* return Ethernet broadcast address */ memset(out_ethaddr, 0xff, ETH_ALEN); return 1; } for (i = 0; i < ARP_TABLE_SIZE; i++) { - if (arptbl->table[i].ar_sip == in_ip_addr) { + if (arptbl->table[i].ar_sip == ip_addr) { memcpy(out_ethaddr, arptbl->table[i].ar_sha, ETH_ALEN); DEBUG_ARGS((dfd, " found hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n", out_ethaddr[0], out_ethaddr[1], out_ethaddr[2], @@ -106,9 +106,6 @@ if_output(struct socket *so, struct mbuf *ifm) ifs_init(ifm); insque(ifm, ifq); - /* Expiration date = Now + 1 second */ - ifm->expiration_date = qemu_get_clock_ns(rt_clock) + 1000000000ULL; - diddit: slirp->if_queued++; @@ -157,9 +154,8 @@ diddit: void if_start(Slirp *slirp) { + uint64_t now = qemu_get_clock_ns(rt_clock); int requeued = 0; - uint64_t now; - struct mbuf *ifm, *ifqt; DEBUG_CALL("if_start"); @@ -172,8 +168,6 @@ if_start(Slirp *slirp) if (!slirp_can_output(slirp->opaque)) return; - now = qemu_get_clock_ns(rt_clock); - /* * See which queue to get next packet from * If there's something in the fastq, select it immediately diff --git a/slirp/slirp.c b/slirp/slirp.c index a86cc6e..2c242ef 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -738,6 +738,9 @@ int if_encap(Slirp *slirp, struct mbuf *ifm) slirp->client_ipaddr = iph->ip_dst; slirp_output(slirp->opaque, arp_req, sizeof(arp_req)); ifm->arp_requested = true; + + /* Expire request and drop outgoing packet after 1 second */ + ifm->expiration_date = qemu_get_clock_ns(rt_clock) + 1000000000ULL; } return 0; } else { diff --git a/slirp/slirp.h b/slirp/slirp.h index 2a070e6..dcf99d5 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -208,9 +208,9 @@ typedef struct ArpTable { int next_victim; } ArpTable; -void arp_table_add(Slirp *slirp, int ip_addr, uint8_t ethaddr[ETH_ALEN]); +void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN]); -bool arp_table_search(Slirp *slirp, int in_ip_addr, +bool arp_table_search(Slirp *slirp, uint32_t ip_addr, uint8_t out_ethaddr[ETH_ALEN]); struct Slirp { diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index 919be12..c2e7bb3 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -426,7 +426,7 @@ int cpu_alpha_exec(CPUAlphaState *s); int cpu_alpha_signal_handler(int host_signum, void *pinfo, void *puc); int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault void do_interrupt (CPUState *env); diff --git a/target-alpha/helper.c b/target-alpha/helper.c index 7049c80..06d2565 100644 --- a/target-alpha/helper.c +++ b/target-alpha/helper.c @@ -160,7 +160,7 @@ void cpu_alpha_store_fpcr (CPUState *env, uint64_t val) #if defined(CONFIG_USER_ONLY) int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { env->exception_index = EXCP_MMFAULT; env->trap_arg0 = address; @@ -316,7 +316,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) } int cpu_alpha_handle_mmu_fault(CPUState *env, target_ulong addr, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { target_ulong phys; int prot, fail; diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c index c2bb679..38be234 100644 --- a/target-alpha/op_helper.c +++ b/target-alpha/op_helper.c @@ -1344,7 +1344,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) generated code */ saved_env = env; env = cpu_single_env; - ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx); if (unlikely(ret != 0)) { do_restore_state(retaddr); /* Exception index and error code are already set */ diff --git a/target-arm/cpu.h b/target-arm/cpu.h index adef427..f17fd6b 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -244,7 +244,7 @@ uint32_t do_arm_semihosting(CPUARMState *env); int cpu_arm_signal_handler(int host_signum, void *pinfo, void *puc); int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw, - int mmu_idx, int is_softmuu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_arm_handle_mmu_fault static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls) diff --git a/target-arm/helper.c b/target-arm/helper.c index ae4f334..1ee199d 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -542,7 +542,7 @@ void do_interrupt (CPUState *env) } int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { if (rw == 2) { env->exception_index = EXCP_PREFETCH_ABORT; @@ -1254,7 +1254,7 @@ static inline int get_phys_addr(CPUState *env, uint32_t address, } int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, - int access_type, int mmu_idx, int is_softmmu) + int access_type, int mmu_idx) { uint32_t phys_addr; target_ulong page_size; diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c index 57e4977..37b77e1 100644 --- a/target-arm/op_helper.c +++ b/target-arm/op_helper.c @@ -86,7 +86,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) generated code */ saved_env = env; env = cpu_single_env; - ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ diff --git a/target-cris/cpu.h b/target-cris/cpu.h index ecb0df1..8ae0ce3 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -226,7 +226,7 @@ static inline int cpu_mmu_index (CPUState *env) } int cpu_cris_handle_mmu_fault(CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_cris_handle_mmu_fault #if defined(CONFIG_USER_ONLY) diff --git a/target-cris/helper.c b/target-cris/helper.c index 962d214..75f0035 100644 --- a/target-cris/helper.c +++ b/target-cris/helper.c @@ -47,7 +47,7 @@ void do_interrupt (CPUState *env) } int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { env->exception_index = 0xaa; env->pregs[PR_EDA] = address; @@ -68,7 +68,7 @@ static void cris_shift_ccs(CPUState *env) } int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { struct cris_mmu_result res; int prot, miss; @@ -104,10 +104,9 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, r = 0; } if (r > 0) - D_LOG("%s returns %d irqreq=%x addr=%x" - " phy=%x ismmu=%d vec=%x pc=%x\n", - __func__, r, env->interrupt_request, - address, res.phy, is_softmmu, res.bf_vec, env->pc); + D_LOG("%s returns %d irqreq=%x addr=%x phy=%x vec=%x pc=%x\n", + __func__, r, env->interrupt_request, address, res.phy, + res.bf_vec, env->pc); return r; } diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c index 246f08f..0cfe1b1 100644 --- a/target-cris/op_helper.c +++ b/target-cris/op_helper.c @@ -70,7 +70,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) D_LOG("%s pc=%x tpc=%x ra=%x\n", __func__, env->pc, env->debug1, retaddr); - ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ diff --git a/target-i386/cpu.h b/target-i386/cpu.h index dcdd95f..4a6f675 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -890,7 +890,7 @@ void host_cpuid(uint32_t function, uint32_t count, /* helper.c */ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, - int is_write, int mmu_idx, int is_softmmu); + int is_write, int mmu_idx); #define cpu_handle_mmu_fault cpu_x86_handle_mmu_fault void cpu_x86_set_a20(CPUX86State *env, int a20_state); diff --git a/target-i386/helper.c b/target-i386/helper.c index 182009a..f8c8633 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -546,7 +546,7 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4) #if defined(CONFIG_USER_ONLY) int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, - int is_write, int mmu_idx, int is_softmmu) + int is_write, int mmu_idx) { /* user mode only emulation */ is_write &= 1; @@ -573,7 +573,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, 1 = generate PF fault */ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, - int is_write1, int mmu_idx, int is_softmmu) + int is_write1, int mmu_idx) { uint64_t ptep, pte; target_ulong pde_addr, pte_addr; @@ -1243,8 +1243,8 @@ CPUX86State *cpu_x86_init(const char *cpu_model) cpu_exec_init(env); env->cpu_model_str = cpu_model; - /* init various static tables */ - if (!inited) { + /* init various static tables used in TCG mode */ + if (tcg_enabled() && !inited) { inited = 1; optimize_flags_init(); #ifndef CONFIG_USER_ONLY diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c index 1380934..1bbc3b5 100644 --- a/target-i386/op_helper.c +++ b/target-i386/op_helper.c @@ -5009,7 +5009,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) saved_env = env; env = cpu_single_env; - ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx); if (ret) { if (retaddr) { /* now we have a real cpu fault */ diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h index 876b5be..037ef52 100644 --- a/target-lm32/cpu.h +++ b/target-lm32/cpu.h @@ -205,7 +205,7 @@ void cpu_lm32_set_phys_msb_ignore(CPUState *env, int value); #define CPU_SAVE_VERSION 1 int cpu_lm32_handle_mmu_fault(CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_lm32_handle_mmu_fault #if defined(CONFIG_USER_ONLY) diff --git a/target-lm32/helper.c b/target-lm32/helper.c index e79428d..48c402e 100644 --- a/target-lm32/helper.c +++ b/target-lm32/helper.c @@ -26,7 +26,7 @@ #include "host-utils.h" int cpu_lm32_handle_mmu_fault(CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { int prot; diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c index 32b9a03..557da6c 100644 --- a/target-lm32/op_helper.c +++ b/target-lm32/op_helper.c @@ -87,7 +87,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) saved_env = env; env = cpu_single_env; - ret = cpu_lm32_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + ret = cpu_lm32_handle_mmu_fault(env, addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index e0f9b32..0667f82 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -231,7 +231,7 @@ static inline int cpu_mmu_index (CPUState *env) } int cpu_m68k_handle_mmu_fault(CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_m68k_handle_mmu_fault #if defined(CONFIG_USER_ONLY) diff --git a/target-m68k/helper.c b/target-m68k/helper.c index a936fe7..7ca75fb 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -344,7 +344,7 @@ void m68k_switch_sp(CPUM68KState *env) #if defined(CONFIG_USER_ONLY) int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { env->exception_index = EXCP_ACCESS; env->mmu.ar = address; @@ -362,7 +362,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) } int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { int prot; diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c index 764b6a0..c66fa0c 100644 --- a/target-m68k/op_helper.c +++ b/target-m68k/op_helper.c @@ -66,7 +66,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) generated code */ saved_env = env; env = cpu_single_env; - ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h index 76f4fc4..a81da62 100644 --- a/target-microblaze/cpu.h +++ b/target-microblaze/cpu.h @@ -309,7 +309,7 @@ static inline int cpu_mmu_index (CPUState *env) } int cpu_mb_handle_mmu_fault(CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_mb_handle_mmu_fault #if defined(CONFIG_USER_ONLY) diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c index 299259c..2cf2802 100644 --- a/target-microblaze/helper.c +++ b/target-microblaze/helper.c @@ -37,7 +37,7 @@ void do_interrupt (CPUState *env) } int cpu_mb_handle_mmu_fault(CPUState * env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { env->exception_index = 0xaa; cpu_dump_state(env, stderr, fprintf, 0); @@ -47,7 +47,7 @@ int cpu_mb_handle_mmu_fault(CPUState * env, target_ulong address, int rw, #else /* !CONFIG_USER_ONLY */ int cpu_mb_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { unsigned int hit; unsigned int mmu_available; diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c index 189c59c..8a7deac 100644 --- a/target-microblaze/op_helper.c +++ b/target-microblaze/op_helper.c @@ -54,7 +54,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) saved_env = env; env = cpu_single_env; - ret = cpu_mb_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + ret = cpu_mb_handle_mmu_fault(env, addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 030f499..c5f70fa 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -636,7 +636,7 @@ void cpu_mips_soft_irq(CPUState *env, int irq, int level); /* helper.c */ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault void do_interrupt (CPUState *env); #if !defined(CONFIG_USER_ONLY) diff --git a/target-mips/helper.c b/target-mips/helper.c index ecf6182..024caa2 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -266,7 +266,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) #endif int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { #if !defined(CONFIG_USER_ONLY) target_phys_addr_t physical; @@ -278,8 +278,8 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, #if 0 log_cpu_state(env, 0); #endif - qemu_log("%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d smmu %d\n", - __func__, env->active_tc.PC, address, rw, mmu_idx, is_softmmu); + qemu_log("%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d\n", + __func__, env->active_tc.PC, address, rw, mmu_idx); rw &= 1; diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 185ae40..056011f 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -2017,7 +2017,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) generated code */ saved_env = env; env = cpu_single_env; - ret = cpu_mips_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + ret = cpu_mips_handle_mmu_fault(env, addr, is_write, mmu_idx); if (ret) { if (retaddr) { /* now we have a real cpu fault */ diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index d903366..024eb6f 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1022,7 +1022,7 @@ void cpu_ppc_close (CPUPPCState *s); int cpu_ppc_signal_handler (int host_signum, void *pinfo, void *puc); int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_ppc_handle_mmu_fault #if !defined(CONFIG_USER_ONLY) int get_physical_address (CPUPPCState *env, mmu_ctx_t *ctx, target_ulong vaddr, diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 176128a..789e6aa 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -78,7 +78,7 @@ void (*cpu_ppc_hypercall)(CPUState *); #if defined(CONFIG_USER_ONLY) int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { int exception, error_code; @@ -1658,7 +1658,7 @@ static void booke206_update_mas_tlb_miss(CPUState *env, target_ulong address, /* Perform address translation */ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { mmu_ctx_t ctx; int access_type; @@ -3091,7 +3091,9 @@ CPUPPCState *cpu_ppc_init (const char *cpu_model) env = qemu_mallocz(sizeof(CPUPPCState)); cpu_exec_init(env); - ppc_translate_init(); + if (tcg_enabled()) { + ppc_translate_init(); + } env->cpu_model_str = cpu_model; cpu_ppc_register_internal(env, def); diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 6e100d9..c5e0601 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -3725,7 +3725,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) generated code */ saved_env = env; env = cpu_single_env; - ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx); if (unlikely(ret != 0)) { if (likely(retaddr)) { /* now we have a real cpu fault */ diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index d48a9b7..f8f0c82 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -280,7 +280,7 @@ void do_interrupt (CPUState *env); int cpu_s390x_signal_handler(int host_signum, void *pinfo, void *puc); int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw, - int mmu_idx, int is_softmuu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_s390x_handle_mmu_fault diff --git a/target-s390x/helper.c b/target-s390x/helper.c index 1ce7079..db88603 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -81,7 +81,7 @@ CPUS390XState *cpu_s390x_init(const char *cpu_model) env = qemu_mallocz(sizeof(CPUS390XState)); cpu_exec_init(env); - if (!inited) { + if (tcg_enabled() && !inited) { inited = 1; s390x_translate_init(); } @@ -110,10 +110,10 @@ void do_interrupt (CPUState *env) } int cpu_s390x_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { - /* fprintf(stderr,"%s: address 0x%lx rw %d mmu_idx %d is_softmmu %d\n", - __FUNCTION__, address, rw, mmu_idx, is_softmmu); */ + /* fprintf(stderr,"%s: address 0x%lx rw %d mmu_idx %d\n", + __FUNCTION__, address, rw, mmu_idx); */ env->exception_index = EXCP_ADDR; env->__excp_addr = address; /* FIXME: find out how this works on a real machine */ return 1; @@ -394,14 +394,14 @@ out: } int cpu_s390x_handle_mmu_fault (CPUState *env, target_ulong _vaddr, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { uint64_t asc = env->psw.mask & PSW_MASK_ASC; target_ulong vaddr, raddr; int prot; - DPRINTF("%s: address 0x%" PRIx64 " rw %d mmu_idx %d is_softmmu %d\n", - __FUNCTION__, _vaddr, rw, mmu_idx, is_softmmu); + DPRINTF("%s: address 0x%" PRIx64 " rw %d mmu_idx %d\n", + __FUNCTION__, _vaddr, rw, mmu_idx); _vaddr &= TARGET_PAGE_MASK; vaddr = _vaddr; diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c index 25a1e81..b3ac630 100644 --- a/target-s390x/op_helper.c +++ b/target-s390x/op_helper.c @@ -63,7 +63,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) generated code */ saved_env = env; env = cpu_single_env; - ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx); if (unlikely(ret != 0)) { if (likely(retaddr)) { /* now we have a real cpu fault */ diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index 00e32f2..7d7fdde 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -194,7 +194,7 @@ int cpu_sh4_exec(CPUSH4State * s); int cpu_sh4_signal_handler(int host_signum, void *pinfo, void *puc); int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_sh4_handle_mmu_fault void do_interrupt(CPUSH4State * env); diff --git a/target-sh4/helper.c b/target-sh4/helper.c index 20e9b13..5a1e15e 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -34,7 +34,7 @@ void do_interrupt (CPUState *env) } int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { env->tea = address; env->exception_index = -1; @@ -440,7 +440,7 @@ static int get_physical_address(CPUState * env, target_ulong * physical, } int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { target_ulong physical; int prot, ret, access_type; diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c index 568bf0d..163858f 100644 --- a/target-sh4/op_helper.c +++ b/target-sh4/op_helper.c @@ -64,7 +64,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) generated code */ saved_env = env; env = cpu_single_env; - ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx); if (ret) { /* now we have a real cpu fault */ cpu_restore_state_from_retaddr(retaddr); diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index a51863c..8654f26 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -490,7 +490,7 @@ CPUSPARCState *cpu_sparc_init(const char *cpu_model); void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf); int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_sparc_handle_mmu_fault target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev); void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env); diff --git a/target-sparc/helper.c b/target-sparc/helper.c index efab885..47110a5 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -42,7 +42,7 @@ static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model); #if defined(CONFIG_USER_ONLY) int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { if (rw & 2) env1->exception_index = TT_TFAULT; @@ -212,7 +212,7 @@ static int get_physical_address(CPUState *env, target_phys_addr_t *physical, /* Perform address translation */ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { target_phys_addr_t paddr; target_ulong vaddr; @@ -638,7 +638,7 @@ static int get_physical_address(CPUState *env, target_phys_addr_t *physical, /* Perform address translation */ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { target_ulong virt_addr, vaddr; target_phys_addr_t paddr; diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index 5aeca2b..d1a8dd9 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -4237,7 +4237,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) saved_env = env; env = cpu_single_env; - ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx); if (ret) { cpu_restore_state2(retaddr); cpu_loop_exit(env); diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 958fbc5..dee67b3 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -1286,7 +1286,6 @@ static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src) } #endif -/* XXX: potentially incorrect if dynamic npc */ static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc, TCGv r_cond) { @@ -1321,13 +1320,17 @@ static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc, } else { dc->pc = dc->npc; dc->jump_pc[0] = target; - dc->jump_pc[1] = dc->npc + 4; - dc->npc = JUMP_PC; + if (unlikely(dc->npc == DYNAMIC_PC)) { + dc->jump_pc[1] = DYNAMIC_PC; + tcg_gen_addi_tl(cpu_pc, cpu_npc, 4); + } else { + dc->jump_pc[1] = dc->npc + 4; + dc->npc = JUMP_PC; + } } } } -/* XXX: potentially incorrect if dynamic npc */ static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc, TCGv r_cond) { @@ -1362,14 +1365,18 @@ static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc, } else { dc->pc = dc->npc; dc->jump_pc[0] = target; - dc->jump_pc[1] = dc->npc + 4; - dc->npc = JUMP_PC; + if (unlikely(dc->npc == DYNAMIC_PC)) { + dc->jump_pc[1] = DYNAMIC_PC; + tcg_gen_addi_tl(cpu_pc, cpu_npc, 4); + } else { + dc->jump_pc[1] = dc->npc + 4; + dc->npc = JUMP_PC; + } } } } #ifdef TARGET_SPARC64 -/* XXX: potentially incorrect if dynamic npc */ static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn, TCGv r_cond, TCGv r_reg) { @@ -1384,8 +1391,13 @@ static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn, } else { dc->pc = dc->npc; dc->jump_pc[0] = target; - dc->jump_pc[1] = dc->npc + 4; - dc->npc = JUMP_PC; + if (unlikely(dc->npc == DYNAMIC_PC)) { + dc->jump_pc[1] = DYNAMIC_PC; + tcg_gen_addi_tl(cpu_pc, cpu_npc, 4); + } else { + dc->jump_pc[1] = dc->npc + 4; + dc->npc = JUMP_PC; + } } } diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h index 9817607..b4e72cf 100644 --- a/target-unicore32/cpu.h +++ b/target-unicore32/cpu.h @@ -130,7 +130,7 @@ CPUState *uc32_cpu_init(const char *cpu_model); int uc32_cpu_exec(CPUState *s); int uc32_cpu_signal_handler(int host_signum, void *pinfo, void *puc); int uc32_cpu_handle_mmu_fault(CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmuu); + int mmu_idx); #define CPU_SAVE_VERSION 2 diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c index 02707d5..8edfcb7 100644 --- a/target-unicore32/helper.c +++ b/target-unicore32/helper.c @@ -104,7 +104,7 @@ void do_interrupt(CPUState *env) } int uc32_cpu_handle_mmu_fault(CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { env->exception_index = UC32_EXCP_TRAP; env->cp0.c4_faultaddr = address; diff --git a/tcg/optimize.c b/tcg/optimize.c index a3bfa5e..7eb5eb1 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -185,12 +185,15 @@ static int op_to_movi(int op) } } -static void tcg_opt_gen_mov(TCGArg *gen_args, TCGArg dst, TCGArg src, - int nb_temps, int nb_globals) +static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args, TCGArg dst, + TCGArg src, int nb_temps, int nb_globals) { reset_temp(dst, nb_temps, nb_globals); assert(temps[src].state != TCG_TEMP_COPY); - if (src >= nb_globals) { + /* Don't try to copy if one of temps is a global or either one + is local and another is register */ + if (src >= nb_globals && dst >= nb_globals && + tcg_arg_is_local(s, src) == tcg_arg_is_local(s, dst)) { assert(temps[src].state != TCG_TEMP_CONST); if (temps[src].state != TCG_TEMP_HAS_COPY) { temps[src].state = TCG_TEMP_HAS_COPY; @@ -474,7 +477,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, gen_opc_buf[op_index] = INDEX_op_nop; } else { gen_opc_buf[op_index] = op_to_mov(op); - tcg_opt_gen_mov(gen_args, args[0], args[1], + tcg_opt_gen_mov(s, gen_args, args[0], args[1], nb_temps, nb_globals); gen_args += 2; args += 3; @@ -500,7 +503,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, gen_opc_buf[op_index] = INDEX_op_nop; } else { gen_opc_buf[op_index] = op_to_mov(op); - tcg_opt_gen_mov(gen_args, args[0], args[1], nb_temps, + tcg_opt_gen_mov(s, gen_args, args[0], args[1], nb_temps, nb_globals); gen_args += 2; args += 3; @@ -523,7 +526,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, break; } if (temps[args[1]].state != TCG_TEMP_CONST) { - tcg_opt_gen_mov(gen_args, args[0], args[1], + tcg_opt_gen_mov(s, gen_args, args[0], args[1], nb_temps, nb_globals); gen_args += 2; args += 2; @@ -410,6 +410,11 @@ static inline TCGv_i64 tcg_temp_local_new_i64(void) void tcg_temp_free_i64(TCGv_i64 arg); char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg); +static inline bool tcg_arg_is_local(TCGContext *s, TCGArg arg) +{ + return s->temps[arg].temp_local; +} + #if defined(CONFIG_DEBUG_TCG) /* If you call tcg_clear_temp_count() at the start of a section of * code which is not supposed to leak any TCG temporaries, then @@ -39,15 +39,16 @@ static SDL_Surface *real_screen; static SDL_Surface *guest_screen = NULL; static int gui_grab; /* if true, all keyboard/mouse events are grabbed */ static int last_vm_running; +static bool gui_saved_scaling; +static int gui_saved_width; +static int gui_saved_height; static int gui_saved_grab; static int gui_fullscreen; static int gui_noframe; static int gui_key_modifier_pressed; static int gui_keysym; -static int gui_fullscreen_initial_grab; static int gui_grab_code = KMOD_LALT | KMOD_LCTRL; static uint8_t modifiers_state[256]; -static int width, height; static SDL_Cursor *sdl_cursor_normal; static SDL_Cursor *sdl_cursor_hidden; static int absolute_enabled = 0; @@ -91,20 +92,21 @@ static void sdl_setdata(DisplayState *ds) ds->surface->pf.bmask, ds->surface->pf.amask); } -static void do_sdl_resize(int new_width, int new_height, int bpp) +static void do_sdl_resize(int width, int height, int bpp) { int flags; // printf("resizing to %d %d\n", w, h); - flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_RESIZABLE; - if (gui_fullscreen) + flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL; + if (gui_fullscreen) { flags |= SDL_FULLSCREEN; + } else { + flags |= SDL_RESIZABLE; + } if (gui_noframe) flags |= SDL_NOFRAME; - width = new_width; - height = new_height; real_screen = SDL_SetVideoMode(width, height, bpp, flags); if (!real_screen) { fprintf(stderr, "Could not open SDL display (%dx%dx%d): %s\n", width, @@ -447,7 +449,7 @@ static void sdl_show_cursor(void) if (!cursor_hide) return; - if (!kbd_mouse_is_absolute()) { + if (!kbd_mouse_is_absolute() || !is_graphic_console()) { SDL_ShowCursor(1); if (guest_cursor && (gui_grab || kbd_mouse_is_absolute() || absolute_enabled)) @@ -485,32 +487,32 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data) { if (kbd_mouse_is_absolute()) { if (!absolute_enabled) { - sdl_hide_cursor(); - if (gui_grab) { - sdl_grab_end(); - } + sdl_grab_start(); absolute_enabled = 1; } } else if (absolute_enabled) { - sdl_show_cursor(); - absolute_enabled = 0; + sdl_grab_end(); + absolute_enabled = 0; } } static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state) { - int buttons; - buttons = 0; - if (state & SDL_BUTTON(SDL_BUTTON_LEFT)) + int buttons = 0; + + if (state & SDL_BUTTON(SDL_BUTTON_LEFT)) { buttons |= MOUSE_EVENT_LBUTTON; - if (state & SDL_BUTTON(SDL_BUTTON_RIGHT)) + } + if (state & SDL_BUTTON(SDL_BUTTON_RIGHT)) { buttons |= MOUSE_EVENT_RBUTTON; - if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) + } + if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) { buttons |= MOUSE_EVENT_MBUTTON; + } if (kbd_mouse_is_absolute()) { - dx = x * 0x7FFF / (width - 1); - dy = y * 0x7FFF / (height - 1); + dx = x * 0x7FFF / (real_screen->w - 1); + dy = y * 0x7FFF / (real_screen->h - 1); } else if (guest_cursor) { x -= guest_x; y -= guest_y; @@ -523,27 +525,331 @@ static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state kbd_mouse_event(dx, dy, dz, buttons); } +static void sdl_scale(DisplayState *ds, int width, int height) +{ + int bpp = real_screen->format->BitsPerPixel; + + if (bpp != 16 && bpp != 32) { + bpp = 32; + } + do_sdl_resize(width, height, bpp); + scaling_active = 1; + if (!is_buffer_shared(ds->surface)) { + ds->surface = qemu_resize_displaysurface(ds, ds_get_width(ds), + ds_get_height(ds)); + dpy_resize(ds); + } +} + static void toggle_full_screen(DisplayState *ds) { gui_fullscreen = !gui_fullscreen; - do_sdl_resize(real_screen->w, real_screen->h, real_screen->format->BitsPerPixel); if (gui_fullscreen) { + gui_saved_width = real_screen->w; + gui_saved_height = real_screen->h; + gui_saved_scaling = scaling_active; + + do_sdl_resize(ds_get_width(ds), ds_get_height(ds), + ds_get_bits_per_pixel(ds)); scaling_active = 0; + gui_saved_grab = gui_grab; sdl_grab_start(); } else { - if (!gui_saved_grab) + if (gui_saved_scaling) { + sdl_scale(ds, gui_saved_width, gui_saved_height); + } else { + do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0); + } + if (!gui_saved_grab || !is_graphic_console()) { sdl_grab_end(); + } } vga_hw_invalidate(); vga_hw_update(); } -static void sdl_refresh(DisplayState *ds) +static void absolute_mouse_grab(void) +{ + int mouse_x, mouse_y; + + if (SDL_GetAppState() & SDL_APPINPUTFOCUS) { + SDL_GetMouseState(&mouse_x, &mouse_y); + if (mouse_x > 0 && mouse_x < real_screen->w - 1 && + mouse_y > 0 && mouse_y < real_screen->h - 1) { + sdl_grab_start(); + } + } +} + +static void handle_keydown(DisplayState *ds, SDL_Event *ev) +{ + int mod_state; + int keycode; + + if (alt_grab) { + mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) == + (gui_grab_code | KMOD_LSHIFT); + } else if (ctrl_grab) { + mod_state = (SDL_GetModState() & KMOD_RCTRL) == KMOD_RCTRL; + } else { + mod_state = (SDL_GetModState() & gui_grab_code) == gui_grab_code; + } + gui_key_modifier_pressed = mod_state; + + if (gui_key_modifier_pressed) { + keycode = sdl_keyevent_to_keycode(&ev->key); + switch (keycode) { + case 0x21: /* 'f' key on US keyboard */ + toggle_full_screen(ds); + gui_keysym = 1; + break; + case 0x16: /* 'u' key on US keyboard */ + if (scaling_active) { + scaling_active = 0; + sdl_resize(ds); + vga_hw_invalidate(); + vga_hw_update(); + } + gui_keysym = 1; + break; + case 0x02 ... 0x0a: /* '1' to '9' keys */ + /* Reset the modifiers sent to the current console */ + reset_keys(); + console_select(keycode - 0x02); + gui_keysym = 1; + if (gui_fullscreen) { + break; + } + if (!is_graphic_console()) { + /* release grab if going to a text console */ + if (gui_grab) { + sdl_grab_end(); + } else if (absolute_enabled) { + sdl_show_cursor(); + } + } else if (absolute_enabled) { + sdl_hide_cursor(); + absolute_mouse_grab(); + } + break; + case 0x1b: /* '+' */ + case 0x35: /* '-' */ + if (!gui_fullscreen) { + int width = MAX(real_screen->w + (keycode == 0x1b ? 50 : -50), + 160); + int height = (ds_get_height(ds) * width) / ds_get_width(ds); + + sdl_scale(ds, width, height); + vga_hw_invalidate(); + vga_hw_update(); + gui_keysym = 1; + } + default: + break; + } + } else if (!is_graphic_console()) { + int keysym = 0; + + if (ev->key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) { + switch (ev->key.keysym.sym) { + case SDLK_UP: + keysym = QEMU_KEY_CTRL_UP; + break; + case SDLK_DOWN: + keysym = QEMU_KEY_CTRL_DOWN; + break; + case SDLK_LEFT: + keysym = QEMU_KEY_CTRL_LEFT; + break; + case SDLK_RIGHT: + keysym = QEMU_KEY_CTRL_RIGHT; + break; + case SDLK_HOME: + keysym = QEMU_KEY_CTRL_HOME; + break; + case SDLK_END: + keysym = QEMU_KEY_CTRL_END; + break; + case SDLK_PAGEUP: + keysym = QEMU_KEY_CTRL_PAGEUP; + break; + case SDLK_PAGEDOWN: + keysym = QEMU_KEY_CTRL_PAGEDOWN; + break; + default: + break; + } + } else { + switch (ev->key.keysym.sym) { + case SDLK_UP: + keysym = QEMU_KEY_UP; + break; + case SDLK_DOWN: + keysym = QEMU_KEY_DOWN; + break; + case SDLK_LEFT: + keysym = QEMU_KEY_LEFT; + break; + case SDLK_RIGHT: + keysym = QEMU_KEY_RIGHT; + break; + case SDLK_HOME: + keysym = QEMU_KEY_HOME; + break; + case SDLK_END: + keysym = QEMU_KEY_END; + break; + case SDLK_PAGEUP: + keysym = QEMU_KEY_PAGEUP; + break; + case SDLK_PAGEDOWN: + keysym = QEMU_KEY_PAGEDOWN; + break; + case SDLK_BACKSPACE: + keysym = QEMU_KEY_BACKSPACE; + break; + case SDLK_DELETE: + keysym = QEMU_KEY_DELETE; + break; + default: + break; + } + } + if (keysym) { + kbd_put_keysym(keysym); + } else if (ev->key.keysym.unicode != 0) { + kbd_put_keysym(ev->key.keysym.unicode); + } + } + if (is_graphic_console() && !gui_keysym) { + sdl_process_key(&ev->key); + } +} + +static void handle_keyup(DisplayState *ds, SDL_Event *ev) { - SDL_Event ev1, *ev = &ev1; int mod_state; + + if (!alt_grab) { + mod_state = (ev->key.keysym.mod & gui_grab_code); + } else { + mod_state = (ev->key.keysym.mod & (gui_grab_code | KMOD_LSHIFT)); + } + if (!mod_state && gui_key_modifier_pressed) { + gui_key_modifier_pressed = 0; + if (gui_keysym == 0) { + /* exit/enter grab if pressing Ctrl-Alt */ + if (!gui_grab) { + /* If the application is not active, do not try to enter grab + * state. It prevents 'SDL_WM_GrabInput(SDL_GRAB_ON)' from + * blocking all the application (SDL bug). */ + if (is_graphic_console() && + SDL_GetAppState() & SDL_APPACTIVE) { + sdl_grab_start(); + } + } else if (!gui_fullscreen) { + sdl_grab_end(); + } + /* SDL does not send back all the modifiers key, so we must + * correct it. */ + reset_keys(); + return; + } + gui_keysym = 0; + } + if (is_graphic_console() && !gui_keysym) { + sdl_process_key(&ev->key); + } +} + +static void handle_mousemotion(DisplayState *ds, SDL_Event *ev) +{ + int max_x, max_y; + + if (is_graphic_console() && + (kbd_mouse_is_absolute() || absolute_enabled)) { + max_x = real_screen->w - 1; + max_y = real_screen->h - 1; + if (gui_grab && (ev->motion.x == 0 || ev->motion.y == 0 || + ev->motion.x == max_x || ev->motion.y == max_y)) { + sdl_grab_end(); + } + if (!gui_grab && SDL_GetAppState() & SDL_APPINPUTFOCUS && + (ev->motion.x > 0 && ev->motion.x < max_x && + ev->motion.y > 0 && ev->motion.y < max_y)) { + sdl_grab_start(); + } + } + if (gui_grab || kbd_mouse_is_absolute() || absolute_enabled) { + sdl_send_mouse_event(ev->motion.xrel, ev->motion.yrel, 0, + ev->motion.x, ev->motion.y, ev->motion.state); + } +} + +static void handle_mousebutton(DisplayState *ds, SDL_Event *ev) +{ int buttonstate = SDL_GetMouseState(NULL, NULL); + SDL_MouseButtonEvent *bev; + int dz; + + if (!is_graphic_console()) { + return; + } + + bev = &ev->button; + if (!gui_grab && !kbd_mouse_is_absolute()) { + if (ev->type == SDL_MOUSEBUTTONDOWN && + (bev->button == SDL_BUTTON_LEFT)) { + /* start grabbing all events */ + sdl_grab_start(); + } + } else { + dz = 0; + if (ev->type == SDL_MOUSEBUTTONDOWN) { + buttonstate |= SDL_BUTTON(bev->button); + } else { + buttonstate &= ~SDL_BUTTON(bev->button); + } +#ifdef SDL_BUTTON_WHEELUP + if (bev->button == SDL_BUTTON_WHEELUP && + ev->type == SDL_MOUSEBUTTONDOWN) { + dz = -1; + } else if (bev->button == SDL_BUTTON_WHEELDOWN && + ev->type == SDL_MOUSEBUTTONDOWN) { + dz = 1; + } +#endif + sdl_send_mouse_event(0, 0, dz, bev->x, bev->y, buttonstate); + } +} + +static void handle_activation(DisplayState *ds, SDL_Event *ev) +{ + if (gui_grab && ev->active.state == SDL_APPINPUTFOCUS && + !ev->active.gain && !gui_fullscreen) { + sdl_grab_end(); + } + if (!gui_grab && ev->active.gain && is_graphic_console() && + (kbd_mouse_is_absolute() || absolute_enabled)) { + absolute_mouse_grab(); + } + if (ev->active.state & SDL_APPACTIVE) { + if (ev->active.gain) { + /* Back to default interval */ + dcl->gui_timer_interval = 0; + dcl->idle = 0; + } else { + /* Sleeping interval */ + dcl->gui_timer_interval = 500; + dcl->idle = 1; + } + } +} + +static void sdl_refresh(DisplayState *ds) +{ + SDL_Event ev1, *ev = &ev1; if (last_vm_running != vm_running) { last_vm_running = vm_running; @@ -559,191 +865,32 @@ static void sdl_refresh(DisplayState *ds) sdl_update(ds, 0, 0, real_screen->w, real_screen->h); break; case SDL_KEYDOWN: + handle_keydown(ds, ev); + break; case SDL_KEYUP: - if (ev->type == SDL_KEYDOWN) { - if (alt_grab) { - mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) == - (gui_grab_code | KMOD_LSHIFT); - } else if (ctrl_grab) { - mod_state = (SDL_GetModState() & KMOD_RCTRL) == KMOD_RCTRL; - } else { - mod_state = (SDL_GetModState() & gui_grab_code) == - gui_grab_code; - } - gui_key_modifier_pressed = mod_state; - if (gui_key_modifier_pressed) { - int keycode; - keycode = sdl_keyevent_to_keycode(&ev->key); - switch(keycode) { - case 0x21: /* 'f' key on US keyboard */ - toggle_full_screen(ds); - gui_keysym = 1; - break; - case 0x16: /* 'u' key on US keyboard */ - scaling_active = 0; - sdl_resize(ds); - vga_hw_invalidate(); - vga_hw_update(); - break; - case 0x02 ... 0x0a: /* '1' to '9' keys */ - /* Reset the modifiers sent to the current console */ - reset_keys(); - console_select(keycode - 0x02); - if (!is_graphic_console()) { - /* display grab if going to a text console */ - if (gui_grab) - sdl_grab_end(); - } - gui_keysym = 1; - break; - default: - break; - } - } else if (!is_graphic_console()) { - int keysym; - keysym = 0; - if (ev->key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) { - switch(ev->key.keysym.sym) { - case SDLK_UP: keysym = QEMU_KEY_CTRL_UP; break; - case SDLK_DOWN: keysym = QEMU_KEY_CTRL_DOWN; break; - case SDLK_LEFT: keysym = QEMU_KEY_CTRL_LEFT; break; - case SDLK_RIGHT: keysym = QEMU_KEY_CTRL_RIGHT; break; - case SDLK_HOME: keysym = QEMU_KEY_CTRL_HOME; break; - case SDLK_END: keysym = QEMU_KEY_CTRL_END; break; - case SDLK_PAGEUP: keysym = QEMU_KEY_CTRL_PAGEUP; break; - case SDLK_PAGEDOWN: keysym = QEMU_KEY_CTRL_PAGEDOWN; break; - default: break; - } - } else { - switch(ev->key.keysym.sym) { - case SDLK_UP: keysym = QEMU_KEY_UP; break; - case SDLK_DOWN: keysym = QEMU_KEY_DOWN; break; - case SDLK_LEFT: keysym = QEMU_KEY_LEFT; break; - case SDLK_RIGHT: keysym = QEMU_KEY_RIGHT; break; - case SDLK_HOME: keysym = QEMU_KEY_HOME; break; - case SDLK_END: keysym = QEMU_KEY_END; break; - case SDLK_PAGEUP: keysym = QEMU_KEY_PAGEUP; break; - case SDLK_PAGEDOWN: keysym = QEMU_KEY_PAGEDOWN; break; - case SDLK_BACKSPACE: keysym = QEMU_KEY_BACKSPACE; break; - case SDLK_DELETE: keysym = QEMU_KEY_DELETE; break; - default: break; - } - } - if (keysym) { - kbd_put_keysym(keysym); - } else if (ev->key.keysym.unicode != 0) { - kbd_put_keysym(ev->key.keysym.unicode); - } - } - } else if (ev->type == SDL_KEYUP) { - if (!alt_grab) { - mod_state = (ev->key.keysym.mod & gui_grab_code); - } else { - mod_state = (ev->key.keysym.mod & - (gui_grab_code | KMOD_LSHIFT)); - } - if (!mod_state) { - if (gui_key_modifier_pressed) { - gui_key_modifier_pressed = 0; - if (gui_keysym == 0) { - /* exit/enter grab if pressing Ctrl-Alt */ - if (!gui_grab) { - /* if the application is not active, - do not try to enter grab state. It - prevents - 'SDL_WM_GrabInput(SDL_GRAB_ON)' - from blocking all the application - (SDL bug). */ - if (SDL_GetAppState() & SDL_APPACTIVE) - sdl_grab_start(); - } else { - sdl_grab_end(); - } - /* SDL does not send back all the - modifiers key, so we must correct it */ - reset_keys(); - break; - } - gui_keysym = 0; - } - } - } - if (is_graphic_console() && !gui_keysym) - sdl_process_key(&ev->key); + handle_keyup(ds, ev); break; case SDL_QUIT: - if (!no_quit) + if (!no_quit) { + no_shutdown = 0; qemu_system_shutdown_request(); + } break; case SDL_MOUSEMOTION: - if (gui_grab || kbd_mouse_is_absolute() || - absolute_enabled) { - sdl_send_mouse_event(ev->motion.xrel, ev->motion.yrel, 0, - ev->motion.x, ev->motion.y, ev->motion.state); - } + handle_mousemotion(ds, ev); break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: - { - SDL_MouseButtonEvent *bev = &ev->button; - if (!gui_grab && !kbd_mouse_is_absolute()) { - if (ev->type == SDL_MOUSEBUTTONDOWN && - (bev->button == SDL_BUTTON_LEFT)) { - /* start grabbing all events */ - sdl_grab_start(); - } - } else { - int dz; - dz = 0; - if (ev->type == SDL_MOUSEBUTTONDOWN) { - buttonstate |= SDL_BUTTON(bev->button); - } else { - buttonstate &= ~SDL_BUTTON(bev->button); - } -#ifdef SDL_BUTTON_WHEELUP - if (bev->button == SDL_BUTTON_WHEELUP && ev->type == SDL_MOUSEBUTTONDOWN) { - dz = -1; - } else if (bev->button == SDL_BUTTON_WHEELDOWN && ev->type == SDL_MOUSEBUTTONDOWN) { - dz = 1; - } -#endif - sdl_send_mouse_event(0, 0, dz, bev->x, bev->y, buttonstate); - } - } + handle_mousebutton(ds, ev); break; case SDL_ACTIVEEVENT: - if (gui_grab && ev->active.state == SDL_APPINPUTFOCUS && - !ev->active.gain && !gui_fullscreen_initial_grab) { - sdl_grab_end(); - } - if (ev->active.state & SDL_APPACTIVE) { - if (ev->active.gain) { - /* Back to default interval */ - dcl->gui_timer_interval = 0; - dcl->idle = 0; - } else { - /* Sleeping interval */ - dcl->gui_timer_interval = 500; - dcl->idle = 1; - } - } + handle_activation(ds, ev); break; - case SDL_VIDEORESIZE: - { - SDL_ResizeEvent *rev = &ev->resize; - int bpp = real_screen->format->BitsPerPixel; - if (bpp != 16 && bpp != 32) - bpp = 32; - do_sdl_resize(rev->w, rev->h, bpp); - scaling_active = 1; - if (!is_buffer_shared(ds->surface)) { - ds->surface = qemu_resize_displaysurface(ds, ds_get_width(ds), ds_get_height(ds)); - dpy_resize(ds); - } + case SDL_VIDEORESIZE: + sdl_scale(ds, ev->resize.w, ev->resize.h); vga_hw_invalidate(); vga_hw_update(); break; - } default: break; } @@ -865,6 +1012,11 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) qemu_free(filename); } + if (full_screen) { + gui_fullscreen = 1; + sdl_grab_start(); + } + dcl = qemu_mallocz(sizeof(DisplayChangeListener)); dcl->dpy_update = sdl_update; dcl->dpy_resize = sdl_resize; @@ -894,9 +1046,4 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) sdl_cursor_normal = SDL_GetCursor(); atexit(sdl_cleanup); - if (full_screen) { - gui_fullscreen = 1; - gui_fullscreen_initial_grab = 1; - sdl_grab_start(); - } } diff --git a/user-exec.c b/user-exec.c index 14c0f25..abf6885 100644 --- a/user-exec.c +++ b/user-exec.c @@ -102,7 +102,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, } /* see if it is an MMU fault */ - ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); + ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX); if (ret < 0) { return 0; /* not an MMU fault */ } @@ -265,6 +265,7 @@ int kvm_allowed = 0; int xen_allowed = 0; uint32_t xen_domid; enum xen_mode xen_mode = XEN_EMULATE; +static int tcg_tb_size; static int default_serial = 1; static int default_parallel = 1; @@ -1932,6 +1933,7 @@ static QEMUMachine *machine_parse(const char *name) static int tcg_init(void) { + tcg_exec_init(tcg_tb_size * 1024 * 1024); return 0; } @@ -2092,7 +2094,6 @@ int main(int argc, char **argv, char **envp) const char *loadvm = NULL; QEMUMachine *machine; const char *cpu_model; - int tb_size; const char *pid_file = NULL; const char *incoming = NULL; #ifdef CONFIG_VNC @@ -2132,7 +2133,6 @@ int main(int argc, char **argv, char **envp) nb_numa_nodes = 0; nb_nics = 0; - tb_size = 0; autostart= 1; /* first pass of option parsing */ @@ -2847,9 +2847,10 @@ int main(int argc, char **argv, char **envp) configure_rtc(opts); break; case QEMU_OPTION_tb_size: - tb_size = strtol(optarg, NULL, 0); - if (tb_size < 0) - tb_size = 0; + tcg_tb_size = strtol(optarg, NULL, 0); + if (tcg_tb_size < 0) { + tcg_tb_size = 0; + } break; case QEMU_OPTION_icount: icount_option = optarg; @@ -3123,8 +3124,7 @@ int main(int argc, char **argv, char **envp) } } - /* init the dynamic translator */ - cpu_exec_init_all(tb_size * 1024 * 1024); + cpu_exec_init_all(); bdrv_init_with_whitelist(); |