Merge remote-tracking branch 'qemu-kvm-tmp/memory/batch' into staging

This commit is contained in:
Anthony Liguori 2011-10-14 10:44:52 -05:00
commit 36f490b176
37 changed files with 538 additions and 397 deletions

View File

@ -82,7 +82,7 @@ common-obj-$(CONFIG_WIN32) += os-win32.o
common-obj-$(CONFIG_POSIX) += os-posix.o common-obj-$(CONFIG_POSIX) += os-posix.o
common-obj-y += tcg-runtime.o host-utils.o common-obj-y += tcg-runtime.o host-utils.o
common-obj-y += irq.o ioport.o input.o common-obj-y += irq.o input.o
common-obj-$(CONFIG_PTIMER) += ptimer.o common-obj-$(CONFIG_PTIMER) += ptimer.o
common-obj-$(CONFIG_MAX7310) += max7310.o common-obj-$(CONFIG_MAX7310) += max7310.o
common-obj-$(CONFIG_WM8750) += wm8750.o common-obj-$(CONFIG_WM8750) += wm8750.o

View File

@ -183,7 +183,7 @@ endif #CONFIG_BSD_USER
# System emulator target # System emulator target
ifdef CONFIG_SOFTMMU ifdef CONFIG_SOFTMMU
obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o ioport.o
# virtio has to be here due to weird dependency between PCI and virtio-net. # virtio has to be here due to weird dependency between PCI and virtio-net.
# need to fix this properly # need to fix this properly
obj-$(CONFIG_NO_PCI) += pci-stub.o obj-$(CONFIG_NO_PCI) += pci-stub.o

View File

@ -48,17 +48,6 @@ static void mpcore_rirq_set_irq(void *opaque, int irq, int level)
} }
} }
static void mpcore_rirq_map(SysBusDevice *dev, target_phys_addr_t base)
{
mpcore_rirq_state *s = FROM_SYSBUS(mpcore_rirq_state, dev);
sysbus_mmio_map(s->priv, 0, base);
}
static void mpcore_rirq_unmap(SysBusDevice *dev, target_phys_addr_t base)
{
/* nothing to do */
}
static int realview_mpcore_init(SysBusDevice *dev) static int realview_mpcore_init(SysBusDevice *dev)
{ {
mpcore_rirq_state *s = FROM_SYSBUS(mpcore_rirq_state, dev); mpcore_rirq_state *s = FROM_SYSBUS(mpcore_rirq_state, dev);
@ -84,7 +73,7 @@ static int realview_mpcore_init(SysBusDevice *dev)
} }
} }
qdev_init_gpio_in(&dev->qdev, mpcore_rirq_set_irq, 64); qdev_init_gpio_in(&dev->qdev, mpcore_rirq_set_irq, 64);
sysbus_init_mmio_cb2(dev, mpcore_rirq_map, mpcore_rirq_unmap); sysbus_init_mmio_region(dev, sysbus_mmio_get_region(s->priv, 0));
return 0; return 0;
} }

View File

@ -424,7 +424,6 @@ typedef struct FDCtrlSysBus {
typedef struct FDCtrlISABus { typedef struct FDCtrlISABus {
ISADevice busdev; ISADevice busdev;
MemoryRegion io_0, io_7;
struct FDCtrl state; struct FDCtrl state;
int32_t bootindexA; int32_t bootindexA;
int32_t bootindexB; int32_t bootindexB;
@ -1880,32 +1879,10 @@ static int fdctrl_init_common(FDCtrl *fdctrl)
return fdctrl_connect_drives(fdctrl); return fdctrl_connect_drives(fdctrl);
} }
static uint32_t fdctrl_read_port_7(void *opaque, uint32_t reg) static const MemoryRegionPortio fdc_portio_list[] = {
{
return fdctrl_read(opaque, reg + 7);
}
static void fdctrl_write_port_7(void *opaque, uint32_t reg, uint32_t value)
{
fdctrl_write(opaque, reg + 7, value);
}
static const MemoryRegionPortio fdc_portio_0[] = {
{ 1, 5, 1, .read = fdctrl_read, .write = fdctrl_write }, { 1, 5, 1, .read = fdctrl_read, .write = fdctrl_write },
PORTIO_END_OF_LIST() { 7, 1, 1, .read = fdctrl_read, .write = fdctrl_write },
}; PORTIO_END_OF_LIST(),
static const MemoryRegionPortio fdc_portio_7[] = {
{ 0, 1, 1, .read = fdctrl_read_port_7, .write = fdctrl_write_port_7 },
PORTIO_END_OF_LIST()
};
static const MemoryRegionOps fdc_ioport_0_ops = {
.old_portio = fdc_portio_0
};
static const MemoryRegionOps fdc_ioport_7_ops = {
.old_portio = fdc_portio_7
}; };
static int isabus_fdc_init1(ISADevice *dev) static int isabus_fdc_init1(ISADevice *dev)
@ -1917,10 +1894,7 @@ static int isabus_fdc_init1(ISADevice *dev)
int dma_chann = 2; int dma_chann = 2;
int ret; int ret;
memory_region_init_io(&isa->io_0, &fdc_ioport_0_ops, fdctrl, "fdc", 6); isa_register_portio_list(dev, iobase, fdc_portio_list, fdctrl, "fdc");
memory_region_init_io(&isa->io_7, &fdc_ioport_7_ops, fdctrl, "fdc", 1);
isa_register_ioport(dev, &isa->io_0, iobase);
isa_register_ioport(dev, &isa->io_7, iobase + 7);
isa_init_irq(&isa->busdev, &fdctrl->irq, isairq); isa_init_irq(&isa->busdev, &fdctrl->irq, isairq);
fdctrl->dma_chann = dma_chann; fdctrl->dma_chann = dma_chann;

View File

@ -232,6 +232,22 @@ static const VMStateDescription vmstate_gus = {
} }
}; };
static const MemoryRegionPortio gus_portio_list1[] = {
{0x000, 1, 1, .write = gus_writeb },
{0x000, 1, 2, .write = gus_writew },
{0x006, 10, 1, .read = gus_readb, .write = gus_writeb },
{0x006, 10, 2, .read = gus_readw, .write = gus_writew },
{0x100, 8, 1, .read = gus_readb, .write = gus_writeb },
{0x100, 8, 2, .read = gus_readw, .write = gus_writew },
PORTIO_END_OF_LIST(),
};
static const MemoryRegionPortio gus_portio_list2[] = {
{0, 1, 1, .read = gus_readb },
{0, 1, 2, .read = gus_readw },
PORTIO_END_OF_LIST(),
};
static int gus_initfn (ISADevice *dev) static int gus_initfn (ISADevice *dev)
{ {
GUSState *s = DO_UPCAST (GUSState, dev, dev); GUSState *s = DO_UPCAST (GUSState, dev, dev);
@ -262,25 +278,9 @@ static int gus_initfn (ISADevice *dev)
s->samples = AUD_get_buffer_size_out (s->voice) >> s->shift; s->samples = AUD_get_buffer_size_out (s->voice) >> s->shift;
s->mixbuf = g_malloc0 (s->samples << s->shift); s->mixbuf = g_malloc0 (s->samples << s->shift);
register_ioport_write (s->port, 1, 1, gus_writeb, s); isa_register_portio_list (dev, s->port, gus_portio_list1, s, "gus");
register_ioport_write (s->port, 1, 2, gus_writew, s); isa_register_portio_list (dev, (s->port + 0x100) & 0xf00,
isa_init_ioport_range (dev, s->port, 2); gus_portio_list2, s, "gus");
register_ioport_read ((s->port + 0x100) & 0xf00, 1, 1, gus_readb, s);
register_ioport_read ((s->port + 0x100) & 0xf00, 1, 2, gus_readw, s);
isa_init_ioport_range (dev, (s->port + 0x100) & 0xf00, 2);
register_ioport_write (s->port + 6, 10, 1, gus_writeb, s);
register_ioport_write (s->port + 6, 10, 2, gus_writew, s);
register_ioport_read (s->port + 6, 10, 1, gus_readb, s);
register_ioport_read (s->port + 6, 10, 2, gus_readw, s);
isa_init_ioport_range (dev, s->port + 6, 10);
register_ioport_write (s->port + 0x100, 8, 1, gus_writeb, s);
register_ioport_write (s->port + 0x100, 8, 2, gus_writew, s);
register_ioport_read (s->port + 0x100, 8, 1, gus_readb, s);
register_ioport_read (s->port + 0x100, 8, 2, gus_readw, s);
isa_init_ioport_range (dev, s->port + 0x100, 8);
DMA_register_channel (s->emu.gusdma, GUS_read_DMA, s); DMA_register_channel (s->emu.gusdma, GUS_read_DMA, s);
s->emu.himemaddr = s->himem; s->emu.himemaddr = s->himem;

View File

@ -25,6 +25,7 @@
#include <hw/hw.h> #include <hw/hw.h>
#include <hw/pc.h> #include <hw/pc.h>
#include <hw/pci.h> #include <hw/pci.h>
#include <hw/isa.h>
#include "qemu-error.h" #include "qemu-error.h"
#include "qemu-timer.h" #include "qemu-timer.h"
#include "sysemu.h" #include "sysemu.h"
@ -1969,20 +1970,27 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
bus->dma = &ide_dma_nop; bus->dma = &ide_dma_nop;
} }
void ide_init_ioport(IDEBus *bus, int iobase, int iobase2) static const MemoryRegionPortio ide_portio_list[] = {
{ { 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write },
register_ioport_write(iobase, 8, 1, ide_ioport_write, bus); { 0, 2, 2, .read = ide_data_readw, .write = ide_data_writew },
register_ioport_read(iobase, 8, 1, ide_ioport_read, bus); { 0, 4, 4, .read = ide_data_readl, .write = ide_data_writel },
if (iobase2) { PORTIO_END_OF_LIST(),
register_ioport_read(iobase2, 1, 1, ide_status_read, bus); };
register_ioport_write(iobase2, 1, 1, ide_cmd_write, bus);
}
/* data ports */ static const MemoryRegionPortio ide_portio2_list[] = {
register_ioport_write(iobase, 2, 2, ide_data_writew, bus); { 0, 1, 1, .read = ide_status_read, .write = ide_cmd_write },
register_ioport_read(iobase, 2, 2, ide_data_readw, bus); PORTIO_END_OF_LIST(),
register_ioport_write(iobase, 4, 4, ide_data_writel, bus); };
register_ioport_read(iobase, 4, 4, ide_data_readl, bus);
void ide_init_ioport(IDEBus *bus, ISADevice *dev, int iobase, int iobase2)
{
/* ??? Assume only ISA and PCI configurations, and that the PCI-ISA
bridge has been setup properly to always register with ISA. */
isa_register_portio_list(dev, iobase, ide_portio_list, bus, "ide");
if (iobase2) {
isa_register_portio_list(dev, iobase2, ide_portio2_list, bus, "ide");
}
} }
static bool is_identify_set(void *opaque, int version_id) static bool is_identify_set(void *opaque, int version_id)

