Merge remote-tracking branch 'qemu-kvm-tmp/memory/batch' into staging
This commit is contained in:
commit
4c54661feb
38
hw/cs4231a.c
38
hw/cs4231a.c
@ -59,6 +59,7 @@ static struct {
|
||||
typedef struct CSState {
|
||||
ISADevice dev;
|
||||
QEMUSoundCard card;
|
||||
MemoryRegion ioports;
|
||||
qemu_irq pic;
|
||||
uint32_t regs[CS_REGS];
|
||||
uint8_t dregs[CS_DREGS];
|
||||
@ -74,14 +75,6 @@ typedef struct CSState {
|
||||
int16_t *tab;
|
||||
} CSState;
|
||||
|
||||
#define IO_READ_PROTO(name) \
|
||||
static uint32_t name (void *opaque, uint32_t addr)
|
||||
|
||||
#define IO_WRITE_PROTO(name) \
|
||||
static void name (void *opaque, uint32_t addr, uint32_t val)
|
||||
|
||||
#define GET_SADDR(addr) (addr & 3)
|
||||
|
||||
#define MODE2 (1 << 6)
|
||||
#define MCE (1 << 6)
|
||||
#define PMCE (1 << 4)
|
||||
@ -353,12 +346,12 @@ static void cs_reset_voices (CSState *s, uint32_t val)
|
||||
}
|
||||
}
|
||||
|
||||
IO_READ_PROTO (cs_read)
|
||||
static uint64_t cs_read(void *opaque, target_phys_addr_t addr, unsigned size)
|
||||
{
|
||||
CSState *s = opaque;
|
||||
uint32_t saddr, iaddr, ret;
|
||||
|
||||
saddr = GET_SADDR (addr);
|
||||
saddr = addr;
|
||||
iaddr = ~0U;
|
||||
|
||||
switch (saddr) {
|
||||
@ -390,12 +383,14 @@ IO_READ_PROTO (cs_read)
|
||||
return ret;
|
||||
}
|
||||
|
||||
IO_WRITE_PROTO (cs_write)
|
||||
static void cs_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val64, unsigned size)
|
||||
{
|
||||
CSState *s = opaque;
|
||||
uint32_t saddr, iaddr;
|
||||
uint32_t saddr, iaddr, val;
|
||||
|
||||
saddr = GET_SADDR (addr);
|
||||
saddr = addr;
|
||||
val = val64;
|
||||
|
||||
switch (saddr) {
|
||||
case Index_Address:
|
||||
@ -637,18 +632,23 @@ static const VMStateDescription vmstate_cs4231a = {
|
||||
}
|
||||
};
|
||||
|
||||
static const MemoryRegionOps cs_ioport_ops = {
|
||||
.read = cs_read,
|
||||
.write = cs_write,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 1,
|
||||
}
|
||||
};
|
||||
|
||||
static int cs4231a_initfn (ISADevice *dev)
|
||||
{
|
||||
CSState *s = DO_UPCAST (CSState, dev, dev);
|
||||
int i;
|
||||
|
||||
isa_init_irq (dev, &s->pic, s->irq);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
isa_init_ioport(dev, i);
|
||||
register_ioport_write (s->port + i, 1, 1, cs_write, s);
|
||||
register_ioport_read (s->port + i, 1, 1, cs_read, s);
|
||||
}
|
||||
memory_region_init_io(&s->ioports, &cs_ioport_ops, s, "cs4231a", 4);
|
||||
isa_register_ioport(dev, &s->ioports, s->port);
|
||||
|
||||
DMA_register_channel (s->dma, cs_dma_read, s);
|
||||
|
||||
|
53
hw/fdc.c
53
hw/fdc.c
@ -424,6 +424,7 @@ typedef struct FDCtrlSysBus {
|
||||
|
||||
typedef struct FDCtrlISABus {
|
||||
ISADevice busdev;
|
||||
MemoryRegion io_0, io_7;
|
||||
struct FDCtrl state;
|
||||
int32_t bootindexA;
|
||||
int32_t bootindexB;
|
||||
@ -489,16 +490,6 @@ static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value)
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t fdctrl_read_port (void *opaque, uint32_t reg)
|
||||
{
|
||||
return fdctrl_read(opaque, reg & 7);
|
||||
}
|
||||
|
||||
static void fdctrl_write_port (void *opaque, uint32_t reg, uint32_t value)
|
||||
{
|
||||
fdctrl_write(opaque, reg & 7, value);
|
||||
}
|
||||
|
||||
static uint32_t fdctrl_read_mem (void *opaque, target_phys_addr_t reg)
|
||||
{
|
||||
return fdctrl_read(opaque, (uint32_t)reg);
|
||||
@ -1889,6 +1880,34 @@ static int fdctrl_init_common(FDCtrl *fdctrl)
|
||||
return fdctrl_connect_drives(fdctrl);
|
||||
}
|
||||
|
||||
static uint32_t fdctrl_read_port_7(void *opaque, uint32_t reg)
|
||||
{
|
||||
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 },
|
||||
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)
|
||||
{
|
||||
FDCtrlISABus *isa = DO_UPCAST(FDCtrlISABus, busdev, dev);
|
||||
@ -1898,16 +1917,10 @@ static int isabus_fdc_init1(ISADevice *dev)
|
||||
int dma_chann = 2;
|
||||
int ret;
|
||||
|
||||
register_ioport_read(iobase + 0x01, 5, 1,
|
||||
&fdctrl_read_port, fdctrl);
|
||||
register_ioport_read(iobase + 0x07, 1, 1,
|
||||
&fdctrl_read_port, fdctrl);
|
||||
register_ioport_write(iobase + 0x01, 5, 1,
|
||||
&fdctrl_write_port, fdctrl);
|
||||
register_ioport_write(iobase + 0x07, 1, 1,
|
||||
&fdctrl_write_port, fdctrl);
|
||||
isa_init_ioport_range(dev, iobase, 6);
|
||||
isa_init_ioport(dev, iobase + 7);
|
||||
memory_region_init_io(&isa->io_0, &fdc_ioport_0_ops, fdctrl, "fdc", 6);
|
||||
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);
|
||||
fdctrl->dma_chann = dma_chann;
|
||||
|
16
hw/i8254.c
16
hw/i8254.c
@ -55,6 +55,7 @@ typedef struct PITChannelState {
|
||||
|
||||
typedef struct PITState {
|
||||
ISADevice dev;
|
||||
MemoryRegion ioports;
|
||||
uint32_t irq;
|
||||
uint32_t iobase;
|
||||
PITChannelState channels[3];
|
||||
@ -506,6 +507,16 @@ void hpet_pit_enable(void)
|
||||
pit_load_count(s, 0);
|
||||
}
|
||||
|
||||
static const MemoryRegionPortio pit_portio[] = {
|
||||
{ 0, 4, 1, .write = pit_ioport_write },
|
||||
{ 0, 3, 1, .read = pit_ioport_read },
|
||||
PORTIO_END_OF_LIST()
|
||||
};
|
||||
|
||||
static const MemoryRegionOps pit_ioport_ops = {
|
||||
.old_portio = pit_portio
|
||||
};
|
||||
|
||||
static int pit_initfn(ISADevice *dev)
|
||||
{
|
||||
PITState *pit = DO_UPCAST(PITState, dev, dev);
|
||||
@ -516,9 +527,8 @@ static int pit_initfn(ISADevice *dev)
|
||||
s->irq_timer = qemu_new_timer_ns(vm_clock, pit_irq_timer, s);
|
||||
s->irq = isa_get_irq(pit->irq);
|
||||
|
||||
register_ioport_write(pit->iobase, 4, 1, pit_ioport_write, pit);
|
||||
register_ioport_read(pit->iobase, 3, 1, pit_ioport_read, pit);
|
||||
isa_init_ioport(dev, pit->iobase);
|
||||
memory_region_init_io(&pit->ioports, &pit_ioport_ops, pit, "pit", 4);
|
||||
isa_register_ioport(dev, &pit->ioports, pit->iobase);
|
||||
|
||||
qdev_set_legacy_instance_id(&dev->qdev, pit->iobase, 2);
|
||||
|
||||
|
65
hw/i8259.c
65
hw/i8259.c
@ -59,6 +59,8 @@ typedef struct PicState {
|
||||
uint8_t elcr; /* PIIX edge/trigger selection*/
|
||||
uint8_t elcr_mask;
|
||||
PicState2 *pics_state;
|
||||
MemoryRegion base_io;
|
||||
MemoryRegion elcr_io;
|
||||
} PicState;
|
||||
|
||||
struct PicState2 {
|
||||
@ -284,13 +286,15 @@ static void pic_reset(void *opaque)
|
||||
/* Note: ELCR is not reset */
|
||||
}
|
||||
|
||||
static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||
static void pic_ioport_write(void *opaque, target_phys_addr_t addr64,
|
||||
uint64_t val64, unsigned size)
|
||||
{
|
||||
PicState *s = opaque;
|
||||
uint32_t addr = addr64;
|
||||
uint32_t val = val64;
|
||||
int priority, cmd, irq;
|
||||
|
||||
DPRINTF("write: addr=0x%02x val=0x%02x\n", addr, val);
|
||||
addr &= 1;
|
||||
if (addr == 0) {
|
||||
if (val & 0x10) {
|
||||
/* init */
|
||||
@ -374,19 +378,21 @@ static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
|
||||
static uint32_t pic_poll_read(PicState *s)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = pic_get_irq(s);
|
||||
if (ret >= 0) {
|
||||
if (addr1 >> 7) {
|
||||
bool slave = (s == &isa_pic->pics[1]);
|
||||
|
||||
if (slave) {
|
||||
s->pics_state->pics[0].isr &= ~(1 << 2);
|
||||
s->pics_state->pics[0].irr &= ~(1 << 2);
|
||||
}
|
||||
s->irr &= ~(1 << ret);
|
||||
s->isr &= ~(1 << ret);
|
||||
if (addr1 >> 7 || ret != 2)
|
||||
if (slave || ret != 2)
|
||||
pic_update_irq(s->pics_state);
|
||||
} else {
|
||||
ret = 0x07;
|
||||
@ -396,16 +402,15 @@ static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t pic_ioport_read(void *opaque, uint32_t addr1)
|
||||
static uint64_t pic_ioport_read(void *opaque, target_phys_addr_t addr1,
|
||||
unsigned size)
|
||||
{
|
||||
PicState *s = opaque;
|
||||
unsigned int addr;
|
||||
unsigned int addr = addr1;
|
||||
int ret;
|
||||
|
||||
addr = addr1;
|
||||
addr &= 1;
|
||||
if (s->poll) {
|
||||
ret = pic_poll_read(s, addr1);
|
||||
ret = pic_poll_read(s);
|
||||
s->poll = 0;
|
||||
} else {
|
||||
if (addr == 0) {
|
||||
@ -417,7 +422,7 @@ static uint32_t pic_ioport_read(void *opaque, uint32_t addr1)
|
||||
ret = s->imr;
|
||||
}
|
||||
}
|
||||
DPRINTF("read: addr=0x%02x val=0x%02x\n", addr1, ret);
|
||||
DPRINTF("read: addr=0x%02x val=0x%02x\n", addr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -427,22 +432,24 @@ uint32_t pic_intack_read(PicState2 *s)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = pic_poll_read(&s->pics[0], 0x00);
|
||||
ret = pic_poll_read(&s->pics[0]);
|
||||
if (ret == 2)
|
||||
ret = pic_poll_read(&s->pics[1], 0x80) + 8;
|
||||
ret = pic_poll_read(&s->pics[1]) + 8;
|
||||
/* Prepare for ISR read */
|
||||
s->pics[0].read_reg_select = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void elcr_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||
static void elcr_ioport_write(void *opaque, target_phys_addr_t addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
PicState *s = opaque;
|
||||
s->elcr = val & s->elcr_mask;
|
||||
}
|
||||
|
||||
static uint32_t elcr_ioport_read(void *opaque, uint32_t addr1)
|
||||
static uint64_t elcr_ioport_read(void *opaque, target_phys_addr_t addr,
|
||||
unsigned size)
|
||||
{
|
||||
PicState *s = opaque;
|
||||
return s->elcr;
|
||||
@ -474,15 +481,35 @@ static const VMStateDescription vmstate_pic = {
|
||||
}
|
||||
};
|
||||
|
||||
static const MemoryRegionOps pic_base_ioport_ops = {
|
||||
.read = pic_ioport_read,
|
||||
.write = pic_ioport_write,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static const MemoryRegionOps pic_elcr_ioport_ops = {
|
||||
.read = elcr_ioport_read,
|
||||
.write = elcr_ioport_write,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/* XXX: add generic master/slave system */
|
||||
static void pic_init1(int io_addr, int elcr_addr, PicState *s)
|
||||
{
|
||||
register_ioport_write(io_addr, 2, 1, pic_ioport_write, s);
|
||||
register_ioport_read(io_addr, 2, 1, pic_ioport_read, s);
|
||||
memory_region_init_io(&s->base_io, &pic_base_ioport_ops, s, "pic", 2);
|
||||
memory_region_init_io(&s->elcr_io, &pic_elcr_ioport_ops, s, "elcr", 1);
|
||||
|
||||
isa_register_ioport(NULL, &s->base_io, io_addr);
|
||||
if (elcr_addr >= 0) {
|
||||
register_ioport_write(elcr_addr, 1, 1, elcr_ioport_write, s);
|
||||
register_ioport_read(elcr_addr, 1, 1, elcr_ioport_read, s);
|
||||
isa_register_ioport(NULL, &s->elcr_io, elcr_addr);
|
||||
}
|
||||
|
||||
vmstate_register(NULL, io_addr, &vmstate_pic, s);
|
||||
qemu_register_reset(pic_reset, s);
|
||||
}
|
||||
|
14
hw/isa-bus.c
14
hw/isa-bus.c
@ -24,6 +24,7 @@
|
||||
|
||||
struct ISABus {
|
||||
BusState qbus;
|
||||
MemoryRegion *address_space_io;
|
||||
qemu_irq *irqs;
|
||||
};
|
||||
static ISABus *isabus;
|
||||
@ -39,7 +40,7 @@ static struct BusInfo isa_bus_info = {
|
||||
.get_fw_dev_path = isabus_get_fw_dev_path,
|
||||
};
|
||||
|
||||
ISABus *isa_bus_new(DeviceState *dev)
|
||||
ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space_io)
|
||||
{
|
||||
if (isabus) {
|
||||
fprintf(stderr, "Can't create a second ISA bus\n");
|
||||
@ -51,6 +52,7 @@ ISABus *isa_bus_new(DeviceState *dev)
|
||||
}
|
||||
|
||||
isabus = FROM_QBUS(ISABus, qbus_create(&isa_bus_info, dev, NULL));
|
||||
isabus->address_space_io = address_space_io;
|
||||
return isabus;
|
||||
}
|
||||
|
||||
@ -106,6 +108,16 @@ 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)
|
||||
{
|
||||
memory_region_add_subregion(isabus->address_space_io, start, io);
|
||||
if (dev != NULL) {
|
||||
assert(dev->nio < ARRAY_SIZE(dev->io));
|
||||
dev->io[dev->nio++] = io;
|
||||
isa_init_ioport_range(dev, start, memory_region_size(io));
|
||||
}
|
||||
}
|
||||
|
||||
static int isa_qdev_init(DeviceState *qdev, DeviceInfo *base)
|
||||
{
|
||||
ISADevice *dev = DO_UPCAST(ISADevice, qdev, qdev);
|
||||
|
7
hw/isa.h
7
hw/isa.h
@ -13,10 +13,12 @@ typedef struct ISADeviceInfo ISADeviceInfo;
|
||||
|
||||
struct ISADevice {
|
||||
DeviceState qdev;
|
||||
MemoryRegion *io[32];
|
||||
uint32_t isairq[2];
|
||||
int nirqs;
|
||||
uint16_t ioports[32];
|
||||
int nirqs;
|
||||
int nioports;
|
||||
int nio;
|
||||
};
|
||||
|
||||
typedef int (*isa_qdev_initfn)(ISADevice *dev);
|
||||
@ -25,10 +27,11 @@ struct ISADeviceInfo {
|
||||
isa_qdev_initfn init;
|
||||
};
|
||||
|
||||
ISABus *isa_bus_new(DeviceState *dev);
|
||||
ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space_io);
|
||||
void isa_bus_irqs(qemu_irq *irqs);
|
||||
qemu_irq isa_get_irq(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);
|
||||
|
@ -102,10 +102,11 @@ static void cpu_request_exit(void *opaque, int irq, int level)
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void mips_jazz_init (MemoryRegion *address_space, ram_addr_t ram_size,
|
||||
const char *cpu_model,
|
||||
enum jazz_model_e jazz_model)
|
||||
static void mips_jazz_init(MemoryRegion *address_space,
|
||||
MemoryRegion *address_space_io,
|
||||
ram_addr_t ram_size,
|
||||
const char *cpu_model,
|
||||
enum jazz_model_e jazz_model)
|
||||
{
|
||||
char *filename;
|
||||
int bios_size, n;
|
||||
@ -114,6 +115,7 @@ void mips_jazz_init (MemoryRegion *address_space, ram_addr_t ram_size,
|
||||
rc4030_dma *dmas;
|
||||
void* rc4030_opaque;
|
||||
MemoryRegion *rtc = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *i8042 = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *dma_dummy = g_new(MemoryRegion, 1);
|
||||
NICInfo *nd;
|
||||
DeviceState *dev;
|
||||
@ -180,8 +182,8 @@ void mips_jazz_init (MemoryRegion *address_space, ram_addr_t ram_size,
|
||||
memory_region_add_subregion(address_space, 0x8000d000, dma_dummy);
|
||||
|
||||
/* ISA devices */
|
||||
isa_bus_new(NULL, address_space_io);
|
||||
i8259 = i8259_init(env->irq[4]);
|
||||
isa_bus_new(NULL);
|
||||
isa_bus_irqs(i8259);
|
||||
cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
|
||||
DMA_init(0, cpu_exit_irq);
|
||||
@ -257,7 +259,8 @@ void mips_jazz_init (MemoryRegion *address_space, ram_addr_t ram_size,
|
||||
memory_region_add_subregion(address_space, 0x80004000, rtc);
|
||||
|
||||
/* Keyboard (i8042) */
|
||||
i8042_mm_init(rc4030[6], rc4030[7], 0x80005000, 0x1000, 0x1);
|
||||
i8042_mm_init(rc4030[6], rc4030[7], i8042, 0x1000, 0x1);
|
||||
memory_region_add_subregion(address_space, 0x80005000, i8042);
|
||||
|
||||
/* Serial ports */
|
||||
if (serial_hds[0]) {
|
||||
@ -299,7 +302,8 @@ void mips_magnum_init (ram_addr_t ram_size,
|
||||
const char *kernel_filename, const char *kernel_cmdline,
|
||||
const char *initrd_filename, const char *cpu_model)
|
||||
{
|
||||
mips_jazz_init(get_system_memory(), ram_size, cpu_model, JAZZ_MAGNUM);
|
||||
mips_jazz_init(get_system_memory(), get_system_io(),
|
||||
ram_size, cpu_model, JAZZ_MAGNUM);
|
||||
}
|
||||
|
||||
static
|
||||
@ -308,7 +312,8 @@ void mips_pica61_init (ram_addr_t ram_size,
|
||||
const char *kernel_filename, const char *kernel_cmdline,
|
||||
const char *initrd_filename, const char *cpu_model)
|
||||
{
|
||||
mips_jazz_init(get_system_memory(), ram_size, cpu_model, JAZZ_PICA61);
|
||||
mips_jazz_init(get_system_memory(), get_system_io(),
|
||||
ram_size, cpu_model, JAZZ_PICA61);
|
||||
}
|
||||
|
||||
static QEMUMachine mips_magnum_machine = {
|
||||
|
@ -778,7 +778,7 @@ void mips_malta_init (ram_addr_t ram_size,
|
||||
int64_t kernel_entry;
|
||||
PCIBus *pci_bus;
|
||||
CPUState *env;
|
||||
qemu_irq *i8259;
|
||||
qemu_irq *i8259 = NULL, *isa_irq;
|
||||
qemu_irq *cpu_exit_irq;
|
||||
int piix4_devfn;
|
||||
i2c_bus *smbus;
|
||||
@ -928,17 +928,27 @@ void mips_malta_init (ram_addr_t ram_size,
|
||||
cpu_mips_irq_init_cpu(env);
|
||||
cpu_mips_clock_init(env);
|
||||
|
||||
/* Interrupt controller */
|
||||
/* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
|
||||
i8259 = i8259_init(env->irq[2]);
|
||||
/*
|
||||
* We have a circular dependency problem: pci_bus depends on isa_irq,
|
||||
* isa_irq is provided by i8259, i8259 depends on ISA, ISA depends
|
||||
* on piix4, and piix4 depends on pci_bus. To stop the cycle we have
|
||||
* qemu_irq_proxy() adds an extra bit of indirection, allowing us
|
||||
* to resolve the isa_irq -> i8259 dependency after i8259 is initialized.
|
||||
*/
|
||||
isa_irq = qemu_irq_proxy(&i8259, 16);
|
||||
|
||||
/* Northbridge */
|
||||
pci_bus = gt64120_register(i8259);
|
||||
pci_bus = gt64120_register(isa_irq);
|
||||
|
||||
/* Southbridge */
|
||||
ide_drive_get(hd, MAX_IDE_BUS);
|
||||
|
||||
piix4_devfn = piix4_init(pci_bus, 80);
|
||||
|
||||
/* Interrupt controller */
|
||||
/* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
|
||||
i8259 = i8259_init(env->irq[2]);
|
||||
|
||||
isa_bus_irqs(i8259);
|
||||
pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
|
||||
usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
|
||||
|
@ -256,8 +256,8 @@ void mips_r4k_init (ram_addr_t ram_size,
|
||||
cpu_mips_clock_init(env);
|
||||
|
||||
/* The PIC is attached to the MIPS CPU INT0 pin */
|
||||
isa_bus_new(NULL, get_system_io());
|
||||
i8259 = i8259_init(env->irq[2]);
|
||||
isa_bus_new(NULL);
|
||||
isa_bus_irqs(i8259);
|
||||
|
||||
rtc_init(2000, NULL);
|
||||
|
2
hw/pc.h
2
hw/pc.h
@ -118,7 +118,7 @@ void vmmouse_set_data(const uint32_t *data);
|
||||
|
||||
void i8042_init(qemu_irq kbd_irq, qemu_irq mouse_irq, uint32_t io_base);
|
||||
void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
|
||||
target_phys_addr_t base, ram_addr_t size,
|
||||
MemoryRegion *region, ram_addr_t size,
|
||||
target_phys_addr_t mask);
|
||||
void i8042_isa_mouse_fake_event(void *opaque);
|
||||
void i8042_setup_a20_line(ISADevice *dev, qemu_irq *a20_out);
|
||||
|
24
hw/pc_piix.c
24
hw/pc_piix.c
@ -130,17 +130,7 @@ static void pc_init1(MemoryRegion *system_memory,
|
||||
pci_enabled ? rom_memory : system_memory, &ram_memory);
|
||||
}
|
||||
|
||||
if (!xen_enabled()) {
|
||||
cpu_irq = pc_allocate_cpu_irq();
|
||||
i8259 = i8259_init(cpu_irq[0]);
|
||||
} else {
|
||||
i8259 = xen_interrupt_controller_init();
|
||||
}
|
||||
isa_irq_state = g_malloc0(sizeof(*isa_irq_state));
|
||||
isa_irq_state->i8259 = i8259;
|
||||
if (pci_enabled) {
|
||||
ioapic_init(isa_irq_state);
|
||||
}
|
||||
isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24);
|
||||
|
||||
if (pci_enabled) {
|
||||
@ -156,11 +146,23 @@ static void pc_init1(MemoryRegion *system_memory,
|
||||
} else {
|
||||
pci_bus = NULL;
|
||||
i440fx_state = NULL;
|
||||
isa_bus_new(NULL);
|
||||
isa_bus_new(NULL, system_io);
|
||||
no_hpet = 1;
|
||||
}
|
||||
isa_bus_irqs(isa_irq);
|
||||
|
||||
if (!xen_enabled()) {
|
||||
cpu_irq = pc_allocate_cpu_irq();
|
||||
i8259 = i8259_init(cpu_irq[0]);
|
||||
} else {
|
||||
i8259 = xen_interrupt_controller_init();
|
||||
}
|
||||
|
||||
isa_irq_state->i8259 = i8259;
|
||||
if (pci_enabled) {
|
||||
ioapic_init(isa_irq_state);
|
||||
}
|
||||
|
||||
pc_register_ferr_irq(isa_get_irq(13));
|
||||
|
||||
pc_vga_init(pci_enabled? pci_bus: NULL);
|
||||
|
5
hw/pci.c
5
hw/pci.c
@ -2124,3 +2124,8 @@ MemoryRegion *pci_address_space(PCIDevice *dev)
|
||||
{
|
||||
return dev->bus->address_space_mem;
|
||||
}
|
||||
|
||||
MemoryRegion *pci_address_space_io(PCIDevice *dev)
|
||||
{
|
||||
return dev->bus->address_space_io;
|
||||
}
|
||||
|
1
hw/pci.h
1
hw/pci.h
@ -218,6 +218,7 @@ void pci_default_write_config(PCIDevice *d,
|
||||
void pci_device_save(PCIDevice *s, QEMUFile *f);
|
||||
int pci_device_load(PCIDevice *s, QEMUFile *f);
|
||||
MemoryRegion *pci_address_space(PCIDevice *dev);
|
||||
MemoryRegion *pci_address_space_io(PCIDevice *dev);
|
||||
|
||||
typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level);
|
||||
typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
|
||||
|
59
hw/pckbd.c
59
hw/pckbd.c
@ -400,33 +400,27 @@ static void kbd_mm_writeb (void *opaque, target_phys_addr_t addr, uint32_t value
|
||||
kbd_write_data(s, 0, value & 0xff);
|
||||
}
|
||||
|
||||
static CPUReadMemoryFunc * const kbd_mm_read[] = {
|
||||
&kbd_mm_readb,
|
||||
&kbd_mm_readb,
|
||||
&kbd_mm_readb,
|
||||
};
|
||||
|
||||
static CPUWriteMemoryFunc * const kbd_mm_write[] = {
|
||||
&kbd_mm_writeb,
|
||||
&kbd_mm_writeb,
|
||||
&kbd_mm_writeb,
|
||||
static const MemoryRegionOps i8042_mmio_ops = {
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
.old_mmio = {
|
||||
.read = { kbd_mm_readb, kbd_mm_readb, kbd_mm_readb },
|
||||
.write = { kbd_mm_writeb, kbd_mm_writeb, kbd_mm_writeb },
|
||||
},
|
||||
};
|
||||
|
||||
void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
|
||||
target_phys_addr_t base, ram_addr_t size,
|
||||
MemoryRegion *region, ram_addr_t size,
|
||||
target_phys_addr_t mask)
|
||||
{
|
||||
KBDState *s = g_malloc0(sizeof(KBDState));
|
||||
int s_io_memory;
|
||||
|
||||
s->irq_kbd = kbd_irq;
|
||||
s->irq_mouse = mouse_irq;
|
||||
s->mask = mask;
|
||||
|
||||
vmstate_register(NULL, 0, &vmstate_kbd, s);
|
||||
s_io_memory = cpu_register_io_memory(kbd_mm_read, kbd_mm_write, s,
|
||||
DEVICE_NATIVE_ENDIAN);
|
||||
cpu_register_physical_memory(base, size, s_io_memory);
|
||||
|
||||
memory_region_init_io(region, &i8042_mmio_ops, s, "i8042", size);
|
||||
|
||||
s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
|
||||
s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
|
||||
@ -435,7 +429,8 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
|
||||
|
||||
typedef struct ISAKBDState {
|
||||
ISADevice dev;
|
||||
KBDState kbd;
|
||||
KBDState kbd;
|
||||
MemoryRegion io[2];
|
||||
} ISAKBDState;
|
||||
|
||||
void i8042_isa_mouse_fake_event(void *opaque)
|
||||
@ -464,19 +459,37 @@ static const VMStateDescription vmstate_kbd_isa = {
|
||||
}
|
||||
};
|
||||
|
||||
static const MemoryRegionPortio i8042_data_portio[] = {
|
||||
{ 0, 1, 1, .read = kbd_read_data, .write = kbd_write_data },
|
||||
PORTIO_END_OF_LIST()
|
||||
};
|
||||
|
||||
static const MemoryRegionPortio i8042_cmd_portio[] = {
|
||||
{ 0, 1, 1, .read = kbd_read_status, .write = kbd_write_command },
|
||||
PORTIO_END_OF_LIST()
|
||||
};
|
||||
|
||||
static const MemoryRegionOps i8042_data_ops = {
|
||||
.old_portio = i8042_data_portio
|
||||
};
|
||||
|
||||
static const MemoryRegionOps i8042_cmd_ops = {
|
||||
.old_portio = i8042_cmd_portio
|
||||
};
|
||||
|
||||
static int i8042_initfn(ISADevice *dev)
|
||||
{
|
||||
KBDState *s = &(DO_UPCAST(ISAKBDState, dev, dev)->kbd);
|
||||
ISAKBDState *isa_s = DO_UPCAST(ISAKBDState, dev, dev);
|
||||
KBDState *s = &isa_s->kbd;
|
||||
|
||||
isa_init_irq(dev, &s->irq_kbd, 1);
|
||||
isa_init_irq(dev, &s->irq_mouse, 12);
|
||||
|
||||
register_ioport_read(0x60, 1, 1, kbd_read_data, s);
|
||||
register_ioport_write(0x60, 1, 1, kbd_write_data, s);
|
||||
isa_init_ioport(dev, 0x60);
|
||||
register_ioport_read(0x64, 1, 1, kbd_read_status, s);
|
||||
register_ioport_write(0x64, 1, 1, kbd_write_command, s);
|
||||
isa_init_ioport(dev, 0x64);
|
||||
memory_region_init_io(isa_s->io + 0, &i8042_data_ops, s, "i8042-data", 1);
|
||||
isa_register_ioport(dev, isa_s->io + 0, 0x60);
|
||||
|
||||
memory_region_init_io(isa_s->io + 1, &i8042_cmd_ops, s, "i8042-cmd", 1);
|
||||
isa_register_ioport(dev, isa_s->io + 1, 0x64);
|
||||
|
||||
s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
|
||||
s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
|
||||
|
@ -87,7 +87,7 @@ static int piix4_initfn(PCIDevice *dev)
|
||||
{
|
||||
PIIX4State *d = DO_UPCAST(PIIX4State, dev, dev);
|
||||
|
||||
isa_bus_new(&d->dev.qdev);
|
||||
isa_bus_new(&d->dev.qdev, pci_address_space_io(dev));
|
||||
piix4_dev = &d->dev;
|
||||
qemu_register_reset(piix4_reset, d);
|
||||
return 0;
|
||||
|
@ -504,7 +504,7 @@ static int piix3_initfn(PCIDevice *dev)
|
||||
{
|
||||
PIIX3State *d = DO_UPCAST(PIIX3State, dev, dev);
|
||||
|
||||
isa_bus_new(&d->dev.qdev);
|
||||
isa_bus_new(&d->dev.qdev, pci_address_space_io(dev));
|
||||
qemu_register_reset(piix3_reset, d);
|
||||
return 0;
|
||||
}
|
||||
|
@ -648,10 +648,10 @@ static void ppc_prep_init (ram_addr_t ram_size,
|
||||
if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
|
||||
hw_error("Only 6xx bus is supported on PREP machine\n");
|
||||
}
|
||||
/* Hmm, prep has no pci-isa bridge ??? */
|
||||
isa_bus_new(NULL, get_system_io());
|
||||
i8259 = i8259_init(first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
|
||||
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);
|
||||
// pci_bus = i440fx_init();
|
||||
/* Register 8 MB of ISA IO space (needed for non-contiguous map) */
|
||||
|
15
hw/serial.c
15
hw/serial.c
@ -157,6 +157,7 @@ struct SerialState {
|
||||
|
||||
typedef struct ISASerialState {
|
||||
ISADevice dev;
|
||||
MemoryRegion io;
|
||||
uint32_t index;
|
||||
uint32_t iobase;
|
||||
uint32_t isairq;
|
||||
@ -755,6 +756,15 @@ void serial_set_frequency(SerialState *s, uint32_t frequency)
|
||||
static const int isa_serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
|
||||
static const int isa_serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
|
||||
|
||||
static const MemoryRegionPortio serial_portio[] = {
|
||||
{ 0, 8, 1, .read = serial_ioport_read, .write = serial_ioport_write },
|
||||
PORTIO_END_OF_LIST()
|
||||
};
|
||||
|
||||
static const MemoryRegionOps serial_io_ops = {
|
||||
.old_portio = serial_portio
|
||||
};
|
||||
|
||||
static int serial_isa_initfn(ISADevice *dev)
|
||||
{
|
||||
static int index;
|
||||
@ -776,9 +786,8 @@ static int serial_isa_initfn(ISADevice *dev)
|
||||
serial_init_core(s);
|
||||
qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 3);
|
||||
|
||||
register_ioport_write(isa->iobase, 8, 1, serial_ioport_write, s);
|
||||
register_ioport_read(isa->iobase, 8, 1, serial_ioport_read, s);
|
||||
isa_init_ioport_range(dev, isa->iobase, 8);
|
||||
memory_region_init_io(&isa->io, &serial_io_ops, s, "serial", 8);
|
||||
isa_register_ioport(dev, &isa->io, isa->iobase);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -548,7 +548,7 @@ pci_ebus_init1(PCIDevice *pci_dev)
|
||||
{
|
||||
EbusState *s = DO_UPCAST(EbusState, pci_dev, pci_dev);
|
||||
|
||||
isa_bus_new(&pci_dev->qdev);
|
||||
isa_bus_new(&pci_dev->qdev, pci_address_space_io(pci_dev));
|
||||
|
||||
pci_dev->config[0x04] = 0x06; // command = bus master, pci mem
|
||||
pci_dev->config[0x05] = 0x00;
|
||||
|
@ -490,7 +490,7 @@ static int vt82c686b_initfn(PCIDevice *d)
|
||||
uint8_t *wmask;
|
||||
int i;
|
||||
|
||||
isa_bus_new(&d->qdev);
|
||||
isa_bus_new(&d->qdev, pci_address_space_io(d));
|
||||
|
||||
pci_conf = d->config;
|
||||
pci_config_set_prog_interface(pci_conf, 0x0);
|
||||
|
Loading…
Reference in New Issue
Block a user