socsvn commit: r305350 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve
iateaca at FreeBSD.org
iateaca at FreeBSD.org
Sun Jun 19 17:41:51 UTC 2016
Author: iateaca
Date: Sun Jun 19 17:41:50 2016
New Revision: 305350
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=305350
Log:
implement the hda_update_intr function: assert or deassert the line interrupt
clear the SDSTS bits when the software (guest) writes them and update the irq
M bhyve/pci_hda.c
Modified:
soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c
Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c
==============================================================================
--- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sun Jun 19 17:00:44 2016 (r305349)
+++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sun Jun 19 17:41:50 2016 (r305350)
@@ -66,6 +66,8 @@
struct pci_devinst *pci_dev;
uint32_t regs[HDA_LAST_OFFSET];
+ uint8_t lintr;
+
struct hda_codec_cmd_ctl corb;
struct hda_codec_cmd_ctl rirb;
@@ -87,6 +89,8 @@
hda_set_field_by_offset(struct hda_softc *sc, uint32_t offset, uint32_t mask, uint32_t value);
static struct hda_softc *hda_init(const char *opts);
+static void
+hda_update_intr(struct hda_softc *sc);
static int
hda_codec_constructor(struct hda_softc *sc, struct hda_codec_class *codec);
static struct hda_codec_class *
@@ -140,6 +144,8 @@
hda_set_sdctl(struct hda_softc *sc, uint32_t offset, uint32_t old);
static void
hda_set_sdctl2(struct hda_softc *sc, uint32_t offset, uint32_t old);
+static void
+hda_set_sdsts(struct hda_softc *sc, uint32_t offset, uint32_t old);
static int
hda_signal_state_change(struct hda_codec_inst *hci);
@@ -170,10 +176,12 @@
#define HDAC_ISTREAM(n, iss, oss) \
[_HDAC_ISDCTL(n, iss, oss)] = hda_set_sdctl, \
[_HDAC_ISDCTL(n, iss, oss) + 2] = hda_set_sdctl2, \
+ [_HDAC_ISDSTS(n, iss, oss)] = hda_set_sdsts, \
#define HDAC_OSTREAM(n, iss, oss) \
[_HDAC_OSDCTL(n, iss, oss)] = hda_set_sdctl, \
[_HDAC_OSDCTL(n, iss, oss) + 2] = hda_set_sdctl2, \
+ [_HDAC_OSDSTS(n, iss, oss)] = hda_set_sdsts, \
HDAC_ISTREAM(0, HDA_ISS_NO, HDA_OSS_NO)
HDAC_ISTREAM(1, HDA_ISS_NO, HDA_OSS_NO)
@@ -288,6 +296,47 @@
return sc;
}
+static void
+hda_update_intr(struct hda_softc *sc)
+{
+ struct pci_devinst *pi = sc->pci_dev;
+ uint32_t intctl = hda_get_reg_by_offset(sc, HDAC_INTCTL);
+ uint32_t intsts = 0;
+ uint32_t sdsts = 0;
+ uint32_t off = 0;
+ int i;
+
+ /* TODO update the CIS bits */
+
+ /* update the SIS bits */
+ for (i = 0; i < HDA_IOSS_NO; i++) {
+ off = hda_get_offset_stream(i);
+ sdsts = hda_get_reg_by_offset(sc, off + HDAC_SDSTS);
+ if (sdsts & HDAC_SDSTS_BCIS)
+ intsts |= (1 << i);
+ }
+
+ /* update the GIS bit */
+ if (intsts)
+ intsts |= HDAC_INTSTS_GIS;
+
+ hda_set_reg_by_offset(sc, HDAC_INTSTS, intsts);
+
+ if ((intctl & HDAC_INTCTL_GIE) && ((intsts & ~HDAC_INTSTS_GIS) & intctl)) {
+ if (!sc->lintr) {
+ pci_lintr_assert(pi);
+ sc->lintr = 1;
+ }
+ } else {
+ if (sc->lintr) {
+ pci_lintr_deassert(pi);
+ sc->lintr = 0;
+ }
+ }
+
+ return;
+}
+
static int
hda_codec_constructor(struct hda_softc *sc, struct hda_codec_class *codec)
{
@@ -757,6 +806,19 @@
return;
}
+static void
+hda_set_sdsts(struct hda_softc *sc, uint32_t offset, uint32_t old)
+{
+ uint32_t value = hda_get_reg_by_offset(sc, offset);
+
+ /* clear the corresponding bits written by the software (guest) */
+ hda_set_field_by_offset(sc, offset, value, 0);
+
+ hda_update_intr(sc);
+
+ return;
+}
+
static int
hda_signal_state_change(struct hda_codec_inst *hci)
{
More information about the svn-soc-all
mailing list