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>