socsvn commit: r305903 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve
iateaca at FreeBSD.org
iateaca at FreeBSD.org
Sat Jul 9 13:51:23 UTC 2016
Author: iateaca
Date: Sat Jul 9 13:51:21 2016
New Revision: 305903
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=305903
Log:
implement the RIRB interrupts
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 Sat Jul 9 12:17:01 2016 (r305902)
+++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sat Jul 9 13:51:21 2016 (r305903)
@@ -81,6 +81,7 @@
uint32_t regs[HDA_LAST_OFFSET];
uint8_t lintr;
+ uint8_t rirb_cnt;
uint64_t wall_clock_start;
struct hda_codec_cmd_ctl corb;
@@ -106,6 +107,8 @@
static struct hda_softc *hda_init(const char *opts);
static void
hda_update_intr(struct hda_softc *sc);
+static void
+hda_response_interrupt(struct hda_softc *sc);
static int
hda_codec_constructor(struct hda_softc *sc, struct hda_codec_class *codec);
static struct hda_codec_class *
@@ -330,11 +333,16 @@
uint32_t intctl = hda_get_reg_by_offset(sc, HDAC_INTCTL);
uint32_t intsts = 0;
uint32_t sdsts = 0;
+ uint32_t rirbsts = 0;
uint32_t off = 0;
int i;
/* TODO update the CIS bits */
+ rirbsts = hda_get_reg_by_offset(sc, HDAC_RIRBSTS);
+ if (rirbsts & (HDAC_RIRBSTS_RINTFL | HDAC_RIRBSTS_RIRBOIS))
+ intsts |= HDAC_INTSTS_CIS;
+
/* update the SIS bits */
for (i = 0; i < HDA_IOSS_NO; i++) {
off = hda_get_offset_stream(i);
@@ -364,6 +372,20 @@
return;
}
+static void
+hda_response_interrupt(struct hda_softc *sc)
+{
+ uint8_t rirbctl = hda_get_reg_by_offset(sc, HDAC_RIRBCTL);
+
+ if ((rirbctl & HDAC_RIRBCTL_RINTCTL) && sc->rirb_cnt) {
+ sc->rirb_cnt = 0;
+ hda_set_field_by_offset(sc, HDAC_RIRBSTS, HDAC_RIRBSTS_RINTFL, HDAC_RIRBSTS_RINTFL);
+ hda_update_intr(sc);
+ }
+
+ return;
+}
+
static int
hda_codec_constructor(struct hda_softc *sc, struct hda_codec_class *codec)
{
@@ -725,6 +747,9 @@
hda_set_reg_by_offset(sc, HDAC_CORBRP, corb->rp);
+ if (corb->run)
+ hda_response_interrupt(sc);
+
return 0;
}
@@ -956,6 +981,7 @@
struct hda_softc *sc = NULL;
struct hda_codec_cmd_ctl *rirb = NULL;
uint32_t response_ex = 0;
+ uint8_t rintcnt = 0;
assert(hci);
assert(hci->cad <= HDA_CODEC_MAX);
@@ -975,8 +1001,14 @@
hda_dma_st_dword(rirb->dma_vaddr + HDA_RIRB_ENTRY_LEN * rirb->wp + 0x04, response_ex);
hda_set_reg_by_offset(sc, HDAC_RIRBWP, rirb->wp);
+
+ sc->rirb_cnt++;
}
+ rintcnt = hda_get_reg_by_offset(sc, HDAC_RINTCNT);
+ if (sc->rirb_cnt == rintcnt)
+ hda_response_interrupt(sc);
+
return 0;
}
More information about the svn-soc-all
mailing list