View File

@ -7,6 +7,7 @@
* non-internal declarations are in hw/ide.h * non-internal declarations are in hw/ide.h
*/ */
#include <hw/ide.h> #include <hw/ide.h>
#include <hw/isa.h>
#include "iorange.h" #include "iorange.h"
#include "dma.h" #include "dma.h"
#include "sysemu.h" #include "sysemu.h"
@ -600,7 +601,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
void ide_init2(IDEBus *bus, qemu_irq irq); void ide_init2(IDEBus *bus, qemu_irq irq);
void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0, void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
DriveInfo *hd1, qemu_irq irq); DriveInfo *hd1, qemu_irq irq);
void ide_init_ioport(IDEBus *bus, int iobase, int iobase2); void ide_init_ioport(IDEBus *bus, ISADevice *isa, int iobase, int iobase2);
void ide_exec_cmd(IDEBus *bus, uint32_t val); void ide_exec_cmd(IDEBus *bus, uint32_t val);
void ide_dma_cb(void *opaque, int ret); void ide_dma_cb(void *opaque, int ret);

View File

@ -66,10 +66,8 @@ static int isa_ide_initfn(ISADevice *dev)
ISAIDEState *s = DO_UPCAST(ISAIDEState, dev, dev); ISAIDEState *s = DO_UPCAST(ISAIDEState, dev, dev);
ide_bus_new(&s->bus, &s->dev.qdev, 0); ide_bus_new(&s->bus, &s->dev.qdev, 0);
ide_init_ioport(&s->bus, s->iobase, s->iobase2); ide_init_ioport(&s->bus, dev, s->iobase, s->iobase2);
isa_init_irq(dev, &s->irq, s->isairq); isa_init_irq(dev, &s->irq, s->isairq);
isa_init_ioport_range(dev, s->iobase, 8);
isa_init_ioport(dev, s->iobase2);
ide_init2(&s->bus, s->irq); ide_init2(&s->bus, s->irq);
vmstate_register(&dev->qdev, 0, &vmstate_ide_isa, s); vmstate_register(&dev->qdev, 0, &vmstate_ide_isa, s);
return 0; return 0;

View File

@ -122,8 +122,7 @@ static void piix3_reset(void *opaque)
} }
static void pci_piix_init_ports(PCIIDEState *d) { static void pci_piix_init_ports(PCIIDEState *d) {
int i; static const struct {
struct {
int iobase; int iobase;
int iobase2; int iobase2;
int isairq; int isairq;
@ -131,10 +130,12 @@ static void pci_piix_init_ports(PCIIDEState *d) {
{0x1f0, 0x3f6, 14}, {0x1f0, 0x3f6, 14},
{0x170, 0x376, 15}, {0x170, 0x376, 15},
}; };
int i;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
ide_bus_new(&d->bus[i], &d->dev.qdev, i); ide_bus_new(&d->bus[i], &d->dev.qdev, i);
ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2); ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
port_info[i].iobase2);
ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq)); ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq));
bmdma_init(&d->bus[i], &d->bmdma[i], d); bmdma_init(&d->bus[i], &d->bmdma[i], d);

View File

@ -146,8 +146,7 @@ static void via_reset(void *opaque)
} }
static void vt82c686b_init_ports(PCIIDEState *d) { static void vt82c686b_init_ports(PCIIDEState *d) {
int i; static const struct {
struct {
int iobase; int iobase;
int iobase2; int iobase2;
int isairq; int isairq;
@ -155,10 +154,12 @@ static void vt82c686b_init_ports(PCIIDEState *d) {
{0x1f0, 0x3f6, 14}, {0x1f0, 0x3f6, 14},
{0x170, 0x376, 15}, {0x170, 0x376, 15},
}; };
int i;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
ide_bus_new(&d->bus[i], &d->dev.qdev, i); ide_bus_new(&d->bus[i], &d->dev.qdev, i);
ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2); ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
port_info[i].iobase2);
ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq)); ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq));
bmdma_init(&d->bus[i], &d->bmdma[i], d); bmdma_init(&d->bus[i], &d->bmdma[i], d);

View File

@ -83,39 +83,32 @@ void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq)
dev->nirqs++; dev->nirqs++;
} }
static void isa_init_ioport_one(ISADevice *dev, uint16_t ioport) static inline void isa_init_ioport(ISADevice *dev, uint16_t ioport)
{ {
assert(dev->nioports < ARRAY_SIZE(dev->ioports)); if (dev && (dev->ioport_id == 0 || ioport < dev->ioport_id)) {
dev->ioports[dev->nioports++] = ioport; dev->ioport_id = ioport;
} }
static int isa_cmp_ports(const void *p1, const void *p2)
{
return *(uint16_t*)p1 - *(uint16_t*)p2;
}
void isa_init_ioport_range(ISADevice *dev, uint16_t start, uint16_t length)
{
int i;
for (i = start; i < start + length; i++) {
isa_init_ioport_one(dev, i);
}
qsort(dev->ioports, dev->nioports, sizeof(dev->ioports[0]), isa_cmp_ports);
}
void isa_init_ioport(ISADevice *dev, uint16_t ioport)
{
isa_init_ioport_range(dev, ioport, 1);
} }
void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start) void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start)
{ {
memory_region_add_subregion(isabus->address_space_io, start, io); memory_region_add_subregion(isabus->address_space_io, start, io);
if (dev != NULL) { isa_init_ioport(dev, start);
assert(dev->nio < ARRAY_SIZE(dev->io));
dev->io[dev->nio++] = io;
isa_init_ioport_range(dev, start, memory_region_size(io));
} }
void isa_register_portio_list(ISADevice *dev, uint16_t start,
const MemoryRegionPortio *pio_start,
void *opaque, const char *name)
{
PortioList *piolist = g_new(PortioList, 1);
/* START is how we should treat DEV, regardless of the actual
contents of the portio array. This is how the old code
actually handled e.g. the FDC device. */
isa_init_ioport(dev, start);
portio_list_init(piolist, pio_start, opaque, name);
portio_list_add(piolist, isabus->address_space_io, start);
} }
static int isa_qdev_init(DeviceState *qdev, DeviceInfo *base) static int isa_qdev_init(DeviceState *qdev, DeviceInfo *base)
@ -208,8 +201,8 @@ static char *isabus_get_fw_dev_path(DeviceState *dev)
int off; int off;
off = snprintf(path, sizeof(path), "%s", qdev_fw_name(dev)); off = snprintf(path, sizeof(path), "%s", qdev_fw_name(dev));
if (d->nioports) { if (d->ioport_id) {
snprintf(path + off, sizeof(path) - off, "@%04x", d->ioports[0]); snprintf(path + off, sizeof(path) - off, "@%04x", d->ioport_id);
} }
return strdup(path); return strdup(path);

View File

@ -13,12 +13,9 @@ typedef struct ISADeviceInfo ISADeviceInfo;
struct ISADevice { struct ISADevice {
DeviceState qdev; DeviceState qdev;
MemoryRegion *io[32];
uint32_t isairq[2]; uint32_t isairq[2];
uint16_t ioports[32];
int nirqs; int nirqs;
int nioports; int ioport_id;
int nio;
}; };
typedef int (*isa_qdev_initfn)(ISADevice *dev); typedef int (*isa_qdev_initfn)(ISADevice *dev);
@ -31,15 +28,42 @@ ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space_io);
void isa_bus_irqs(qemu_irq *irqs); void isa_bus_irqs(qemu_irq *irqs);
qemu_irq isa_get_irq(int isairq); qemu_irq isa_get_irq(int isairq);
void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq); void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq);
void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start);
void isa_init_ioport(ISADevice *dev, uint16_t ioport);
void isa_init_ioport_range(ISADevice *dev, uint16_t start, uint16_t length);
void isa_qdev_register(ISADeviceInfo *info); void isa_qdev_register(ISADeviceInfo *info);
MemoryRegion *isa_address_space(ISADevice *dev); MemoryRegion *isa_address_space(ISADevice *dev);
ISADevice *isa_create(const char *name); ISADevice *isa_create(const char *name);
ISADevice *isa_try_create(const char *name); ISADevice *isa_try_create(const char *name);
ISADevice *isa_create_simple(const char *name); ISADevice *isa_create_simple(const char *name);
/**
* isa_register_ioport: Install an I/O port region on the ISA bus.
*
* Register an I/O port region via memory_region_add_subregion
* inside the ISA I/O address space.
*
* @dev: the ISADevice against which these are registered; may be NULL.
* @io: the #MemoryRegion being registered.
* @start: the base I/O port.
*/
void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start);
/**
* isa_register_portio_list: Initialize a set of ISA io ports
*
* Several ISA devices have many dis-joint I/O ports. Worse, these I/O
* ports can be interleaved with I/O ports from other devices. This
* function makes it easy to create multiple MemoryRegions for a single
* device and use the legacy portio routines.
*
* @dev: the ISADevice against which these are registered; may be NULL.
* @start: the base I/O port against which the portio->offset is applied.
* @portio: the ports, sorted by offset.
* @opaque: passed into the old_portio callbacks.
* @name: passed into memory_region_init_io.
*/
void isa_register_portio_list(ISADevice *dev, uint16_t start,
const MemoryRegionPortio *portio,
void *opaque, const char *name);
extern target_phys_addr_t isa_mem_base; extern target_phys_addr_t isa_mem_base;
void isa_mmio_setup(MemoryRegion *mr, target_phys_addr_t size); void isa_mmio_setup(MemoryRegion *mr, target_phys_addr_t size);

