Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 19 Jun 2016 17:41:50 GMT
From:      iateaca@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r305350 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve
Message-ID:  <201606191741.u5JHfoGH067506@socsvn.freebsd.org>

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



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