提交 4cdd2e66 编写于 作者: B Blue Swirl

Merge branch 'memory-ioport' of git://github.com/afaerber/qemu-cpu

* 'memory-ioport' of git://github.com/afaerber/qemu-cpu:
  hw/dma.c: Replace register_ioport_*
  hw/pc.c: Replace register_ioport_*
  serial: Replace register_ioport_*
  hw/cirrus_vga.c: Replace register_ioport_*
  hw/apm.c: Replace register_ioport_*
  isa: Add isa_address_space_io()
......@@ -438,7 +438,7 @@ static int piix4_pm_initfn(PCIDevice *dev)
pci_conf[0x3d] = 0x01; // interrupt pin 1
/* APM */
apm_init(&s->apm, apm_ctrl_changed, s);
apm_init(dev, &s->apm, apm_ctrl_changed, s);
register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s);
......
......@@ -22,6 +22,7 @@
#include "apm.h"
#include "hw.h"
#include "pci.h"
//#define DEBUG
......@@ -35,7 +36,8 @@
#define APM_CNT_IOPORT 0xb2
#define APM_STS_IOPORT 0xb3
static void apm_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
static void apm_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
unsigned size)
{
APMState *apm = opaque;
addr &= 1;
......@@ -51,7 +53,7 @@ static void apm_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
}
}
static uint32_t apm_ioport_readb(void *opaque, uint32_t addr)
static uint64_t apm_ioport_readb(void *opaque, hwaddr addr, unsigned size)
{
APMState *apm = opaque;
uint32_t val;
......@@ -78,12 +80,23 @@ const VMStateDescription vmstate_apm = {
}
};
void apm_init(APMState *apm, apm_ctrl_changed_t callback, void *arg)
static const MemoryRegionOps apm_ops = {
.read = apm_ioport_readb,
.write = apm_ioport_writeb,
.impl = {
.min_access_size = 1,
.max_access_size = 1,
},
};
void apm_init(PCIDevice *dev, APMState *apm, apm_ctrl_changed_t callback,
void *arg)
{
apm->callback = callback;
apm->arg = arg;
/* ioport 0xb2, 0xb3 */
register_ioport_write(APM_CNT_IOPORT, 2, 1, apm_ioport_writeb, apm);
register_ioport_read(APM_CNT_IOPORT, 2, 1, apm_ioport_readb, apm);
memory_region_init_io(&apm->io, &apm_ops, apm, "apm-io", 2);
memory_region_add_subregion(pci_address_space_io(dev), APM_CNT_IOPORT,
&apm->io);
}
......@@ -4,6 +4,7 @@
#include <stdint.h>
#include "qemu-common.h"
#include "hw.h"
#include "memory.h"
typedef void (*apm_ctrl_changed_t)(uint32_t val, void *arg);
......@@ -13,9 +14,11 @@ typedef struct APMState {
apm_ctrl_changed_t callback;
void *arg;
MemoryRegion io;
} APMState;
void apm_init(APMState *s, apm_ctrl_changed_t callback, void *arg);
void apm_init(PCIDevice *dev, APMState *s, apm_ctrl_changed_t callback,
void *arg);
extern const VMStateDescription vmstate_apm;
......
......@@ -197,6 +197,7 @@ typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
typedef struct CirrusVGAState {
VGACommonState vga;
MemoryRegion cirrus_vga_io;
MemoryRegion cirrus_linear_io;
MemoryRegion cirrus_linear_bitblt_io;
MemoryRegion cirrus_mmio_io;
......@@ -2432,13 +2433,15 @@ static void cirrus_update_memory_access(CirrusVGAState *s)
/* I/O ports */
static uint32_t cirrus_vga_ioport_read(void *opaque, uint32_t addr)
static uint64_t cirrus_vga_ioport_read(void *opaque, hwaddr addr,
unsigned size)
{
CirrusVGAState *c = opaque;
VGACommonState *s = &c->vga;
int val, index;
qemu_flush_coalesced_mmio_buffer();
addr += 0x3b0;
if (vga_ioport_invalid(s, addr)) {
val = 0xff;
......@@ -2527,13 +2530,15 @@ static uint32_t cirrus_vga_ioport_read(void *opaque, uint32_t addr)
return val;
}
static void cirrus_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val,
unsigned size)
{
CirrusVGAState *c = opaque;
VGACommonState *s = &c->vga;
int index;
qemu_flush_coalesced_mmio_buffer();
addr += 0x3b0;
/* check port range access depending on color/monochrome mode */
if (vga_ioport_invalid(s, addr)) {
......@@ -2646,7 +2651,7 @@ static uint64_t cirrus_mmio_read(void *opaque, hwaddr addr,
if (addr >= 0x100) {
return cirrus_mmio_blt_read(s, addr - 0x100);
} else {
return cirrus_vga_ioport_read(s, addr + 0x3c0);
return cirrus_vga_ioport_read(s, addr + 0x10, size);
}
}
......@@ -2658,7 +2663,7 @@ static void cirrus_mmio_write(void *opaque, hwaddr addr,
if (addr >= 0x100) {
cirrus_mmio_blt_write(s, addr - 0x100, val);
} else {
cirrus_vga_ioport_write(s, addr + 0x3c0, val);
cirrus_vga_ioport_write(s, addr + 0x10, val, size);
}
}
......@@ -2784,8 +2789,19 @@ static const MemoryRegionOps cirrus_linear_io_ops = {
},
};
static const MemoryRegionOps cirrus_vga_io_ops = {
.read = cirrus_vga_ioport_read,
.write = cirrus_vga_ioport_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,
MemoryRegion *system_memory)
MemoryRegion *system_memory,
MemoryRegion *system_io)
{
int i;
static int inited;
......@@ -2817,19 +2833,10 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci,
s->bustype = CIRRUS_BUSTYPE_ISA;
}
register_ioport_write(0x3c0, 16, 1, cirrus_vga_ioport_write, s);
register_ioport_write(0x3b4, 2, 1, cirrus_vga_ioport_write, s);
register_ioport_write(0x3d4, 2, 1, cirrus_vga_ioport_write, s);
register_ioport_write(0x3ba, 1, 1, cirrus_vga_ioport_write, s);
register_ioport_write(0x3da, 1, 1, cirrus_vga_ioport_write, s);
register_ioport_read(0x3c0, 16, 1, cirrus_vga_ioport_read, s);
register_ioport_read(0x3b4, 2, 1, cirrus_vga_ioport_read, s);
register_ioport_read(0x3d4, 2, 1, cirrus_vga_ioport_read, s);
register_ioport_read(0x3ba, 1, 1, cirrus_vga_ioport_read, s);
register_ioport_read(0x3da, 1, 1, cirrus_vga_ioport_read, s);
/* Register ioport 0x3b0 - 0x3df */
memory_region_init_io(&s->cirrus_vga_io, &cirrus_vga_io_ops, s,
"cirrus-io", 0x30);
memory_region_add_subregion(system_io, 0x3b0, &s->cirrus_vga_io);
memory_region_init(&s->low_mem_container,
"cirrus-lowmem-container",
......@@ -2900,7 +2907,7 @@ static int vga_initfn(ISADevice *dev)
vga_common_init(s);
cirrus_init_common(&d->cirrus_vga, CIRRUS_ID_CLGD5430, 0,
isa_address_space(dev));
isa_address_space(dev), isa_address_space_io(dev));
s->ds = graphic_console_init(s->update, s->invalidate,
s->screen_dump, s->text_update,
s);
......@@ -2948,7 +2955,8 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
/* setup VGA */
vga_common_init(&s->vga);
cirrus_init_common(s, device_id, 1, pci_address_space(dev));
cirrus_init_common(s, device_id, 1, pci_address_space(dev),
pci_address_space_io(dev));
s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate,
s->vga.screen_dump, s->vga.text_update,
&s->vga);
......
......@@ -58,6 +58,8 @@ static struct dma_cont {
int dshift;
struct dma_regs regs[4];
qemu_irq *cpu_request_exit;
MemoryRegion channel_io;
MemoryRegion cont_io;
} dma_controllers[2];
enum {
......@@ -149,7 +151,7 @@ static inline int getff (struct dma_cont *d)
return ff;
}
static uint32_t read_chan (void *opaque, uint32_t nport)
static uint64_t read_chan(void *opaque, hwaddr nport, unsigned size)
{
struct dma_cont *d = opaque;
int ichan, nreg, iport, ff, val, dir;
......@@ -171,7 +173,8 @@ static uint32_t read_chan (void *opaque, uint32_t nport)
return (val >> (d->dshift + (ff << 3))) & 0xff;
}
static void write_chan (void *opaque, uint32_t nport, uint32_t data)
static void write_chan(void *opaque, hwaddr nport, uint64_t data,
unsigned size)
{
struct dma_cont *d = opaque;
int iport, ichan, nreg;
......@@ -189,22 +192,23 @@ static void write_chan (void *opaque, uint32_t nport, uint32_t data)
}
}
static void write_cont (void *opaque, uint32_t nport, uint32_t data)
static void write_cont(void *opaque, hwaddr nport, uint64_t data,
unsigned size)
{
struct dma_cont *d = opaque;
int iport, ichan = 0;
iport = (nport >> d->dshift) & 0x0f;
switch (iport) {
case 0x08: /* command */
case 0x01: /* command */
if ((data != 0) && (data & CMD_NOT_SUPPORTED)) {
dolog ("command %#x not supported\n", data);
dolog("command %"PRIx64" not supported\n", data);
return;
}
d->command = data;
break;
case 0x09:
case 0x02:
ichan = data & 3;
if (data & 4) {
d->status |= 1 << (ichan + 4);
......@@ -216,7 +220,7 @@ static void write_cont (void *opaque, uint32_t nport, uint32_t data)
DMA_run();
break;
case 0x0a: /* single mask */
case 0x03: /* single mask */
if (data & 4)
d->mask |= 1 << (data & 3);
else
......@@ -224,7 +228,7 @@ static void write_cont (void *opaque, uint32_t nport, uint32_t data)
DMA_run();
break;
case 0x0b: /* mode */
case 0x04: /* mode */
{
ichan = data & 3;
#ifdef DEBUG_DMA
......@@ -243,23 +247,23 @@ static void write_cont (void *opaque, uint32_t nport, uint32_t data)
break;
}
case 0x0c: /* clear flip flop */
case 0x05: /* clear flip flop */
d->flip_flop = 0;
break;
case 0x0d: /* reset */
case 0x06: /* reset */
d->flip_flop = 0;
d->mask = ~0;
d->status = 0;
d->command = 0;
break;
case 0x0e: /* clear mask for all channels */
case 0x07: /* clear mask for all channels */
d->mask = 0;
DMA_run();
break;
case 0x0f: /* write mask for all channels */
case 0x08: /* write mask for all channels */
d->mask = data;
DMA_run();
break;
......@@ -277,7 +281,7 @@ static void write_cont (void *opaque, uint32_t nport, uint32_t data)
#endif
}
static uint32_t read_cont (void *opaque, uint32_t nport)
static uint64_t read_cont(void *opaque, hwaddr nport, unsigned size)
{
struct dma_cont *d = opaque;
int iport, val;
......@@ -463,7 +467,7 @@ void DMA_schedule(int nchan)
static void dma_reset(void *opaque)
{
struct dma_cont *d = opaque;
write_cont (d, (0x0d << d->dshift), 0);
write_cont(d, (0x06 << d->dshift), 0, 1);
}
static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len)
......@@ -473,38 +477,68 @@ static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len)
return dma_pos;
}
static const MemoryRegionOps channel_io_ops = {
.read = read_chan,
.write = write_chan,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 1,
.max_access_size = 1,
},
};
/* IOport from page_base */
static const MemoryRegionPortio page_portio_list[] = {
{ 0x01, 3, 1, .write = write_page, .read = read_page, },
{ 0x07, 1, 1, .write = write_page, .read = read_page, },
PORTIO_END_OF_LIST(),
};
/* IOport from pageh_base */
static const MemoryRegionPortio pageh_portio_list[] = {
{ 0x01, 3, 1, .write = write_pageh, .read = read_pageh, },
{ 0x07, 3, 1, .write = write_pageh, .read = read_pageh, },
PORTIO_END_OF_LIST(),
};
static const MemoryRegionOps cont_io_ops = {
.read = read_cont,
.write = write_cont,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 1,
.max_access_size = 1,
},
};
/* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */
static void dma_init2(struct dma_cont *d, int base, int dshift,
int page_base, int pageh_base,
qemu_irq *cpu_request_exit)
{
static const int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 };
int i;
d->dshift = dshift;
d->cpu_request_exit = cpu_request_exit;
for (i = 0; i < 8; i++) {
register_ioport_write (base + (i << dshift), 1, 1, write_chan, d);
register_ioport_read (base + (i << dshift), 1, 1, read_chan, d);
}
for (i = 0; i < ARRAY_SIZE (page_port_list); i++) {
register_ioport_write (page_base + page_port_list[i], 1, 1,
write_page, d);
register_ioport_read (page_base + page_port_list[i], 1, 1,
read_page, d);
if (pageh_base >= 0) {
register_ioport_write (pageh_base + page_port_list[i], 1, 1,
write_pageh, d);
register_ioport_read (pageh_base + page_port_list[i], 1, 1,
read_pageh, d);
}
}
for (i = 0; i < 8; i++) {
register_ioport_write (base + ((i + 8) << dshift), 1, 1,
write_cont, d);
register_ioport_read (base + ((i + 8) << dshift), 1, 1,
read_cont, d);
memory_region_init_io(&d->channel_io, &channel_io_ops, d,
"dma-chan", 8 << d->dshift);
memory_region_add_subregion(isa_address_space_io(NULL),
base, &d->channel_io);
isa_register_portio_list(NULL, page_base, page_portio_list, d,
"dma-page");
if (pageh_base >= 0) {
isa_register_portio_list(NULL, pageh_base, pageh_portio_list, d,
"dma-pageh");
}
memory_region_init_io(&d->cont_io, &cont_io_ops, d, "dma-cont",
8 << d->dshift);
memory_region_add_subregion(isa_address_space_io(NULL),
base + (8 << d->dshift), &d->cont_io);
qemu_register_reset(dma_reset, d);
dma_reset(d);
for (i = 0; i < ARRAY_SIZE (d->regs); ++i) {
......
......@@ -264,4 +264,13 @@ MemoryRegion *isa_address_space(ISADevice *dev)
return get_system_memory();
}
MemoryRegion *isa_address_space_io(ISADevice *dev)
{
if (dev) {
return isa_bus_from_device(dev)->address_space_io;
}
return isabus->address_space_io;
}
type_init(isabus_register_types)
......@@ -43,6 +43,7 @@ void isa_bus_irqs(ISABus *bus, qemu_irq *irqs);
qemu_irq isa_get_irq(ISADevice *dev, int isairq);
void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq);
MemoryRegion *isa_address_space(ISADevice *dev);
MemoryRegion *isa_address_space_io(ISADevice *dev);
ISADevice *isa_create(ISABus *bus, const char *name);
ISADevice *isa_try_create(ISABus *bus, const char *name);
ISADevice *isa_create_simple(ISABus *bus, const char *name);
......
......@@ -472,7 +472,7 @@ static int ich9_lpc_initfn(PCIDevice *d)
lpc->isa_bus = isa_bus;
ich9_cc_init(lpc);
apm_init(&lpc->apm, ich9_apm_ctrl_changed, lpc);
apm_init(d, &lpc->apm, ich9_apm_ctrl_changed, lpc);
return 0;
}
......
......@@ -217,7 +217,8 @@ mips_mipssim_init(QEMUMachineInitArgs *args)
/* A single 16450 sits at offset 0x3f8. It is attached to
MIPS CPU INT2, which is interrupt 4. */
if (serial_hds[0])
serial_init(0x3f8, env->irq[4], 115200, serial_hds[0]);
serial_init(0x3f8, env->irq[4], 115200, serial_hds[0],
get_system_io());
if (nd_table[0].used)
/* MIPSnet uses the MIPS CPU INT0, which is interrupt 2. */
......
......@@ -98,7 +98,8 @@ void gsi_handler(void *opaque, int n, int level)
qemu_set_irq(s->ioapic_irq[n], level);
}
static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
static void ioport80_write(void *opaque, hwaddr addr, uint64_t data,
unsigned size)
{
}
......@@ -116,7 +117,8 @@ void cpu_set_ferr(CPUX86State *s)
qemu_irq_raise(ferr_irq);
}
static void ioportF0_write(void *opaque, uint32_t addr, uint32_t data)
static void ioportF0_write(void *opaque, hwaddr addr, uint64_t data,
unsigned size)
{
qemu_irq_lower(ferr_irq);
}
......@@ -567,6 +569,14 @@ int e820_add_entry(uint64_t address, uint64_t length, uint32_t type)
return index;
}
static const MemoryRegionPortio bochs_bios_portio_list[] = {
{ 0x500, 1, 1, .write = bochs_bios_write, }, /* 0x500 */
{ 0x501, 1, 1, .write = bochs_bios_write, }, /* 0x501 */
{ 0x501, 2, 2, .write = bochs_bios_write, }, /* 0x501 */
{ 0x8900, 1, 1, .write = bochs_bios_write, }, /* 0x8900 */
PORTIO_END_OF_LIST(),
};
static void *bochs_bios_init(void)
{
void *fw_cfg;
......@@ -574,12 +584,11 @@ static void *bochs_bios_init(void)
size_t smbios_len;
uint64_t *numa_fw_cfg;
int i, j;
PortioList *bochs_bios_port_list = g_new(PortioList, 1);
register_ioport_write(0x8900, 1, 1, bochs_bios_write, NULL);
register_ioport_write(0x501, 1, 1, bochs_bios_write, NULL);
register_ioport_write(0x501, 1, 2, bochs_bios_write, NULL);
register_ioport_write(0x502, 1, 2, bochs_bios_write, NULL);
portio_list_init(bochs_bios_port_list, bochs_bios_portio_list,
NULL, "bochs-bios");
portio_list_add(bochs_bios_port_list, get_system_io(), 0x0);
fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0);
......@@ -967,6 +976,24 @@ static void cpu_request_exit(void *opaque, int irq, int level)
}
}
static const MemoryRegionOps ioport80_io_ops = {
.write = ioport80_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 1,
.max_access_size = 1,
},
};
static const MemoryRegionOps ioportF0_io_ops = {
.write = ioportF0_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 1,
.max_access_size = 1,
},
};
void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
ISADevice **rtc_state,
ISADevice **floppy,
......@@ -981,10 +1008,14 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
qemu_irq *a20_line;
ISADevice *i8042, *port92, *vmmouse, *pit = NULL;
qemu_irq *cpu_exit_irq;
MemoryRegion *ioport80_io = g_new(MemoryRegion, 1);
MemoryRegion *ioportF0_io = g_new(MemoryRegion, 1);
register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
memory_region_init_io(ioport80_io, &ioport80_io_ops, NULL, "ioport80", 1);
memory_region_add_subregion(isa_bus->address_space_io, 0x80, ioport80_io);
register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);
memory_region_init_io(ioportF0_io, &ioportF0_io_ops, NULL, "ioportF0", 1);
memory_region_add_subregion(isa_bus->address_space_io, 0xf0, ioportF0_io);
/*
* Check if an HPET shall be created.
......
......@@ -718,7 +718,7 @@ const MemoryRegionOps serial_io_ops = {
};
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
CharDriverState *chr)
CharDriverState *chr, MemoryRegion *system_io)
{
SerialState *s;
......@@ -732,7 +732,7 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
vmstate_register(NULL, base, &vmstate_serial, s);
memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8);
memory_region_add_subregion(get_system_io(), base, &s->io);
memory_region_add_subregion(system_io, base, &s->io);
return s;
}
......
......@@ -89,7 +89,7 @@ void serial_set_frequency(SerialState *s, uint32_t frequency);
/* legacy pre qom */
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
CharDriverState *chr);
CharDriverState *chr, MemoryRegion *system_io);
SerialState *serial_mm_init(MemoryRegion *address_space,
hwaddr base, int it_shift,
qemu_irq irq, int baudbase,
......
......@@ -427,7 +427,7 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
register_ioport_write(s->smb_io_base, 0xf, 1, smb_ioport_writeb, &s->smb);
register_ioport_read(s->smb_io_base, 0xf, 1, smb_ioport_readb, &s->smb);
apm_init(&s->apm, NULL, s);
apm_init(dev, &s->apm, NULL, s);
acpi_pm_tmr_init(&s->ar, pm_tmr_timer);
acpi_pm1_cnt_init(&s->ar);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册