[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