aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS10
-rw-r--r--bsd-user/main.c3
-rwxr-xr-xconfigure16
-rw-r--r--coroutine-ucontext.c2
-rw-r--r--darwin-user/main.c4
-rw-r--r--darwin-user/signal.c1
-rw-r--r--exec-memory.h5
-rw-r--r--exec.c34
-rw-r--r--hw/ac97.c88
-rw-r--r--hw/apb_pci.c1
-rw-r--r--hw/bonito.c1
-rw-r--r--hw/cirrus_vga.c459
-rw-r--r--hw/cuda.c6
-rw-r--r--hw/e1000.c113
-rw-r--r--hw/eepro100.c181
-rw-r--r--hw/es1370.c43
-rw-r--r--hw/escc.c42
-rw-r--r--hw/escc.h2
-rw-r--r--hw/fw_cfg.c13
-rw-r--r--hw/grackle_pci.c8
-rw-r--r--hw/gt64xxx.c4
-rw-r--r--hw/heathrow_pic.c29
-rw-r--r--hw/ide.h2
-rw-r--r--hw/ide/ahci.c31
-rw-r--r--hw/ide/ahci.h2
-rw-r--r--hw/ide/cmd646.c204
-rw-r--r--hw/ide/ich.c3
-rw-r--r--hw/ide/macio.c36
-rw-r--r--hw/ide/pci.c25
-rw-r--r--hw/ide/pci.h19
-rw-r--r--hw/ide/piix.c63
-rw-r--r--hw/ide/via.c64
-rw-r--r--hw/intel-hda.c35
-rw-r--r--hw/isa.h2
-rw-r--r--hw/isa_mmio.c29
-rw-r--r--hw/ivshmem.c158
-rw-r--r--hw/lance.c31
-rw-r--r--hw/lsi53c895a.c257
-rw-r--r--hw/mac_dbdma.c32
-rw-r--r--hw/mac_dbdma.h4
-rw-r--r--hw/mac_nvram.c39
-rw-r--r--hw/macio.c73
-rw-r--r--hw/msix.c64
-rw-r--r--hw/msix.h6
-rw-r--r--hw/ne2000-isa.c13
-rw-r--r--hw/ne2000.c77
-rw-r--r--hw/ne2000.h8
-rw-r--r--hw/openpic.c81
-rw-r--r--hw/openpic.h2
-rw-r--r--hw/pc.h4
-rw-r--r--hw/pc_piix.c6
-rw-r--r--hw/pci.c133
-rw-r--r--hw/pci.h26
-rw-r--r--hw/pci_internals.h3
-rw-r--r--hw/pcnet-pci.c74
-rw-r--r--hw/pcnet.h4
-rw-r--r--hw/piix_pci.c14
-rw-r--r--hw/ppc4xx_pci.c1
-rw-r--r--hw/ppc_mac.h27
-rw-r--r--hw/ppc_newworld.c34
-rw-r--r--hw/ppc_oldworld.c27
-rw-r--r--hw/ppc_prep.c2
-rw-r--r--hw/ppce500_pci.c7
-rw-r--r--hw/prep_pci.c8
-rw-r--r--hw/prep_pci.h4
-rw-r--r--hw/qdev.c14
-rw-r--r--hw/qxl-render.c2
-rw-r--r--hw/qxl.c129
-rw-r--r--hw/qxl.h6
-rw-r--r--hw/rtl8139.c70
-rw-r--r--hw/sh_pci.c4
-rw-r--r--hw/sun4u.c49
-rw-r--r--hw/unin_pci.c16
-rw-r--r--hw/usb-ehci.c36
-rw-r--r--hw/usb-ohci.c2
-rw-r--r--hw/usb-uhci.c41
-rw-r--r--hw/versatile_pci.c2
-rw-r--r--hw/vga-isa-mm.c46
-rw-r--r--hw/vga-isa.c10
-rw-r--r--hw/vga-pci.c27
-rw-r--r--hw/vga.c178
-rw-r--r--hw/vga_int.h18
-rw-r--r--hw/virtio-pci.c85
-rw-r--r--hw/virtio-pci.h3
-rw-r--r--hw/vmware_vga.c153
-rw-r--r--hw/wdt_i6300esb.c43
-rw-r--r--hw/xen_platform.c82
-rw-r--r--linux-user/main.c3
-rw-r--r--memory.c27
-rw-r--r--memory.h2
-rw-r--r--migration.c19
-rw-r--r--net/socket.c10
-rw-r--r--net/tap-bsd.c26
-rw-r--r--qemu-common.h5
-rw-r--r--qemu-doc.texi8
-rw-r--r--slirp/arp_table.c16
-rw-r--r--slirp/if.c8
-rw-r--r--slirp/slirp.c3
-rw-r--r--slirp/slirp.h4
-rw-r--r--target-alpha/cpu.h2
-rw-r--r--target-alpha/helper.c4
-rw-r--r--target-alpha/op_helper.c2
-rw-r--r--target-arm/cpu.h2
-rw-r--r--target-arm/helper.c4
-rw-r--r--target-arm/op_helper.c2
-rw-r--r--target-cris/cpu.h2
-rw-r--r--target-cris/helper.c11
-rw-r--r--target-cris/op_helper.c2
-rw-r--r--target-i386/cpu.h2
-rw-r--r--target-i386/helper.c8
-rw-r--r--target-i386/op_helper.c2
-rw-r--r--target-lm32/cpu.h2
-rw-r--r--target-lm32/helper.c2
-rw-r--r--target-lm32/op_helper.c2
-rw-r--r--target-m68k/cpu.h2
-rw-r--r--target-m68k/helper.c4
-rw-r--r--target-m68k/op_helper.c2
-rw-r--r--target-microblaze/cpu.h2
-rw-r--r--target-microblaze/helper.c4
-rw-r--r--target-microblaze/op_helper.c2
-rw-r--r--target-mips/cpu.h2
-rw-r--r--target-mips/helper.c6
-rw-r--r--target-mips/op_helper.c2
-rw-r--r--target-ppc/cpu.h2
-rw-r--r--target-ppc/helper.c8
-rw-r--r--target-ppc/op_helper.c2
-rw-r--r--target-s390x/cpu.h2
-rw-r--r--target-s390x/helper.c14
-rw-r--r--target-s390x/op_helper.c2
-rw-r--r--target-sh4/cpu.h2
-rw-r--r--target-sh4/helper.c4
-rw-r--r--target-sh4/op_helper.c2
-rw-r--r--target-sparc/cpu.h2
-rw-r--r--target-sparc/helper.c6
-rw-r--r--target-sparc/op_helper.c2
-rw-r--r--target-sparc/translate.c30
-rw-r--r--target-unicore32/cpu.h2
-rw-r--r--target-unicore32/helper.c2
-rw-r--r--tcg/optimize.c15
-rw-r--r--tcg/tcg.h5
-rw-r--r--ui/sdl.c547
-rw-r--r--user-exec.c2
-rw-r--r--vl.c14
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);
diff --git a/configure b/configure
index 408d454..0c67a4a 100755
--- a/configure
+++ b/configure
@@ -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);
diff --git a/exec.c b/exec.c
index 476b507..be7e4b2 100644
--- a/exec.c
+++ b/exec.c
@@ -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) */
diff --git a/hw/ac97.c b/hw/ac97.c
index 0b59896..541d9a4 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -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,
diff --git a/hw/cuda.c b/hw/cuda.c
index 065c362..5c92d81 100644
--- a/hw/cuda.c
+++ b/hw/cuda.c
@@ -117,6 +117,7 @@ typedef struct CUDATimer {
} CUDATimer;
typedef struct CUDAState {
+ MemoryRegion mem;
/* cuda registers */
uint8_t b; /* B-side data */
uint8_t a; /* A-side data */
@@ -722,7 +723,7 @@ static void cuda_reset(void *opaque)
set_counter(s, &s->timers[1], 0xffff);
}
-void cuda_init (int *cuda_mem_index, qemu_irq irq)
+void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq)
{
struct tm tm;
CUDAState *s = &cuda_state;
@@ -738,8 +739,9 @@ void cuda_init (int *cuda_mem_index, qemu_irq irq)
s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
s->adb_poll_timer = qemu_new_timer_ns(vm_clock, cuda_adb_poll, s);
- *cuda_mem_index = cpu_register_io_memory(cuda_read, cuda_write, s,
+ cpu_register_io_memory(cuda_read, cuda_write, s,
DEVICE_NATIVE_ENDIAN);
+ *cuda_mem = &s->mem;
vmstate_register(NULL, -1, &vmstate_cuda, s);
qemu_register_reset(cuda_reset, s);
}
diff --git a/hw/e1000.c b/hw/e1000.c
index 96d84f9..29b453f 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -82,7 +82,8 @@ typedef struct E1000State_st {
PCIDevice dev;
NICState *nic;
NICConf conf;
- int mmio_index;
+ MemoryRegion mmio;
+ MemoryRegion io;
uint32_t mac_reg[0x8000];
uint16_t phy_reg[0x20];
@@ -151,14 +152,6 @@ static const char phy_regcap[0x20] = {
};
static void
-ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr,
- pcibus_t size, int type)
-{
- DBGOUT(IO, "e1000_ioport_map addr=0x%04"FMT_PCIBUS
- " size=0x%08"FMT_PCIBUS"\n", addr, size);
-}
-
-static void
set_interrupt_cause(E1000State *s, int index, uint32_t val)
{
if (val)
@@ -905,7 +898,8 @@ static void (*macreg_writeops[])(E1000State *, int, uint32_t) = {
enum { NWRITEOPS = ARRAY_SIZE(macreg_writeops) };
static void
-e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+e1000_mmio_write(void *opaque, target_phys_addr_t addr, uint64_t val,
+ unsigned size)
{
E1000State *s = opaque;
unsigned int index = (addr & 0x1ffff) >> 2;
@@ -913,31 +907,15 @@ e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
if (index < NWRITEOPS && macreg_writeops[index]) {
macreg_writeops[index](s, index, val);
} else if (index < NREADOPS && macreg_readops[index]) {
- DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04x\n", index<<2, val);
+ DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04"PRIx64"\n", index<<2, val);
} else {
- DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08x\n",
+ DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08"PRIx64"\n",
index<<2, val);
}
}
-static void
-e1000_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- // emulate hw without byte enables: no RMW
- e1000_mmio_writel(opaque, addr & ~3,
- (val & 0xffff) << (8*(addr & 3)));
-}
-
-static void
-e1000_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- // emulate hw without byte enables: no RMW
- e1000_mmio_writel(opaque, addr & ~3,
- (val & 0xff) << (8*(addr & 3)));
-}
-
-static uint32_t
-e1000_mmio_readl(void *opaque, target_phys_addr_t addr)
+static uint64_t
+e1000_mmio_read(void *opaque, target_phys_addr_t addr, unsigned size)
{
E1000State *s = opaque;
unsigned int index = (addr & 0x1ffff) >> 2;
@@ -950,20 +928,39 @@ e1000_mmio_readl(void *opaque, target_phys_addr_t addr)
return 0;
}
-static uint32_t
-e1000_mmio_readb(void *opaque, target_phys_addr_t addr)
+static const MemoryRegionOps e1000_mmio_ops = {
+ .read = e1000_mmio_read,
+ .write = e1000_mmio_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .impl = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+};
+
+static uint64_t e1000_io_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
- return ((e1000_mmio_readl(opaque, addr & ~3)) >>
- (8 * (addr & 3))) & 0xff;
+ E1000State *s = opaque;
+
+ (void)s;
+ return 0;
}
-static uint32_t
-e1000_mmio_readw(void *opaque, target_phys_addr_t addr)
+static void e1000_io_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
- return ((e1000_mmio_readl(opaque, addr & ~3)) >>
- (8 * (addr & 3))) & 0xffff;
+ E1000State *s = opaque;
+
+ (void)s;
}
+static const MemoryRegionOps e1000_io_ops = {
+ .read = e1000_io_read,
+ .write = e1000_io_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
static bool is_version_1(void *opaque, int version_id)
{
return version_id == 1;
@@ -1083,36 +1080,22 @@ static const uint32_t mac_reg_init[] = {
/* PCI interface */
-static CPUWriteMemoryFunc * const e1000_mmio_write[] = {
- e1000_mmio_writeb, e1000_mmio_writew, e1000_mmio_writel
-};
-
-static CPUReadMemoryFunc * const e1000_mmio_read[] = {
- e1000_mmio_readb, e1000_mmio_readw, e1000_mmio_readl
-};
-
static void
-e1000_mmio_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+e1000_mmio_setup(E1000State *d)
{
- E1000State *d = DO_UPCAST(E1000State, dev, pci_dev);
int i;
const uint32_t excluded_regs[] = {
E1000_MDIC, E1000_ICR, E1000_ICS, E1000_IMS,
E1000_IMC, E1000_TCTL, E1000_TDT, PNPMMIO_SIZE
};
-
- DBGOUT(MMIO, "e1000_mmio_map addr=0x%08"FMT_PCIBUS" 0x%08"FMT_PCIBUS"\n",
- addr, size);
-
- cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
- qemu_register_coalesced_mmio(addr, excluded_regs[0]);
-
+ memory_region_init_io(&d->mmio, &e1000_mmio_ops, d, "e1000-mmio",
+ PNPMMIO_SIZE);
+ memory_region_add_coalescing(&d->mmio, 0, excluded_regs[0]);
for (i = 0; excluded_regs[i] != PNPMMIO_SIZE; i++)
- qemu_register_coalesced_mmio(addr + excluded_regs[i] + 4,
- excluded_regs[i + 1] -
- excluded_regs[i] - 4);
+ memory_region_add_coalescing(&d->mmio, excluded_regs[i] + 4,
+ excluded_regs[i+1] - excluded_regs[i] - 4);
+ memory_region_init_io(&d->io, &e1000_io_ops, d, "e1000-io", IOPORT_SIZE);
}
static void
@@ -1128,7 +1111,8 @@ pci_e1000_uninit(PCIDevice *dev)
{
E1000State *d = DO_UPCAST(E1000State, dev, dev);
- cpu_unregister_io_memory(d->mmio_index);
+ memory_region_destroy(&d->mmio);
+ memory_region_destroy(&d->io);
qemu_del_vlan_client(&d->nic->nc);
return 0;
}
@@ -1172,14 +1156,11 @@ static int pci_e1000_init(PCIDevice *pci_dev)
/* TODO: RST# value should be 0 if programmable, PCI spec 6.2.4 */
pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
- d->mmio_index = cpu_register_io_memory(e1000_mmio_read,
- e1000_mmio_write, d, DEVICE_LITTLE_ENDIAN);
+ e1000_mmio_setup(d);
- pci_register_bar(&d->dev, 0, PNPMMIO_SIZE,
- PCI_BASE_ADDRESS_SPACE_MEMORY, e1000_mmio_map);
+ pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
- pci_register_bar(&d->dev, 1, IOPORT_SIZE,
- PCI_BASE_ADDRESS_SPACE_IO, ioport_map);
+ pci_register_bar(&d->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->io);
memmove(d->eeprom_data, e1000_eeprom_template,
sizeof e1000_eeprom_template);
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 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,
diff --git a/hw/escc.c b/hw/escc.c
index f6fd919..bea5873 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -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,
diff --git a/hw/escc.h b/hw/escc.h
index 015b9d0..d1da46f 100644
--- a/hw/escc.h
+++ b/hw/escc.h
@@ -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);
diff --git a/hw/ide.h b/hw/ide.h
index a490cbb..9059aae 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -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;
}
diff --git a/hw/isa.h b/hw/isa.h
index d2b6126..f1f2181 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -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;
diff --git a/hw/lance.c b/hw/lance.c
index ddb1cbb..8e20360 100644
--- a/hw/lance.c
+++ b/hw/lance.c
@@ -55,8 +55,8 @@ static void parent_lance_reset(void *opaque, int irq, int level)
pcnet_h_reset(&d->state);
}
-static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
- uint32_t val)
+static void lance_mem_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
SysBusPCNetState *d = opaque;
@@ -64,7 +64,8 @@ static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
pcnet_ioport_writew(&d->state, addr, val & 0xffff);
}
-static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
+static uint64_t lance_mem_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
SysBusPCNetState *d = opaque;
uint32_t val;
@@ -74,16 +75,14 @@ static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
return val & 0xffff;
}
-static CPUReadMemoryFunc * const lance_mem_read[3] = {
- NULL,
- lance_mem_readw,
- NULL,
-};
-
-static CPUWriteMemoryFunc * const lance_mem_write[3] = {
- NULL,
- lance_mem_writew,
- NULL,
+static const MemoryRegionOps lance_mem_ops = {
+ .read = lance_mem_read,
+ .write = lance_mem_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 2,
+ .max_access_size = 2,
+ },
};
static void lance_cleanup(VLANClientState *nc)
@@ -117,13 +116,11 @@ static int lance_init(SysBusDevice *dev)
SysBusPCNetState *d = FROM_SYSBUS(SysBusPCNetState, dev);
PCNetState *s = &d->state;
- s->mmio_index =
- cpu_register_io_memory(lance_mem_read, lance_mem_write, d,
- DEVICE_NATIVE_ENDIAN);
+ memory_region_init_io(&s->mmio, &lance_mem_ops, 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 */
diff --git a/hw/macio.c b/hw/macio.c
index 789ca55..cc6ae40 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -30,58 +30,55 @@
typedef struct macio_state_t macio_state_t;
struct macio_state_t {
int is_oldworld;
- int pic_mem_index;
- int dbdma_mem_index;
- int cuda_mem_index;
- int escc_mem_index;
+ MemoryRegion bar;
+ MemoryRegion *pic_mem;
+ MemoryRegion *dbdma_mem;
+ MemoryRegion *cuda_mem;
+ MemoryRegion *escc_mem;
void *nvram;
int nb_ide;
- int ide_mem_index[4];
+ MemoryRegion *ide_mem[4];
};
-static void macio_map (PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+static void macio_bar_setup(macio_state_t *macio_state)
{
- macio_state_t *macio_state;
int i;
+ MemoryRegion *bar = &macio_state->bar;
- macio_state = (macio_state_t *)(pci_dev + 1);
- if (macio_state->pic_mem_index >= 0) {
+ memory_region_init(bar, "macio", 0x80000);
+ if (macio_state->pic_mem) {
if (macio_state->is_oldworld) {
/* Heathrow PIC */
- cpu_register_physical_memory(addr + 0x00000, 0x1000,
- macio_state->pic_mem_index);
+ memory_region_add_subregion(bar, 0x00000, macio_state->pic_mem);
} else {
/* OpenPIC */
- cpu_register_physical_memory(addr + 0x40000, 0x40000,
- macio_state->pic_mem_index);
+ memory_region_add_subregion(bar, 0x40000, macio_state->pic_mem);
}
}
- if (macio_state->dbdma_mem_index >= 0) {
- cpu_register_physical_memory(addr + 0x08000, 0x1000,
- macio_state->dbdma_mem_index);
+ if (macio_state->dbdma_mem) {
+ memory_region_add_subregion(bar, 0x08000, macio_state->dbdma_mem);
}
- if (macio_state->escc_mem_index >= 0) {
- cpu_register_physical_memory(addr + 0x13000, ESCC_SIZE << 4,
- macio_state->escc_mem_index);
+ if (macio_state->escc_mem) {
+ memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem);
}
- if (macio_state->cuda_mem_index >= 0) {
- cpu_register_physical_memory(addr + 0x16000, 0x2000,
- macio_state->cuda_mem_index);
+ if (macio_state->cuda_mem) {
+ memory_region_add_subregion(bar, 0x16000, macio_state->cuda_mem);
}
for (i = 0; i < macio_state->nb_ide; i++) {
- if (macio_state->ide_mem_index[i] >= 0) {
- cpu_register_physical_memory(addr + 0x1f000 + (i * 0x1000), 0x1000,
- macio_state->ide_mem_index[i]);
+ if (macio_state->ide_mem[i]) {
+ memory_region_add_subregion(bar, 0x1f000 + (i * 0x1000),
+ macio_state->ide_mem[i]);
}
}
if (macio_state->nvram != NULL)
- macio_nvram_map(macio_state->nvram, addr + 0x60000);
+ macio_nvram_setup_bar(macio_state->nvram, bar, 0x60000);
}
-void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
- int dbdma_mem_index, int cuda_mem_index, void *nvram,
- int nb_ide, int *ide_mem_index, int escc_mem_index)
+void macio_init (PCIBus *bus, int device_id, int is_oldworld,
+ MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
+ MemoryRegion *cuda_mem, void *nvram,
+ int nb_ide, MemoryRegion **ide_mem,
+ MemoryRegion *escc_mem)
{
PCIDevice *d;
macio_state_t *macio_state;
@@ -92,18 +89,18 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
-1, NULL, NULL);
macio_state = (macio_state_t *)(d + 1);
macio_state->is_oldworld = is_oldworld;
- macio_state->pic_mem_index = pic_mem_index;
- macio_state->dbdma_mem_index = dbdma_mem_index;
- macio_state->cuda_mem_index = cuda_mem_index;
- macio_state->escc_mem_index = escc_mem_index;
+ macio_state->pic_mem = pic_mem;
+ macio_state->dbdma_mem = dbdma_mem;
+ macio_state->cuda_mem = cuda_mem;
+ macio_state->escc_mem = escc_mem;
macio_state->nvram = nvram;
if (nb_ide > 4)
nb_ide = 4;
macio_state->nb_ide = nb_ide;
for (i = 0; i < nb_ide; i++)
- macio_state->ide_mem_index[i] = ide_mem_index[i];
+ macio_state->ide_mem[i] = ide_mem[i];
for (; i < 4; i++)
- macio_state->ide_mem_index[i] = -1;
+ macio_state->ide_mem[i] = NULL;
/* Note: this code is strongly inspirated from the corresponding code
in PearPC */
@@ -113,6 +110,6 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
d->config[0x3d] = 0x01; // interrupt on pin 1
- pci_register_bar(d, 0, 0x80000,
- PCI_BASE_ADDRESS_SPACE_MEMORY, macio_map);
+ macio_bar_setup(macio_state);
+ pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &macio_state->bar);
}
diff --git a/hw/msix.c b/hw/msix.c
index e67e700..8536c3f 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -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);
diff --git a/hw/msix.h b/hw/msix.h
index a9f7993..7e04336 100644
--- a/hw/msix.h
+++ b/hw/msix.h
@@ -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);
diff --git a/hw/pc.h b/hw/pc.h
index a2de0fe..ec34db7 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -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);
diff --git a/hw/pci.c b/hw/pci.c
index 8621d3d..dc7271a 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -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;
}
/*
diff --git a/hw/pci.h b/hw/pci.h
index c51156d..d7ad7fb 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -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;
diff --git a/hw/pcnet.h b/hw/pcnet.h
index 534bdf9..7e1c685 100644
--- a/hw/pcnet.h
+++ b/hw/pcnet.h
@@ -4,6 +4,7 @@
#define PCNET_LOOPTEST_CRC 1
#define PCNET_LOOPTEST_NOCRC 2
+#include "memory.h"
typedef struct PCNetState_st PCNetState;
@@ -17,7 +18,8 @@ struct PCNetState_st {
uint16_t csr[128];
uint16_t bcr[32];
uint64_t timer;
- int mmio_index, xmit_pos;
+ MemoryRegion mmio;
+ int xmit_pos;
uint8_t buffer[4096];
int tx_busy;
qemu_irq irq;
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 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
diff --git a/hw/qdev.c b/hw/qdev.c
index b4ea8e1..6819537 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -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;
diff --git a/hw/qxl.c b/hw/qxl.c
index b684608..db7ae7a 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -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,
diff --git a/hw/qxl.h b/hw/qxl.h
index 4bcf7e1..868db81 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -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);
diff --git a/hw/sun4u.c b/hw/sun4u.c
index d7dcaf0..7b2d0b1 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -91,6 +91,12 @@ struct hwdef {
uint64_t console_serial_base;
};
+typedef struct EbusState {
+ PCIDevice pci_dev;
+ MemoryRegion bar0;
+ MemoryRegion bar1;
+} EbusState;
+
int DMA_get_channel_mode (int nchan)
{
return 0;
@@ -518,21 +524,6 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit)
}
}
-static void ebus_mmio_mapfunc(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- EBUS_DPRINTF("Mapping region %d registers at %" FMT_PCIBUS "\n",
- region_num, addr);
- switch (region_num) {
- case 0:
- isa_mmio_init(addr, 0x1000000);
- break;
- case 1:
- isa_mmio_init(addr, 0x800000);
- break;
- }
-}
-
static void dummy_isa_irq_handler(void *opaque, int n, int level)
{
}
@@ -549,27 +540,29 @@ pci_ebus_init(PCIBus *bus, int devfn)
}
static int
-pci_ebus_init1(PCIDevice *s)
+pci_ebus_init1(PCIDevice *pci_dev)
{
- isa_bus_new(&s->qdev);
+ EbusState *s = DO_UPCAST(EbusState, pci_dev, pci_dev);
+
+ isa_bus_new(&pci_dev->qdev);
- s->config[0x04] = 0x06; // command = bus master, pci mem
- s->config[0x05] = 0x00;
- s->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
- s->config[0x07] = 0x03; // status = medium devsel
- s->config[0x09] = 0x00; // programming i/f
- s->config[0x0D] = 0x0a; // latency_timer
+ pci_dev->config[0x04] = 0x06; // command = bus master, pci mem
+ pci_dev->config[0x05] = 0x00;
+ pci_dev->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
+ pci_dev->config[0x07] = 0x03; // status = medium devsel
+ pci_dev->config[0x09] = 0x00; // programming i/f
+ pci_dev->config[0x0D] = 0x0a; // latency_timer
- pci_register_bar(s, 0, 0x1000000, PCI_BASE_ADDRESS_SPACE_MEMORY,
- ebus_mmio_mapfunc);
- pci_register_bar(s, 1, 0x800000, PCI_BASE_ADDRESS_SPACE_MEMORY,
- ebus_mmio_mapfunc);
+ isa_mmio_setup(&s->bar0, 0x1000000);
+ pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar0);
+ isa_mmio_setup(&s->bar1, 0x800000);
+ pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar1);
return 0;
}
static PCIDeviceInfo ebus_info = {
.qdev.name = "ebus",
- .qdev.size = sizeof(PCIDevice),
+ .qdev.size = sizeof(EbusState),
.init = pci_ebus_init1,
.vendor_id = PCI_VENDOR_ID_SUN,
.device_id = PCI_DEVICE_ID_SUN_EBUS,
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 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) */
diff --git a/hw/vga.c b/hw/vga.c
index 0f54734..33dc478 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -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);
diff --git a/memory.c b/memory.c
index 5c6e63d..be891c6 100644
--- a/memory.c
+++ b/memory.c
@@ -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;
diff --git a/memory.h b/memory.h
index 4e518b2..da00a3b 100644
--- a/memory.h
+++ b/memory.h
@@ -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],
diff --git a/slirp/if.c b/slirp/if.c
index 2d79e45..2852396 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -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;
diff --git a/tcg/tcg.h b/tcg/tcg.h
index e76f9af..e2a7095 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -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
diff --git a/ui/sdl.c b/ui/sdl.c
index 6dbc5cb..30cde86 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -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 */
}
diff --git a/vl.c b/vl.c
index 426cea7..c714127 100644
--- a/vl.c
+++ b/vl.c
@@ -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();