[Spice-commits] Branch 'audio.2' - 7 commits - hw/hda-audio.c hw/intel-hda.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Thu Oct 28 08:04:35 PDT 2010


 hw/hda-audio.c |   55 ++++++++++++++--------
 hw/intel-hda.c |  139 ++++++++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 139 insertions(+), 55 deletions(-)

New commits:
commit 1044dc9c1e7b49ea75763d39c83e7c443f82115f
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Oct 28 16:39:49 2010 +0200

    intel-hda: add immediate command support

diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 511a511..94d440e 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -152,6 +152,10 @@ struct IntelHDAState {
     uint32_t dp_lbase;
     uint32_t dp_ubase;
 
+    uint32_t icw;
+    uint32_t irr;
+    uint32_t ics;
+
     /* streams */
     IntelHDAStream st[8];
 
@@ -261,11 +265,32 @@ static void intel_hda_update_irq(IntelHDAState *d)
     qemu_set_irq(d->pci.irq[0], level);
 }
 
+static int intel_hda_send_command(IntelHDAState *d, uint32_t verb)
+{
+    uint32_t cad, nid, data;
+    HDACodecDevice *codec;
+
+    cad = (verb >> 28) & 0x0f;
+    assert(!(verb & (1 << 27))); /* indirect addressing, unspecified */
+    nid = (verb >> 20) & 0x7f;
+    data = verb & 0xfffff;
+
+    codec = hda_codec_find(&d->codecs, cad);
+    assert(codec != NULL);
+    codec->info->command(codec, nid, data);
+    return 0;
+}
+
 static void intel_hda_corb_run(IntelHDAState *d)
 {
     target_phys_addr_t addr;
-    uint32_t rp, verb, cad, nid, data;
-    HDACodecDevice *codec;
+    uint32_t rp, verb;
+
+    if (d->ics & ICH6_IRS_BUSY) {
+        dprint(d, 2, "%s: [icw] verb 0x%08x\n", __FUNCTION__, d->icw);
+        intel_hda_send_command(d, d->icw);
+        return;
+    }
 
     for (;;) {
         if (!(d->corb_ctl & ICH6_CORBCTL_RUN)) {
@@ -286,16 +311,8 @@ static void intel_hda_corb_run(IntelHDAState *d)
         verb = ldl_phys_le(addr + 4*rp);
         d->corb_rp = rp;
 
-        cad = (verb >> 28) & 0x0f;
-        assert(!(verb & (1 << 27))); /* indirect addressing, unspecified */
-        nid = (verb >> 20) & 0x7f;
-        data = verb & 0xfffff;
-
-        dprint(d, 2, "%s: [rp 0x%x] verb 0x%08x: cad %d, nid %d, data 0x%x\n",
-               __FUNCTION__, rp, verb, cad, nid, data);
-        codec = hda_codec_find(&d->codecs, cad);
-        assert(codec != NULL);
-        codec->info->command(codec, nid, data);
+        dprint(d, 2, "%s: [rp 0x%x] verb 0x%08x\n", __FUNCTION__, rp, verb);
+        intel_hda_send_command(d, verb);
     }
 }
 
@@ -306,6 +323,15 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res
     target_phys_addr_t addr;
     uint32_t wp, ex;
 
+    if (d->ics & ICH6_IRS_BUSY) {
+        dprint(d, 2, "%s: [irr] response 0x%x, cad 0x%x\n",
+               __FUNCTION__, response, dev->cad);
+        d->irr = response;
+        d->ics &= ~(ICH6_IRS_BUSY | 0xf0);
+        d->ics |= (ICH6_IRS_VALID | (dev->cad << 4));
+        return;
+    }
+
     assert(d->rirb_ctl & ICH6_RBCTL_DMA_EN);
 
     ex = (solicited ? 0 : (1 << 4)) | dev->cad;
@@ -507,6 +533,13 @@ static void intel_hda_set_rirb_sts(IntelHDAState *d, const IntelHDAReg *reg, uin
     }
 }
 
