pcnet-pci: Fix PIO word access to PROM
Implement the various IO access widths according to the spec. This specifically unbreaks word and dword access to the PROM area that is mapped into IO space. It also drops redundant upper limit checks and spurious "return void". Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
488a1a5dfe
commit
7ba7974197
|
@ -76,12 +76,24 @@ static uint64_t pcnet_ioport_read(void *opaque, target_phys_addr_t addr,
|
||||||
{
|
{
|
||||||
PCNetState *d = opaque;
|
PCNetState *d = opaque;
|
||||||
|
|
||||||
if (addr < 16 && size == 1) {
|
if (addr < 0x10) {
|
||||||
return pcnet_aprom_readb(d, addr);
|
if (!BCR_DWIO(d) && size == 1) {
|
||||||
} else if (addr >= 0x10 && addr < 0x20 && size == 2) {
|
return pcnet_aprom_readb(d, addr);
|
||||||
return pcnet_ioport_readw(d, addr);
|
} else if (!BCR_DWIO(d) && (addr & 1) == 0 && size == 2) {
|
||||||
} else if (addr >= 0x10 && addr < 0x20 && size == 4) {
|
return pcnet_aprom_readb(d, addr) |
|
||||||
return pcnet_ioport_readl(d, addr);
|
(pcnet_aprom_readb(d, addr + 1) << 8);
|
||||||
|
} else if (BCR_DWIO(d) && (addr & 3) == 0 && size == 4) {
|
||||||
|
return pcnet_aprom_readb(d, addr) |
|
||||||
|
(pcnet_aprom_readb(d, addr + 1) << 8) |
|
||||||
|
(pcnet_aprom_readb(d, addr + 2) << 16) |
|
||||||
|
(pcnet_aprom_readb(d, addr + 3) << 24);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (size == 2) {
|
||||||
|
return pcnet_ioport_readw(d, addr);
|
||||||
|
} else if (size == 4) {
|
||||||
|
return pcnet_ioport_readl(d, addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ((uint64_t)1 << (size * 8)) - 1;
|
return ((uint64_t)1 << (size * 8)) - 1;
|
||||||
}
|
}
|
||||||
|
@ -91,12 +103,24 @@ static void pcnet_ioport_write(void *opaque, target_phys_addr_t addr,
|
||||||
{
|
{
|
||||||
PCNetState *d = opaque;
|
PCNetState *d = opaque;
|
||||||
|
|
||||||
if (addr < 16 && size == 1) {
|
if (addr < 0x10) {
|
||||||
return pcnet_aprom_writeb(d, addr, data);
|
if (!BCR_DWIO(d) && size == 1) {
|
||||||
} else if (addr >= 0x10 && addr < 0x20 && size == 2) {
|
pcnet_aprom_writeb(d, addr, data);
|
||||||
return pcnet_ioport_writew(d, addr, data);
|
} else if (!BCR_DWIO(d) && (addr & 1) == 0 && size == 2) {
|
||||||
} else if (addr >= 0x10 && addr < 0x20 && size == 4) {
|
pcnet_aprom_writeb(d, addr, data & 0xff);
|
||||||
return pcnet_ioport_writel(d, addr, data);
|
pcnet_aprom_writeb(d, addr + 1, data >> 8);
|
||||||
|
} else if (BCR_DWIO(d) && (addr & 3) == 0 && size == 4) {
|
||||||
|
pcnet_aprom_writeb(d, addr, data & 0xff);
|
||||||
|
pcnet_aprom_writeb(d, addr + 1, (data >> 8) & 0xff);
|
||||||
|
pcnet_aprom_writeb(d, addr + 2, (data >> 16) & 0xff);
|
||||||
|
pcnet_aprom_writeb(d, addr + 3, data >> 24);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (size == 2) {
|
||||||
|
pcnet_ioport_writew(d, addr, data);
|
||||||
|
} else if (size == 4) {
|
||||||
|
pcnet_ioport_writel(d, addr, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue