From patchwork Sun Jul 10 18:14:33 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Avi Kivity X-Patchwork-Id: 104119 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C5A41B7090 for ; Mon, 11 Jul 2011 06:38:09 +1000 (EST) Received: from localhost ([::1]:47030 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qg0lS-0006eW-A7 for incoming@patchwork.ozlabs.org; Sun, 10 Jul 2011 16:38:06 -0400 Received: from eggs.gnu.org ([140.186.70.92]:47019) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QfyXR-0004HB-UV for qemu-devel@nongnu.org; Sun, 10 Jul 2011 14:15:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QfyXI-0007bJ-Vx for qemu-devel@nongnu.org; Sun, 10 Jul 2011 14:15:28 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56297) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QfyXE-0007Xl-Qh for qemu-devel@nongnu.org; Sun, 10 Jul 2011 14:15:17 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p6AIFFEd012391 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 10 Jul 2011 14:15:16 -0400 Received: from cleopatra.tlv.redhat.com (cleopatra.tlv.redhat.com [10.35.255.11]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p6AIFEkC032756; Sun, 10 Jul 2011 14:15:15 -0400 Received: from s01.tlv.redhat.com (s01.tlv.redhat.com [10.35.255.8]) by cleopatra.tlv.redhat.com (Postfix) with ESMTP id 3B878250B43; Sun, 10 Jul 2011 21:15:11 +0300 (IDT) From: Avi Kivity To: qemu-devel@nongnu.org Date: Sun, 10 Jul 2011 21:14:33 +0300 Message-Id: <1310321709-30770-21-git-send-email-avi@redhat.com> In-Reply-To: <1310321709-30770-1-git-send-email-avi@redhat.com> References: <1310321709-30770-1-git-send-email-avi@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: kvm@vger.kernel.org Subject: [Qemu-devel] [RFC v3 20/56] vga: convert vga and its derivatives to the memory API X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Convert all vga memory to the memory API. Note we need to fall back to get_system_memory(), since the various buses don't pass the vga window as a memory region. Signed-off-by: Avi Kivity --- hw/cirrus_vga.c | 345 +++++++++++++++++++++++++++++++++---------------------- hw/qxl-render.c | 2 +- hw/qxl.c | 131 ++++++++-------------- hw/qxl.h | 6 +- hw/vga-isa-mm.c | 61 +++++++--- hw/vga-isa.c | 11 +- hw/vga-pci.c | 28 +---- hw/vga.c | 146 +++++++++++------------- hw/vga_int.h | 15 +-- hw/vmware_vga.c | 165 ++++++++++++++++----------- 10 files changed, 478 insertions(+), 432 deletions(-) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index f39d1f8..0cd2aee 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -200,9 +200,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 +617,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 +1182,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 +1920,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 +1945,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); } /*************************************** @@ -2057,8 +2056,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, @@ -2099,16 +2097,37 @@ static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_ 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 uint64_t cirrus_vga_mem_read(void *opaque, + target_phys_addr_t addr, + uint32_t size) +{ + CirrusVGAState *s = opaque; + + switch (size) { + case 1: return cirrus_vga_mem_readb(s, addr); + case 2: return cirrus_vga_mem_readw(s, addr); + case 4: return cirrus_vga_mem_readl(s, addr); + default: abort(); + } +} + +static void cirrus_vga_mem_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) +{ + CirrusVGAState *s = opaque; + + switch (size) { + case 1: return cirrus_vga_mem_writeb(s, addr, data); + case 2: return cirrus_vga_mem_writew(s, addr, data); + case 4: return cirrus_vga_mem_writel(s, addr, data); + default: abort(); + } }; -static CPUWriteMemoryFunc * const cirrus_vga_mem_write[3] = { - cirrus_vga_mem_writeb, - cirrus_vga_mem_writew, - cirrus_vga_mem_writel, +static MemoryRegionOps cirrus_vga_mem_ops = { + .read = cirrus_vga_mem_read, + .write = cirrus_vga_mem_write, + .endianness = DEVICE_LITTLE_ENDIAN, }; /*************************************** @@ -2365,7 +2384,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); @@ -2393,17 +2412,31 @@ static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr, } -static CPUReadMemoryFunc * const cirrus_linear_read[3] = { - cirrus_linear_readb, - cirrus_linear_readw, - cirrus_linear_readl, -}; +static uint64_t cirrus_linear_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + CirrusVGAState *s = opaque; -static CPUWriteMemoryFunc * const cirrus_linear_write[3] = { - cirrus_linear_writeb, - cirrus_linear_writew, - cirrus_linear_writel, -}; + switch (size) { + case 1: return cirrus_linear_readb(s, addr); + case 2: return cirrus_linear_readw(s, addr); + case 4: return cirrus_linear_readl(s, addr); + default: abort(); + } +} + +static void cirrus_linear_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) +{ + CirrusVGAState *s = opaque; + + switch (size) { + case 1: return cirrus_linear_writeb(s, addr, data); + case 2: return cirrus_linear_writew(s, addr, data); + case 4: return cirrus_linear_writel(s, addr, data); + default: abort(); + } +} /*************************************** * @@ -2471,67 +2504,97 @@ static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr, cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff); } +static uint64_t cirrus_linear_bitblt_read(void *opaque, + target_phys_addr_t addr, + unsigned size) +{ + CirrusVGAState *s = opaque; -static CPUReadMemoryFunc * const cirrus_linear_bitblt_read[3] = { - cirrus_linear_bitblt_readb, - cirrus_linear_bitblt_readw, - cirrus_linear_bitblt_readl, + switch (size) { + case 1: return cirrus_linear_bitblt_readb(s, addr); + case 2: return cirrus_linear_bitblt_readw(s, addr); + case 4: return cirrus_linear_bitblt_readl(s, addr); + default: abort(); + } }; -static CPUWriteMemoryFunc * const cirrus_linear_bitblt_write[3] = { - cirrus_linear_bitblt_writeb, - cirrus_linear_bitblt_writew, - cirrus_linear_bitblt_writel, +static void cirrus_linear_bitblt_write(void *opaque, + target_phys_addr_t addr, + uint64_t data, + unsigned size) +{ + CirrusVGAState *s = opaque; + + switch (size) { + case 1: return cirrus_linear_bitblt_writeb(s, addr, data); + case 2: return cirrus_linear_bitblt_writew(s, addr, data); + case 4: return cirrus_linear_bitblt_writel(s, addr, data); + default: abort(); + } }; -static void map_linear_vram(CirrusVGAState *s) +static MemoryRegionOps cirrus_linear_bitblt_io_ops = { + .read = cirrus_linear_bitblt_read, + .write = cirrus_linear_bitblt_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +#include "exec-memory.h" + +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 */ @@ -2829,16 +2892,36 @@ static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr, } -static CPUReadMemoryFunc * const cirrus_mmio_read[3] = { - cirrus_mmio_readb, - cirrus_mmio_readw, - cirrus_mmio_readl, +static uint64_t cirrus_mmio_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + CirrusVGAState *s = opaque; + + switch (size) { + case 1: return cirrus_mmio_readb(s, addr); + case 2: return cirrus_mmio_readw(s, addr); + case 4: return cirrus_mmio_readl(s, addr); + default: abort(); + } }; -static CPUWriteMemoryFunc * const cirrus_mmio_write[3] = { - cirrus_mmio_writeb, - cirrus_mmio_writew, - cirrus_mmio_writel, +static void cirrus_mmio_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) +{ + CirrusVGAState *s = opaque; + + switch (size) { + case 1: return cirrus_mmio_writeb(s, addr, data); + case 2: return cirrus_mmio_writew(s, addr, data); + case 4: return cirrus_mmio_writel(s, addr, data); + default: abort(); + } +}; + +static MemoryRegionOps cirrus_mmio_io_ops = { + .read = cirrus_mmio_read, + .write = cirrus_mmio_write, + .endianness = DEVICE_LITTLE_ENDIAN, }; /* load/save state */ @@ -2947,6 +3030,12 @@ static void cirrus_reset(void *opaque) s->cirrus_hidden_dac_data = 0; } +static MemoryRegionOps cirrus_linear_io_ops = { + .read = cirrus_linear_read, + .write = cirrus_linear_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci) { int i; @@ -2993,28 +3082,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 +3154,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 +3170,23 @@ 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); + + vga_dirty_log_start(&s->vga); + /* 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_region(&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_region(&d->dev, 1, 0, &s->cirrus_mmio_io); } return 0; } @@ -3138,7 +3204,6 @@ static PCIDeviceInfo cirrus_vga_info = { .no_hotplug = 1, .init = pci_cirrus_vga_initfn, .romfile = VGABIOS_CIRRUS_FILENAME, - .config_write = pci_cirrus_write_config, .vendor_id = PCI_VENDOR_ID_CIRRUS, .device_id = CIRRUS_ID_CLGD5446, .class_id = PCI_CLASS_DISPLAY_VGA, diff --git a/hw/qxl-render.c b/hw/qxl-render.c index 1316066..4f626dc 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; diff --git a/hw/qxl.c b/hw/qxl.c index 16316f2..da323f6 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -147,7 +147,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; @@ -223,39 +223,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); } /* @@ -613,20 +611,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; @@ -752,10 +736,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 */ @@ -915,10 +899,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; switch (io_port) { case QXL_IO_RESET: @@ -964,7 +949,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) 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: @@ -1008,7 +993,8 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) } } -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; @@ -1016,42 +1002,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 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) { @@ -1170,8 +1128,7 @@ static void qxl_vm_change_state_handler(void *opaque, int running, int reason) /* dirty all vram (which holds surfaces) to make sure it is 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 addr = qxl->vram_offset; - qxl_set_dirty(addr, addr + qxl->vram_size); + qxl_set_dirty(&qxl->vram_bar, 0, qxl->vram_size); } } @@ -1236,7 +1193,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); @@ -1247,26 +1205,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; } - pci_register_bar(&qxl->pci, QXL_IO_RANGE_INDEX, - io_size, PCI_BASE_ADDRESS_SPACE_IO, qxl_map); + 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_region(&qxl->pci, QXL_IO_RANGE_INDEX, + 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_register_bar_region(&qxl->pci, QXL_ROM_RANGE_INDEX, + 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_register_bar_region(&qxl->pci, QXL_RAM_RANGE_INDEX, + 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_region(&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; @@ -1325,9 +1289,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); } @@ -1489,7 +1453,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, .class_id = PCI_CLASS_DISPLAY_VGA, diff --git a/hw/qxl.h b/hw/qxl.h index f6c450d..987a5e7 100644 --- a/hw/qxl.h +++ b/hw/qxl.h @@ -72,14 +72,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/vga-isa-mm.c b/hw/vga-isa-mm.c index 4954bb1..d2661ef 100644 --- a/hw/vga-isa-mm.c +++ b/hw/vga-isa-mm.c @@ -79,35 +79,62 @@ 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 uint64_t vga_mm_read_ctrl(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + ISAVGAMMState *s = opaque; + + switch (size) { + case 1: return vga_mm_readb(s, addr); + case 2: return vga_mm_readw(s, addr); + case 4: return vga_mm_readl(s, addr); + default: abort(); + } +} + +static void vga_mm_write_ctrl(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) +{ + ISAVGAMMState *s = opaque; + + switch (size) { + case 1: return vga_mm_writeb(s, addr, data); + case 2: return vga_mm_writew(s, addr, data); + case 4: return vga_mm_writel(s, addr, data); + default: abort(); + } +} -static CPUWriteMemoryFunc * const vga_mm_write_ctrl[] = { - &vga_mm_writeb, - &vga_mm_writew, - &vga_mm_writel, +static MemoryRegionOps vga_mm_ctrl_ops = { + .read = vga_mm_read_ctrl, + .write = vga_mm_write_ctrl, + .endianness = DEVICE_NATIVE_ENDIAN, }; +#include "exec-memory.h" + 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..518cecc 100644 --- a/hw/vga-isa.c +++ b/hw/vga-isa.c @@ -42,17 +42,20 @@ static void vga_reset_isa(DeviceState *dev) vga_common_reset(s); } +#include "exec-memory.h" + 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..7062c4d 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,8 @@ 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_region(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, + &s->vram); if (!dev->rom_bar) { /* compatibility with pc-0.13 and older */ @@ -106,7 +83,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) */ diff --git a/hw/vga.c b/hw/vga.c index 0f54734..b969e9f 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -825,7 +825,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 +838,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,7 +912,7 @@ 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); } } @@ -1553,57 +1553,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 +1733,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 +1787,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 +1869,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 +2099,36 @@ 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; + + switch (size) { + case 1: return vga_mem_readb(s, addr); + case 2: return vga_mem_readw(s, addr); + case 4: return vga_mem_readl(s, addr); + default: abort(); + } +} -CPUWriteMemoryFunc * const vga_mem_write[3] = { - vga_mem_writeb, - vga_mem_writew, - vga_mem_writel, +static void vga_mem_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) +{ + VGACommonState *s = opaque; + + switch (size) { + case 1: return vga_mem_writeb(s, addr, data); + case 2: return vga_mem_writew(s, addr, data); + case 4: return vga_mem_writel(s, addr, data); + default: abort(); + } +} + +MemoryRegionOps vga_mem_ops = { + .read = vga_mem_read, + .write = vga_mem_write, + .endianness = DEVICE_LITTLE_ENDIAN, }; static int vga_common_post_load(void *opaque, int version_id) @@ -2236,8 +2214,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; @@ -2260,8 +2238,10 @@ void vga_common_init(VGACommonState *s, int vga_ram_size) } /* 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 +2272,38 @@ 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; } +#include "exec-memory.h" + 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 d2811bd..f4e0d8d 100644 --- a/hw/vga_int.h +++ b/hw/vga_int.h @@ -23,6 +23,7 @@ */ #include +#include "memory.h" #define MSR_COLOR_EMULATION 0x01 #define MSR_PAGE_SELECT 0x20 @@ -105,13 +106,8 @@ typedef void (* vga_update_retrace_info_fn)(struct VGACommonState *s); typedef struct VGACommonState { uint8_t *vram_ptr; - ram_addr_t vram_offset; + MemoryRegion vram; uint32_t vram_size; - uint32_t lfb_addr; - uint32_t lfb_end; - uint32_t map_addr; - uint32_t map_end; - uint32_t lfb_vram_mapped; /* whether 0xa0000 is mapped as ram */ uint32_t latch; uint8_t sr_index; uint8_t sr[256]; @@ -134,7 +130,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 +187,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); @@ -229,5 +225,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 MemoryRegionOps vga_mem_ops; diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c index 190b005..feb7197 100644 --- a/hw/vmware_vga.c +++ b/hw/vmware_vga.c @@ -65,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; @@ -92,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 @@ -789,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; @@ -1135,17 +1138,45 @@ 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, -}; +typedef struct DirectMem DirectMem; -static CPUWriteMemoryFunc * const vmsvga_vram_write[] = { - vmsvga_vram_writeb, - vmsvga_vram_writew, - vmsvga_vram_writel, +struct DirectMem { + MemoryRegion mr; + struct vmsvga_state_s *chip; }; + +static uint64_t vmsvga_vram_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + struct vmsvga_state_s *s = opaque; + + switch (size) { + case 1: return vmsvga_vram_readb(s, addr); + case 2: return vmsvga_vram_readw(s, addr); + case 4: return vmsvga_vram_readl(s, addr); + default: abort(); + } +} + +static void vmsvga_vram_read(void *opaque, target_phys_addr_t addr, + unsigned size, uint64_t data) +{ + struct vmsvga_state_s *s = opaque; + + switch (size) { + case 1: return vmsvga_vram_writeb(s, addr, data); + case 2: return vmsvga_vram_writew(s, addr, data); + case 4: return vmsvga_vram_writel(s, addr, data); + default: abort(); + } +} + +static MemoryRegionOps vmsvga_vram_io_ops = { + .read = vmsvga_vram_read, + .write = vmsvga_vram_write, + .endianness = DEVICE_NATIVE_ENDIAN, +} + #endif static int vmsvga_post_load(void *opaque, int version_id) @@ -1211,8 +1242,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); @@ -1221,79 +1252,77 @@ 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; - -#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(addr, 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 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)); + + directmem->chip = &s->chip; + iomem = &directmem->mr; + memory_region_init_io(iomem, &vmsvga_vram_io_ops, "vmsvga", &s->chip, + 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_region(&s->card, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar); vmsvga_init(&s->chip, VGA_RAM_SIZE); + pci_register_bar_region(&s->card, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, iomem); + pci_register_bar_region(&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);