Date: Sun, 22 May 2016 19:37:58 GMT From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r303606 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve Message-ID: <201605221937.u4MJbwXP040671@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: iateaca Date: Sun May 22 19:37:57 2016 New Revision: 303606 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=303606 Log: add hda_codec module design the interface of communication between the hda controller and codec using data set design the concept of hda_codec_class and hda_codec_inst when CORBWP is set load from the system memory the VERB command using DMA M bhyve/Makefile A bhyve/hda_codec.c M bhyve/pci_hda.c A bhyve/pci_hda.h Added: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.h Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/Makefile soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/Makefile ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/Makefile Sun May 22 18:20:45 2016 (r303605) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/Makefile Sun May 22 19:37:57 2016 (r303606) @@ -20,6 +20,7 @@ consport.c \ dbgport.c \ fwctl.c \ + hda_codec.c \ inout.c \ ioapic.c \ mem.c \ Added: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sun May 22 19:37:57 2016 (r303606) @@ -0,0 +1,18 @@ + +#include "pci_hda.h" + +static int +hda_codec_init(struct hda_codec_inst *hci, const char *opts) +{ + DPRINTF("cad: 0x%x opts: %s\n", hci->cad, opts); + + return 0; +} + +struct hda_codec_class hda_codec = { + .name = "hda_codec", + .init = hda_codec_init, +}; + +HDA_EMUL_SET(hda_codec); + Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sun May 22 18:20:45 2016 (r303605) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sun May 22 19:37:57 2016 (r303606) @@ -1,28 +1,10 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <assert.h> - +#include "pci_hda.h" #include "bhyverun.h" #include "pci_emul.h" #include "hdac_reg.h" /* - * HDA Debug Log - */ -#define DEBUG_HDA 1 -#if DEBUG_HDA == 1 -static FILE *dbg; -#define DPRINTF(fmt, arg...) \ -do {fprintf(dbg, "%s-%d: " fmt, __func__, __LINE__, ##arg); \ -fflush(dbg); } while (0) -#else -#define DPRINTF(fmt, arg...) -#endif - -/* * HDA defines */ #define INTEL_VENDORID 0x8086 @@ -30,6 +12,7 @@ #define HDA_OSS_NO 0x04 #define HDA_ISS_NO 0x04 +#define HDA_CODEC_MAX 0x10 #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 @@ -57,6 +40,9 @@ struct hda_codec_cmd_ctl corb; struct hda_codec_cmd_ctl rirb; + + struct hda_codec_inst *codecs[HDA_CODEC_MAX]; + uint8_t codecs_no; }; /* @@ -70,6 +56,11 @@ hda_set_field_by_offset(struct hda_softc *sc, uint32_t offset, uint32_t mask, uint32_t value); static struct hda_softc *hda_init(const char *opts); +static int +hda_codec_constructor(struct hda_softc *sc, struct hda_codec_class *codec); +static struct hda_codec_class * +hda_find_codec_class(const char *name); + static void hda_reset_regs(struct hda_softc *sc); static uint32_t hda_read(struct hda_softc *sc, uint32_t offset); @@ -98,6 +89,8 @@ static void hda_set_gctl(struct hda_softc *sc, uint32_t offset, uint32_t old); static void +hda_set_corbwp(struct hda_softc *sc, uint32_t offset, uint32_t old); +static void hda_set_corbctl(struct hda_softc *sc, uint32_t offset, uint32_t old); static void hda_set_rirbctl(struct hda_softc *sc, uint32_t offset, uint32_t old); @@ -121,6 +114,7 @@ static const hda_set_reg_handler hda_set_reg_table[] = { [HDAC_GCTL] = hda_set_gctl, + [HDAC_CORBWP] = hda_set_corbwp, [HDAC_CORBCTL] = hda_set_corbctl, [HDAC_RIRBCTL] = hda_set_rirbctl, @@ -166,6 +160,12 @@ PCI_EMUL_SET(pci_de_hda); +SET_DECLARE(hda_codec_class_set, struct hda_codec_class); + +#if DEBUG_HDA == 1 +FILE *dbg; +#endif + /* * HDA module function definitions */ @@ -204,6 +204,8 @@ static struct hda_softc *hda_init(const char *opts) { struct hda_softc *sc = NULL; + struct hda_codec_class *codec = NULL; + int err; #if DEBUG_HDA == 1 dbg = fopen("/tmp/bhyve_hda.log", "w+"); @@ -217,9 +219,58 @@ hda_reset_regs(sc); + /* + * TODO search all the codecs declared in opts + * For now we play with one single codec + */ + codec = hda_find_codec_class("hda_codec"); + if (codec) { + err = hda_codec_constructor(sc, codec); + assert(!err); + } + return sc; } +static int +hda_codec_constructor(struct hda_softc *sc, struct hda_codec_class *codec) +{ + struct hda_codec_inst *hci = NULL; + int err; + + if (sc->codecs_no >= HDA_CODEC_MAX) + return -1; + + hci = calloc(1, sizeof(struct hda_codec_inst)); + if (!hci) + return -1; + + hci->hda = sc; + hci->cad = sc->codecs_no; + + sc->codecs[sc->codecs_no++] = hci; + + err = codec->init(hci, NULL); + assert(!err); + + return 0; +} + +static struct hda_codec_class * +hda_find_codec_class(const char *name) +{ + struct hda_codec_class **pdpp = NULL, *pdp = NULL; + + SET_FOREACH(pdpp, hda_codec_class_set) { + pdp = *pdpp; + if (!strcmp(pdp->name, name)) { + return (pdp); + } + } + + return NULL; +} + static void hda_reset_regs(struct hda_softc *sc) { DPRINTF("Reset the HDA controller registers ...\n"); @@ -395,12 +446,40 @@ if (!(value & HDAC_GCTL_CRST)) { hda_reset_regs(sc); + hda_set_reg_by_offset(sc, HDAC_STATESTS, 0x0001); } return; } static void +hda_set_corbwp(struct hda_softc *sc, uint32_t offset, uint32_t old) +{ + struct hda_codec_cmd_ctl *corb = &sc->corb; + uint32_t value = sc->regs[offset]; + uint32_t verb = 0; + + corb->wp = value; + + /* + * TODO do it in loop + */ + if (corb->wp != corb->rp && corb->run) { + corb->rp++; + verb = hda_dma_ld_dword(corb->dma_vaddr + HDA_CORB_ENTRY_LEN * corb->rp); + + /* + * TODO get cad from verb and send command to codec[cad] + */ + DPRINTF("VERB: 0x%x\n", verb); + } + + hda_set_reg_by_offset(sc, HDAC_CORBRP, corb->rp); + + return; +} + +static void hda_set_corbctl(struct hda_softc *sc, uint32_t offset, uint32_t old) { uint32_t value = sc->regs[offset]; Added: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.h Sun May 22 19:37:57 2016 (r303606) @@ -0,0 +1,43 @@ + +#ifndef _HDA_EMUL_H_ +#define _HDA_EMUL_H_ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <assert.h> + +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/kernel.h> + +/* + * HDA Debug Log + */ +#define DEBUG_HDA 1 +#if DEBUG_HDA == 1 +extern FILE *dbg; +#define DPRINTF(fmt, arg...) \ +do {fprintf(dbg, "%s-%d: " fmt, __func__, __LINE__, ##arg); \ +fflush(dbg); } while (0) +#else +#define DPRINTF(fmt, arg...) +#endif + +struct hda_softc; + +struct hda_codec_inst { + struct hda_softc *hda; + uint8_t cad; + void *priv; +}; + +struct hda_codec_class { + char *name; + int (*init)(struct hda_codec_inst *hci, const char *opts); +}; + +#define HDA_EMUL_SET(x) DATA_SET(hda_codec_class_set, x); + +#endif /* _HDA_EMUL_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605221937.u4MJbwXP040671>