View File

@ -152,7 +152,7 @@ typedef struct {
NICState *nic; NICState *nic;
NICConf conf; NICConf conf;
qemu_irq irq; qemu_irq irq;
int mmio_index; MemoryRegion mmio;
ptimer_state *timer; ptimer_state *timer;
uint32_t irq_cfg; uint32_t irq_cfg;
@ -895,7 +895,7 @@ static void lan9118_tick(void *opaque)
} }
static void lan9118_writel(void *opaque, target_phys_addr_t offset, static void lan9118_writel(void *opaque, target_phys_addr_t offset,
uint32_t val) uint64_t val, unsigned size)
{ {
lan9118_state *s = (lan9118_state *)opaque; lan9118_state *s = (lan9118_state *)opaque;
offset &= 0xff; offset &= 0xff;
@ -1022,13 +1022,14 @@ static void lan9118_writel(void *opaque, target_phys_addr_t offset,
break; break;
default: default:
hw_error("lan9118_write: Bad reg 0x%x = %x\n", (int)offset, val); hw_error("lan9118_write: Bad reg 0x%x = %x\n", (int)offset, (int)val);
break; break;
} }
lan9118_update(s); lan9118_update(s);
} }
static uint32_t lan9118_readl(void *opaque, target_phys_addr_t offset) static uint64_t lan9118_readl(void *opaque, target_phys_addr_t offset,
unsigned size)
{ {
lan9118_state *s = (lan9118_state *)opaque; lan9118_state *s = (lan9118_state *)opaque;
@ -1101,16 +1102,10 @@ static uint32_t lan9118_readl(void *opaque, target_phys_addr_t offset)
return 0; return 0;
} }
static CPUReadMemoryFunc * const lan9118_readfn[] = { static const MemoryRegionOps lan9118_mem_ops = {
lan9118_readl, .read = lan9118_readl,
lan9118_readl, .write = lan9118_writel,
lan9118_readl .endianness = DEVICE_NATIVE_ENDIAN,
};
static CPUWriteMemoryFunc * const lan9118_writefn[] = {
lan9118_writel,
lan9118_writel,
lan9118_writel
}; };
static void lan9118_cleanup(VLANClientState *nc) static void lan9118_cleanup(VLANClientState *nc)
@ -1135,10 +1130,8 @@ static int lan9118_init1(SysBusDevice *dev)
QEMUBH *bh; QEMUBH *bh;
int i; int i;
s->mmio_index = cpu_register_io_memory(lan9118_readfn, memory_region_init_io(&s->mmio, &lan9118_mem_ops, s, "lan9118-mmio", 0x100);
lan9118_writefn, s, sysbus_init_mmio_region(dev, &s->mmio);
DEVICE_NATIVE_ENDIAN);
sysbus_init_mmio(dev, 0x100, s->mmio_index);
sysbus_init_irq(dev, &s->irq); sysbus_init_irq(dev, &s->irq);
qemu_macaddr_default_if_unset(&s->conf.macaddr); qemu_macaddr_default_if_unset(&s->conf.macaddr);

View File

@ -73,6 +73,7 @@ struct M48t59State {
typedef struct M48t59ISAState { typedef struct M48t59ISAState {
ISADevice busdev; ISADevice busdev;
M48t59State state; M48t59State state;
MemoryRegion io;
} M48t59ISAState; } M48t59ISAState;
typedef struct M48t59SysBusState { typedef struct M48t59SysBusState {
@ -626,6 +627,15 @@ static void m48t59_reset_sysbus(DeviceState *d)
m48t59_reset_common(NVRAM); m48t59_reset_common(NVRAM);
} }
static const MemoryRegionPortio m48t59_portio[] = {
{0, 4, 1, .read = NVRAM_readb, .write = NVRAM_writeb },
PORTIO_END_OF_LIST(),
};
static const MemoryRegionOps m48t59_io_ops = {
.old_portio = m48t59_portio,
};
/* Initialisation routine */ /* Initialisation routine */
M48t59State *m48t59_init(qemu_irq IRQ, target_phys_addr_t mem_base, M48t59State *m48t59_init(qemu_irq IRQ, target_phys_addr_t mem_base,
uint32_t io_base, uint16_t size, int type) uint32_t io_base, uint16_t size, int type)
@ -669,10 +679,9 @@ M48t59State *m48t59_init_isa(uint32_t io_base, uint16_t size, int type)
d = DO_UPCAST(M48t59ISAState, busdev, dev); d = DO_UPCAST(M48t59ISAState, busdev, dev);
s = &d->state; s = &d->state;
memory_region_init_io(&d->io, &m48t59_io_ops, s, "m48t59", 4);
if (io_base != 0) { if (io_base != 0) {
register_ioport_read(io_base, 0x04, 1, NVRAM_readb, s); isa_register_ioport(dev, &d->io, io_base);
register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, s);
isa_init_ioport_range(dev, io_base, 4);
} }
return s; return s;

View File

@ -81,6 +81,7 @@
typedef struct RTCState { typedef struct RTCState {
ISADevice dev; ISADevice dev;
MemoryRegion io;
uint8_t cmos_data[128]; uint8_t cmos_data[128];
uint8_t cmos_index; uint8_t cmos_index;
struct tm current_tm; struct tm current_tm;
@ -604,6 +605,15 @@ static void rtc_reset(void *opaque)
#endif #endif
} }
static const MemoryRegionPortio cmos_portio[] = {
{0, 2, 1, .read = cmos_ioport_read, .write = cmos_ioport_write },
PORTIO_END_OF_LIST(),
};
static const MemoryRegionOps cmos_ops = {
.old_portio = cmos_portio
};
static int rtc_initfn(ISADevice *dev) static int rtc_initfn(ISADevice *dev)
{ {
RTCState *s = DO_UPCAST(RTCState, dev, dev); RTCState *s = DO_UPCAST(RTCState, dev, dev);
@ -632,9 +642,8 @@ static int rtc_initfn(ISADevice *dev)
qemu_get_clock_ns(rtc_clock) + (get_ticks_per_sec() * 99) / 100; qemu_get_clock_ns(rtc_clock) + (get_ticks_per_sec() * 99) / 100;
qemu_mod_timer(s->second_timer2, s->next_second_time); qemu_mod_timer(s->second_timer2, s->next_second_time);
register_ioport_write(base, 2, 1, cmos_ioport_write, s); memory_region_init_io(&s->io, &cmos_ops, s, "rtc", 2);
register_ioport_read(base, 2, 1, cmos_ioport_read, s); isa_register_ioport(dev, &s->io, base);
isa_init_ioport_range(dev, base, 2);
qdev_set_legacy_instance_id(&dev->qdev, base, 2); qdev_set_legacy_instance_id(&dev->qdev, base, 2);
qemu_register_reset(rtc_reset, s); qemu_register_reset(rtc_reset, s);

View File

@ -68,10 +68,7 @@ static int isa_ne2000_initfn(ISADevice *dev)
NE2000State *s = &isa->ne2000; NE2000State *s = &isa->ne2000;
ne2000_setup_io(s, 0x20); ne2000_setup_io(s, 0x20);
isa_init_ioport_range(dev, isa->iobase, 16); isa_register_ioport(dev, &s->io, isa->iobase);
isa_init_ioport_range(dev, isa->iobase + 0x10, 2);
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); isa_init_irq(dev, &s->irq, isa->isairq);

View File

@ -54,16 +54,12 @@ static void static_write(void *opaque, target_phys_addr_t offset,
#endif #endif
} }
static CPUReadMemoryFunc * const static_readfn[] = { static const MemoryRegionOps static_ops = {
static_readb, .old_mmio = {
static_readh, .read = { static_readb, static_readh, static_readw, },
static_readw, .write = { static_write, static_write, static_write, },
}; },
.endianness = DEVICE_NATIVE_ENDIAN,
static CPUWriteMemoryFunc * const static_writefn[] = {
static_write,
static_write,
static_write,
}; };
/* Palm Tunsgten|E support */ /* Palm Tunsgten|E support */
@ -203,34 +199,35 @@ static void palmte_init(ram_addr_t ram_size,
struct omap_mpu_state_s *cpu; struct omap_mpu_state_s *cpu;
int flash_size = 0x00800000; int flash_size = 0x00800000;
int sdram_size = palmte_binfo.ram_size; int sdram_size = palmte_binfo.ram_size;
int io;
static uint32_t cs0val = 0xffffffff; static uint32_t cs0val = 0xffffffff;
static uint32_t cs1val = 0x0000e1a0; static uint32_t cs1val = 0x0000e1a0;
static uint32_t cs2val = 0x0000e1a0; static uint32_t cs2val = 0x0000e1a0;
static uint32_t cs3val = 0xe1a0e1a0; static uint32_t cs3val = 0xe1a0e1a0;
int rom_size, rom_loaded = 0; int rom_size, rom_loaded = 0;
DisplayState *ds = get_displaystate(); DisplayState *ds = get_displaystate();
MemoryRegion *flash = g_new(MemoryRegion, 1);
MemoryRegion *cs = g_new(MemoryRegion, 4);
cpu = omap310_mpu_init(address_space_mem, sdram_size, cpu_model); cpu = omap310_mpu_init(address_space_mem, sdram_size, cpu_model);
/* External Flash (EMIFS) */ /* External Flash (EMIFS) */
cpu_register_physical_memory(OMAP_CS0_BASE, flash_size, memory_region_init_ram(flash, NULL, "palmte.flash", flash_size);
qemu_ram_alloc(NULL, "palmte.flash", memory_region_set_readonly(flash, true);
flash_size) | IO_MEM_ROM); memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE, flash);
io = cpu_register_io_memory(static_readfn, static_writefn, &cs0val, memory_region_init_io(&cs[0], &static_ops, &cs0val, "palmte-cs0",
DEVICE_NATIVE_ENDIAN); OMAP_CS0_SIZE - flash_size);
cpu_register_physical_memory(OMAP_CS0_BASE + flash_size, memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE + flash_size,
OMAP_CS0_SIZE - flash_size, io); &cs[0]);
io = cpu_register_io_memory(static_readfn, static_writefn, &cs1val, memory_region_init_io(&cs[1], &static_ops, &cs1val, "palmte-cs1",
DEVICE_NATIVE_ENDIAN); OMAP_CS1_SIZE);
cpu_register_physical_memory(OMAP_CS1_BASE, OMAP_CS1_SIZE, io); memory_region_add_subregion(address_space_mem, OMAP_CS1_BASE, &cs[1]);
io = cpu_register_io_memory(static_readfn, static_writefn, &cs2val, memory_region_init_io(&cs[2], &static_ops, &cs2val, "palmte-cs2",
DEVICE_NATIVE_ENDIAN); OMAP_CS2_SIZE);
cpu_register_physical_memory(OMAP_CS2_BASE, OMAP_CS2_SIZE, io); memory_region_add_subregion(address_space_mem, OMAP_CS2_BASE, &cs[2]);
io = cpu_register_io_memory(static_readfn, static_writefn, &cs3val, memory_region_init_io(&cs[3], &static_ops, &cs3val, "palmte-cs3",
DEVICE_NATIVE_ENDIAN); OMAP_CS3_SIZE);
cpu_register_physical_memory(OMAP_CS3_BASE, OMAP_CS3_SIZE, io); memory_region_add_subregion(address_space_mem, OMAP_CS3_BASE, &cs[3]);
palmte_microwire_setup(cpu); palmte_microwire_setup(cpu);