+static void intel_hda_set_ics(IntelHDAState *d, const IntelHDAReg *reg, uint32_t old)
+{
+    if (d->ics & ICH6_IRS_BUSY) {
+        intel_hda_corb_run(d);
+    }
+}
+
 static void intel_hda_set_st_ctl(IntelHDAState *d, const IntelHDAReg *reg, uint32_t old)
 {
     IntelHDAStream *st = d->st + reg->stream;
@@ -706,6 +739,7 @@ static const struct IntelHDAReg regtab[] = {
         .reset    = 0x42,
         .offset   = offsetof(IntelHDAState, rirb_size),
     },
+
     [ ICH6_REG_DPLBASE ] = {
         .name     = "DPLBASE",
         .size     = 4,
@@ -719,6 +753,26 @@ static const struct IntelHDAReg regtab[] = {
         .offset   = offsetof(IntelHDAState, dp_ubase),
     },
 
+    [ ICH6_REG_IC ] = {
+        .name     = "ICW",
+        .size     = 4,
+        .wmask    = 0xffffffff,
+        .offset   = offsetof(IntelHDAState, icw),
+    },
+    [ ICH6_REG_IR ] = {
+        .name     = "IRR",
+        .size     = 4,
+        .offset   = offsetof(IntelHDAState, irr),
+    },
+    [ ICH6_REG_IRS ] = {
+        .name     = "ICS",
+        .size     = 2,
+        .wmask    = 0x0003,
+        .wclear   = 0x0002,
+        .offset   = offsetof(IntelHDAState, ics),
+        .whandler = intel_hda_set_ics,
+    },
+
 #define HDA_STREAM(_t, _i)                                            \
     [ ST_REG(_i, ICH6_REG_SD_CTL) ] = {                               \
 	.stream   = _i,                                               \
commit 9d3a3c12dbd8e9ced25996f9f001cd0c95d7a125
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Oct 28 15:37:29 2010 +0200

    intel-hda: zap obsolete comment

diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 6e8ef40..511a511 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -401,7 +401,6 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,
         addr = intel_hda_addr(d->dp_lbase & ~0x01, d->dp_ubase);
         stl_phys_le(addr + 8*s, st->lpib);
     }
-    /* TODO: update DP */
     dprint(d, 3, "dma: --\n");
 
     if (irq) {
commit cb76409db54144fdaecd688faa02251638472ed1
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Oct 28 15:36:07 2010 +0200

    intel-hda: code style: add braces

diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 74c0629..6e8ef40 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -221,12 +221,15 @@ static void intel_hda_update_int_sts(IntelHDAState *d)
     uint32_t i;
 
     /* update controller status */
-    if (d->rirb_sts & ICH6_RBSTS_IRQ)
+    if (d->rirb_sts & ICH6_RBSTS_IRQ) {
         sts |= (1 << 30);
-    if (d->rirb_sts & ICH6_RBSTS_OVERRUN)
+    }
+    if (d->rirb_sts & ICH6_RBSTS_OVERRUN) {
         sts |= (1 << 30);
-    if (d->state_sts)
+    }
+    if (d->state_sts) {
         sts |= (1 << 30);
+    }
 
     /* update stream status */
     for (i = 0; i < 8; i++) {
@@ -237,8 +240,9 @@ static void intel_hda_update_int_sts(IntelHDAState *d)
     }
 
     /* update global status */
-    if (sts & d->int_ctl)
+    if (sts & d->int_ctl) {
         sts |= (1 << 31);
+    }
 
     d->int_sts = sts;
 }
@@ -347,16 +351,19 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,
             break;
         }
     }
