[Spice-commits] Branch 'audio.2' - 2 commits - hw/intel-hda.c
Gerd Hoffmann
kraxel at kemper.freedesktop.org
Fri Oct 29 07:35:18 PDT 2010
hw/intel-hda.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 87 insertions(+), 11 deletions(-)
New commits:
commit bd17cbbccd6d77a9f4cf46acffe88b77bd923045
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Fri Oct 29 16:33:48 2010 +0200
intel-hda: savevm support [not tested yet]
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index f75459c..72d91d5 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -165,7 +165,7 @@ struct IntelHDAState {
/* state */
int mmio_addr;
uint32_t rirb_count;
- qemu_timeval wall_base;
+ uint64_t wall_base_usecs;
/* debug logging */
const IntelHDAReg *last_reg;
@@ -509,13 +509,11 @@ static void intel_hda_set_int_ctl(IntelHDAState *d, const IntelHDAReg *reg, uint
static void intel_hda_get_wall_clk(IntelHDAState *d, const IntelHDAReg *reg)
{
qemu_timeval tv;
- uint64_t usec;
+ uint64_t usecs;
qemu_gettimeofday(&tv);
- usec = (tv.tv_sec - d->wall_base.tv_sec) * 1000000;
- usec += tv.tv_usec;
- usec -= d->wall_base.tv_sec;
- d->wall_clk = usec * 24; /* 24 MHz */
+ usecs = (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec;
+ d->wall_clk = (uint32_t)((usecs - d->wall_base_usecs) * 24); /* 24 MHz */
}
static void intel_hda_set_corb_wp(IntelHDAState *d, const IntelHDAReg *reg, uint32_t old)
@@ -1098,9 +1096,11 @@ static void intel_hda_reset(DeviceState *dev)
IntelHDAState *d = DO_UPCAST(IntelHDAState, pci.qdev, dev);
DeviceState *qdev;
HDACodecDevice *cdev;
+ qemu_timeval tv;
intel_hda_regs_reset(d);
- qemu_gettimeofday(&d->wall_base);
+ qemu_gettimeofday(&tv);
+ d->wall_base_usecs = (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec;
/* reset codecs */
QLIST_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
@@ -1140,11 +1140,77 @@ static int intel_hda_init(PCIDevice *pci)
return 0;
}
+static int intel_hda_post_load(void *opaque, int version)
+{
+ IntelHDAState* d = opaque;
+ int i;
+
+ dprint(d, 1, "%s\n", __FUNCTION__);
+ for (i = 0; i < ARRAY_SIZE(d->st); i++) {
+ if (d->st[i].ctl & 0x02) {
+ intel_hda_parse_bdl(d, &d->st[i]);
+ }
+ }
+ intel_hda_update_irq(d);
+ return 0;
+}
+
+static const VMStateDescription vmstate_intel_hda_stream = {
+ .name = "intel-hda-stream",
+ .version_id = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_UINT32(ctl, IntelHDAStream),
+ VMSTATE_UINT32(lpib, IntelHDAStream),
+ VMSTATE_UINT32(cbl, IntelHDAStream),
+ VMSTATE_UINT32(lvi, IntelHDAStream),
+ VMSTATE_UINT32(fmt, IntelHDAStream),
+ VMSTATE_UINT32(bdlp_lbase, IntelHDAStream),
+ VMSTATE_UINT32(bdlp_ubase, IntelHDAStream),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static const VMStateDescription vmstate_intel_hda = {
.name = "intel-hda",
.version_id = 1,
- .fields = (VMStateField []) {
+ .post_load = intel_hda_post_load,
+ .fields = (VMStateField []) {
VMSTATE_PCI_DEVICE(pci, IntelHDAState),
+
+ /* registers */
+ VMSTATE_UINT32(g_ctl, IntelHDAState),
+ VMSTATE_UINT32(wake_en, IntelHDAState),
+ VMSTATE_UINT32(state_sts, IntelHDAState),
+ VMSTATE_UINT32(int_ctl, IntelHDAState),
+ VMSTATE_UINT32(int_sts, IntelHDAState),
+ VMSTATE_UINT32(wall_clk, IntelHDAState),
+ VMSTATE_UINT32(corb_lbase, IntelHDAState),
+ VMSTATE_UINT32(corb_ubase, IntelHDAState),
+ VMSTATE_UINT32(corb_rp, IntelHDAState),
+ VMSTATE_UINT32(corb_wp, IntelHDAState),
+ VMSTATE_UINT32(corb_ctl, IntelHDAState),
+ VMSTATE_UINT32(corb_sts, IntelHDAState),
+ VMSTATE_UINT32(corb_size, IntelHDAState),
+ VMSTATE_UINT32(rirb_lbase, IntelHDAState),
+ VMSTATE_UINT32(rirb_ubase, IntelHDAState),
+ VMSTATE_UINT32(rirb_wp, IntelHDAState),
+ VMSTATE_UINT32(rirb_cnt, IntelHDAState),
+ VMSTATE_UINT32(rirb_ctl, IntelHDAState),
+ VMSTATE_UINT32(rirb_sts, IntelHDAState),
+ VMSTATE_UINT32(rirb_size, IntelHDAState),
+ VMSTATE_UINT32(dp_lbase, IntelHDAState),
+ VMSTATE_UINT32(dp_ubase, IntelHDAState),
+ VMSTATE_UINT32(icw, IntelHDAState),
+ VMSTATE_UINT32(irr, IntelHDAState),
+ VMSTATE_UINT32(ics, IntelHDAState),
+ VMSTATE_STRUCT_ARRAY(st, IntelHDAState, 8, 0,
+ vmstate_intel_hda_stream,
+ IntelHDAStream),
+
+ /* additional state info */
+ VMSTATE_UINT32(rirb_count, IntelHDAState),
+ VMSTATE_UINT64(wall_base_usecs, IntelHDAState),
+
VMSTATE_END_OF_LIST()
}
};
commit cc59f91031d65f88d5c712cee94fba16b2616ad1
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Fri Oct 29 15:53:16 2010 +0200
intel-hda: drop guest-triggerable asserts
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 053936a..f75459c 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -274,12 +274,19 @@ static int intel_hda_send_command(IntelHDAState *d, uint32_t verb)
HDACodecDevice *codec;
cad = (verb >> 28) & 0x0f;
- assert(!(verb & (1 << 27))); /* indirect addressing, unspecified */
+ if (verb & (1 << 27)) {
+ /* indirect node addressing, not specified in HDA 1.0 */
+ dprint(d, 1, "%s: indirect node addressing (guest bug?)\n", __FUNCTION__);
+ return -1;
+ }
nid = (verb >> 20) & 0x7f;
data = verb & 0xfffff;
codec = hda_codec_find(&d->codecs, cad);
- assert(codec != NULL);
+ if (codec == NULL) {
+ dprint(d, 1, "%s: addressed non-existing codec\n", __FUNCTION__);
+ return -1;
+ }
codec->info->command(codec, nid, data);
return 0;
}
@@ -335,7 +342,10 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res
return;
}
- assert(d->rirb_ctl & ICH6_RBCTL_DMA_EN);
+ if (!(d->rirb_ctl & ICH6_RBCTL_DMA_EN)) {
+ dprint(d, 1, "%s: rirb dma disabled, drop codec response\n", __FUNCTION__);
+ return;
+ }
ex = (solicited ? 0 : (1 << 4)) | dev->cad;
wp = (d->rirb_wp + 1) & 0xff;
More information about the Spice-commits
mailing list