Date: Sat, 21 May 2016 14:38:08 GMT From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r303547 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve Message-ID: <201605211438.u4LEc8nv082380@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: iateaca Date: Sat May 21 14:38:08 2016 New Revision: 303547 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=303547 Log: design the HDA command and control data structure (CORB or RIBB) implement the CORB engine initialization implement the DMA store and load functions 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 11:40:41 2016 (r303546) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sat May 21 14:38:08 2016 (r303547) @@ -2,9 +2,12 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/types.h> +#include <assert.h> -#include "hdac_reg.h" +#include "bhyverun.h" #include "pci_emul.h" +#include "hdac_reg.h" /* * HDA Debug Log @@ -28,6 +31,8 @@ #define HDA_OSS_NO 0x04 #define HDA_ISS_NO 0x04 #define HDA_LAST_OFFSET (0x80 + ((HDA_ISS_NO) * 0x20) + ((HDA_OSS_NO) * 0x20)) +#define HDA_CORB_ENTRY_LEN 0x04 +#define HDA_RIRB_ENTRY_LEN 0x08 /* * HDA data structures @@ -37,8 +42,21 @@ typedef void (*hda_set_reg_handler)(struct hda_softc *sc, uint32_t offset, uint32_t old); +struct hda_codec_cmd_ctl { + char *name; + void *dma_vaddr; + uint16_t size; + uint16_t wp; + uint16_t rp; + uint8_t run; +}; + struct hda_softc { + struct pci_devinst *pci_dev; uint32_t regs[HDA_LAST_OFFSET]; + + struct hda_codec_cmd_ctl corb; + struct hda_codec_cmd_ctl rirb; }; /* @@ -58,6 +76,20 @@ static int hda_write(struct hda_softc *sc, uint32_t offset, uint32_t value); +static void +hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl *p); +static int +hda_corb_start(struct hda_softc *sc); +static int +hda_corb_run(struct hda_softc *sc); + +static void * +hda_dma_get_vaddr(struct hda_softc *sc, uint64_t dma_paddr, size_t len); +static void +hda_dma_st_dword(void *dma_vaddr, uint32_t data); +static uint32_t +hda_dma_ld_dword(void *dma_vaddr); + static inline uint8_t hda_get_stream_by_offsets(uint32_t offset, uint8_t reg_offset); @@ -109,6 +141,13 @@ [HDA_LAST_OFFSET] = NULL, }; +static const uint16_t hda_corb_sizes[] = { + [HDAC_CORBSIZE_CORBSIZE_2] = 2, + [HDAC_CORBSIZE_CORBSIZE_16] = 16, + [HDAC_CORBSIZE_CORBSIZE_256] = 256, + [HDAC_CORBSIZE_CORBSIZE_MASK] = 0, +}; + struct pci_devemu pci_de_hda = { .pe_emu = "hda", .pe_init = pci_hda_init, @@ -209,6 +248,90 @@ return 0; } +static void +hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl *p) +{ + char *name = p->name; + + 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); + + return; +} + +static int +hda_corb_start(struct hda_softc *sc) +{ + struct hda_codec_cmd_ctl *corb = &sc->corb; + uint8_t corbsize = 0; + uint64_t corblbase = 0; + uint64_t corbubase = 0; + uint64_t corbpaddr; + + corb->name = "CORB"; + + corbsize = hda_get_reg_by_offset(sc, HDAC_CORBSIZE) & HDAC_CORBSIZE_CORBSIZE_MASK; + corb->size = hda_corb_sizes[corbsize]; + + if (!corb->size) { + DPRINTF("Invalid corb size\n"); + return -1; + } + + corblbase = hda_get_reg_by_offset(sc, HDAC_CORBLBASE); + corbubase = hda_get_reg_by_offset(sc, HDAC_CORBUBASE); + + corbpaddr = corblbase | (corbubase << 32); + DPRINTF("CORB dma_paddr: %p\n", (void *)corbpaddr); + + corb->dma_vaddr = hda_dma_get_vaddr(sc, corbpaddr, HDA_CORB_ENTRY_LEN * corb->size); + if (!corb->dma_vaddr) { + DPRINTF("Fail to get the guest virtual address\n"); + return -1; + } + + corb->wp = hda_get_reg_by_offset(sc, HDAC_CORBWP); + corb->rp = hda_get_reg_by_offset(sc, HDAC_CORBRP); + + corb->run = 1; + + hda_print_cmd_ctl_data(corb); + + return 0; +} + +static int +hda_corb_run(struct hda_softc *sc) +{ + return 0; +} + +static void * +hda_dma_get_vaddr(struct hda_softc *sc, uint64_t dma_paddr, size_t len) +{ + struct pci_devinst *pi = sc->pci_dev; + + assert(pi); + + return paddr_guest2host(pi->pi_vmctx, (uintptr_t)dma_paddr, len); +} + +static void +hda_dma_st_dword(void *dma_vaddr, uint32_t data) +{ + *(uint32_t*)dma_vaddr = data; + + return; +} + +static uint32_t +hda_dma_ld_dword(void *dma_vaddr) +{ + return *(uint32_t*)dma_vaddr; +} + static inline uint8_t hda_get_stream_by_offsets(uint32_t offset, uint8_t reg_offset) { @@ -230,6 +353,18 @@ static void hda_set_corbctl(struct hda_softc *sc, uint32_t offset, uint32_t old) { + uint32_t value = sc->regs[offset]; + int err; + struct hda_codec_cmd_ctl *corb = NULL; + + if (value & HDAC_CORBCTL_CORBRUN) { + err = hda_corb_start(sc); + assert(!err); + } else { + corb = &sc->corb; + memset(corb, 0, sizeof(*corb)); + } + return; } @@ -277,6 +412,7 @@ if (!sc) return -1; + sc->pci_dev = pi; pi->pi_arg = sc; return 0;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605211438.u4LEc8nv082380>