-    if (st == NULL)
+    if (st == NULL) {
         return false;
-    if (st->bpl == NULL)
+    }
+    if (st->bpl == NULL) {
         return false;
-    if (st->ctl & (1 << 26))
+    }
+    if (st->ctl & (1 << 26)) {
         /*
          * Wait with the next DMA xfer until the guest
          * has acked the buffer completion interrupt
          */
         return false;
+    }
 
     left = len;
     while (left > 0) {
@@ -436,8 +443,9 @@ static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool runn
 
     QLIST_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
         cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
-        if (cdev->info->stream)
+        if (cdev->info->stream) {
             cdev->info->stream(cdev, stream, running);
+        }
     }
 }
 
@@ -484,8 +492,9 @@ static void intel_hda_set_corb_ctl(IntelHDAState *d, const IntelHDAReg *reg, uin
 
 static void intel_hda_set_rirb_wp(IntelHDAState *d, const IntelHDAReg *reg, uint32_t old)
 {
-    if (d->rirb_wp & ICH6_RIRBWP_RST)
+    if (d->rirb_wp & ICH6_RIRBWP_RST) {
         d->rirb_wp = 0;
+    }
 }
 
 static void intel_hda_set_rirb_sts(IntelHDAState *d, const IntelHDAReg *reg, uint32_t old)
@@ -809,11 +818,13 @@ static const IntelHDAReg *intel_hda_reg_find(IntelHDAState *d, target_phys_addr_
 {
     const IntelHDAReg *reg;
 
-    if (addr >= sizeof(regtab)/sizeof(regtab[0]))
+    if (addr >= sizeof(regtab)/sizeof(regtab[0])) {
         goto noreg;
+    }
     reg = regtab+addr;
-    if (reg->name == NULL)
+    if (reg->name == NULL) {
         goto noreg;
+    }
     return reg;
 
 noreg:
@@ -835,8 +846,9 @@ static void intel_hda_reg_write(IntelHDAState *d, const IntelHDAReg *reg, uint32
     uint32_t *addr;
     uint32_t old;
 
-    if (!reg)
+    if (!reg) {
         return;
+    }
 
     if (d->debug) {
         time_t now = time(NULL);
@@ -883,8 +895,9 @@ static uint32_t intel_hda_reg_read(IntelHDAState *d, const IntelHDAReg *reg,
 {
     uint32_t *addr, ret;
 
-    if (!reg)
+    if (!reg) {
         return 0;
+    }
 
     if (reg->rhandler) {
         reg->rhandler(d, reg);
@@ -931,10 +944,12 @@ static void intel_hda_regs_reset(IntelHDAState *d)
     int i;
 
     for (i = 0; i < sizeof(regtab)/sizeof(regtab[0]); i++) {
-        if (regtab[i].name == NULL)
+        if (regtab[i].name == NULL) {
             continue;
-        if (regtab[i].offset == 0)
+        }
+        if (regtab[i].offset == 0) {
             continue;
+        }
         addr = intel_hda_reg_addr(d, regtab + i);
         *addr = regtab[i].reset;
     }
@@ -1024,8 +1039,9 @@ static void intel_hda_reset(DeviceState *dev)
     /* reset codecs */
     QLIST_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
         cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
-        if (qdev->info->reset)
+        if (qdev->info->reset) {
             qdev->info->reset(qdev);
+        }
         d->state_sts |= (1 << cdev->cad);
     }
     intel_hda_update_irq(d);
commit cc37bcaca308908e53283e99a9483a782a561b60
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Oct 28 15:23:38 2010 +0200

    hda-audio: code style: add braces

diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index 229d679..7524990 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -483,8 +483,9 @@ static void hda_audio_input_cb(void *opaque, int avail)
         }
         rc = hda_codec_xfer(&st->state->hda, st->stream, false,
                             st->buf, sizeof(st->buf));
-        if (!rc)
+        if (!rc) {
             break;
+        }
         st->wbuf = false;
     }
 }
@@ -498,8 +499,9 @@ static void hda_audio_output_cb(void *opaque, int avail)
     while (avail - sent >= sizeof(st->buf)) {
         rc = hda_codec_xfer(&st->state->hda, st->stream, true,
                             st->buf, sizeof(st->buf));
-        if (!rc)
+        if (!rc) {
             break;
+        }
         AUD_write(st->voice.out, st->buf, sizeof(st->buf));
         sent += sizeof(st->buf);
     }
@@ -507,10 +509,12 @@ static void hda_audio_output_cb(void *opaque, int avail)
 
 static void hda_audio_set_running(HDAAudioStream *st, bool running)
 {
-    if (st->node == NULL)
+    if (st->node == NULL) {
         return;
-    if (st->running == running)
+    }
+    if (st->running == running) {
         return;
+    }
     st->running = running;
     dprint(st->state, 1, "%s: %s (stream %d)\n", st->node->name,
            st->running ? "on" : "off", st->stream);
@@ -526,8 +530,9 @@ static void hda_audio_set_amp(HDAAudioStream *st)
     bool muted;
     uint32_t left, right;
 
-    if (st->node == NULL)
+    if (st->node == NULL) {
         return;
+    }
 
     muted = st->mute_left && st->mute_right;
     left  = st->mute_left  ? 0 : st->gain_left;
@@ -545,8 +550,9 @@ static void hda_audio_set_amp(HDAAudioStream *st)
 
 static void hda_audio_setup(HDAAudioStream *st)
 {
-    if (st->node == NULL)
+    if (st->node == NULL) {
         return;
+    }
 
     dprint(st->state, 1, "%s: format: %d x %s @ %d Hz\n",
            st->node->name, st->as.nchannels,
@@ -582,8 +588,9 @@ static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)
     }
 
     node = hda_codec_find_node(a->desc, nid);
-    if (node == NULL)
+    if (node == NULL) {
         goto fail;
+    }
     dprint(a, 2, "%s: nid %d (%s), verb 0x%x, payload 0x%x\n",
            __FUNCTION__, nid, node->name, verb, payload);
 
@@ -591,8 +598,9 @@ static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)
     /* all nodes */
     case AC_VERB_PARAMETERS:
         param = hda_codec_find_param(node, payload);
-        if (param == NULL)
+        if (param == NULL) {
             goto fail;
+        }
         hda_codec_response(hda, true, param->val);
         break;
     case AC_VERB_GET_SUBSYSTEM_ID:
@@ -630,8 +638,9 @@ static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)
     /* audio in/out widget */
     case AC_VERB_SET_CHANNEL_STREAMID:
         st = a->st + node->stindex;
-        if (st->node == NULL)
+        if (st->node == NULL) {
             goto fail;
+        }
         hda_audio_set_running(st, false);
         st->stream = (payload >> 4) & 0x0f;
         st->channel = payload & 0x0f;
@@ -642,15 +651,17 @@ static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)
         break;
     case AC_VERB_GET_CONV:
         st = a->st + node->stindex;
-        if (st->node == NULL)
+        if (st->node == NULL) {
             goto fail;
+        }
         response = st->stream << 4 | st->channel;
         hda_codec_response(hda, true, response);
         break;
     case AC_VERB_SET_STREAM_FORMAT:
         st = a->st + node->stindex;
-        if (st->node == NULL)
+        if (st->node == NULL) {
             goto fail;
+        }
         st->format = payload;
         hda_codec_parse_fmt(st->format, &st->as);
         hda_audio_setup(st);
@@ -658,14 +669,16 @@ static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)
         break;
     case AC_VERB_GET_STREAM_FORMAT:
         st = a->st + node->stindex;
-        if (st->node == NULL)
+        if (st->node == NULL) {
             goto fail;
+        }
         hda_codec_response(hda, true, st->format);
         break;
     case AC_VERB_GET_AMP_GAIN_MUTE:
         st = a->st + node->stindex;
-        if (st->node == NULL)
+        if (st->node == NULL) {
             goto fail;
+        }
         if (payload & AC_AMP_GET_LEFT) {
             response = st->gain_left | (st->mute_left ? AC_AMP_MUTE : 0);
         } else {
@@ -675,8 +688,9 @@ static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)
         break;
     case AC_VERB_SET_AMP_GAIN_MUTE:
         st = a->st + node->stindex;
-        if (st->node == NULL)
+        if (st->node == NULL) {
             goto fail;
+        }
         dprint(a, 1, "amp (%s): %s%s%s%s index %d  gain %3d %s\n",
                st->node->name,
                (payload & AC_AMP_SET_OUTPUT) ? "o" : "-",
@@ -722,10 +736,12 @@ static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running)
 
     a->running[stnr] = running;
     for (s = 0; s < ARRAY_SIZE(a->st); s++) {
-        if (a->st[s].node == NULL)
+        if (a->st[s].node == NULL) {
             continue;
-        if (a->st[s].stream != stnr)
+        }
+        if (a->st[s].stream != stnr) {
             continue;
+        }
         hda_audio_set_running(&a->st[s], running);
     }
 }
