mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-24 03:59:52 +00:00
hw/audio/intel-hda: Do not ignore DMA overrun errors
Per the "High Definition Audio Specification" manual (rev. 1.0a), section "3.3.30 Offset 5Dh: RIRBSTS - RIRB Status": Response Overrun Interrupt Status (RIRBOIS): Hardware sets this bit to a 1 when an overrun occurs in the RIRB. An interrupt may be generated if the Response Overrun Interrupt Control bit is set. This bit will be set if the RIRB DMA engine is not able to write the incoming responses to memory before additional incoming responses overrun the internal FIFO. When hardware detects an overrun, it will drop the responses which overrun the buffer and set the RIRBOIS status bit to indicate the error condition. Optionally, if the RIRBOIC is set, the hardware will also generate an error to alert software to the problem. QEMU emulates the DMA engine with the stl_le_pci_dma() calls. This function returns a MemTxResult indicating whether the DMA access was successful. Handle any MemTxResult error as "DMA engine is not able to write the incoming responses to memory" and raise the Overrun Interrupt flag when this case occurs. Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> Message-Id: <20211218160912.1591633-2-philmd@redhat.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
parent
3ab6fdc91b
commit
be5a8cf347
@ -350,6 +350,7 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res
|
|||||||
IntelHDAState *d = container_of(bus, IntelHDAState, codecs);
|
IntelHDAState *d = container_of(bus, IntelHDAState, codecs);
|
||||||
hwaddr addr;
|
hwaddr addr;
|
||||||
uint32_t wp, ex;
|
uint32_t wp, ex;
|
||||||
|
MemTxResult res = MEMTX_OK;
|
||||||
|
|
||||||
if (d->ics & ICH6_IRS_BUSY) {
|
if (d->ics & ICH6_IRS_BUSY) {
|
||||||
dprint(d, 2, "%s: [irr] response 0x%x, cad 0x%x\n",
|
dprint(d, 2, "%s: [irr] response 0x%x, cad 0x%x\n",
|
||||||
@ -368,8 +369,12 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res
|
|||||||
ex = (solicited ? 0 : (1 << 4)) | dev->cad;
|
ex = (solicited ? 0 : (1 << 4)) | dev->cad;
|
||||||
wp = (d->rirb_wp + 1) & 0xff;
|
wp = (d->rirb_wp + 1) & 0xff;
|
||||||
addr = intel_hda_addr(d->rirb_lbase, d->rirb_ubase);
|
addr = intel_hda_addr(d->rirb_lbase, d->rirb_ubase);
|
||||||
stl_le_pci_dma(&d->pci, addr + 8 * wp, response, attrs);
|
res |= stl_le_pci_dma(&d->pci, addr + 8 * wp, response, attrs);
|
||||||
stl_le_pci_dma(&d->pci, addr + 8 * wp + 4, ex, attrs);
|
res |= stl_le_pci_dma(&d->pci, addr + 8 * wp + 4, ex, attrs);
|
||||||
|
if (res != MEMTX_OK && (d->rirb_ctl & ICH6_RBCTL_OVERRUN_EN)) {
|
||||||
|
d->rirb_sts |= ICH6_RBSTS_OVERRUN;
|
||||||
|
intel_hda_update_irq(d);
|
||||||
|
}
|
||||||
d->rirb_wp = wp;
|
d->rirb_wp = wp;
|
||||||
|
|
||||||
dprint(d, 2, "%s: [wp 0x%x] response 0x%x, extra 0x%x\n",
|
dprint(d, 2, "%s: [wp 0x%x] response 0x%x, extra 0x%x\n",
|
||||||
|
Loading…
Reference in New Issue
Block a user