#include "hw/pci/pci.h"
#include "hw/pci/msi.h"
#include "qemu/timer.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
#include "hw/audio/soundhw.h"
#include "intel-hda.h"
+#include "migration/vmstate.h"
#include "intel-hda-defs.h"
#include "sysemu/dma.h"
#include "qapi/error.h"
} else {
level = 0;
}
- dprint(d, 2, "%s: level %d [%s]\n", __FUNCTION__,
+ dprint(d, 2, "%s: level %d [%s]\n", __func__,
level, msi ? "msi" : "intx");
if (msi) {
if (level) {
cad = (verb >> 28) & 0x0f;
if (verb & (1 << 27)) {
/* indirect node addressing, not specified in HDA 1.0 */
- dprint(d, 1, "%s: indirect node addressing (guest bug?)\n", __FUNCTION__);
+ dprint(d, 1, "%s: indirect node addressing (guest bug?)\n", __func__);
return -1;
}
nid = (verb >> 20) & 0x7f;
codec = hda_codec_find(&d->codecs, cad);
if (codec == NULL) {
- dprint(d, 1, "%s: addressed non-existing codec\n", __FUNCTION__);
+ dprint(d, 1, "%s: addressed non-existing codec\n", __func__);
return -1;
}
cdc = HDA_CODEC_DEVICE_GET_CLASS(codec);
uint32_t rp, verb;
if (d->ics & ICH6_IRS_BUSY) {
- dprint(d, 2, "%s: [icw] verb 0x%08x\n", __FUNCTION__, d->icw);
+ dprint(d, 2, "%s: [icw] verb 0x%08x\n", __func__, d->icw);
intel_hda_send_command(d, d->icw);
return;
}
for (;;) {
if (!(d->corb_ctl & ICH6_CORBCTL_RUN)) {
- dprint(d, 2, "%s: !run\n", __FUNCTION__);
+ dprint(d, 2, "%s: !run\n", __func__);
return;
}
if ((d->corb_rp & 0xff) == d->corb_wp) {
- dprint(d, 2, "%s: corb ring empty\n", __FUNCTION__);
+ dprint(d, 2, "%s: corb ring empty\n", __func__);
return;
}
if (d->rirb_count == d->rirb_cnt) {
- dprint(d, 2, "%s: rirb count reached\n", __FUNCTION__);
+ dprint(d, 2, "%s: rirb count reached\n", __func__);
return;
}
verb = ldl_le_pci_dma(&d->pci, addr + 4*rp);
d->corb_rp = rp;
- dprint(d, 2, "%s: [rp 0x%x] verb 0x%08x\n", __FUNCTION__, rp, verb);
+ dprint(d, 2, "%s: [rp 0x%x] verb 0x%08x\n", __func__, rp, verb);
intel_hda_send_command(d, verb);
}
}
if (d->ics & ICH6_IRS_BUSY) {
dprint(d, 2, "%s: [irr] response 0x%x, cad 0x%x\n",
- __FUNCTION__, response, dev->cad);
+ __func__, response, dev->cad);
d->irr = response;
d->ics &= ~(ICH6_IRS_BUSY | 0xf0);
d->ics |= (ICH6_IRS_VALID | (dev->cad << 4));
}
if (!(d->rirb_ctl & ICH6_RBCTL_DMA_EN)) {
- dprint(d, 1, "%s: rirb dma disabled, drop codec response\n", __FUNCTION__);
+ dprint(d, 1, "%s: rirb dma disabled, drop codec response\n", __func__);
return;
}
d->rirb_wp = wp;
dprint(d, 2, "%s: [wp 0x%x] response 0x%x, extra 0x%x\n",
- __FUNCTION__, wp, response, ex);
+ __func__, wp, response, ex);
d->rirb_count++;
if (d->rirb_count == d->rirb_cnt) {
- dprint(d, 2, "%s: rirb count reached (%d)\n", __FUNCTION__, d->rirb_count);
+ dprint(d, 2, "%s: rirb count reached (%d)\n", __func__, d->rirb_count);
if (d->rirb_ctl & ICH6_RBCTL_IRQ_EN) {
d->rirb_sts |= ICH6_RBSTS_IRQ;
intel_hda_update_irq(d);
}
} else if ((d->corb_rp & 0xff) == d->corb_wp) {
- dprint(d, 2, "%s: corb ring empty (%d/%d)\n", __FUNCTION__,
+ dprint(d, 2, "%s: corb ring empty (%d/%d)\n", __func__,
d->rirb_count, d->rirb_cnt);
if (d->rirb_ctl & ICH6_RBCTL_IRQ_EN) {
d->rirb_sts |= ICH6_RBSTS_IRQ;
if (st->bpl == NULL) {
return false;
}
- if (st->ctl & (1 << 26)) {
- /*
- * Wait with the next DMA xfer until the guest
- * has acked the buffer completion interrupt
- */
- return false;
- }
left = len;
s = st->bentries;
if (!reg) {
return;
}
+ if (!reg->wmask) {
+ qemu_log_mask(LOG_GUEST_ERROR, "intel-hda: write to r/o reg %s\n",
+ reg->name);
+ return;
+ }
if (d->debug) {
time_t now = time(NULL);
/* --------------------------------------------------------------------- */
-static void intel_hda_mmio_writeb(void *opaque, hwaddr addr, uint32_t val)
+static void intel_hda_mmio_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned size)
{
IntelHDAState *d = opaque;
const IntelHDAReg *reg = intel_hda_reg_find(d, addr);
- intel_hda_reg_write(d, reg, val, 0xff);
+ intel_hda_reg_write(d, reg, val, MAKE_64BIT_MASK(0, size * 8));
}
-static void intel_hda_mmio_writew(void *opaque, hwaddr addr, uint32_t val)
+static uint64_t intel_hda_mmio_read(void *opaque, hwaddr addr, unsigned size)
{
IntelHDAState *d = opaque;
const IntelHDAReg *reg = intel_hda_reg_find(d, addr);
- intel_hda_reg_write(d, reg, val, 0xffff);
-}
-
-static void intel_hda_mmio_writel(void *opaque, hwaddr addr, uint32_t val)
-{
- IntelHDAState *d = opaque;
- const IntelHDAReg *reg = intel_hda_reg_find(d, addr);
-
- intel_hda_reg_write(d, reg, val, 0xffffffff);
-}
-
-static uint32_t intel_hda_mmio_readb(void *opaque, hwaddr addr)
-{
- IntelHDAState *d = opaque;
- const IntelHDAReg *reg = intel_hda_reg_find(d, addr);
-
- return intel_hda_reg_read(d, reg, 0xff);
-}
-
-static uint32_t intel_hda_mmio_readw(void *opaque, hwaddr addr)
-{
- IntelHDAState *d = opaque;
- const IntelHDAReg *reg = intel_hda_reg_find(d, addr);
-
- return intel_hda_reg_read(d, reg, 0xffff);
-}
-
-static uint32_t intel_hda_mmio_readl(void *opaque, hwaddr addr)
-{
- IntelHDAState *d = opaque;
- const IntelHDAReg *reg = intel_hda_reg_find(d, addr);
-
- return intel_hda_reg_read(d, reg, 0xffffffff);
+ return intel_hda_reg_read(d, reg, MAKE_64BIT_MASK(0, size * 8));
}
static const MemoryRegionOps intel_hda_mmio_ops = {
- .old_mmio = {
- .read = {
- intel_hda_mmio_readb,
- intel_hda_mmio_readw,
- intel_hda_mmio_readl,
- },
- .write = {
- intel_hda_mmio_writeb,
- intel_hda_mmio_writew,
- intel_hda_mmio_writel,
- },
+ .read = intel_hda_mmio_read,
+ .write = intel_hda_mmio_write,
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 4,
},
.endianness = DEVICE_NATIVE_ENDIAN,
};
IntelHDAState* d = opaque;
int i;
- dprint(d, 1, "%s\n", __FUNCTION__);
+ dprint(d, 1, "%s\n", __func__);
for (i = 0; i < ARRAY_SIZE(d->st); i++) {
if (d->st[i].ctl & 0x02) {
intel_hda_parse_bdl(d, &d->st[i]);
.instance_size = sizeof(IntelHDAState),
.class_init = intel_hda_class_init,
.abstract = true,
+ .interfaces = (InterfaceInfo[]) {
+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+ { },
+ },
};
static const TypeInfo intel_hda_info_ich6 = {