View File

@ -448,6 +448,29 @@ static void parallel_reset(void *opaque)
static const int isa_parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc }; static const int isa_parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
static const MemoryRegionPortio isa_parallel_portio_hw_list[] = {
{ 0, 8, 1,
.read = parallel_ioport_read_hw,
.write = parallel_ioport_write_hw },
{ 4, 1, 2,
.read = parallel_ioport_eppdata_read_hw2,
.write = parallel_ioport_eppdata_write_hw2 },
{ 4, 1, 4,
.read = parallel_ioport_eppdata_read_hw4,
.write = parallel_ioport_eppdata_write_hw4 },
{ 0x400, 8, 1,
.read = parallel_ioport_ecp_read,
.write = parallel_ioport_ecp_write },
PORTIO_END_OF_LIST(),
};
static const MemoryRegionPortio isa_parallel_portio_sw_list[] = {
{ 0, 8, 1,
.read = parallel_ioport_read_sw,
.write = parallel_ioport_write_sw },
PORTIO_END_OF_LIST(),
};
static int parallel_isa_initfn(ISADevice *dev) static int parallel_isa_initfn(ISADevice *dev)
{ {
static int index; static int index;
@ -478,25 +501,11 @@ static int parallel_isa_initfn(ISADevice *dev)
s->status = dummy; s->status = dummy;
} }
if (s->hw_driver) { isa_register_portio_list(dev, base,
register_ioport_write(base, 8, 1, parallel_ioport_write_hw, s); (s->hw_driver
register_ioport_read(base, 8, 1, parallel_ioport_read_hw, s); ? &isa_parallel_portio_hw_list[0]
isa_init_ioport_range(dev, base, 8); : &isa_parallel_portio_sw_list[0]),
s, "parallel");
register_ioport_write(base+4, 1, 2, parallel_ioport_eppdata_write_hw2, s);
register_ioport_read(base+4, 1, 2, parallel_ioport_eppdata_read_hw2, s);
register_ioport_write(base+4, 1, 4, parallel_ioport_eppdata_write_hw4, s);
register_ioport_read(base+4, 1, 4, parallel_ioport_eppdata_read_hw4, s);
isa_init_ioport(dev, base+4);
register_ioport_write(base+0x400, 8, 1, parallel_ioport_ecp_write, s);
register_ioport_read(base+0x400, 8, 1, parallel_ioport_ecp_read, s);
isa_init_ioport_range(dev, base+0x400, 8);
}
else {
register_ioport_write(base, 8, 1, parallel_ioport_write_sw, s);
register_ioport_read(base, 8, 1, parallel_ioport_read_sw, s);
isa_init_ioport_range(dev, base, 8);
}
return 0; return 0;
} }

16
hw/pc.c
View File

@ -428,6 +428,7 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
/* port 92 stuff: could be split off */ /* port 92 stuff: could be split off */
typedef struct Port92State { typedef struct Port92State {
ISADevice dev; ISADevice dev;
MemoryRegion io;
uint8_t outport; uint8_t outport;
qemu_irq *a20_out; qemu_irq *a20_out;
} Port92State; } Port92State;
@ -479,13 +480,22 @@ static void port92_reset(DeviceState *d)
s->outport &= ~1; s->outport &= ~1;
} }
static const MemoryRegionPortio port92_portio[] = {
{ 0, 1, 1, .read = port92_read, .write = port92_write },
PORTIO_END_OF_LIST(),
};
static const MemoryRegionOps port92_ops = {
.old_portio = port92_portio
};
static int port92_initfn(ISADevice *dev) static int port92_initfn(ISADevice *dev)
{ {
Port92State *s = DO_UPCAST(Port92State, dev, dev); Port92State *s = DO_UPCAST(Port92State, dev, dev);
register_ioport_read(0x92, 1, 1, port92_read, s); memory_region_init_io(&s->io, &port92_ops, s, "port92", 1);
register_ioport_write(0x92, 1, 1, port92_write, s); isa_register_ioport(dev, &s->io, 0x92);
isa_init_ioport(dev, 0x92);
s->outport = 0; s->outport = 0;
return 0; return 0;
} }

View File

