[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