diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/char/pl011.c | 24 | ||||
-rw-r--r-- | hw/ide/ahci.c | 13 |
2 files changed, 24 insertions, 13 deletions
diff --git a/hw/char/pl011.c b/hw/char/pl011.c index a8ae6f4706..644aad7cf0 100644 --- a/hw/char/pl011.c +++ b/hw/char/pl011.c @@ -20,6 +20,7 @@ typedef struct PL011State { uint32_t readbuff; uint32_t flags; uint32_t lcr; + uint32_t rsr; uint32_t cr; uint32_t dmacr; uint32_t int_enabled; @@ -81,13 +82,14 @@ static uint64_t pl011_read(void *opaque, hwaddr offset, } if (s->read_count == s->read_trigger - 1) s->int_level &= ~ PL011_INT_RX; + s->rsr = c >> 8; pl011_update(s); if (s->chr) { qemu_chr_accept_input(s->chr); } return c; - case 1: /* UARTCR */ - return 0; + case 1: /* UARTRSR */ + return s->rsr; case 6: /* UARTFR */ return s->flags; case 8: /* UARTILPR */ @@ -146,8 +148,8 @@ static void pl011_write(void *opaque, hwaddr offset, s->int_level |= PL011_INT_TX; pl011_update(s); break; - case 1: /* UARTCR */ - s->cr = value; + case 1: /* UARTRSR/UARTECR */ + s->rsr = 0; break; case 6: /* UARTFR */ /* Writes to Flag register are ignored. */ @@ -162,6 +164,11 @@ static void pl011_write(void *opaque, hwaddr offset, s->fbrd = value; break; case 11: /* UARTLCR_H */ + /* Reset the FIFO state on FIFO enable or disable */ + if ((s->lcr ^ value) & 0x10) { + s->read_count = 0; + s->read_pos = 0; + } s->lcr = value; pl011_set_read_trigger(s); break; @@ -214,7 +221,7 @@ static void pl011_put_fifo(void *opaque, uint32_t value) s->read_fifo[slot] = value; s->read_count++; s->flags &= ~PL011_FLAG_RXFE; - if (s->cr & 0x10 || s->read_count == 16) { + if (!(s->lcr & 0x10) || s->read_count == 16) { s->flags |= PL011_FLAG_RXFF; } if (s->read_count == s->read_trigger) { @@ -242,13 +249,14 @@ static const MemoryRegionOps pl011_ops = { static const VMStateDescription vmstate_pl011 = { .name = "pl011", - .version_id = 1, - .minimum_version_id = 1, - .minimum_version_id_old = 1, + .version_id = 2, + .minimum_version_id = 2, + .minimum_version_id_old = 2, .fields = (VMStateField[]) { VMSTATE_UINT32(readbuff, PL011State), VMSTATE_UINT32(flags, PL011State), VMSTATE_UINT32(lcr, PL011State), + VMSTATE_UINT32(rsr, PL011State), VMSTATE_UINT32(cr, PL011State), VMSTATE_UINT32(dmacr, PL011State), VMSTATE_UINT32(int_enabled, PL011State), diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index fbea9e8886..bfe633f3a5 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -118,11 +118,12 @@ static uint32_t ahci_port_read(AHCIState *s, int port, int offset) static void ahci_irq_raise(AHCIState *s, AHCIDevice *dev) { AHCIPCIState *d = container_of(s, AHCIPCIState, ahci); - PCIDevice *pci_dev = PCI_DEVICE(d); + PCIDevice *pci_dev = + (PCIDevice *)object_dynamic_cast(OBJECT(d), TYPE_PCI_DEVICE); DPRINTF(0, "raise irq\n"); - if (msi_enabled(pci_dev)) { + if (pci_dev && msi_enabled(pci_dev)) { msi_notify(pci_dev, 0); } else { qemu_irq_raise(s->irq); @@ -132,10 +133,12 @@ static void ahci_irq_raise(AHCIState *s, AHCIDevice *dev) static void ahci_irq_lower(AHCIState *s, AHCIDevice *dev) { AHCIPCIState *d = container_of(s, AHCIPCIState, ahci); + PCIDevice *pci_dev = + (PCIDevice *)object_dynamic_cast(OBJECT(d), TYPE_PCI_DEVICE); DPRINTF(0, "lower irq\n"); - if (!msi_enabled(PCI_DEVICE(d))) { + if (!pci_dev || !msi_enabled(pci_dev)) { qemu_irq_lower(s->irq); } } @@ -1311,7 +1314,7 @@ static const VMStateDescription vmstate_sysbus_ahci = { .name = "sysbus-ahci", .unmigratable = 1, /* Still buggy under I/O load */ .fields = (VMStateField []) { - VMSTATE_AHCI(ahci, AHCIPCIState), + VMSTATE_AHCI(ahci, SysbusAHCIState), VMSTATE_END_OF_LIST() }, }; @@ -1328,7 +1331,7 @@ static void sysbus_ahci_realize(DeviceState *dev, Error **errp) SysBusDevice *sbd = SYS_BUS_DEVICE(dev); SysbusAHCIState *s = SYSBUS_AHCI(dev); - ahci_init(&s->ahci, dev, NULL, s->num_ports); + ahci_init(&s->ahci, dev, &address_space_memory, s->num_ports); sysbus_init_mmio(sbd, &s->ahci.mem); sysbus_init_irq(sbd, &s->ahci.irq); |