@ -149,8 +149,8 @@ petalogix_ml605_init(ram_addr_t ram_size,
DriveInfo *dinfo; DriveInfo *dinfo;
int i; int i;
target_phys_addr_t ddr_base = MEMORY_BASEADDR; target_phys_addr_t ddr_base = MEMORY_BASEADDR;
ram_addr_t phys_lmb_bram; MemoryRegion *phys_lmb_bram = g_new(MemoryRegion, 1);
ram_addr_t phys_ram; MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
qemu_irq irq[32], *cpu_irq; qemu_irq irq[32], *cpu_irq;
/* init CPUs */ /* init CPUs */
@ -162,13 +162,12 @@ petalogix_ml605_init(ram_addr_t ram_size,
qemu_register_reset(main_cpu_reset, env); qemu_register_reset(main_cpu_reset, env);
/* Attach emulated BRAM through the LMB. */ /* Attach emulated BRAM through the LMB. */
phys_lmb_bram = qemu_ram_alloc(NULL, "petalogix_ml605.lmb_bram", memory_region_init_ram(phys_lmb_bram, NULL, "petalogix_ml605.lmb_bram",
LMB_BRAM_SIZE); LMB_BRAM_SIZE);
cpu_register_physical_memory(0x00000000, LMB_BRAM_SIZE, memory_region_add_subregion(address_space_mem, 0x00000000, phys_lmb_bram);
phys_lmb_bram | IO_MEM_RAM);
phys_ram = qemu_ram_alloc(NULL, "petalogix_ml605.ram", ram_size); memory_region_init_ram(phys_ram, NULL, "petalogix_ml605.ram", ram_size);
cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM); memory_region_add_subregion(address_space_mem, ddr_base, phys_ram);
dinfo = drive_get(IF_PFLASH, 0, 0); dinfo = drive_get(IF_PFLASH, 0, 0);
/* 5th parameter 2 means bank-width /* 5th parameter 2 means bank-width

View File

@ -35,6 +35,7 @@
#include "loader.h" #include "loader.h"
#include "elf.h" #include "elf.h"
#include "blockdev.h" #include "blockdev.h"
#include "exec-memory.h"
#include "microblaze_pic_cpu.h" #include "microblaze_pic_cpu.h"
@ -125,9 +126,10 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
DriveInfo *dinfo; DriveInfo *dinfo;
int i; int i;
target_phys_addr_t ddr_base = 0x90000000; target_phys_addr_t ddr_base = 0x90000000;
ram_addr_t phys_lmb_bram; MemoryRegion *phys_lmb_bram = g_new(MemoryRegion, 1);
ram_addr_t phys_ram; MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
qemu_irq irq[32], *cpu_irq; qemu_irq irq[32], *cpu_irq;
MemoryRegion *sysmem = get_system_memory();
/* init CPUs */ /* init CPUs */
if (cpu_model == NULL) { if (cpu_model == NULL) {
@ -139,13 +141,13 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
qemu_register_reset(main_cpu_reset, env); qemu_register_reset(main_cpu_reset, env);
/* Attach emulated BRAM through the LMB. */ /* Attach emulated BRAM through the LMB. */
phys_lmb_bram = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.lmb_bram", memory_region_init_ram(phys_lmb_bram, NULL,
LMB_BRAM_SIZE); "petalogix_s3adsp1800.lmb_bram", LMB_BRAM_SIZE);
cpu_register_physical_memory(0x00000000, LMB_BRAM_SIZE, memory_region_add_subregion(sysmem, 0x00000000, phys_lmb_bram);
phys_lmb_bram | IO_MEM_RAM);
phys_ram = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.ram", ram_size); memory_region_init_ram(phys_ram, NULL, "petalogix_s3adsp1800.ram",
cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM); ram_size);
memory_region_add_subregion(sysmem, ddr_base, phys_ram);
dinfo = drive_get(IF_PFLASH, 0, 0); dinfo = drive_get(IF_PFLASH, 0, 0);
pflash_cfi01_register(0xa0000000, pflash_cfi01_register(0xa0000000,

View File

@ -137,16 +137,16 @@ static void ref405ep_fpga_writel (void *opaque,
ref405ep_fpga_writeb(opaque, addr + 3, value & 0xFF); ref405ep_fpga_writeb(opaque, addr + 3, value & 0xFF);
} }
static CPUReadMemoryFunc * const ref405ep_fpga_read[] = { static const MemoryRegionOps ref405ep_fpga_ops = {
&ref405ep_fpga_readb, .old_mmio = {
&ref405ep_fpga_readw, .read = {
&ref405ep_fpga_readl, ref405ep_fpga_readb, ref405ep_fpga_readw, ref405ep_fpga_readl,
}; },
.write = {
static CPUWriteMemoryFunc * const ref405ep_fpga_write[] = { ref405ep_fpga_writeb, ref405ep_fpga_writew, ref405ep_fpga_writel,
&ref405ep_fpga_writeb, },
&ref405ep_fpga_writew, },
&ref405ep_fpga_writel, .endianness = DEVICE_NATIVE_ENDIAN,
}; };
static void ref405ep_fpga_reset (void *opaque) static void ref405ep_fpga_reset (void *opaque)
@ -158,16 +158,15 @@ static void ref405ep_fpga_reset (void *opaque)
fpga->reg1 = 0x0F; fpga->reg1 = 0x0F;
} }
static void ref405ep_fpga_init (uint32_t base) static void ref405ep_fpga_init (MemoryRegion *sysmem, uint32_t base)
{ {
ref405ep_fpga_t *fpga; ref405ep_fpga_t *fpga;
int fpga_memory; MemoryRegion *fpga_memory = g_new(MemoryRegion, 1);
fpga = g_malloc0(sizeof(ref405ep_fpga_t)); fpga = g_malloc0(sizeof(ref405ep_fpga_t));
fpga_memory = cpu_register_io_memory(ref405ep_fpga_read, memory_region_init_io(fpga_memory, &ref405ep_fpga_ops, fpga,
ref405ep_fpga_write, fpga, "fpga", 0x00000100);
DEVICE_NATIVE_ENDIAN); memory_region_add_subregion(sysmem, base, fpga_memory);
cpu_register_physical_memory(base, 0x00000100, fpga_memory);
qemu_register_reset(&ref405ep_fpga_reset, fpga); qemu_register_reset(&ref405ep_fpga_reset, fpga);
} }
@ -183,7 +182,8 @@ static void ref405ep_init (ram_addr_t ram_size,
CPUPPCState *env; CPUPPCState *env;
qemu_irq *pic; qemu_irq *pic;
MemoryRegion *bios; MemoryRegion *bios;
ram_addr_t sram_offset, bdloc; MemoryRegion *sram = g_new(MemoryRegion, 1);
ram_addr_t bdloc;
MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories)); MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
target_phys_addr_t ram_bases[2], ram_sizes[2]; target_phys_addr_t ram_bases[2], ram_sizes[2];
target_ulong sram_size; target_ulong sram_size;
@ -195,6 +195,7 @@ static void ref405ep_init (ram_addr_t ram_size,
int linux_boot; int linux_boot;
int fl_idx, fl_sectors, len; int fl_idx, fl_sectors, len;
DriveInfo *dinfo; DriveInfo *dinfo;
MemoryRegion *sysmem = get_system_memory();
/* XXX: fix this */ /* XXX: fix this */
memory_region_init_ram(&ram_memories[0], NULL, "ef405ep.ram", 0x08000000); memory_region_init_ram(&ram_memories[0], NULL, "ef405ep.ram", 0x08000000);
@ -207,17 +208,12 @@ static void ref405ep_init (ram_addr_t ram_size,
#ifdef DEBUG_BOARD_INIT #ifdef DEBUG_BOARD_INIT
printf("%s: register cpu\n", __func__); printf("%s: register cpu\n", __func__);
#endif #endif
env = ppc405ep_init(get_system_memory(), ram_memories, ram_bases, ram_sizes, env = ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes,
33333333, &pic, kernel_filename == NULL ? 0 : 1); 33333333, &pic, kernel_filename == NULL ? 0 : 1);
/* allocate SRAM */ /* allocate SRAM */
sram_size = 512 * 1024; sram_size = 512 * 1024;
sram_offset = qemu_ram_alloc(NULL, "ef405ep.sram", sram_size); memory_region_init_ram(sram, NULL, "ef405ep.sram", sram_size);
#ifdef DEBUG_BOARD_INIT memory_region_add_subregion(sysmem, 0xFFF00000, sram);
printf("%s: register SRAM at offset " RAM_ADDR_FMT "\n",
__func__, sram_offset);
#endif
cpu_register_physical_memory(0xFFF00000, sram_size,
sram_offset | IO_MEM_RAM);
/* allocate and load BIOS */ /* allocate and load BIOS */
#ifdef DEBUG_BOARD_INIT #ifdef DEBUG_BOARD_INIT
printf("%s: register BIOS\n", __func__); printf("%s: register BIOS\n", __func__);
@ -264,14 +260,13 @@ static void ref405ep_init (ram_addr_t ram_size,
} }
bios_size = (bios_size + 0xfff) & ~0xfff; bios_size = (bios_size + 0xfff) & ~0xfff;
memory_region_set_readonly(bios, true); memory_region_set_readonly(bios, true);
memory_region_add_subregion(get_system_memory(), memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
(uint32_t)(-bios_size), bios);
} }
/* Register FPGA */ /* Register FPGA */
#ifdef DEBUG_BOARD_INIT #ifdef DEBUG_BOARD_INIT
printf("%s: register FPGA\n", __func__); printf("%s: register FPGA\n", __func__);
#endif #endif
ref405ep_fpga_init(0xF0300000); ref405ep_fpga_init(sysmem, 0xF0300000);
/* Register NVRAM */ /* Register NVRAM */
#ifdef DEBUG_BOARD_INIT #ifdef DEBUG_BOARD_INIT
printf("%s: register NVRAM\n", __func__); printf("%s: register NVRAM\n", __func__);
@ -469,16 +464,12 @@ static void taihu_cpld_writel (void *opaque,
taihu_cpld_writeb(opaque, addr + 3, value & 0xFF); taihu_cpld_writeb(opaque, addr + 3, value & 0xFF);
} }
static CPUReadMemoryFunc * const taihu_cpld_read[] = { static const MemoryRegionOps taihu_cpld_ops = {
&taihu_cpld_readb, .old_mmio = {
&taihu_cpld_readw, .read = { taihu_cpld_readb, taihu_cpld_readw, taihu_cpld_readl, },
&taihu_cpld_readl, .write = { taihu_cpld_writeb, taihu_cpld_writew, taihu_cpld_writel, },
}; },
.endianness = DEVICE_NATIVE_ENDIAN,
static CPUWriteMemoryFunc * const taihu_cpld_write[] = {
&taihu_cpld_writeb,
&taihu_cpld_writew,
&taihu_cpld_writel,
}; };
static void taihu_cpld_reset (void *opaque) static void taihu_cpld_reset (void *opaque)
@ -490,16 +481,14 @@ static void taihu_cpld_reset (void *opaque)
cpld->reg1 = 0x80; cpld->reg1 = 0x80;
} }
static void taihu_cpld_init (uint32_t base) static void taihu_cpld_init (MemoryRegion *sysmem, uint32_t base)
{ {
taihu_cpld_t *cpld; taihu_cpld_t *cpld;
int cpld_memory; MemoryRegion *cpld_memory = g_new(MemoryRegion, 1);
cpld = g_malloc0(sizeof(taihu_cpld_t)); cpld = g_malloc0(sizeof(taihu_cpld_t));
cpld_memory = cpu_register_io_memory(taihu_cpld_read, memory_region_init_io(cpld_memory, &taihu_cpld_ops, cpld, "cpld", 0x100);
taihu_cpld_write, cpld, memory_region_add_subregion(sysmem, base, cpld_memory);
DEVICE_NATIVE_ENDIAN);
cpu_register_physical_memory(base, 0x00000100, cpld_memory);
qemu_register_reset(&taihu_cpld_reset, cpld); qemu_register_reset(&taihu_cpld_reset, cpld);
} }
@ -512,6 +501,7 @@ static void taihu_405ep_init(ram_addr_t ram_size,
{ {
char *filename; char *filename;
qemu_irq *pic; qemu_irq *pic;
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *bios; MemoryRegion *bios;
MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories)); MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
target_phys_addr_t ram_bases[2], ram_sizes[2]; target_phys_addr_t ram_bases[2], ram_sizes[2];
@ -535,7 +525,7 @@ static void taihu_405ep_init(ram_addr_t ram_size,
#ifdef DEBUG_BOARD_INIT #ifdef DEBUG_BOARD_INIT
printf("%s: register cpu\n", __func__); printf("%s: register cpu\n", __func__);
#endif #endif
ppc405ep_init(get_system_memory(), ram_memories, ram_bases, ram_sizes, ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes,
33333333, &pic, kernel_filename == NULL ? 0 : 1); 33333333, &pic, kernel_filename == NULL ? 0 : 1);
/* allocate and load BIOS */ /* allocate and load BIOS */
#ifdef DEBUG_BOARD_INIT #ifdef DEBUG_BOARD_INIT
@ -585,8 +575,7 @@ static void taihu_405ep_init(ram_addr_t ram_size,
} }
bios_size = (bios_size + 0xfff) & ~0xfff; bios_size = (bios_size + 0xfff) & ~0xfff;
memory_region_set_readonly(bios, true); memory_region_set_readonly(bios, true);
memory_region_add_subregion(get_system_memory(), (uint32_t)(-bios_size), memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
bios);
} }
/* Register Linux flash */ /* Register Linux flash */
dinfo = drive_get(IF_PFLASH, 0, fl_idx); dinfo = drive_get(IF_PFLASH, 0, fl_idx);
@ -611,7 +600,7 @@ static void taihu_405ep_init(ram_addr_t ram_size,
#ifdef DEBUG_BOARD_INIT #ifdef DEBUG_BOARD_INIT
printf("%s: register CPLD\n", __func__); printf("%s: register CPLD\n", __func__);
#endif #endif
taihu_cpld_init(0x50100000); taihu_cpld_init(sysmem, 0x50100000);
/* Load kernel */ /* Load kernel */
linux_boot = (kernel_filename != NULL); linux_boot = (kernel_filename != NULL);
if (linux_boot) { if (linux_boot) {

View File

@ -84,12 +84,13 @@
#endif #endif
/* UniN device */ /* UniN device */
static void unin_writel (void *opaque, target_phys_addr_t addr, uint32_t value) static void unin_write(void *opaque, target_phys_addr_t addr, uint64_t value,
unsigned size)
{ {
UNIN_DPRINTF("writel addr " TARGET_FMT_plx " val %x\n", addr, value); UNIN_DPRINTF("write addr " TARGET_FMT_plx " val %"PRIx64"\n", addr, value);
} }
static uint32_t unin_readl (void *opaque, target_phys_addr_t addr) static uint64_t unin_read(void *opaque, target_phys_addr_t addr, unsigned size)
{ {
uint32_t value; uint32_t value;
@ -99,16 +100,10 @@ static uint32_t unin_readl (void *opaque, target_phys_addr_t addr)
return value; return value;
} }
static CPUWriteMemoryFunc * const unin_write[] = { static const MemoryRegionOps unin_ops = {
&unin_writel, .read = unin_read,
&unin_writel, .write = unin_write,
&unin_writel, .endianness = DEVICE_NATIVE_ENDIAN,
};
static CPUReadMemoryFunc * const unin_read[] = {
&unin_readl,
&unin_readl,
&unin_readl,
}; };
static int fw_cfg_boot_set(void *opaque, const char *boot_device) static int fw_cfg_boot_set(void *opaque, const char *boot_device)
@ -138,9 +133,9 @@ static void ppc_core99_init (ram_addr_t ram_size,
CPUState *env = NULL; CPUState *env = NULL;
char *filename; char *filename;
qemu_irq *pic, **openpic_irqs; qemu_irq *pic, **openpic_irqs;
int unin_memory; MemoryRegion *unin_memory = g_new(MemoryRegion, 1);
int linux_boot, i; int linux_boot, i;
ram_addr_t ram_offset, bios_offset; MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1);
target_phys_addr_t kernel_base, initrd_base, cmdline_base = 0; target_phys_addr_t kernel_base, initrd_base, cmdline_base = 0;
long kernel_size, initrd_size; long kernel_size, initrd_size;
PCIBus *pci_bus; PCIBus *pci_bus;
@ -176,15 +171,16 @@ static void ppc_core99_init (ram_addr_t ram_size,
} }
/* allocate RAM */ /* allocate RAM */
ram_offset = qemu_ram_alloc(NULL, "ppc_core99.ram", ram_size); memory_region_init_ram(ram, NULL, "ppc_core99.ram", ram_size);
cpu_register_physical_memory(0, ram_size, ram_offset); memory_region_add_subregion(get_system_memory(), 0, ram);
/* allocate and load BIOS */ /* allocate and load BIOS */
bios_offset = qemu_ram_alloc(NULL, "ppc_core99.bios", BIOS_SIZE); memory_region_init_ram(bios, NULL, "ppc_core99.bios", BIOS_SIZE);
if (bios_name == NULL) if (bios_name == NULL)
bios_name = PROM_FILENAME; bios_name = PROM_FILENAME;
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
cpu_register_physical_memory(PROM_ADDR, BIOS_SIZE, bios_offset | IO_MEM_ROM); memory_region_set_readonly(bios, true);
memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios);
/* Load OpenBIOS (ELF) */ /* Load OpenBIOS (ELF) */
if (filename) { if (filename) {
@ -267,9 +263,8 @@ static void ppc_core99_init (ram_addr_t ram_size,
isa_mmio_init(0xf2000000, 0x00800000); isa_mmio_init(0xf2000000, 0x00800000);
/* UniN init */ /* UniN init */
unin_memory = cpu_register_io_memory(unin_read, unin_write, NULL, memory_region_init_io(unin_memory, &unin_ops, NULL, "unin", 0x1000);
DEVICE_NATIVE_ENDIAN); memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory);
cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory);
openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
openpic_irqs[0] = openpic_irqs[0] =

View File

@ -1601,7 +1601,7 @@ static int qxl_init_primary(PCIDevice *dev)
ram_size = 32 * 1024 * 1024; ram_size = 32 * 1024 * 1024;
} }
vga_common_init(vga, ram_size); vga_common_init(vga, ram_size);
vga_init(vga, pci_address_space(dev)); vga_init(vga, pci_address_space(dev), pci_address_space_io(dev), false);
register_ioport_write(0x3c0, 16, 1, qxl_vga_ioport_write, vga); register_ioport_write(0x3c0, 16, 1, qxl_vga_ioport_write, vga);
register_ioport_write(0x3b4, 2, 1, qxl_vga_ioport_write, vga); register_ioport_write(0x3b4, 2, 1, qxl_vga_ioport_write, vga);
register_ioport_write(0x3d4, 2, 1, qxl_vga_ioport_write, vga); register_ioport_write(0x3d4, 2, 1, qxl_vga_ioport_write, vga);

View File

@ -272,8 +272,16 @@ static void realview_init(ram_addr_t ram_size,
sysbus_create_simple("pl031", 0x10017000, pic[10]); sysbus_create_simple("pl031", 0x10017000, pic[10]);
if (!is_pb) { if (!is_pb) {
dev = sysbus_create_varargs("realview_pci", 0x60000000, dev = qdev_create(NULL, "realview_pci");
pic[48], pic[49], pic[50], pic[51], NULL); busdev = sysbus_from_qdev(dev);
qdev_init_nofail(dev);
sysbus_mmio_map(busdev, 0, 0x61000000); /* PCI self-config */
sysbus_mmio_map(busdev, 1, 0x62000000); /* PCI config */
sysbus_mmio_map(busdev, 2, 0x63000000); /* PCI I/O */
sysbus_connect_irq(busdev, 0, pic[48]);
sysbus_connect_irq(busdev, 1, pic[49]);
sysbus_connect_irq(busdev, 2, pic[50]);
sysbus_connect_irq(busdev, 3, pic[51]);
pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci"); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
if (usb_enabled) { if (usb_enabled) {
usb_ohci_init_pci(pci_bus, -1); usb_ohci_init_pci(pci_bus, -1);

View File

@ -1341,12 +1341,21 @@ static const VMStateDescription vmstate_sb16 = {
} }
}; };
static const MemoryRegionPortio sb16_ioport_list[] = {
{ 4, 1, 1, .write = mixer_write_indexb },
{ 4, 1, 2, .write = mixer_write_indexw },
{ 5, 1, 1, .read = mixer_read, .write = mixer_write_datab },
{ 6, 1, 1, .read = dsp_read, .write = dsp_write },
{ 10, 1, 1, .read = dsp_read },
{ 12, 1, 1, .write = dsp_write },
{ 12, 4, 1, .read = dsp_read },
PORTIO_END_OF_LIST(),
};
static int sb16_initfn (ISADevice *dev) static int sb16_initfn (ISADevice *dev)
{ {
static const uint8_t dsp_write_ports[] = {0x6, 0xc};
static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
SB16State *s; SB16State *s;
int i;
s = DO_UPCAST (SB16State, dev, dev); s = DO_UPCAST (SB16State, dev, dev);
@ -1366,22 +1375,7 @@ static int sb16_initfn (ISADevice *dev)
dolog ("warning: Could not create auxiliary timer\n"); dolog ("warning: Could not create auxiliary timer\n");
} }
for (i = 0; i < ARRAY_SIZE (dsp_write_ports); i++) { isa_register_portio_list (dev, s->port, sb16_ioport_list, s, "sb16");
register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
isa_init_ioport (dev, s->port + dsp_write_ports[i]);
}
for (i = 0; i < ARRAY_SIZE (dsp_read_ports); i++) {
register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
isa_init_ioport (dev, s->port + dsp_read_ports[i]);
}
register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
isa_init_ioport (dev, s->port + 0x4);
register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
isa_init_ioport (dev, s->port + 0x5);
DMA_register_channel (s->hdma, SB_read_DMA, s); DMA_register_channel (s->hdma, SB_read_DMA, s);
DMA_register_channel (s->dma, SB_read_DMA, s); DMA_register_channel (s->dma, SB_read_DMA, s);

View File

@ -58,38 +58,6 @@ static void pci_vpb_set_irq(void *opaque, int irq_num, int level)
qemu_set_irq(pic[irq_num], level); qemu_set_irq(pic[irq_num], level);
} }
static void pci_vpb_map(SysBusDevice *dev, target_phys_addr_t base)
{
PCIVPBState *s = (PCIVPBState *)dev;
/* Selfconfig area. */
memory_region_add_subregion(get_system_memory(), base + 0x01000000,
&s->mem_config);
/* Normal config area. */
memory_region_add_subregion(get_system_memory(), base + 0x02000000,
&s->mem_config2);
if (s->realview) {
/* IO memory area. */
memory_region_add_subregion(get_system_memory(), base + 0x03000000,
&s->isa);
}
}
static void pci_vpb_unmap(SysBusDevice *dev, target_phys_addr_t base)
{
PCIVPBState *s = (PCIVPBState *)dev;
/* Selfconfig area. */
memory_region_del_subregion(get_system_memory(), &s->mem_config);
/* Normal config area. */
memory_region_del_subregion(get_system_memory(), &s->mem_config2);
if (s->realview) {
/* IO memory area. */
memory_region_del_subregion(get_system_memory(), &s->isa);
}
}
static int pci_vpb_init(SysBusDevice *dev) static int pci_vpb_init(SysBusDevice *dev)
{ {
PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev); PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev);
@ -106,16 +74,22 @@ static int pci_vpb_init(SysBusDevice *dev)
/* ??? Register memory space. */ /* ??? Register memory space. */
/* Our memory regions are:
* 0 : PCI self config window
* 1 : PCI config window
* 2 : PCI IO window (realview_pci only)
*/
memory_region_init_io(&s->mem_config, &pci_vpb_config_ops, bus, memory_region_init_io(&s->mem_config, &pci_vpb_config_ops, bus,
"pci-vpb-selfconfig", 0x1000000); "pci-vpb-selfconfig", 0x1000000);
sysbus_init_mmio_region(dev, &s->mem_config);
memory_region_init_io(&s->mem_config2, &pci_vpb_config_ops, bus, memory_region_init_io(&s->mem_config2, &pci_vpb_config_ops, bus,
"pci-vpb-config", 0x1000000); "pci-vpb-config", 0x1000000);
sysbus_init_mmio_region(dev, &s->mem_config2);
if (s->realview) { if (s->realview) {
isa_mmio_setup(&s->isa, 0x0100000); isa_mmio_setup(&s->isa, 0x0100000);
sysbus_init_mmio_region(dev, &s->isa);
} }
sysbus_init_mmio_cb2(dev, pci_vpb_map, pci_vpb_unmap);
pci_create_simple(bus, -1, "versatile_pci_host"); pci_create_simple(bus, -1, "versatile_pci_host");
return 0; return 0;
} }

View File

@ -181,6 +181,7 @@ static void versatile_init(ram_addr_t ram_size,
qemu_irq pic[32]; qemu_irq pic[32];
qemu_irq sic[32]; qemu_irq sic[32];
DeviceState *dev, *sysctl; DeviceState *dev, *sysctl;
SysBusDevice *busdev;
PCIBus *pci_bus; PCIBus *pci_bus;
NICInfo *nd; NICInfo *nd;
int n; int n;
@ -219,8 +220,15 @@ static void versatile_init(ram_addr_t ram_size,
sysbus_create_simple("pl050_keyboard", 0x10006000, sic[3]); sysbus_create_simple("pl050_keyboard", 0x10006000, sic[3]);
sysbus_create_simple("pl050_mouse", 0x10007000, sic[4]); sysbus_create_simple("pl050_mouse", 0x10007000, sic[4]);
dev = sysbus_create_varargs("versatile_pci", 0x40000000, dev = qdev_create(NULL, "versatile_pci");
sic[27], sic[28], sic[29], sic[30], NULL); busdev = sysbus_from_qdev(dev);
qdev_init_nofail(dev);
sysbus_mmio_map(busdev, 0, 0x41000000); /* PCI self-config */
sysbus_mmio_map(busdev, 1, 0x42000000); /* PCI config */
sysbus_connect_irq(busdev, 0, sic[27]);
sysbus_connect_irq(busdev, 1, sic[28]);
sysbus_connect_irq(busdev, 2, sic[29]);
sysbus_connect_irq(busdev, 3, sic[30]);
pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci"); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
/* The Versatile PCI bridge does not provide access to PCI IO space, /* The Versatile PCI bridge does not provide access to PCI IO space,

View File

@ -47,24 +47,19 @@ static int vga_initfn(ISADevice *dev)
ISAVGAState *d = DO_UPCAST(ISAVGAState, dev, dev); ISAVGAState *d = DO_UPCAST(ISAVGAState, dev, dev);
VGACommonState *s = &d->state; VGACommonState *s = &d->state;
MemoryRegion *vga_io_memory; MemoryRegion *vga_io_memory;
const MemoryRegionPortio *vga_ports, *vbe_ports;
vga_common_init(s, VGA_RAM_SIZE); vga_common_init(s, VGA_RAM_SIZE);
s->legacy_address_space = isa_address_space(dev); s->legacy_address_space = isa_address_space(dev);
vga_io_memory = vga_init_io(s); vga_io_memory = vga_init_io(s, &vga_ports, &vbe_ports);
isa_register_portio_list(dev, 0x3b0, vga_ports, s, "vga");
if (vbe_ports) {
isa_register_portio_list(dev, 0x1ce, vbe_ports, s, "vbe");
}
memory_region_add_subregion_overlap(isa_address_space(dev), memory_region_add_subregion_overlap(isa_address_space(dev),
isa_mem_base + 0x000a0000, isa_mem_base + 0x000a0000,
vga_io_memory, 1); vga_io_memory, 1);
memory_region_set_coalescing(vga_io_memory); memory_region_set_coalescing(vga_io_memory);
isa_init_ioport(dev, 0x3c0);
isa_init_ioport(dev, 0x3b4);
isa_init_ioport(dev, 0x3ba);
isa_init_ioport(dev, 0x3da);
isa_init_ioport(dev, 0x3c0);
#ifdef CONFIG_BOCHS_VBE
isa_init_ioport(dev, 0x1ce);
isa_init_ioport(dev, 0x1cf);
isa_init_ioport(dev, 0x1d0);
#endif /* CONFIG_BOCHS_VBE */
s->ds = graphic_console_init(s->update, s->invalidate, s->ds = graphic_console_init(s->update, s->invalidate,
s->screen_dump, s->text_update, s); s->screen_dump, s->text_update, s);

View File

@ -54,7 +54,7 @@ static int pci_vga_initfn(PCIDevice *dev)
// vga + console init // vga + console init
vga_common_init(s, VGA_RAM_SIZE); vga_common_init(s, VGA_RAM_SIZE);
vga_init(s, pci_address_space(dev)); vga_init(s, pci_address_space(dev), pci_address_space_io(dev), true);
s->ds = graphic_console_init(s->update, s->invalidate, s->ds = graphic_console_init(s->update, s->invalidate,
s->screen_dump, s->text_update, s); s->screen_dump, s->text_update, s);

View File

@ -2241,40 +2241,39 @@ void vga_common_init(VGACommonState *s, int vga_ram_size)
vga_dirty_log_start(s); vga_dirty_log_start(s);
} }
/* used by both ISA and PCI */ static const MemoryRegionPortio vga_portio_list[] = {
MemoryRegion *vga_init_io(VGACommonState *s) { 0x04, 2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */
{ 0x0a, 1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */
{ 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */
{ 0x24, 2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */
{ 0x2a, 1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */
PORTIO_END_OF_LIST(),
};
#ifdef CONFIG_BOCHS_VBE
static const MemoryRegionPortio vbe_portio_list[] = {
{ 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
# ifdef TARGET_I386
{ 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
# else
{ 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
# endif
PORTIO_END_OF_LIST(),
};
#endif /* CONFIG_BOCHS_VBE */
/* Used by both ISA and PCI */
MemoryRegion *vga_init_io(VGACommonState *s,
const MemoryRegionPortio **vga_ports,
const MemoryRegionPortio **vbe_ports)
{ {
MemoryRegion *vga_mem; MemoryRegion *vga_mem;
register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s); *vga_ports = vga_portio_list;
*vbe_ports = NULL;
register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s);
register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s);
register_ioport_write(0x3da, 1, 1, vga_ioport_write, s);
register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s);
register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s);
register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s);
register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
#ifdef CONFIG_BOCHS_VBE #ifdef CONFIG_BOCHS_VBE
#if defined (TARGET_I386) *vbe_ports = vbe_portio_list;
register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
register_ioport_read(0x1cf, 1, 2, vbe_ioport_read_data, s);
register_ioport_write(0x1ce, 1, 2, vbe_ioport_write_index, s);
register_ioport_write(0x1cf, 1, 2, vbe_ioport_write_data, s);
#else
register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
register_ioport_read(0x1d0, 1, 2, vbe_ioport_read_data, s);
register_ioport_write(0x1ce, 1, 2, vbe_ioport_write_index, s);
register_ioport_write(0x1d0, 1, 2, vbe_ioport_write_data, s);
#endif #endif
#endif /* CONFIG_BOCHS_VBE */
vga_mem = g_malloc(sizeof(*vga_mem)); vga_mem = g_malloc(sizeof(*vga_mem));
memory_region_init_io(vga_mem, &vga_mem_ops, s, memory_region_init_io(vga_mem, &vga_mem_ops, s,
@ -2283,9 +2282,13 @@ MemoryRegion *vga_init_io(VGACommonState *s)
return vga_mem; return vga_mem;
} }
void vga_init(VGACommonState *s, MemoryRegion *address_space) void vga_init(VGACommonState *s, MemoryRegion *address_space,
MemoryRegion *address_space_io, bool init_vga_ports)
{ {
MemoryRegion *vga_io_memory; MemoryRegion *vga_io_memory;
const MemoryRegionPortio *vga_ports, *vbe_ports;
PortioList *vga_port_list = g_new(PortioList, 1);
PortioList *vbe_port_list = g_new(PortioList, 1);
qemu_register_reset(vga_reset, s); qemu_register_reset(vga_reset, s);
@ -2293,12 +2296,20 @@ void vga_init(VGACommonState *s, MemoryRegion *address_space)
s->legacy_address_space = address_space; s->legacy_address_space = address_space;
vga_io_memory = vga_init_io(s); vga_io_memory = vga_init_io(s, &vga_ports, &vbe_ports);
memory_region_add_subregion_overlap(address_space, memory_region_add_subregion_overlap(address_space,
isa_mem_base + 0x000a0000, isa_mem_base + 0x000a0000,
vga_io_memory, vga_io_memory,
1); 1);
memory_region_set_coalescing(vga_io_memory); memory_region_set_coalescing(vga_io_memory);
if (init_vga_ports) {
portio_list_init(vga_port_list, vga_ports, s, "vga");
portio_list_add(vga_port_list, address_space_io, 0x3b0);
}
if (vbe_ports) {
portio_list_init(vbe_port_list, vbe_ports, s, "vbe");
portio_list_add(vbe_port_list, address_space_io, 0x1ce);
}
} }
void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory) void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)

View File

@ -187,8 +187,11 @@ static inline int c6_to_8(int v)
} }
void vga_common_init(VGACommonState *s, int vga_ram_size); void vga_common_init(VGACommonState *s, int vga_ram_size);
void vga_init(VGACommonState *s, MemoryRegion *address_space); void vga_init(VGACommonState *s, MemoryRegion *address_space,
MemoryRegion *vga_init_io(VGACommonState *s); MemoryRegion *address_space_io, bool init_vga_ports);
MemoryRegion *vga_init_io(VGACommonState *s,
const MemoryRegionPortio **vga_ports,
const MemoryRegionPortio **vbe_ports);
void vga_common_reset(VGACommonState *s); void vga_common_reset(VGACommonState *s);
void vga_dirty_log_start(VGACommonState *s); void vga_dirty_log_start(VGACommonState *s);

