Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 9 Jul 2016 13:51:22 GMT
From:      iateaca@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r305903 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve
Message-ID:  <201607091351.u69DpMTx067055@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201607091351.u69DpMTx067055>