[Spice-commits] Branch 'audio.2' - 4 commits - hw/hda-audio.c hw/hw.h hw/intel-hda.c savevm.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Mon Nov 1 04:05:13 PDT 2010


 hw/hda-audio.c |  109 +++++++++++++++++++++++++++++++++++++++++++++------------
 hw/hw.h        |   14 +++++++
 hw/intel-hda.c |   17 +++-----
 savevm.c       |   21 ++++++++++
 4 files changed, 129 insertions(+), 32 deletions(-)

New commits:
commit 2b7b1acbca4fd8a5464b7e42f3deb9a26aa026df
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Mon Nov 1 12:00:54 2010 +0100

    hda-audio: add savevm, handle partial audio reads/writes, misc tweaks.

diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index 6f47429..a21f9a1 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -443,8 +443,8 @@ typedef struct HDAAudioStream HDAAudioStream;
 
 struct HDAAudioStream {
     HDAAudioState *state;
-    bool output, running, wbuf;
     const desc_node *node;
+    bool output, running;
     uint32_t stream;
     uint32_t channel;
     uint32_t format;
@@ -456,11 +456,12 @@ struct HDAAudioStream {
         SWVoiceOut *out;
     } voice;
     uint8_t buf[HDA_BUFFER_SIZE];
+    uint32_t bpos;
 };
 
 struct HDAAudioState {
     HDACodecDevice hda;
-    char name[32];
+    const char *name;
 
     QEMUSoundCard card;
     const desc_codec *desc;
@@ -475,20 +476,25 @@ static void hda_audio_input_cb(void *opaque, int avail)
 {
     HDAAudioStream *st = opaque;
     int recv = 0;
+    int len;
     bool rc;
 
     while (avail - recv >= sizeof(st->buf)) {
-        if (!st->wbuf) {
-            AUD_read(st->voice.in, st->buf, sizeof(st->buf));
-            recv += sizeof(st->buf);
-            st->wbuf = true;
+        if (st->bpos != sizeof(st->buf)) {
+            len = AUD_read(st->voice.in, st->buf + st->bpos,
+                           sizeof(st->buf) - st->bpos);
+            st->bpos += len;
+            recv += len;
+            if (st->bpos != sizeof(st->buf)) {
+                break;
+            }
         }
         rc = hda_codec_xfer(&st->state->hda, st->stream, false,
                             st->buf, sizeof(st->buf));
         if (!rc) {
             break;
         }
-        st->wbuf = false;
+        st->bpos = 0;
     }
 }
 
@@ -496,16 +502,25 @@ static void hda_audio_output_cb(void *opaque, int avail)
 {
     HDAAudioStream *st = opaque;
     int sent = 0;
+    int len;
     bool rc;
 
     while (avail - sent >= sizeof(st->buf)) {
-        rc = hda_codec_xfer(&st->state->hda, st->stream, true,
-                            st->buf, sizeof(st->buf));
-        if (!rc) {
+        if (st->bpos == sizeof(st->buf)) {
+            rc = hda_codec_xfer(&st->state->hda, st->stream, true,
+                                st->buf, sizeof(st->buf));
+            if (!rc) {
+                break;
+            }
+            st->bpos = 0;
+        }
+        len = AUD_write(st->voice.out, st->buf + st->bpos,
+                        sizeof(st->buf) - st->bpos);
+        st->bpos += len;
+        sent += len;
+        if (st->bpos != sizeof(st->buf)) {
             break;
         }
-        AUD_write(st->voice.out, st->buf, sizeof(st->buf));
-        sent += sizeof(st->buf);
     }
 }
 
@@ -757,8 +772,7 @@ static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
     uint32_t i, type;
 
     a->desc = desc;
-    snprintf(a->name, sizeof(a->name), "%s/%s",
-             a->hda.qdev.info->name, a->desc->name);
+    a->name = a->hda.qdev.info->name;
     dprint(a, 1, "%s: cad %d\n", __FUNCTION__, a->hda.cad);
 
     AUD_register_card("hda", &a->card);
@@ -779,6 +793,7 @@ static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
                 /* unmute output by default */
                 st->gain_left = QEMU_HDA_AMP_STEPS;
                 st->gain_right = QEMU_HDA_AMP_STEPS;
+                st->bpos = sizeof(st->buf);
                 st->output = true;
             } else {
                 st->output = false;
@@ -795,8 +810,20 @@ static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
 
 static int hda_audio_post_load(void *opaque, int version)
 {
-//    HDAAudioState* a = opaque;
+    HDAAudioState *a = opaque;
+    HDAAudioStream *st;
+    int i;
 
+    dprint(a, 1, "%s\n", __FUNCTION__);
+    for (i = 0; i < ARRAY_SIZE(a->st); i++) {
+        st = a->st + i;
+        if (st->node == NULL)
+            continue;
+        hda_codec_parse_fmt(st->format, &st->as);
+        hda_audio_setup(st);
+        hda_audio_set_amp(st);
+        hda_audio_set_running(st, a->running[st->stream]);
+    }
     return 0;
 }
 
@@ -804,6 +831,15 @@ static const VMStateDescription vmstate_hda_audio_stream = {
     .name = "hda-audio-stream",
     .version_id = 1,
     .fields = (VMStateField []) {
+        VMSTATE_UINT32(stream, HDAAudioStream),
+        VMSTATE_UINT32(channel, HDAAudioStream),
+        VMSTATE_UINT32(format, HDAAudioStream),
+        VMSTATE_UINT32(gain_left, HDAAudioStream),
+        VMSTATE_UINT32(gain_right, HDAAudioStream),
+        VMSTATE_BOOL(mute_left, HDAAudioStream),
+        VMSTATE_BOOL(mute_right, HDAAudioStream),
+        VMSTATE_UINT32(bpos, HDAAudioStream),
+        VMSTATE_BUFFER(buf, HDAAudioStream),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -816,10 +852,16 @@ static const VMStateDescription vmstate_hda_audio = {
         VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0,
                              vmstate_hda_audio_stream,
                              HDAAudioStream),
+        VMSTATE_BOOL_ARRAY(running, HDAAudioState, 16),
         VMSTATE_END_OF_LIST()
     }
 };
 
+static Property hda_audio_properties[] = {
+    DEFINE_PROP_UINT32("debug", HDAAudioState, debug, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static int hda_audio_init_output(HDACodecDevice *hda)
 {
     return hda_audio_init(hda, &output);
@@ -834,26 +876,22 @@ static HDACodecDeviceInfo hda_audio_info_output = {
     .qdev.name    = "hda-output",
     .qdev.desc    = "HDA Audio Codec, output-only",
     .qdev.size    = sizeof(HDAAudioState),
+    .qdev.vmsd    = &vmstate_hda_audio,
+    .qdev.props   = hda_audio_properties,
     .init         = hda_audio_init_output,
     .command      = hda_audio_command,
     .stream       = hda_audio_stream,
-    .qdev.props   = (Property[]) {
-        DEFINE_PROP_UINT32("debug", HDAAudioState, debug, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
 };
 
 static HDACodecDeviceInfo hda_audio_info_duplex = {
     .qdev.name    = "hda-duplex",
     .qdev.desc    = "HDA Audio Codec, duplex",
     .qdev.size    = sizeof(HDAAudioState),
+    .qdev.vmsd    = &vmstate_hda_audio,
+    .qdev.props   = hda_audio_properties,
     .init         = hda_audio_init_duplex,
     .command      = hda_audio_command,
     .stream       = hda_audio_stream,
-    .qdev.props   = (Property[]) {
-        DEFINE_PROP_UINT32("debug", HDAAudioState, debug, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
 };
 
 static void hda_audio_register(void)
commit 54b93d05d41c5dc1826c99944dabb9dae007db4b
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Mon Nov 1 11:58:49 2010 +0100

    add VMSTATE_BOOL

diff --git a/hw/hw.h b/hw/hw.h
index 4405092..9d2cfc2 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -333,6 +333,8 @@ struct VMStateDescription {
     const VMStateSubsection *subsections;
 };
 
+extern const VMStateInfo vmstate_info_bool;
+
 extern const VMStateInfo vmstate_info_int8;
 extern const VMStateInfo vmstate_info_int16;
 extern const VMStateInfo vmstate_info_int32;
@@ -602,6 +604,9 @@ extern const VMStateDescription vmstate_i2c_slave;
 #define VMSTATE_STRUCT_POINTER(_field, _state, _vmsd, _type)          \
     VMSTATE_STRUCT_POINTER_TEST(_field, _state, NULL, _vmsd, _type)
 
+#define VMSTATE_BOOL_V(_f, _s, _v)                                    \
+    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_bool, bool)
+
 #define VMSTATE_INT8_V(_f, _s, _v)                                    \
     VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int8, int8_t)
 #define VMSTATE_INT16_V(_f, _s, _v)                                   \
@@ -620,6 +625,9 @@ extern const VMStateDescription vmstate_i2c_slave;
 #define VMSTATE_UINT64_V(_f, _s, _v)                                  \
     VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint64, uint64_t)
 
+#define VMSTATE_BOOL(_f, _s)                                          \
+    VMSTATE_BOOL_V(_f, _s, 0)
+
 #define VMSTATE_INT8(_f, _s)                                          \
     VMSTATE_INT8_V(_f, _s, 0)
 #define VMSTATE_INT16(_f, _s)                                         \
@@ -674,6 +682,12 @@ extern const VMStateDescription vmstate_i2c_slave;
 #define VMSTATE_PTIMER(_f, _s)                                        \
     VMSTATE_PTIMER_V(_f, _s, 0)
 
+#define VMSTATE_BOOL_ARRAY_V(_f, _s, _n, _v)                         \
+    VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_bool, bool)
+
+#define VMSTATE_BOOL_ARRAY(_f, _s, _n)                               \
+    VMSTATE_BOOL_ARRAY_V(_f, _s, _n, 0)
+
 #define VMSTATE_UINT16_ARRAY_V(_f, _s, _n, _v)                         \
     VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint16, uint16_t)
 
diff --git a/savevm.c b/savevm.c
index 2d8cadc..4e49765 100644
--- a/savevm.c
+++ b/savevm.c
@@ -675,6 +675,27 @@ uint64_t qemu_get_be64(QEMUFile *f)
     return v;
 }
 
+/* bool */
+
+static int get_bool(QEMUFile *f, void *pv, size_t size)
+{
+    bool *v = pv;
+    *v = qemu_get_byte(f);
+    return 0;
+}
+
+static void put_bool(QEMUFile *f, void *pv, size_t size)
+{
+    bool *v = pv;
+    qemu_put_byte(f, *v);
+}
+
+const VMStateInfo vmstate_info_bool = {
+    .name = "bool",
+    .get  = get_bool,
+    .put  = put_bool,
+};
+
 /* 8 bit int */
 
 static int get_int8(QEMUFile *f, void *pv, size_t size)
commit f79dd26ee53b9995cac5edf1b60d47c33f5d0b0a
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Mon Nov 1 10:29:18 2010 +0100

    intel-hda: fix wall clock to use qemu_get_clock()

diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 72d91d5..ccb059d 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -19,6 +19,7 @@
 
 #include "hw.h"
 #include "pci.h"
+#include "qemu-timer.h"
 #include "audiodev.h"
 #include "intel-hda.h"
 #include "intel-hda-defs.h"
@@ -165,7 +166,7 @@ struct IntelHDAState {
     /* state */
     int mmio_addr;
     uint32_t rirb_count;
-    uint64_t wall_base_usecs;
+    int64_t wall_base_ns;
 
     /* debug logging */
     const IntelHDAReg *last_reg;
@@ -508,12 +509,10 @@ 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 usecs;
+    int64_t ns;
 
-    qemu_gettimeofday(&tv);
-    usecs  = (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec;
-    d->wall_clk = (uint32_t)((usecs - d->wall_base_usecs) * 24);  /* 24 MHz */
+    ns = qemu_get_clock_ns(vm_clock) - d->wall_base_ns;
+    d->wall_clk = (uint32_t)(ns * 24 / 1000);  /* 24 MHz */
 }
 
 static void intel_hda_set_corb_wp(IntelHDAState *d, const IntelHDAReg *reg, uint32_t old)
@@ -1096,11 +1095,9 @@ 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(&tv);
-    d->wall_base_usecs = (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec;
+    d->wall_base_ns = qemu_get_clock(vm_clock);
 
     /* reset codecs */
     QLIST_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
@@ -1209,7 +1206,7 @@ static const VMStateDescription vmstate_intel_hda = {
 
         /* additional state info */
         VMSTATE_UINT32(rirb_count, IntelHDAState),
-        VMSTATE_UINT64(wall_base_usecs, IntelHDAState),
+        VMSTATE_INT64(wall_base_ns, IntelHDAState),
 
         VMSTATE_END_OF_LIST()
     }
commit ce51f3f7b78910af082df6d5d4ec73c06633603c
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Mon Nov 1 10:08:22 2010 +0100

    hda-audio: savevm support [incomplete]

diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index d99bdd7..6f47429 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -793,6 +793,33 @@ static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
     return 0;
 }
 
+static int hda_audio_post_load(void *opaque, int version)
+{
+//    HDAAudioState* a = opaque;
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_hda_audio_stream = {
+    .name = "hda-audio-stream",
+    .version_id = 1,
+    .fields = (VMStateField []) {
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_hda_audio = {
+    .name = "hda-audio",
+    .version_id = 1,
+    .post_load = hda_audio_post_load,
+    .fields = (VMStateField []) {
+        VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0,
+                             vmstate_hda_audio_stream,
+                             HDAAudioStream),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static int hda_audio_init_output(HDACodecDevice *hda)
 {
     return hda_audio_init(hda, &output);


More information about the Spice-commits mailing list