View File

@ -38,6 +38,7 @@
typedef struct _VMPortState typedef struct _VMPortState
{ {
ISADevice dev; ISADevice dev;
MemoryRegion io;
IOPortReadFunc *func[VMPORT_ENTRIES]; IOPortReadFunc *func[VMPORT_ENTRIES];
void *opaque[VMPORT_ENTRIES]; void *opaque[VMPORT_ENTRIES];
} VMPortState; } VMPortState;
@ -120,13 +121,22 @@ void vmmouse_set_data(const uint32_t *data)
env->regs[R_ESI] = data[4]; env->regs[R_EDI] = data[5]; env->regs[R_ESI] = data[4]; env->regs[R_EDI] = data[5];
} }
static const MemoryRegionPortio vmport_portio[] = {
{0, 1, 4, .read = vmport_ioport_read, .write = vmport_ioport_write },
PORTIO_END_OF_LIST(),
};
static const MemoryRegionOps vmport_ops = {
.old_portio = vmport_portio
};
static int vmport_initfn(ISADevice *dev) static int vmport_initfn(ISADevice *dev)
{ {
VMPortState *s = DO_UPCAST(VMPortState, dev, dev); VMPortState *s = DO_UPCAST(VMPortState, dev, dev);
register_ioport_read(0x5658, 1, 4, vmport_ioport_read, s); memory_region_init_io(&s->io, &vmport_ops, s, "vmport", 1);
register_ioport_write(0x5658, 1, 4, vmport_ioport_write, s); isa_register_ioport(dev, &s->io, 0x5658);
isa_init_ioport(dev, 0x5658);
port_state = s; port_state = s;
/* Register some generic port commands */ /* Register some generic port commands */
vmport_register(VMPORT_CMD_GETVERSION, vmport_cmd_get_version, NULL); vmport_register(VMPORT_CMD_GETVERSION, vmport_cmd_get_version, NULL);

View File

@ -1079,7 +1079,7 @@ static const VMStateDescription vmstate_vmware_vga = {
}; };
static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size, static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size,
MemoryRegion *address_space) MemoryRegion *address_space, MemoryRegion *io)
{ {
s->scratch_size = SVGA_SCRATCH_SIZE; s->scratch_size = SVGA_SCRATCH_SIZE;
s->scratch = g_malloc(s->scratch_size * 4); s->scratch = g_malloc(s->scratch_size * 4);
@ -1095,7 +1095,7 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size,
s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram); s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram);
vga_common_init(&s->vga, vga_ram_size); vga_common_init(&s->vga, vga_ram_size);
vga_init(&s->vga, address_space); vga_init(&s->vga, address_space, io, true);
vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga); vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga);
s->depth = ds_get_bits_per_pixel(s->vga.ds); s->depth = ds_get_bits_per_pixel(s->vga.ds);
@ -1183,7 +1183,8 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
"vmsvga-io", 0x10); "vmsvga-io", 0x10);
pci_register_bar(&s->card, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar); pci_register_bar(&s->card, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
vmsvga_init(&s->chip, VGA_RAM_SIZE, pci_address_space(dev)); vmsvga_init(&s->chip, VGA_RAM_SIZE, pci_address_space(dev),
pci_address_space_io(dev));
pci_register_bar(&s->card, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, iomem); pci_register_bar(&s->card, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, iomem);
pci_register_bar(&s->card, 2, PCI_BASE_ADDRESS_MEM_PREFETCH, pci_register_bar(&s->card, 2, PCI_BASE_ADDRESS_MEM_PREFETCH,

108
ioport.c
View File

@ -27,6 +27,7 @@
#include "ioport.h" #include "ioport.h"
#include "trace.h" #include "trace.h"
#include "memory.h"
/***********************************************************/ /***********************************************************/
/* IO Port */ /* IO Port */
@ -313,3 +314,110 @@ uint32_t cpu_inl(pio_addr_t addr)
LOG_IOPORT("inl : %04"FMT_pioaddr" %08"PRIx32"\n", addr, val); LOG_IOPORT("inl : %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);
return val; return val;
} }
void portio_list_init(PortioList *piolist,
const MemoryRegionPortio *callbacks,
void *opaque, const char *name)
{
unsigned n = 0;
while (callbacks[n].size) {
++n;
}
piolist->ports = callbacks;
piolist->nr = 0;
piolist->regions = g_new0(MemoryRegion *, n);
piolist->address_space = NULL;
piolist->opaque = opaque;
piolist->name = name;
}
void portio_list_destroy(PortioList *piolist)
{
g_free(piolist->regions);
}
static void portio_list_add_1(PortioList *piolist,
const MemoryRegionPortio *pio_init,
unsigned count, unsigned start,
unsigned off_low, unsigned off_high)
{
MemoryRegionPortio *pio;
MemoryRegionOps *ops;
MemoryRegion *region;
unsigned i;
/* Copy the sub-list and null-terminate it. */
pio = g_new(MemoryRegionPortio, count + 1);
memcpy(pio, pio_init, sizeof(MemoryRegionPortio) * count);
memset(pio + count, 0, sizeof(MemoryRegionPortio));
/* Adjust the offsets to all be zero-based for the region. */
for (i = 0; i < count; ++i) {
pio[i].offset -= off_low;
}
ops = g_new0(MemoryRegionOps, 1);
ops->old_portio = pio;
region = g_new(MemoryRegion, 1);
memory_region_init_io(region, ops, piolist->opaque, piolist->name,
off_high - off_low);
memory_region_set_offset(region, start + off_low);
memory_region_add_subregion(piolist->address_space,
start + off_low, region);
piolist->regions[piolist->nr++] = region;
}
void portio_list_add(PortioList *piolist,
MemoryRegion *address_space,
uint32_t start)
{
const MemoryRegionPortio *pio, *pio_start = piolist->ports;
unsigned int off_low, off_high, off_last, count;
piolist->address_space = address_space;
/* Handle the first entry specially. */
off_last = off_low = pio_start->offset;
off_high = off_low + pio_start->len;
count = 1;
for (pio = pio_start + 1; pio->size != 0; pio++, count++) {
/* All entries must be sorted by offset. */
assert(pio->offset >= off_last);
off_last = pio->offset;
/* If we see a hole, break the region. */
if (off_last > off_high) {
portio_list_add_1(piolist, pio_start, count, start, off_low,
off_high);
/* ... and start collecting anew. */
pio_start = pio;
off_low = off_last;
off_high = off_low + pio->len;
count = 0;
} else if (off_last + pio->len > off_high) {
off_high = off_last + pio->len;
}
}
/* There will always be an open sub-list. */
portio_list_add_1(piolist, pio_start, count, start, off_low, off_high);
}
void portio_list_del(PortioList *piolist)
{
MemoryRegion *mr;
unsigned i;
for (i = 0; i < piolist->nr; ++i) {
mr = piolist->regions[i];
memory_region_del_subregion(piolist->address_space, mr);
memory_region_destroy(mr);
g_free((MemoryRegionOps *)mr->ops);
g_free(mr);
piolist->regions[i] = NULL;
}
}

View File

@ -52,4 +52,25 @@ uint8_t cpu_inb(pio_addr_t addr);
uint16_t cpu_inw(pio_addr_t addr); uint16_t cpu_inw(pio_addr_t addr);
uint32_t cpu_inl(pio_addr_t addr); uint32_t cpu_inl(pio_addr_t addr);
struct MemoryRegion;
struct MemoryRegionPortio;
typedef struct PortioList {
const struct MemoryRegionPortio *ports;
struct MemoryRegion *address_space;
unsigned nr;
struct MemoryRegion **regions;
void *opaque;
const char *name;
} PortioList;
void portio_list_init(PortioList *piolist,
const struct MemoryRegionPortio *callbacks,
void *opaque, const char *name);
void portio_list_destroy(PortioList *piolist);
void portio_list_add(PortioList *piolist,
struct MemoryRegion *address_space,
uint32_t addr);
void portio_list_del(PortioList *piolist);
#endif /* IOPORT_H */ #endif /* IOPORT_H */

View File

@ -403,12 +403,17 @@ static void memory_region_iorange_read(IORange *iorange,
*data = ((uint64_t)1 << (width * 8)) - 1; *data = ((uint64_t)1 << (width * 8)) - 1;
if (mrp) { if (mrp) {
*data = mrp->read(mr->opaque, offset); *data = mrp->read(mr->opaque, offset + mr->offset);
} else if (width == 2) {
mrp = find_portio(mr, offset, 1, false);
assert(mrp);
*data = mrp->read(mr->opaque, offset + mr->offset) |
(mrp->read(mr->opaque, offset + mr->offset + 1) << 8);
} }
return; return;
} }
*data = 0; *data = 0;
access_with_adjusted_size(offset, data, width, access_with_adjusted_size(offset + mr->offset, data, width,
mr->ops->impl.min_access_size, mr->ops->impl.min_access_size,
mr->ops->impl.max_access_size, mr->ops->impl.max_access_size,
memory_region_read_accessor, mr); memory_region_read_accessor, mr);
@ -425,11 +430,16 @@ static void memory_region_iorange_write(IORange *iorange,
const MemoryRegionPortio *mrp = find_portio(mr, offset, width, true); const MemoryRegionPortio *mrp = find_portio(mr, offset, width, true);
if (mrp) { if (mrp) {
mrp->write(mr->opaque, offset, data); mrp->write(mr->opaque, offset + mr->offset, data);
} else if (width == 2) {
mrp = find_portio(mr, offset, 1, false);
assert(mrp);
mrp->write(mr->opaque, offset + mr->offset, data & 0xff);
mrp->write(mr->opaque, offset + mr->offset + 1, data >> 8);
} }
return; return;
} }
access_with_adjusted_size(offset, &data, width, access_with_adjusted_size(offset + mr->offset, &data, width,
mr->ops->impl.min_access_size, mr->ops->impl.min_access_size,
mr->ops->impl.max_access_size, mr->ops->impl.max_access_size,
memory_region_write_accessor, mr); memory_region_write_accessor, mr);