Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 9 Jul 2016 18:46:32 GMT
From:      iateaca@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r305909 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve
Message-ID:  <201607091846.u69IkWxX093600@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: iateaca
Date: Sat Jul  9 18:46:31 2016
New Revision: 305909
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=305909

Log:
  implement the DMA Position in Buffer mechanism in order to allow the guest to read the position in buffer of each stream
  
  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 17:48:45 2016	(r305908)
+++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c	Sat Jul  9 18:46:31 2016	(r305909)
@@ -20,6 +20,7 @@
 #define HDA_CORB_ENTRY_LEN	0x04
 #define HDA_RIRB_ENTRY_LEN	0x08
 #define HDA_BDL_ENTRY_LEN	0x10
+#define HDA_DMA_PIB_ENTRY_LEN	0x08
 #define HDA_STREAM_TAGS_CNT	0x10
 #define HDA_STREAM_REGS_BASE	0x80
 #define HDA_STREAM_REGS_LEN	0x20
@@ -91,6 +92,9 @@
 	struct hda_codec_inst *codecs[HDA_CODEC_MAX];
 	uint8_t codecs_no;
 
+	/* Base Address of the DMA Position Buffer */
+	void *dma_pib_vaddr;
+
 	struct hda_stream_desc streams[HDA_IOSS_NO];
 	uint8_t stream_map[HDA_STREAM_TAGS_CNT];
 };
@@ -168,6 +172,8 @@
 static void
 hda_set_rirbsts(struct hda_softc *sc, uint32_t offset, uint32_t old);
 static void
+hda_set_dpiblbase(struct hda_softc *sc, uint32_t offset, uint32_t old);
+static void
 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);
@@ -205,6 +211,7 @@
 	[HDAC_CORBCTL] = hda_set_corbctl,
 	[HDAC_RIRBCTL] = hda_set_rirbctl,
 	[HDAC_RIRBSTS] = hda_set_rirbsts,
+	[HDAC_DPIBLBASE] = hda_set_dpiblbase,
 
 #define HDAC_ISTREAM(n, iss, oss)				\
 	[_HDAC_ISDCTL(n, iss, oss)] = hda_set_sdctl,		\
@@ -631,6 +638,8 @@
 	st->bp = 0;
 	st->be = 0;
 	hda_set_reg_by_offset(sc, off + HDAC_SDLPIB, 0);
+	if (sc->dma_pib_vaddr)
+		*(uint32_t *)(sc->dma_pib_vaddr + stream_ind * HDA_DMA_PIB_ENTRY_LEN) = 0;
 
 	st->run = 1;
 
@@ -931,6 +940,36 @@
 }
 
 static void
+hda_set_dpiblbase(struct hda_softc *sc, uint32_t offset, uint32_t old)
+{
+	uint32_t value = hda_get_reg_by_offset(sc, offset);
+	uint64_t dpiblbase = 0;
+	uint64_t dpibubase = 0;
+	uint64_t dpibpaddr = 0;
+
+	if ((value & HDAC_DPLBASE_DPLBASE_DMAPBE) != (old & HDAC_DPLBASE_DPLBASE_DMAPBE)) {
+		if (value & HDAC_DPLBASE_DPLBASE_DMAPBE) {
+			dpiblbase = value & HDAC_DPLBASE_DPLBASE_MASK;
+			dpibubase = hda_get_reg_by_offset(sc, HDAC_DPIBUBASE);
+
+			dpibpaddr = dpiblbase | (dpibubase << 32);
+			DPRINTF("DMA Position In Buffer dma_paddr: %p\n", (void *)dpibpaddr);
+
+			sc->dma_pib_vaddr = hda_dma_get_vaddr(sc, dpibpaddr, HDA_DMA_PIB_ENTRY_LEN * HDA_IOSS_NO);
+			if (!sc->dma_pib_vaddr) {
+				DPRINTF("Fail to get the guest virtual address\n");
+				assert(0);
+			}
+		} else {
+			DPRINTF("DMA Position In Buffer Reset\n");
+			sc->dma_pib_vaddr = NULL;
+		}
+	}
+
+	return;
+}
+
+static void
 hda_set_sdctl(struct hda_softc *sc, uint32_t offset, uint32_t old)
 {
 	uint8_t stream_ind = hda_get_stream_by_offsets(offset, HDAC_SDCTL0);
@@ -1111,6 +1150,8 @@
 	}
 
 	hda_set_reg_by_offset(sc, off + HDAC_SDLPIB, lpib);
+	if (sc->dma_pib_vaddr)
+		*(uint32_t *)(sc->dma_pib_vaddr + stream_ind * HDA_DMA_PIB_ENTRY_LEN) = lpib;
 
 	if (irq) {
 		hda_set_field_by_offset(sc, off + HDAC_SDSTS, HDAC_SDSTS_BCIS, HDAC_SDSTS_BCIS);



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