mirror of https://github.com/xemu-project/xemu.git
i8259: Convert to MemoryRegion
The only non-obvious part is pic_poll_read which used "addr1 >> 7" to detect whether one referred to either the master or slave PIC. Instead, test this directly. Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
parent
bac8ad41ab
commit
098d314a32
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; /* PIIX edge/trigger selection*/
|
||||||
uint8_t elcr_mask;
|
uint8_t elcr_mask;
|
||||||
PicState2 *pics_state;
|
PicState2 *pics_state;
|
||||||
|
MemoryRegion base_io;
|
||||||
|
MemoryRegion elcr_io;
|
||||||
} PicState;
|
} PicState;
|
||||||
|
|
||||||
struct PicState2 {
|
struct PicState2 {
|
||||||
|
@ -284,13 +286,15 @@ static void pic_reset(void *opaque)
|
||||||
/* Note: ELCR is not reset */
|
/* 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;
|
PicState *s = opaque;
|
||||||
|
uint32_t addr = addr64;
|
||||||
|
uint32_t val = val64;
|
||||||
int priority, cmd, irq;
|
int priority, cmd, irq;
|
||||||
|
|
||||||
DPRINTF("write: addr=0x%02x val=0x%02x\n", addr, val);
|
DPRINTF("write: addr=0x%02x val=0x%02x\n", addr, val);
|
||||||
addr &= 1;
|
|
||||||
if (addr == 0) {
|
if (addr == 0) {
|
||||||
if (val & 0x10) {
|
if (val & 0x10) {
|
||||||
/* init */
|
/* 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;
|
int ret;
|
||||||
|
|
||||||
ret = pic_get_irq(s);
|
ret = pic_get_irq(s);
|
||||||
if (ret >= 0) {
|
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].isr &= ~(1 << 2);
|
||||||
s->pics_state->pics[0].irr &= ~(1 << 2);
|
s->pics_state->pics[0].irr &= ~(1 << 2);
|
||||||
}
|
}
|
||||||
s->irr &= ~(1 << ret);
|
s->irr &= ~(1 << ret);
|
||||||
s->isr &= ~(1 << ret);
|
s->isr &= ~(1 << ret);
|
||||||
if (addr1 >> 7 || ret != 2)
|
if (slave || ret != 2)
|
||||||
pic_update_irq(s->pics_state);
|
pic_update_irq(s->pics_state);
|
||||||
} else {
|
} else {
|
||||||
ret = 0x07;
|
ret = 0x07;
|
||||||
|
@ -396,16 +402,15 @@ static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
|
||||||
return ret;
|
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;
|
PicState *s = opaque;
|
||||||
unsigned int addr;
|
unsigned int addr = addr1;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
addr = addr1;
|
|
||||||
addr &= 1;
|
|
||||||
if (s->poll) {
|
if (s->poll) {
|
||||||
ret = pic_poll_read(s, addr1);
|
ret = pic_poll_read(s);
|
||||||
s->poll = 0;
|
s->poll = 0;
|
||||||
} else {
|
} else {
|
||||||
if (addr == 0) {
|
if (addr == 0) {
|
||||||
|
@ -417,7 +422,7 @@ static uint32_t pic_ioport_read(void *opaque, uint32_t addr1)
|
||||||
ret = s->imr;
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,22 +432,24 @@ uint32_t pic_intack_read(PicState2 *s)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = pic_poll_read(&s->pics[0], 0x00);
|
ret = pic_poll_read(&s->pics[0]);
|
||||||
if (ret == 2)
|
if (ret == 2)
|
||||||
ret = pic_poll_read(&s->pics[1], 0x80) + 8;
|
ret = pic_poll_read(&s->pics[1]) + 8;
|
||||||
/* Prepare for ISR read */
|
/* Prepare for ISR read */
|
||||||
s->pics[0].read_reg_select = 1;
|
s->pics[0].read_reg_select = 1;
|
||||||
|
|
||||||
return ret;
|
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;
|
PicState *s = opaque;
|
||||||
s->elcr = val & s->elcr_mask;
|
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;
|
PicState *s = opaque;
|
||||||
return s->elcr;
|
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 */
|
/* XXX: add generic master/slave system */
|
||||||
static void pic_init1(int io_addr, int elcr_addr, PicState *s)
|
static void pic_init1(int io_addr, int elcr_addr, PicState *s)
|
||||||
{
|
{
|
||||||
register_ioport_write(io_addr, 2, 1, pic_ioport_write, s);
|
memory_region_init_io(&s->base_io, &pic_base_ioport_ops, s, "pic", 2);
|
||||||
register_ioport_read(io_addr, 2, 1, pic_ioport_read, s);
|
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) {
|
if (elcr_addr >= 0) {
|
||||||
register_ioport_write(elcr_addr, 1, 1, elcr_ioport_write, s);
|
isa_register_ioport(NULL, &s->elcr_io, elcr_addr);
|
||||||
register_ioport_read(elcr_addr, 1, 1, elcr_ioport_read, s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vmstate_register(NULL, io_addr, &vmstate_pic, s);
|
vmstate_register(NULL, io_addr, &vmstate_pic, s);
|
||||||
qemu_register_reset(pic_reset, s);
|
qemu_register_reset(pic_reset, s);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue