2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2016 Alex Teaca <iateaca@FreeBSD.org>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
43 #define PCIR_HDCTL 0x40
44 #define INTEL_VENDORID 0x8086
45 #define HDA_INTEL_82801G 0x27d8
47 #define HDA_IOSS_NO 0x08
48 #define HDA_OSS_NO 0x04
49 #define HDA_ISS_NO 0x04
50 #define HDA_CODEC_MAX 0x0f
51 #define HDA_LAST_OFFSET \
52 (0x2084 + ((HDA_ISS_NO) * 0x20) + ((HDA_OSS_NO) * 0x20))
53 #define HDA_SET_REG_TABLE_SZ \
54 (0x80 + ((HDA_ISS_NO) * 0x20) + ((HDA_OSS_NO) * 0x20))
55 #define HDA_CORB_ENTRY_LEN 0x04
56 #define HDA_RIRB_ENTRY_LEN 0x08
57 #define HDA_BDL_ENTRY_LEN 0x10
58 #define HDA_DMA_PIB_ENTRY_LEN 0x08
59 #define HDA_STREAM_TAGS_CNT 0x10
60 #define HDA_STREAM_REGS_BASE 0x80
61 #define HDA_STREAM_REGS_LEN 0x20
63 #define HDA_DMA_ACCESS_LEN (sizeof(uint32_t))
64 #define HDA_BDL_MAX_LEN 0x0100
66 #define HDAC_SDSTS_FIFORDY (1 << 5)
68 #define HDA_RIRBSTS_IRQ_MASK (HDAC_RIRBSTS_RINTFL | HDAC_RIRBSTS_RIRBOIS)
69 #define HDA_STATESTS_IRQ_MASK ((1 << HDA_CODEC_MAX) - 1)
70 #define HDA_SDSTS_IRQ_MASK \
71 (HDAC_SDSTS_DESE | HDAC_SDSTS_FIFOE | HDAC_SDSTS_BCIS)
79 typedef void (*hda_set_reg_handler)(struct hda_softc *sc, uint32_t offset,
89 struct hda_bdle_desc {
95 struct hda_codec_cmd_ctl {
104 struct hda_stream_desc {
109 /* bp is the no. of bytes transferred in the current bdle */
111 /* be is the no. of bdles transferred in the bdl */
115 struct hda_bdle_desc bdl[HDA_BDL_MAX_LEN];
119 struct pci_devinst *pci_dev;
120 uint32_t regs[HDA_LAST_OFFSET];
124 uint64_t wall_clock_start;
126 struct hda_codec_cmd_ctl corb;
127 struct hda_codec_cmd_ctl rirb;
130 struct hda_codec_inst *codecs[HDA_CODEC_MAX];
132 /* Base Address of the DMA Position Buffer */
135 struct hda_stream_desc streams[HDA_IOSS_NO];
136 /* 2 tables for output and input */
137 uint8_t stream_map[2][HDA_STREAM_TAGS_CNT];
141 * HDA module function declarations
143 static inline void hda_set_reg_by_offset(struct hda_softc *sc, uint32_t offset,
145 static inline uint32_t hda_get_reg_by_offset(struct hda_softc *sc,
147 static inline void hda_set_field_by_offset(struct hda_softc *sc,
148 uint32_t offset, uint32_t mask, uint32_t value);
150 static uint8_t hda_parse_config(const char *opts, const char *key, char *val);
151 static struct hda_softc *hda_init(const char *opts);
152 static void hda_update_intr(struct hda_softc *sc);
153 static void hda_response_interrupt(struct hda_softc *sc);
154 static int hda_codec_constructor(struct hda_softc *sc,
155 struct hda_codec_class *codec, const char *play, const char *rec,
157 static struct hda_codec_class *hda_find_codec_class(const char *name);
159 static int hda_send_command(struct hda_softc *sc, uint32_t verb);
160 static int hda_notify_codecs(struct hda_softc *sc, uint8_t run,
161 uint8_t stream, uint8_t dir);
162 static void hda_reset(struct hda_softc *sc);
163 static void hda_reset_regs(struct hda_softc *sc);
164 static void hda_stream_reset(struct hda_softc *sc, uint8_t stream_ind);
165 static int hda_stream_start(struct hda_softc *sc, uint8_t stream_ind);
166 static int hda_stream_stop(struct hda_softc *sc, uint8_t stream_ind);
167 static uint32_t hda_read(struct hda_softc *sc, uint32_t offset);
168 static int hda_write(struct hda_softc *sc, uint32_t offset, uint8_t size,
171 static inline void hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl *p);
172 static int hda_corb_start(struct hda_softc *sc);
173 static int hda_corb_run(struct hda_softc *sc);
174 static int hda_rirb_start(struct hda_softc *sc);
176 static void *hda_dma_get_vaddr(struct hda_softc *sc, uint64_t dma_paddr,
178 static void hda_dma_st_dword(void *dma_vaddr, uint32_t data);
179 static uint32_t hda_dma_ld_dword(void *dma_vaddr);
181 static inline uint8_t hda_get_stream_by_offsets(uint32_t offset,
183 static inline uint32_t hda_get_offset_stream(uint8_t stream_ind);
185 static void hda_set_gctl(struct hda_softc *sc, uint32_t offset, uint32_t old);
186 static void hda_set_statests(struct hda_softc *sc, uint32_t offset,
188 static void hda_set_corbwp(struct hda_softc *sc, uint32_t offset, uint32_t old);
189 static void hda_set_corbctl(struct hda_softc *sc, uint32_t offset,
191 static void hda_set_rirbctl(struct hda_softc *sc, uint32_t offset,
193 static void hda_set_rirbsts(struct hda_softc *sc, uint32_t offset,
195 static void hda_set_dpiblbase(struct hda_softc *sc, uint32_t offset,
197 static void hda_set_sdctl(struct hda_softc *sc, uint32_t offset, uint32_t old);
198 static void hda_set_sdctl2(struct hda_softc *sc, uint32_t offset, uint32_t old);
199 static void hda_set_sdsts(struct hda_softc *sc, uint32_t offset, uint32_t old);
201 static int hda_signal_state_change(struct hda_codec_inst *hci);
202 static int hda_response(struct hda_codec_inst *hci, uint32_t response,
204 static int hda_transfer(struct hda_codec_inst *hci, uint8_t stream,
205 uint8_t dir, void *buf, size_t count);
207 static void hda_set_pib(struct hda_softc *sc, uint8_t stream_ind, uint32_t pib);
208 static uint64_t hda_get_clock_ns(void);
211 * PCI HDA function declarations
213 static int pci_hda_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts);
214 static void pci_hda_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
215 int baridx, uint64_t offset, int size, uint64_t value);
216 static uint64_t pci_hda_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
217 int baridx, uint64_t offset, int size);
222 static const hda_set_reg_handler hda_set_reg_table[] = {
223 [HDAC_GCTL] = hda_set_gctl,
224 [HDAC_STATESTS] = hda_set_statests,
225 [HDAC_CORBWP] = hda_set_corbwp,
226 [HDAC_CORBCTL] = hda_set_corbctl,
227 [HDAC_RIRBCTL] = hda_set_rirbctl,
228 [HDAC_RIRBSTS] = hda_set_rirbsts,
229 [HDAC_DPIBLBASE] = hda_set_dpiblbase,
231 #define HDAC_ISTREAM(n, iss, oss) \
232 [_HDAC_ISDCTL(n, iss, oss)] = hda_set_sdctl, \
233 [_HDAC_ISDCTL(n, iss, oss) + 2] = hda_set_sdctl2, \
234 [_HDAC_ISDSTS(n, iss, oss)] = hda_set_sdsts, \
236 #define HDAC_OSTREAM(n, iss, oss) \
237 [_HDAC_OSDCTL(n, iss, oss)] = hda_set_sdctl, \
238 [_HDAC_OSDCTL(n, iss, oss) + 2] = hda_set_sdctl2, \
239 [_HDAC_OSDSTS(n, iss, oss)] = hda_set_sdsts, \
241 HDAC_ISTREAM(0, HDA_ISS_NO, HDA_OSS_NO)
242 HDAC_ISTREAM(1, HDA_ISS_NO, HDA_OSS_NO)
243 HDAC_ISTREAM(2, HDA_ISS_NO, HDA_OSS_NO)
244 HDAC_ISTREAM(3, HDA_ISS_NO, HDA_OSS_NO)
246 HDAC_OSTREAM(0, HDA_ISS_NO, HDA_OSS_NO)
247 HDAC_OSTREAM(1, HDA_ISS_NO, HDA_OSS_NO)
248 HDAC_OSTREAM(2, HDA_ISS_NO, HDA_OSS_NO)
249 HDAC_OSTREAM(3, HDA_ISS_NO, HDA_OSS_NO)
251 [HDA_SET_REG_TABLE_SZ] = NULL,
254 static const uint16_t hda_corb_sizes[] = {
255 [HDAC_CORBSIZE_CORBSIZE_2] = 2,
256 [HDAC_CORBSIZE_CORBSIZE_16] = 16,
257 [HDAC_CORBSIZE_CORBSIZE_256] = 256,
258 [HDAC_CORBSIZE_CORBSIZE_MASK] = 0,
261 static const uint16_t hda_rirb_sizes[] = {
262 [HDAC_RIRBSIZE_RIRBSIZE_2] = 2,
263 [HDAC_RIRBSIZE_RIRBSIZE_16] = 16,
264 [HDAC_RIRBSIZE_RIRBSIZE_256] = 256,
265 [HDAC_RIRBSIZE_RIRBSIZE_MASK] = 0,
268 static struct hda_ops hops = {
269 .signal = hda_signal_state_change,
270 .response = hda_response,
271 .transfer = hda_transfer,
274 struct pci_devemu pci_de_hda = {
276 .pe_init = pci_hda_init,
277 .pe_barwrite = pci_hda_write,
278 .pe_barread = pci_hda_read
281 PCI_EMUL_SET(pci_de_hda);
283 SET_DECLARE(hda_codec_class_set, struct hda_codec_class);
290 * HDA module function definitions
294 hda_set_reg_by_offset(struct hda_softc *sc, uint32_t offset, uint32_t value)
296 assert(offset < HDA_LAST_OFFSET);
297 sc->regs[offset] = value;
300 static inline uint32_t
301 hda_get_reg_by_offset(struct hda_softc *sc, uint32_t offset)
303 assert(offset < HDA_LAST_OFFSET);
304 return sc->regs[offset];
308 hda_set_field_by_offset(struct hda_softc *sc, uint32_t offset,
309 uint32_t mask, uint32_t value)
311 uint32_t reg_value = 0;
313 reg_value = hda_get_reg_by_offset(sc, offset);
316 reg_value |= (value & mask);
318 hda_set_reg_by_offset(sc, offset, reg_value);
322 hda_parse_config(const char *opts, const char *key, char *val)
334 if (len >= sizeof(buf)) {
335 DPRINTF("Opts too big");
339 DPRINTF("opts: %s", opts);
343 for (i = 0; i < len; i++)
350 if (!memcmp(s, key, strlen(key))) {
351 strncpy(val, s + strlen(key), 64);
359 if (!memcmp(s, key, strlen(key))) {
360 strncpy(val, s + strlen(key), 64);
367 static struct hda_softc *
368 hda_init(const char *opts)
370 struct hda_softc *sc = NULL;
371 struct hda_codec_class *codec = NULL;
377 dbg = fopen("/tmp/bhyve_hda.log", "w+");
380 DPRINTF("opts: %s", opts);
382 sc = calloc(1, sizeof(*sc));
389 * TODO search all the codecs declared in opts
390 * For now we play with one single codec
392 codec = hda_find_codec_class("hda_codec");
394 p = hda_parse_config(opts, "play=", play);
395 r = hda_parse_config(opts, "rec=", rec);
396 DPRINTF("play: %s rec: %s", play, rec);
398 err = hda_codec_constructor(sc, codec, p ? \
399 play : NULL, r ? rec : NULL, NULL);
408 hda_update_intr(struct hda_softc *sc)
410 struct pci_devinst *pi = sc->pci_dev;
411 uint32_t intctl = hda_get_reg_by_offset(sc, HDAC_INTCTL);
414 uint32_t rirbsts = 0;
416 uint32_t statests = 0;
420 /* update the CIS bits */
421 rirbsts = hda_get_reg_by_offset(sc, HDAC_RIRBSTS);
422 if (rirbsts & (HDAC_RIRBSTS_RINTFL | HDAC_RIRBSTS_RIRBOIS))
423 intsts |= HDAC_INTSTS_CIS;
425 wakeen = hda_get_reg_by_offset(sc, HDAC_WAKEEN);
426 statests = hda_get_reg_by_offset(sc, HDAC_STATESTS);
427 if (statests & wakeen)
428 intsts |= HDAC_INTSTS_CIS;
430 /* update the SIS bits */
431 for (i = 0; i < HDA_IOSS_NO; i++) {
432 off = hda_get_offset_stream(i);
433 sdsts = hda_get_reg_by_offset(sc, off + HDAC_SDSTS);
434 if (sdsts & HDAC_SDSTS_BCIS)
438 /* update the GIS bit */
440 intsts |= HDAC_INTSTS_GIS;
442 hda_set_reg_by_offset(sc, HDAC_INTSTS, intsts);
444 if ((intctl & HDAC_INTCTL_GIE) && ((intsts & \
445 ~HDAC_INTSTS_GIS) & intctl)) {
447 pci_lintr_assert(pi);
452 pci_lintr_deassert(pi);
459 hda_response_interrupt(struct hda_softc *sc)
461 uint8_t rirbctl = hda_get_reg_by_offset(sc, HDAC_RIRBCTL);
463 if ((rirbctl & HDAC_RIRBCTL_RINTCTL) && sc->rirb_cnt) {
465 hda_set_field_by_offset(sc, HDAC_RIRBSTS, HDAC_RIRBSTS_RINTFL,
466 HDAC_RIRBSTS_RINTFL);
472 hda_codec_constructor(struct hda_softc *sc, struct hda_codec_class *codec,
473 const char *play, const char *rec, const char *opts)
475 struct hda_codec_inst *hci = NULL;
477 if (sc->codecs_no >= HDA_CODEC_MAX)
480 hci = calloc(1, sizeof(struct hda_codec_inst));
486 hci->cad = sc->codecs_no;
489 sc->codecs[sc->codecs_no++] = hci;
492 DPRINTF("This codec does not implement the init function");
496 return (codec->init(hci, play, rec, opts));
499 static struct hda_codec_class *
500 hda_find_codec_class(const char *name)
502 struct hda_codec_class **pdpp = NULL, *pdp = NULL;
504 SET_FOREACH(pdpp, hda_codec_class_set) {
506 if (!strcmp(pdp->name, name)) {
515 hda_send_command(struct hda_softc *sc, uint32_t verb)
517 struct hda_codec_inst *hci = NULL;
518 struct hda_codec_class *codec = NULL;
519 uint8_t cad = (verb >> HDA_CMD_CAD_SHIFT) & 0x0f;
521 hci = sc->codecs[cad];
525 DPRINTF("cad: 0x%x verb: 0x%x", cad, verb);
530 if (!codec->command) {
531 DPRINTF("This codec does not implement the command function");
535 return (codec->command(hci, verb));
539 hda_notify_codecs(struct hda_softc *sc, uint8_t run, uint8_t stream,
542 struct hda_codec_inst *hci = NULL;
543 struct hda_codec_class *codec = NULL;
547 /* Notify each codec */
548 for (i = 0; i < sc->codecs_no; i++) {
556 err = codec->notify(hci, run, stream, dir);
562 return (i == sc->codecs_no ? (-1) : 0);
566 hda_reset(struct hda_softc *sc)
569 struct hda_codec_inst *hci = NULL;
570 struct hda_codec_class *codec = NULL;
574 /* Reset each codec */
575 for (i = 0; i < sc->codecs_no; i++) {
586 sc->wall_clock_start = hda_get_clock_ns();
590 hda_reset_regs(struct hda_softc *sc)
595 DPRINTF("Reset the HDA controller registers ...");
597 memset(sc->regs, 0, sizeof(sc->regs));
599 hda_set_reg_by_offset(sc, HDAC_GCAP,
601 (HDA_ISS_NO << HDAC_GCAP_ISS_SHIFT) |
602 (HDA_OSS_NO << HDAC_GCAP_OSS_SHIFT));
603 hda_set_reg_by_offset(sc, HDAC_VMAJ, 0x01);
604 hda_set_reg_by_offset(sc, HDAC_OUTPAY, 0x3c);
605 hda_set_reg_by_offset(sc, HDAC_INPAY, 0x1d);
606 hda_set_reg_by_offset(sc, HDAC_CORBSIZE,
607 HDAC_CORBSIZE_CORBSZCAP_256 | HDAC_CORBSIZE_CORBSIZE_256);
608 hda_set_reg_by_offset(sc, HDAC_RIRBSIZE,
609 HDAC_RIRBSIZE_RIRBSZCAP_256 | HDAC_RIRBSIZE_RIRBSIZE_256);
611 for (i = 0; i < HDA_IOSS_NO; i++) {
612 off = hda_get_offset_stream(i);
613 hda_set_reg_by_offset(sc, off + HDAC_SDFIFOS, HDA_FIFO_SIZE);
618 hda_stream_reset(struct hda_softc *sc, uint8_t stream_ind)
620 struct hda_stream_desc *st = &sc->streams[stream_ind];
621 uint32_t off = hda_get_offset_stream(stream_ind);
623 DPRINTF("Reset the HDA stream: 0x%x", stream_ind);
625 /* Reset the Stream Descriptor registers */
626 memset(sc->regs + HDA_STREAM_REGS_BASE + off, 0, HDA_STREAM_REGS_LEN);
628 /* Reset the Stream Descriptor */
629 memset(st, 0, sizeof(*st));
631 hda_set_field_by_offset(sc, off + HDAC_SDSTS,
632 HDAC_SDSTS_FIFORDY, HDAC_SDSTS_FIFORDY);
633 hda_set_field_by_offset(sc, off + HDAC_SDCTL0,
634 HDAC_SDCTL_SRST, HDAC_SDCTL_SRST);
638 hda_stream_start(struct hda_softc *sc, uint8_t stream_ind)
640 struct hda_stream_desc *st = &sc->streams[stream_ind];
641 struct hda_bdle_desc *bdle_desc = NULL;
642 struct hda_bdle *bdle = NULL;
644 uint32_t bdl_cnt = 0;
647 uint64_t bdl_paddr = 0;
648 void *bdl_vaddr = NULL;
649 uint32_t bdle_sz = 0;
650 uint64_t bdle_addrl = 0;
651 uint64_t bdle_addrh = 0;
652 uint64_t bdle_paddr = 0;
653 void *bdle_vaddr = NULL;
654 uint32_t off = hda_get_offset_stream(stream_ind);
662 lvi = hda_get_reg_by_offset(sc, off + HDAC_SDLVI);
663 bdpl = hda_get_reg_by_offset(sc, off + HDAC_SDBDPL);
664 bdpu = hda_get_reg_by_offset(sc, off + HDAC_SDBDPU);
667 assert(bdl_cnt <= HDA_BDL_MAX_LEN);
669 bdl_paddr = bdpl | (bdpu << 32);
670 bdl_vaddr = hda_dma_get_vaddr(sc, bdl_paddr,
671 HDA_BDL_ENTRY_LEN * bdl_cnt);
673 DPRINTF("Fail to get the guest virtual address");
677 DPRINTF("stream: 0x%x bdl_cnt: 0x%x bdl_paddr: 0x%lx",
678 stream_ind, bdl_cnt, bdl_paddr);
680 st->bdl_cnt = bdl_cnt;
682 bdle = (struct hda_bdle *)bdl_vaddr;
683 for (i = 0; i < bdl_cnt; i++, bdle++) {
685 assert(!(bdle_sz % HDA_DMA_ACCESS_LEN));
687 bdle_addrl = bdle->addrl;
688 bdle_addrh = bdle->addrh;
690 bdle_paddr = bdle_addrl | (bdle_addrh << 32);
691 bdle_vaddr = hda_dma_get_vaddr(sc, bdle_paddr, bdle_sz);
693 DPRINTF("Fail to get the guest virtual address");
697 bdle_desc = &st->bdl[i];
698 bdle_desc->addr = bdle_vaddr;
699 bdle_desc->len = bdle_sz;
700 bdle_desc->ioc = bdle->ioc;
702 DPRINTF("bdle: 0x%x bdle_sz: 0x%x", i, bdle_sz);
705 sdctl = hda_get_reg_by_offset(sc, off + HDAC_SDCTL0);
706 strm = (sdctl >> 20) & 0x0f;
707 dir = stream_ind >= HDA_ISS_NO;
709 DPRINTF("strm: 0x%x, dir: 0x%x", strm, dir);
711 sc->stream_map[dir][strm] = stream_ind;
717 hda_set_pib(sc, stream_ind, 0);
721 hda_notify_codecs(sc, 1, strm, dir);
727 hda_stream_stop(struct hda_softc *sc, uint8_t stream_ind)
729 struct hda_stream_desc *st = &sc->streams[stream_ind];
730 uint8_t strm = st->stream;
731 uint8_t dir = st->dir;
733 DPRINTF("stream: 0x%x, strm: 0x%x, dir: 0x%x", stream_ind, strm, dir);
737 hda_notify_codecs(sc, 0, strm, dir);
743 hda_read(struct hda_softc *sc, uint32_t offset)
745 if (offset == HDAC_WALCLK)
746 return (24 * (hda_get_clock_ns() - \
747 sc->wall_clock_start) / 1000);
749 return (hda_get_reg_by_offset(sc, offset));
753 hda_write(struct hda_softc *sc, uint32_t offset, uint8_t size, uint32_t value)
755 uint32_t old = hda_get_reg_by_offset(sc, offset);
756 uint32_t masks[] = {0x00000000, 0x000000ff, 0x0000ffff,
757 0x00ffffff, 0xffffffff};
758 hda_set_reg_handler set_reg_handler = hda_set_reg_table[offset];
760 hda_set_field_by_offset(sc, offset, masks[size], value);
763 set_reg_handler(sc, offset, old);
769 hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl *p)
772 char *name = p->name;
774 DPRINTF("%s size: %d", name, p->size);
775 DPRINTF("%s dma_vaddr: %p", name, p->dma_vaddr);
776 DPRINTF("%s wp: 0x%x", name, p->wp);
777 DPRINTF("%s rp: 0x%x", name, p->rp);
781 hda_corb_start(struct hda_softc *sc)
783 struct hda_codec_cmd_ctl *corb = &sc->corb;
784 uint8_t corbsize = 0;
785 uint64_t corblbase = 0;
786 uint64_t corbubase = 0;
787 uint64_t corbpaddr = 0;
791 corbsize = hda_get_reg_by_offset(sc, HDAC_CORBSIZE) & \
792 HDAC_CORBSIZE_CORBSIZE_MASK;
793 corb->size = hda_corb_sizes[corbsize];
796 DPRINTF("Invalid corb size");
800 corblbase = hda_get_reg_by_offset(sc, HDAC_CORBLBASE);
801 corbubase = hda_get_reg_by_offset(sc, HDAC_CORBUBASE);
803 corbpaddr = corblbase | (corbubase << 32);
804 DPRINTF("CORB dma_paddr: %p", (void *)corbpaddr);
806 corb->dma_vaddr = hda_dma_get_vaddr(sc, corbpaddr,
807 HDA_CORB_ENTRY_LEN * corb->size);
808 if (!corb->dma_vaddr) {
809 DPRINTF("Fail to get the guest virtual address");
813 corb->wp = hda_get_reg_by_offset(sc, HDAC_CORBWP);
814 corb->rp = hda_get_reg_by_offset(sc, HDAC_CORBRP);
818 hda_print_cmd_ctl_data(corb);
824 hda_corb_run(struct hda_softc *sc)
826 struct hda_codec_cmd_ctl *corb = &sc->corb;
830 corb->wp = hda_get_reg_by_offset(sc, HDAC_CORBWP);
832 while (corb->rp != corb->wp && corb->run) {
834 corb->rp %= corb->size;
836 verb = hda_dma_ld_dword(corb->dma_vaddr + \
837 HDA_CORB_ENTRY_LEN * corb->rp);
839 err = hda_send_command(sc, verb);
843 hda_set_reg_by_offset(sc, HDAC_CORBRP, corb->rp);
846 hda_response_interrupt(sc);
852 hda_rirb_start(struct hda_softc *sc)
854 struct hda_codec_cmd_ctl *rirb = &sc->rirb;
855 uint8_t rirbsize = 0;
856 uint64_t rirblbase = 0;
857 uint64_t rirbubase = 0;
858 uint64_t rirbpaddr = 0;
862 rirbsize = hda_get_reg_by_offset(sc, HDAC_RIRBSIZE) & \
863 HDAC_RIRBSIZE_RIRBSIZE_MASK;
864 rirb->size = hda_rirb_sizes[rirbsize];
867 DPRINTF("Invalid rirb size");
871 rirblbase = hda_get_reg_by_offset(sc, HDAC_RIRBLBASE);
872 rirbubase = hda_get_reg_by_offset(sc, HDAC_RIRBUBASE);
874 rirbpaddr = rirblbase | (rirbubase << 32);
875 DPRINTF("RIRB dma_paddr: %p", (void *)rirbpaddr);
877 rirb->dma_vaddr = hda_dma_get_vaddr(sc, rirbpaddr,
878 HDA_RIRB_ENTRY_LEN * rirb->size);
879 if (!rirb->dma_vaddr) {
880 DPRINTF("Fail to get the guest virtual address");
884 rirb->wp = hda_get_reg_by_offset(sc, HDAC_RIRBWP);
889 hda_print_cmd_ctl_data(rirb);
895 hda_dma_get_vaddr(struct hda_softc *sc, uint64_t dma_paddr, size_t len)
897 struct pci_devinst *pi = sc->pci_dev;
901 return (paddr_guest2host(pi->pi_vmctx, (uintptr_t)dma_paddr, len));
905 hda_dma_st_dword(void *dma_vaddr, uint32_t data)
907 *(uint32_t*)dma_vaddr = data;
911 hda_dma_ld_dword(void *dma_vaddr)
913 return (*(uint32_t*)dma_vaddr);
916 static inline uint8_t
917 hda_get_stream_by_offsets(uint32_t offset, uint8_t reg_offset)
919 uint8_t stream_ind = (offset - reg_offset) >> 5;
921 assert(stream_ind < HDA_IOSS_NO);
926 static inline uint32_t
927 hda_get_offset_stream(uint8_t stream_ind)
929 return (stream_ind << 5);
933 hda_set_gctl(struct hda_softc *sc, uint32_t offset, uint32_t old)
935 uint32_t value = hda_get_reg_by_offset(sc, offset);
937 if (!(value & HDAC_GCTL_CRST)) {
943 hda_set_statests(struct hda_softc *sc, uint32_t offset, uint32_t old)
945 uint32_t value = hda_get_reg_by_offset(sc, offset);
947 hda_set_reg_by_offset(sc, offset, old);
949 /* clear the corresponding bits written by the software (guest) */
950 hda_set_field_by_offset(sc, offset, value & HDA_STATESTS_IRQ_MASK, 0);
956 hda_set_corbwp(struct hda_softc *sc, uint32_t offset, uint32_t old)
962 hda_set_corbctl(struct hda_softc *sc, uint32_t offset, uint32_t old)
964 uint32_t value = hda_get_reg_by_offset(sc, offset);
966 struct hda_codec_cmd_ctl *corb = NULL;
968 if (value & HDAC_CORBCTL_CORBRUN) {
969 if (!(old & HDAC_CORBCTL_CORBRUN)) {
970 err = hda_corb_start(sc);
975 memset(corb, 0, sizeof(*corb));
982 hda_set_rirbctl(struct hda_softc *sc, uint32_t offset, uint32_t old)
984 uint32_t value = hda_get_reg_by_offset(sc, offset);
986 struct hda_codec_cmd_ctl *rirb = NULL;
988 if (value & HDAC_RIRBCTL_RIRBDMAEN) {
989 err = hda_rirb_start(sc);
993 memset(rirb, 0, sizeof(*rirb));
998 hda_set_rirbsts(struct hda_softc *sc, uint32_t offset, uint32_t old)
1000 uint32_t value = hda_get_reg_by_offset(sc, offset);
1002 hda_set_reg_by_offset(sc, offset, old);
1004 /* clear the corresponding bits written by the software (guest) */
1005 hda_set_field_by_offset(sc, offset, value & HDA_RIRBSTS_IRQ_MASK, 0);
1007 hda_update_intr(sc);
1011 hda_set_dpiblbase(struct hda_softc *sc, uint32_t offset, uint32_t old)
1013 uint32_t value = hda_get_reg_by_offset(sc, offset);
1014 uint64_t dpiblbase = 0;
1015 uint64_t dpibubase = 0;
1016 uint64_t dpibpaddr = 0;
1018 if ((value & HDAC_DPLBASE_DPLBASE_DMAPBE) != (old & \
1019 HDAC_DPLBASE_DPLBASE_DMAPBE)) {
1020 if (value & HDAC_DPLBASE_DPLBASE_DMAPBE) {
1021 dpiblbase = value & HDAC_DPLBASE_DPLBASE_MASK;
1022 dpibubase = hda_get_reg_by_offset(sc, HDAC_DPIBUBASE);
1024 dpibpaddr = dpiblbase | (dpibubase << 32);
1025 DPRINTF("DMA Position In Buffer dma_paddr: %p",
1028 sc->dma_pib_vaddr = hda_dma_get_vaddr(sc, dpibpaddr,
1029 HDA_DMA_PIB_ENTRY_LEN * HDA_IOSS_NO);
1030 if (!sc->dma_pib_vaddr) {
1031 DPRINTF("Fail to get the guest \
1036 DPRINTF("DMA Position In Buffer Reset");
1037 sc->dma_pib_vaddr = NULL;
1043 hda_set_sdctl(struct hda_softc *sc, uint32_t offset, uint32_t old)
1045 uint8_t stream_ind = hda_get_stream_by_offsets(offset, HDAC_SDCTL0);
1046 uint32_t value = hda_get_reg_by_offset(sc, offset);
1049 DPRINTF("stream_ind: 0x%x old: 0x%x value: 0x%x",
1050 stream_ind, old, value);
1052 if (value & HDAC_SDCTL_SRST) {
1053 hda_stream_reset(sc, stream_ind);
1056 if ((value & HDAC_SDCTL_RUN) != (old & HDAC_SDCTL_RUN)) {
1057 if (value & HDAC_SDCTL_RUN) {
1058 err = hda_stream_start(sc, stream_ind);
1061 err = hda_stream_stop(sc, stream_ind);
1068 hda_set_sdctl2(struct hda_softc *sc, uint32_t offset, uint32_t old)
1070 uint32_t value = hda_get_reg_by_offset(sc, offset);
1072 hda_set_field_by_offset(sc, offset - 2, 0x00ff0000, value << 16);
1076 hda_set_sdsts(struct hda_softc *sc, uint32_t offset, uint32_t old)
1078 uint32_t value = hda_get_reg_by_offset(sc, offset);
1080 hda_set_reg_by_offset(sc, offset, old);
1082 /* clear the corresponding bits written by the software (guest) */
1083 hda_set_field_by_offset(sc, offset, value & HDA_SDSTS_IRQ_MASK, 0);
1085 hda_update_intr(sc);
1089 hda_signal_state_change(struct hda_codec_inst *hci)
1091 struct hda_softc *sc = NULL;
1092 uint32_t sdiwake = 0;
1097 DPRINTF("cad: 0x%x", hci->cad);
1100 sdiwake = 1 << hci->cad;
1102 hda_set_field_by_offset(sc, HDAC_STATESTS, sdiwake, sdiwake);
1103 hda_update_intr(sc);
1109 hda_response(struct hda_codec_inst *hci, uint32_t response, uint8_t unsol)
1111 struct hda_softc *sc = NULL;
1112 struct hda_codec_cmd_ctl *rirb = NULL;
1113 uint32_t response_ex = 0;
1114 uint8_t rintcnt = 0;
1117 assert(hci->cad <= HDA_CODEC_MAX);
1119 response_ex = hci->cad | unsol;
1128 rirb->wp %= rirb->size;
1130 hda_dma_st_dword(rirb->dma_vaddr + HDA_RIRB_ENTRY_LEN * \
1131 rirb->wp, response);
1132 hda_dma_st_dword(rirb->dma_vaddr + HDA_RIRB_ENTRY_LEN * \
1133 rirb->wp + 0x04, response_ex);
1135 hda_set_reg_by_offset(sc, HDAC_RIRBWP, rirb->wp);
1140 rintcnt = hda_get_reg_by_offset(sc, HDAC_RINTCNT);
1141 if (sc->rirb_cnt == rintcnt)
1142 hda_response_interrupt(sc);
1148 hda_transfer(struct hda_codec_inst *hci, uint8_t stream, uint8_t dir,
1149 void *buf, size_t count)
1151 struct hda_softc *sc = NULL;
1152 struct hda_stream_desc *st = NULL;
1153 struct hda_bdle_desc *bdl = NULL;
1154 struct hda_bdle_desc *bdle_desc = NULL;
1155 uint8_t stream_ind = 0;
1164 assert(!(count % HDA_DMA_ACCESS_LEN));
1167 DPRINTF("Invalid stream");
1173 assert(stream < HDA_STREAM_TAGS_CNT);
1174 stream_ind = sc->stream_map[dir][stream];
1177 assert(stream_ind < HDA_ISS_NO);
1179 assert(stream_ind >= HDA_ISS_NO && stream_ind < HDA_IOSS_NO);
1181 st = &sc->streams[stream_ind];
1183 DPRINTF("Stream 0x%x stopped", stream);
1187 assert(st->stream == stream);
1189 off = hda_get_offset_stream(stream_ind);
1191 lpib = hda_get_reg_by_offset(sc, off + HDAC_SDLPIB);
1195 assert(st->be < st->bdl_cnt);
1196 assert(st->bp < bdl[st->be].len);
1200 bdle_desc = &bdl[st->be];
1203 *(uint32_t *)buf = \
1204 hda_dma_ld_dword(bdle_desc->addr + st->bp);
1206 hda_dma_st_dword(bdle_desc->addr + st->bp,
1209 buf += HDA_DMA_ACCESS_LEN;
1210 st->bp += HDA_DMA_ACCESS_LEN;
1211 lpib += HDA_DMA_ACCESS_LEN;
1212 left -= HDA_DMA_ACCESS_LEN;
1214 if (st->bp == bdle_desc->len) {
1219 if (st->be == st->bdl_cnt) {
1223 bdle_desc = &bdl[st->be];
1227 hda_set_pib(sc, stream_ind, lpib);
1230 hda_set_field_by_offset(sc, off + HDAC_SDSTS,
1231 HDAC_SDSTS_BCIS, HDAC_SDSTS_BCIS);
1232 hda_update_intr(sc);
1239 hda_set_pib(struct hda_softc *sc, uint8_t stream_ind, uint32_t pib)
1241 uint32_t off = hda_get_offset_stream(stream_ind);
1243 hda_set_reg_by_offset(sc, off + HDAC_SDLPIB, pib);
1245 hda_set_reg_by_offset(sc, 0x2000 + off + HDAC_SDLPIB, pib);
1246 if (sc->dma_pib_vaddr)
1247 *(uint32_t *)(sc->dma_pib_vaddr + stream_ind * \
1248 HDA_DMA_PIB_ENTRY_LEN) = pib;
1251 static uint64_t hda_get_clock_ns(void)
1256 err = clock_gettime(CLOCK_MONOTONIC, &ts);
1259 return (ts.tv_sec * 1000000000LL + ts.tv_nsec);
1263 * PCI HDA function definitions
1266 pci_hda_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
1268 struct hda_softc *sc = NULL;
1270 assert(ctx != NULL);
1273 pci_set_cfgdata16(pi, PCIR_VENDOR, INTEL_VENDORID);
1274 pci_set_cfgdata16(pi, PCIR_DEVICE, HDA_INTEL_82801G);
1276 pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_MULTIMEDIA_HDA);
1277 pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_MULTIMEDIA);
1279 /* select the Intel HDA mode */
1280 pci_set_cfgdata8(pi, PCIR_HDCTL, 0x01);
1282 /* allocate one BAR register for the Memory address offsets */
1283 pci_emul_alloc_bar(pi, 0, PCIBAR_MEM32, HDA_LAST_OFFSET);
1285 /* allocate an IRQ pin for our slot */
1286 pci_lintr_request(pi);
1288 sc = hda_init(opts);
1299 pci_hda_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
1300 int baridx, uint64_t offset, int size, uint64_t value)
1302 struct hda_softc *sc = pi->pi_arg;
1306 assert(baridx == 0);
1309 DPRINTF("offset: 0x%lx value: 0x%lx", offset, value);
1311 err = hda_write(sc, offset, size, value);
1316 pci_hda_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
1317 int baridx, uint64_t offset, int size)
1319 struct hda_softc *sc = pi->pi_arg;
1323 assert(baridx == 0);
1326 value = hda_read(sc, offset);
1328 DPRINTF("offset: 0x%lx value: 0x%lx", offset, value);