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