socsvn commit: r303549 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve

iateaca at FreeBSD.org iateaca at FreeBSD.org
Sat May 21 15:54:42 UTC 2016


Author: iateaca
Date: Sat May 21 15:54:41 2016
New Revision: 303549
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=303549

Log:
  implement the RIRB initialization
  
  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 May 21 14:51:49 2016	(r303548)
+++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c	Sat May 21 15:54:41 2016	(r303549)
@@ -82,6 +82,8 @@
 hda_corb_start(struct hda_softc *sc);
 static int
 hda_corb_run(struct hda_softc *sc);
+static int
+hda_rirb_start(struct hda_softc *sc);
 
 static void *
 hda_dma_get_vaddr(struct hda_softc *sc, uint64_t dma_paddr, size_t len);
@@ -148,6 +150,13 @@
 	[HDAC_CORBSIZE_CORBSIZE_MASK]	= 0,
 };
 
+static const uint16_t hda_rirb_sizes[] = {
+	[HDAC_RIRBSIZE_RIRBSIZE_2]	= 2,
+	[HDAC_RIRBSIZE_RIRBSIZE_16]	= 16,
+	[HDAC_RIRBSIZE_RIRBSIZE_256]	= 256,
+	[HDAC_RIRBSIZE_RIRBSIZE_MASK]	= 0,
+};
+
 struct pci_devemu pci_de_hda = {
 	.pe_emu		= "hda",
 	.pe_init	= pci_hda_init,
@@ -255,8 +264,8 @@
 
 	DPRINTF("%s size: %d\n", name, p->size);
 	DPRINTF("%s dma_vaddr: %p\n", name, p->dma_vaddr);
-	DPRINTF("%s wp: %d\n", name, p->wp);
-	DPRINTF("%s rp: %d\n", name, p->rp);
+	DPRINTF("%s wp: 0x%x\n", name, p->wp);
+	DPRINTF("%s rp: 0x%x\n", name, p->rp);
 
 	return;
 }
@@ -268,7 +277,7 @@
 	uint8_t corbsize = 0;
 	uint64_t corblbase = 0;
 	uint64_t corbubase = 0;
-	uint64_t corbpaddr;
+	uint64_t corbpaddr = 0;
 
 	corb->name = "CORB";
 
@@ -308,6 +317,47 @@
 	return 0;
 }
 
+static int
+hda_rirb_start(struct hda_softc *sc)
+{
+	struct hda_codec_cmd_ctl *rirb = &sc->rirb;
+	uint8_t rirbsize = 0;
+	uint64_t rirblbase = 0;
+	uint64_t rirbubase = 0;
+	uint64_t rirbpaddr = 0;
+
+	rirb->name = "RIRB";
+
+	rirbsize = hda_get_reg_by_offset(sc, HDAC_RIRBSIZE) & HDAC_RIRBSIZE_RIRBSIZE_MASK;
+	rirb->size = hda_rirb_sizes[rirbsize];
+
+	if (!rirb->size) {
+		DPRINTF("Invalid rirb size\n");
+		return -1;
+	}
+
+	rirblbase = hda_get_reg_by_offset(sc, HDAC_RIRBLBASE);
+	rirbubase = hda_get_reg_by_offset(sc, HDAC_RIRBUBASE);
+
+	rirbpaddr = rirblbase | (rirbubase << 32);
+	DPRINTF("RIRB dma_paddr: %p\n", (void *)rirbpaddr);
+
+	rirb->dma_vaddr = hda_dma_get_vaddr(sc, rirbpaddr, HDA_RIRB_ENTRY_LEN * rirb->size);
+	if (!rirb->dma_vaddr) {
+		DPRINTF("Fail to get the guest virtual address\n");
+		return -1;
+	}
+
+	rirb->wp = hda_get_reg_by_offset(sc, HDAC_RIRBWP);
+	rirb->rp = 0x0000;
+
+	rirb->run = 1;
+
+	hda_print_cmd_ctl_data(rirb);
+
+	return 0;
+}
+
 static void *
 hda_dma_get_vaddr(struct hda_softc *sc, uint64_t dma_paddr, size_t len)
 {
@@ -371,6 +421,18 @@
 static void
 hda_set_rirbctl(struct hda_softc *sc, uint32_t offset, uint32_t old)
 {
+	uint32_t value = sc->regs[offset];
+	int err;
+	struct hda_codec_cmd_ctl *rirb = NULL;
+
+	if (value & HDAC_RIRBCTL_RIRBDMAEN) {
+		err = hda_rirb_start(sc);
+		assert(!err);
+	} else {
+		rirb = &sc->rirb;
+		memset(rirb, 0, sizeof(*rirb));
+	}
+
 	return;
 }
 


More information about the svn-soc-all mailing list