commit e165e863de0fa732685ffbc7aee9e2013de4e7de
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Oct 28 15:19:58 2010 +0200

    hda-audio: remove debug message

diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index d34f9fe..229d679 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -653,9 +653,6 @@ static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)
             goto fail;
         st->format = payload;
         hda_codec_parse_fmt(st->format, &st->as);
-        dprint(a, 1, "%s: format: %d x %s @ %d Hz\n",
-               st->node->name, st->as.nchannels,
-               fmt2name[st->as.fmt], st->as.freq);
         hda_audio_setup(st);
         hda_codec_response(hda, true, 0);
         break;
commit 60037226472e68eee284c7c1832b32b7853bef92
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Oct 28 15:19:07 2010 +0200

    hda-audio: don't abort when the guest asks for (unsupported) non-pcm formats

diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index f2bc787..d34f9fe 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -72,7 +72,9 @@ static const desc_node* hda_codec_find_node(const desc_codec *codec, uint32_t ni
 
 static void hda_codec_parse_fmt(uint32_t format, struct audsettings *as)
 {
-    assert(!(format & AC_FMT_TYPE_NON_PCM));
+    if (format & AC_FMT_TYPE_NON_PCM) {
+        return;
+    }
 
     as->freq = (format & AC_FMT_BASE_44K) ? 44100 : 48000;
 
commit ec2ca423734d2b9986dcf994a0c4600ae1e2ac00
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Oct 28 15:02:47 2010 +0200

    intel-hda: don't pass unchecked guest address to qemu_get_ram_ptr

diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index c9ec826..74c0629 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -407,18 +407,18 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,
 static void intel_hda_parse_bdl(IntelHDAState *d, IntelHDAStream *st)
 {
     target_phys_addr_t addr;
-    uint8_t *ptr;
+    uint8_t buf[16];
     uint32_t i;
 
     addr = intel_hda_addr(st->bdlp_lbase, st->bdlp_ubase);
-    ptr = qemu_get_ram_ptr(addr);
     st->bentries = st->lvi +1;
     qemu_free(st->bpl);
     st->bpl = qemu_malloc(sizeof(bpl) * st->bentries);
-    for (i = 0; i < st->bentries; i++, ptr += 16) {
-        st->bpl[i].addr  = le64_to_cpu(*(uint64_t *)ptr);
-        st->bpl[i].len   = le32_to_cpu(*(uint32_t *)(ptr + 8));
-        st->bpl[i].flags = le32_to_cpu(*(uint32_t *)(ptr + 12));
+    for (i = 0; i < st->bentries; i++, addr += 16) {
+        cpu_physical_memory_read(addr, buf, 16);
+        st->bpl[i].addr  = le64_to_cpu(*(uint64_t *)buf);
+        st->bpl[i].len   = le32_to_cpu(*(uint32_t *)(buf + 8));
+        st->bpl[i].flags = le32_to_cpu(*(uint32_t *)(buf + 12));
         dprint(d, 1, "bdl/%d: 0x%" PRIx64 " +0x%x, 0x%x\n",
                i, st->bpl[i].addr, st->bpl[i].len, st->bpl[i].flags);
     }


More information about the Spice-commits mailing list