xref: /freebsd/usr.sbin/bhyve/pci_hda.c (revision 44d780e32b9d798a93b758fe0957d770e3190988)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2016 Alex Teaca <iateaca@FreeBSD.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
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.
15  *
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
26  * SUCH DAMAGE.
27  *
28  */
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 #include <time.h>
34 
35 #include "pci_hda.h"
36 #include "bhyverun.h"
37 #include "pci_emul.h"
38 #include "hdac_reg.h"
39 
40 /*
41  * HDA defines
42  */
43 #define PCIR_HDCTL		0x40
44 #define INTEL_VENDORID		0x8086
45 #define HDA_INTEL_82801G	0x27d8
46 
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
62 
63 #define HDA_DMA_ACCESS_LEN	(sizeof(uint32_t))
64 #define HDA_BDL_MAX_LEN		0x0100
65 
66 #define HDAC_SDSTS_FIFORDY	(1 << 5)
67 
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)
72 
73 /*
74  * HDA data structures
75  */
76 
77 struct hda_softc;
78 
79 typedef void (*hda_set_reg_handler)(struct hda_softc *sc, uint32_t offset,
80 		uint32_t old);
81 
82 struct hda_bdle {
83 	uint32_t addrl;
84 	uint32_t addrh;
85 	uint32_t len;
86 	uint32_t ioc;
87 } __packed;
88 
89 struct hda_bdle_desc {
90 	void *addr;
91 	uint8_t ioc;
92 	uint32_t len;
93 };
94 
95 struct hda_codec_cmd_ctl {
96 	char *name;
97 	void *dma_vaddr;
98 	uint8_t run;
99 	uint16_t rp;
100 	uint16_t size;
101 	uint16_t wp;
102 };
103 
104 struct hda_stream_desc {
105 	uint8_t dir;
106 	uint8_t run;
107 	uint8_t stream;
108 
109 	/* bp is the no. of bytes transferred in the current bdle */
110 	uint32_t bp;
111 	/* be is the no. of bdles transferred in the bdl */
112 	uint32_t be;
113 
114 	uint32_t bdl_cnt;
115 	struct hda_bdle_desc bdl[HDA_BDL_MAX_LEN];
116 };
117 
118 struct hda_softc {
119 	struct pci_devinst *pci_dev;
120 	uint32_t regs[HDA_LAST_OFFSET];
121 
122 	uint8_t lintr;
123 	uint8_t rirb_cnt;
124 	uint64_t wall_clock_start;
125 
126 	struct hda_codec_cmd_ctl corb;
127 	struct hda_codec_cmd_ctl rirb;
128 
129 	uint8_t codecs_no;
130 	struct hda_codec_inst *codecs[HDA_CODEC_MAX];
131 
132 	/* Base Address of the DMA Position Buffer */
133 	void *dma_pib_vaddr;
134 
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];
138 };
139 
140 /*
141  * HDA module function declarations
142  */
143 static inline void hda_set_reg_by_offset(struct hda_softc *sc, uint32_t offset,
144     uint32_t value);
145 static inline uint32_t hda_get_reg_by_offset(struct hda_softc *sc,
146     uint32_t offset);
147 static inline void hda_set_field_by_offset(struct hda_softc *sc,
148     uint32_t offset, uint32_t mask, uint32_t value);
149 
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,
156     const char *opts);
157 static struct hda_codec_class *hda_find_codec_class(const char *name);
158 
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,
169     uint32_t value);
170 
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);
175 
176 static void *hda_dma_get_vaddr(struct hda_softc *sc, uint64_t dma_paddr,
177     size_t len);
178 static void hda_dma_st_dword(void *dma_vaddr, uint32_t data);
179 static uint32_t hda_dma_ld_dword(void *dma_vaddr);
180 
181 static inline uint8_t hda_get_stream_by_offsets(uint32_t offset,
182     uint8_t reg_offset);
183 static inline uint32_t hda_get_offset_stream(uint8_t stream_ind);
184 
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,
187     uint32_t old);
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,
190     uint32_t old);
191 static void hda_set_rirbctl(struct hda_softc *sc, uint32_t offset,
192     uint32_t old);
193 static void hda_set_rirbsts(struct hda_softc *sc, uint32_t offset,
194     uint32_t old);
195 static void hda_set_dpiblbase(struct hda_softc *sc, uint32_t offset,
196     uint32_t old);
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);
200 
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,
203     uint8_t unsol);
204 static int hda_transfer(struct hda_codec_inst *hci, uint8_t stream,
205     uint8_t dir, void *buf, size_t count);
206 
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);
209 
210 /*
211  * PCI HDA function declarations
212  */
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);
218 /*
219  * HDA global data
220  */
221 
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,
230 
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,		\
235 
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,		\
240 
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)
245 
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)
250 
251 	[HDA_SET_REG_TABLE_SZ] = NULL,
252 };
253 
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,
259 };
260 
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,
266 };
267 
268 static struct hda_ops hops = {
269 	.signal		= hda_signal_state_change,
270 	.response	= hda_response,
271 	.transfer	= hda_transfer,
272 };
273 
274 struct pci_devemu pci_de_hda = {
275 	.pe_emu		= "hda",
276 	.pe_init	= pci_hda_init,
277 	.pe_barwrite	= pci_hda_write,
278 	.pe_barread	= pci_hda_read
279 };
280 
281 PCI_EMUL_SET(pci_de_hda);
282 
283 SET_DECLARE(hda_codec_class_set, struct hda_codec_class);
284 
285 #if DEBUG_HDA == 1
286 FILE *dbg;
287 #endif
288 
289 /*
290  * HDA module function definitions
291  */
292 
293 static inline void
294 hda_set_reg_by_offset(struct hda_softc *sc, uint32_t offset, uint32_t value)
295 {
296 	assert(offset < HDA_LAST_OFFSET);
297 	sc->regs[offset] = value;
298 }
299 
300 static inline uint32_t
301 hda_get_reg_by_offset(struct hda_softc *sc, uint32_t offset)
302 {
303 	assert(offset < HDA_LAST_OFFSET);
304 	return sc->regs[offset];
305 }
306 
307 static inline void
308 hda_set_field_by_offset(struct hda_softc *sc, uint32_t offset,
309     uint32_t mask, uint32_t value)
310 {
311 	uint32_t reg_value = 0;
312 
313 	reg_value = hda_get_reg_by_offset(sc, offset);
314 
315 	reg_value &= ~mask;
316 	reg_value |= (value & mask);
317 
318 	hda_set_reg_by_offset(sc, offset, reg_value);
319 }
320 
321 static uint8_t
322 hda_parse_config(const char *opts, const char *key, char *val)
323 {
324 	char buf[64];
325 	char *s = buf;
326 	char *tmp = NULL;
327 	size_t len;
328 	int i;
329 
330 	if (!opts)
331 		return (0);
332 
333 	len = strlen(opts);
334 	if (len >= sizeof(buf)) {
335 		DPRINTF("Opts too big\n\r");
336 		return (0);
337 	}
338 
339 	DPRINTF("opts: %s\n\r", opts);
340 
341 	strcpy(buf, opts);
342 
343 	for (i = 0; i < len; i++)
344 		if (buf[i] == ',') {
345 			buf[i] = 0;
346 			tmp = buf + i + 1;
347 			break;
348 		}
349 
350 	if (!memcmp(s, key, strlen(key))) {
351 		strncpy(val, s + strlen(key), 64);
352 		return (1);
353 	}
354 
355 	if (!tmp)
356 		return (0);
357 
358 	s = tmp;
359 	if (!memcmp(s, key, strlen(key))) {
360 		strncpy(val, s + strlen(key), 64);
361 		return (1);
362 	}
363 
364 	return (0);
365 }
366 
367 static struct hda_softc *
368 hda_init(const char *opts)
369 {
370 	struct hda_softc *sc = NULL;
371 	struct hda_codec_class *codec = NULL;
372 	char play[64];
373 	char rec[64];
374 	int err, p, r;
375 
376 #if DEBUG_HDA == 1
377 	dbg = fopen("/tmp/bhyve_hda.log", "w+");
378 #endif
379 
380 	DPRINTF("opts: %s\n\r", opts);
381 
382 	sc = calloc(1, sizeof(*sc));
383 	if (!sc)
384 		return (NULL);
385 
386 	hda_reset_regs(sc);
387 
388 	/*
389 	 * TODO search all the codecs declared in opts
390 	 * For now we play with one single codec
391 	 */
392 	codec = hda_find_codec_class("hda_codec");
393 	if (codec) {
394 		p = hda_parse_config(opts, "play=", play);
395 		r = hda_parse_config(opts, "rec=", rec);
396 		DPRINTF("play: %s rec: %s\n\r", play, rec);
397 		if (p | r) {
398 			err = hda_codec_constructor(sc, codec, p ?	\
399 				play : NULL, r ? rec : NULL, NULL);
400 			assert(!err);
401 		}
402 	}
403 
404 	return (sc);
405 }
406 
407 static void
408 hda_update_intr(struct hda_softc *sc)
409 {
410 	struct pci_devinst *pi = sc->pci_dev;
411 	uint32_t intctl = hda_get_reg_by_offset(sc, HDAC_INTCTL);
412 	uint32_t intsts = 0;
413 	uint32_t sdsts = 0;
414 	uint32_t rirbsts = 0;
415 	uint32_t wakeen = 0;
416 	uint32_t statests = 0;
417 	uint32_t off = 0;
418 	int i;
419 
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;
424 
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;
429 
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)
435 			intsts |= (1 << i);
436 	}
437 
438 	/* update the GIS bit */
439 	if (intsts)
440 		intsts |= HDAC_INTSTS_GIS;
441 
442 	hda_set_reg_by_offset(sc, HDAC_INTSTS, intsts);
443 
444 	if ((intctl & HDAC_INTCTL_GIE) && ((intsts &			\
445 		~HDAC_INTSTS_GIS) & intctl)) {
446 		if (!sc->lintr) {
447 			pci_lintr_assert(pi);
448 			sc->lintr = 1;
449 		}
450 	} else {
451 		if (sc->lintr) {
452 			pci_lintr_deassert(pi);
453 			sc->lintr = 0;
454 		}
455 	}
456 }
457 
458 static void
459 hda_response_interrupt(struct hda_softc *sc)
460 {
461 	uint8_t rirbctl = hda_get_reg_by_offset(sc, HDAC_RIRBCTL);
462 
463 	if ((rirbctl & HDAC_RIRBCTL_RINTCTL) && sc->rirb_cnt) {
464 		sc->rirb_cnt = 0;
465 		hda_set_field_by_offset(sc, HDAC_RIRBSTS, HDAC_RIRBSTS_RINTFL,
466 				HDAC_RIRBSTS_RINTFL);
467 		hda_update_intr(sc);
468 	}
469 }
470 
471 static int
472 hda_codec_constructor(struct hda_softc *sc, struct hda_codec_class *codec,
473     const char *play, const char *rec, const char *opts)
474 {
475 	struct hda_codec_inst *hci = NULL;
476 
477 	if (sc->codecs_no >= HDA_CODEC_MAX)
478 		return (-1);
479 
480 	hci = calloc(1, sizeof(struct hda_codec_inst));
481 	if (!hci)
482 		return (-1);
483 
484 	hci->hda = sc;
485 	hci->hops = &hops;
486 	hci->cad = sc->codecs_no;
487 	hci->codec = codec;
488 
489 	sc->codecs[sc->codecs_no++] = hci;
490 
491 	if (!codec->init) {
492 		DPRINTF("This codec does not implement the init function\n\r");
493 		return (-1);
494 	}
495 
496 	return (codec->init(hci, play, rec, opts));
497 }
498 
499 static struct hda_codec_class *
500 hda_find_codec_class(const char *name)
501 {
502 	struct hda_codec_class **pdpp = NULL, *pdp = NULL;
503 
504 	SET_FOREACH(pdpp, hda_codec_class_set) {
505 		pdp = *pdpp;
506 		if (!strcmp(pdp->name, name)) {
507 			return (pdp);
508 		}
509 	}
510 
511 	return (NULL);
512 }
513 
514 static int
515 hda_send_command(struct hda_softc *sc, uint32_t verb)
516 {
517 	struct hda_codec_inst *hci = NULL;
518 	struct hda_codec_class *codec = NULL;
519 	uint8_t cad = (verb >> HDA_CMD_CAD_SHIFT) & 0x0f;
520 
521 	hci = sc->codecs[cad];
522 	if (!hci)
523 		return (-1);
524 
525 	DPRINTF("cad: 0x%x verb: 0x%x\n\r", cad, verb);
526 
527 	codec = hci->codec;
528 	assert(codec);
529 
530 	if (!codec->command) {
531 		DPRINTF("This codec does not implement the command function\n\r");
532 		return (-1);
533 	}
534 
535 	return (codec->command(hci, verb));
536 }
537 
538 static int
539 hda_notify_codecs(struct hda_softc *sc, uint8_t run, uint8_t stream,
540     uint8_t dir)
541 {
542 	struct hda_codec_inst *hci = NULL;
543 	struct hda_codec_class *codec = NULL;
544 	int err;
545 	int i;
546 
547 	/* Notify each codec */
548 	for (i = 0; i < sc->codecs_no; i++) {
549 		hci = sc->codecs[i];
550 		assert(hci);
551 
552 		codec = hci->codec;
553 		assert(codec);
554 
555 		if (codec->notify) {
556 			err = codec->notify(hci, run, stream, dir);
557 			if (!err)
558 				break;
559 		}
560 	}
561 
562 	return (i == sc->codecs_no ? (-1) : 0);
563 }
564 
565 static void
566 hda_reset(struct hda_softc *sc)
567 {
568 	int i;
569 	struct hda_codec_inst *hci = NULL;
570 	struct hda_codec_class *codec = NULL;
571 
572 	hda_reset_regs(sc);
573 
574 	/* Reset each codec */
575 	for (i = 0; i < sc->codecs_no; i++) {
576 		hci = sc->codecs[i];
577 		assert(hci);
578 
579 		codec = hci->codec;
580 		assert(codec);
581 
582 		if (codec->reset)
583 			codec->reset(hci);
584 	}
585 
586 	sc->wall_clock_start = hda_get_clock_ns();
587 }
588 
589 static void
590 hda_reset_regs(struct hda_softc *sc)
591 {
592 	uint32_t off = 0;
593 	uint8_t i;
594 
595 	DPRINTF("Reset the HDA controller registers ...\n\r");
596 
597 	memset(sc->regs, 0, sizeof(sc->regs));
598 
599 	hda_set_reg_by_offset(sc, HDAC_GCAP,
600 			HDAC_GCAP_64OK |
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);
610 
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);
614 	}
615 }
616 
617 static void
618 hda_stream_reset(struct hda_softc *sc, uint8_t stream_ind)
619 {
620 	struct hda_stream_desc *st = &sc->streams[stream_ind];
621 	uint32_t off = hda_get_offset_stream(stream_ind);
622 
623 	DPRINTF("Reset the HDA stream: 0x%x\n\r", stream_ind);
624 
625 	/* Reset the Stream Descriptor registers */
626 	memset(sc->regs + HDA_STREAM_REGS_BASE + off, 0, HDA_STREAM_REGS_LEN);
627 
628 	/* Reset the Stream Descriptor */
629 	memset(st, 0, sizeof(*st));
630 
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);
635 }
636 
637 static int
638 hda_stream_start(struct hda_softc *sc, uint8_t stream_ind)
639 {
640 	struct hda_stream_desc *st = &sc->streams[stream_ind];
641 	struct hda_bdle_desc *bdle_desc = NULL;
642 	struct hda_bdle *bdle = NULL;
643 	uint32_t lvi = 0;
644 	uint32_t bdl_cnt = 0;
645 	uint64_t bdpl = 0;
646 	uint64_t bdpu = 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);
655 	uint32_t sdctl = 0;
656 	uint8_t strm = 0;
657 	uint8_t dir = 0;
658 	int i;
659 
660 	assert(!st->run);
661 
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);
665 
666 	bdl_cnt = lvi + 1;
667 	assert(bdl_cnt <= HDA_BDL_MAX_LEN);
668 
669 	bdl_paddr = bdpl | (bdpu << 32);
670 	bdl_vaddr = hda_dma_get_vaddr(sc, bdl_paddr,
671 	    HDA_BDL_ENTRY_LEN * bdl_cnt);
672 	if (!bdl_vaddr) {
673 		DPRINTF("Fail to get the guest virtual address\n\r");
674 		return (-1);
675 	}
676 
677 	DPRINTF("stream: 0x%x bdl_cnt: 0x%x bdl_paddr: 0x%lx\n\r",
678 	    stream_ind, bdl_cnt, bdl_paddr);
679 
680 	st->bdl_cnt = bdl_cnt;
681 
682 	bdle = (struct hda_bdle *)bdl_vaddr;
683 	for (i = 0; i < bdl_cnt; i++, bdle++) {
684 		bdle_sz = bdle->len;
685 		assert(!(bdle_sz % HDA_DMA_ACCESS_LEN));
686 
687 		bdle_addrl = bdle->addrl;
688 		bdle_addrh = bdle->addrh;
689 
690 		bdle_paddr = bdle_addrl | (bdle_addrh << 32);
691 		bdle_vaddr = hda_dma_get_vaddr(sc, bdle_paddr, bdle_sz);
692 		if (!bdle_vaddr) {
693 			DPRINTF("Fail to get the guest virtual address\n\r");
694 			return (-1);
695 		}
696 
697 		bdle_desc = &st->bdl[i];
698 		bdle_desc->addr = bdle_vaddr;
699 		bdle_desc->len = bdle_sz;
700 		bdle_desc->ioc = bdle->ioc;
701 
702 		DPRINTF("bdle: 0x%x bdle_sz: 0x%x\n\r", i, bdle_sz);
703 	}
704 
705 	sdctl = hda_get_reg_by_offset(sc, off + HDAC_SDCTL0);
706 	strm = (sdctl >> 20) & 0x0f;
707 	dir = stream_ind >= HDA_ISS_NO;
708 
709 	DPRINTF("strm: 0x%x, dir: 0x%x\n\r", strm, dir);
710 
711 	sc->stream_map[dir][strm] = stream_ind;
712 	st->stream = strm;
713 	st->dir = dir;
714 	st->bp = 0;
715 	st->be = 0;
716 
717 	hda_set_pib(sc, stream_ind, 0);
718 
719 	st->run = 1;
720 
721 	hda_notify_codecs(sc, 1, strm, dir);
722 
723 	return (0);
724 }
725 
726 static int
727 hda_stream_stop(struct hda_softc *sc, uint8_t stream_ind)
728 {
729 	struct hda_stream_desc *st = &sc->streams[stream_ind];
730 	uint8_t strm = st->stream;
731 	uint8_t dir = st->dir;
732 
733 	DPRINTF("stream: 0x%x, strm: 0x%x, dir: 0x%x\n\r", stream_ind, strm, dir);
734 
735 	st->run = 0;
736 
737 	hda_notify_codecs(sc, 0, strm, dir);
738 
739 	return (0);
740 }
741 
742 static uint32_t
743 hda_read(struct hda_softc *sc, uint32_t offset)
744 {
745 	if (offset == HDAC_WALCLK)
746 		return (24 * (hda_get_clock_ns() -			\
747 			sc->wall_clock_start) / 1000);
748 
749 	return (hda_get_reg_by_offset(sc, offset));
750 }
751 
752 static int
753 hda_write(struct hda_softc *sc, uint32_t offset, uint8_t size, uint32_t value)
754 {
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];
759 
760 	hda_set_field_by_offset(sc, offset, masks[size], value);
761 
762 	if (set_reg_handler)
763 		set_reg_handler(sc, offset, old);
764 
765 	return (0);
766 }
767 
768 static inline void
769 hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl *p)
770 {
771 #if DEBUG_HDA == 1
772 	char *name = p->name;
773 #endif
774 	DPRINTF("%s size: %d\n\r", name, p->size);
775 	DPRINTF("%s dma_vaddr: %p\n\r", name, p->dma_vaddr);
776 	DPRINTF("%s wp: 0x%x\n\r", name, p->wp);
777 	DPRINTF("%s rp: 0x%x\n\r", name, p->rp);
778 }
779 
780 static int
781 hda_corb_start(struct hda_softc *sc)
782 {
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;
788 
789 	corb->name = "CORB";
790 
791 	corbsize = hda_get_reg_by_offset(sc, HDAC_CORBSIZE) &		\
792 		   HDAC_CORBSIZE_CORBSIZE_MASK;
793 	corb->size = hda_corb_sizes[corbsize];
794 
795 	if (!corb->size) {
796 		DPRINTF("Invalid corb size\n\r");
797 		return (-1);
798 	}
799 
800 	corblbase = hda_get_reg_by_offset(sc, HDAC_CORBLBASE);
801 	corbubase = hda_get_reg_by_offset(sc, HDAC_CORBUBASE);
802 
803 	corbpaddr = corblbase | (corbubase << 32);
804 	DPRINTF("CORB dma_paddr: %p\n\r", (void *)corbpaddr);
805 
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\n\r");
810 		return (-1);
811 	}
812 
813 	corb->wp = hda_get_reg_by_offset(sc, HDAC_CORBWP);
814 	corb->rp = hda_get_reg_by_offset(sc, HDAC_CORBRP);
815 
816 	corb->run = 1;
817 
818 	hda_print_cmd_ctl_data(corb);
819 
820 	return (0);
821 }
822 
823 static int
824 hda_corb_run(struct hda_softc *sc)
825 {
826 	struct hda_codec_cmd_ctl *corb = &sc->corb;
827 	uint32_t verb = 0;
828 	int err;
829 
830 	corb->wp = hda_get_reg_by_offset(sc, HDAC_CORBWP);
831 
832 	while (corb->rp != corb->wp && corb->run) {
833 		corb->rp++;
834 		corb->rp %= corb->size;
835 
836 		verb = hda_dma_ld_dword(corb->dma_vaddr +		\
837 				HDA_CORB_ENTRY_LEN * corb->rp);
838 
839 		err = hda_send_command(sc, verb);
840 		assert(!err);
841 	}
842 
843 	hda_set_reg_by_offset(sc, HDAC_CORBRP, corb->rp);
844 
845 	if (corb->run)
846 		hda_response_interrupt(sc);
847 
848 	return (0);
849 }
850 
851 static int
852 hda_rirb_start(struct hda_softc *sc)
853 {
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;
859 
860 	rirb->name = "RIRB";
861 
862 	rirbsize = hda_get_reg_by_offset(sc, HDAC_RIRBSIZE) &		\
863 		   HDAC_RIRBSIZE_RIRBSIZE_MASK;
864 	rirb->size = hda_rirb_sizes[rirbsize];
865 
866 	if (!rirb->size) {
867 		DPRINTF("Invalid rirb size\n\r");
868 		return (-1);
869 	}
870 
871 	rirblbase = hda_get_reg_by_offset(sc, HDAC_RIRBLBASE);
872 	rirbubase = hda_get_reg_by_offset(sc, HDAC_RIRBUBASE);
873 
874 	rirbpaddr = rirblbase | (rirbubase << 32);
875 	DPRINTF("RIRB dma_paddr: %p\n\r", (void *)rirbpaddr);
876 
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\n\r");
881 		return (-1);
882 	}
883 
884 	rirb->wp = hda_get_reg_by_offset(sc, HDAC_RIRBWP);
885 	rirb->rp = 0x0000;
886 
887 	rirb->run = 1;
888 
889 	hda_print_cmd_ctl_data(rirb);
890 
891 	return (0);
892 }
893 
894 static void *
895 hda_dma_get_vaddr(struct hda_softc *sc, uint64_t dma_paddr, size_t len)
896 {
897 	struct pci_devinst *pi = sc->pci_dev;
898 
899 	assert(pi);
900 
901 	return (paddr_guest2host(pi->pi_vmctx, (uintptr_t)dma_paddr, len));
902 }
903 
904 static void
905 hda_dma_st_dword(void *dma_vaddr, uint32_t data)
906 {
907 	*(uint32_t*)dma_vaddr = data;
908 }
909 
910 static uint32_t
911 hda_dma_ld_dword(void *dma_vaddr)
912 {
913 	return (*(uint32_t*)dma_vaddr);
914 }
915 
916 static inline uint8_t
917 hda_get_stream_by_offsets(uint32_t offset, uint8_t reg_offset)
918 {
919 	uint8_t stream_ind = (offset - reg_offset) >> 5;
920 
921 	assert(stream_ind < HDA_IOSS_NO);
922 
923 	return (stream_ind);
924 }
925 
926 static inline uint32_t
927 hda_get_offset_stream(uint8_t stream_ind)
928 {
929 	return (stream_ind << 5);
930 }
931 
932 static void
933 hda_set_gctl(struct hda_softc *sc, uint32_t offset, uint32_t old)
934 {
935 	uint32_t value = hda_get_reg_by_offset(sc, offset);
936 
937 	if (!(value & HDAC_GCTL_CRST)) {
938 		hda_reset(sc);
939 	}
940 }
941 
942 static void
943 hda_set_statests(struct hda_softc *sc, uint32_t offset, uint32_t old)
944 {
945 	uint32_t value = hda_get_reg_by_offset(sc, offset);
946 
947 	hda_set_reg_by_offset(sc, offset, old);
948 
949 	/* clear the corresponding bits written by the software (guest) */
950 	hda_set_field_by_offset(sc, offset, value & HDA_STATESTS_IRQ_MASK, 0);
951 
952 	hda_update_intr(sc);
953 }
954 
955 static void
956 hda_set_corbwp(struct hda_softc *sc, uint32_t offset, uint32_t old)
957 {
958 	hda_corb_run(sc);
959 }
960 
961 static void
962 hda_set_corbctl(struct hda_softc *sc, uint32_t offset, uint32_t old)
963 {
964 	uint32_t value = hda_get_reg_by_offset(sc, offset);
965 	int err;
966 	struct hda_codec_cmd_ctl *corb = NULL;
967 
968 	if (value & HDAC_CORBCTL_CORBRUN) {
969 		if (!(old & HDAC_CORBCTL_CORBRUN)) {
970 			err = hda_corb_start(sc);
971 			assert(!err);
972 		}
973 	} else {
974 		corb = &sc->corb;
975 		memset(corb, 0, sizeof(*corb));
976 	}
977 
978 	hda_corb_run(sc);
979 }
980 
981 static void
982 hda_set_rirbctl(struct hda_softc *sc, uint32_t offset, uint32_t old)
983 {
984 	uint32_t value = hda_get_reg_by_offset(sc, offset);
985 	int err;
986 	struct hda_codec_cmd_ctl *rirb = NULL;
987 
988 	if (value & HDAC_RIRBCTL_RIRBDMAEN) {
989 		err = hda_rirb_start(sc);
990 		assert(!err);
991 	} else {
992 		rirb = &sc->rirb;
993 		memset(rirb, 0, sizeof(*rirb));
994 	}
995 }
996 
997 static void
998 hda_set_rirbsts(struct hda_softc *sc, uint32_t offset, uint32_t old)
999 {
1000 	uint32_t value = hda_get_reg_by_offset(sc, offset);
1001 
1002 	hda_set_reg_by_offset(sc, offset, old);
1003 
1004 	/* clear the corresponding bits written by the software (guest) */
1005 	hda_set_field_by_offset(sc, offset, value & HDA_RIRBSTS_IRQ_MASK, 0);
1006 
1007 	hda_update_intr(sc);
1008 }
1009 
1010 static void
1011 hda_set_dpiblbase(struct hda_softc *sc, uint32_t offset, uint32_t old)
1012 {
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;
1017 
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);
1023 
1024 			dpibpaddr = dpiblbase | (dpibubase << 32);
1025 			DPRINTF("DMA Position In Buffer dma_paddr: %p\n\r",
1026 			    (void *)dpibpaddr);
1027 
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 \
1032 					 virtual address\n\r");
1033 				assert(0);
1034 			}
1035 		} else {
1036 			DPRINTF("DMA Position In Buffer Reset\n\r");
1037 			sc->dma_pib_vaddr = NULL;
1038 		}
1039 	}
1040 }
1041 
1042 static void
1043 hda_set_sdctl(struct hda_softc *sc, uint32_t offset, uint32_t old)
1044 {
1045 	uint8_t stream_ind = hda_get_stream_by_offsets(offset, HDAC_SDCTL0);
1046 	uint32_t value = hda_get_reg_by_offset(sc, offset);
1047 	int err;
1048 
1049 	DPRINTF("stream_ind: 0x%x old: 0x%x value: 0x%x\n\r",
1050 	    stream_ind, old, value);
1051 
1052 	if (value & HDAC_SDCTL_SRST) {
1053 		hda_stream_reset(sc, stream_ind);
1054 	}
1055 
1056 	if ((value & HDAC_SDCTL_RUN) != (old & HDAC_SDCTL_RUN)) {
1057 		if (value & HDAC_SDCTL_RUN) {
1058 			err = hda_stream_start(sc, stream_ind);
1059 			assert(!err);
1060 		} else {
1061 			err = hda_stream_stop(sc, stream_ind);
1062 			assert(!err);
1063 		}
1064 	}
1065 }
1066 
1067 static void
1068 hda_set_sdctl2(struct hda_softc *sc, uint32_t offset, uint32_t old)
1069 {
1070 	uint32_t value = hda_get_reg_by_offset(sc, offset);
1071 
1072 	hda_set_field_by_offset(sc, offset - 2, 0x00ff0000, value << 16);
1073 }
1074 
1075 static void
1076 hda_set_sdsts(struct hda_softc *sc, uint32_t offset, uint32_t old)
1077 {
1078 	uint32_t value = hda_get_reg_by_offset(sc, offset);
1079 
1080 	hda_set_reg_by_offset(sc, offset, old);
1081 
1082 	/* clear the corresponding bits written by the software (guest) */
1083 	hda_set_field_by_offset(sc, offset, value & HDA_SDSTS_IRQ_MASK, 0);
1084 
1085 	hda_update_intr(sc);
1086 }
1087 
1088 static int
1089 hda_signal_state_change(struct hda_codec_inst *hci)
1090 {
1091 	struct hda_softc *sc = NULL;
1092 	uint32_t sdiwake = 0;
1093 
1094 	assert(hci);
1095 	assert(hci->hda);
1096 
1097 	DPRINTF("cad: 0x%x\n\r", hci->cad);
1098 
1099 	sc = hci->hda;
1100 	sdiwake = 1 << hci->cad;
1101 
1102 	hda_set_field_by_offset(sc, HDAC_STATESTS, sdiwake, sdiwake);
1103 	hda_update_intr(sc);
1104 
1105 	return (0);
1106 }
1107 
1108 static int
1109 hda_response(struct hda_codec_inst *hci, uint32_t response, uint8_t unsol)
1110 {
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;
1115 
1116 	assert(hci);
1117 	assert(hci->cad <= HDA_CODEC_MAX);
1118 
1119 	response_ex = hci->cad | unsol;
1120 
1121 	sc = hci->hda;
1122 	assert(sc);
1123 
1124 	rirb = &sc->rirb;
1125 
1126 	if (rirb->run) {
1127 		rirb->wp++;
1128 		rirb->wp %= rirb->size;
1129 
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);
1134 
1135 		hda_set_reg_by_offset(sc, HDAC_RIRBWP, rirb->wp);
1136 
1137 		sc->rirb_cnt++;
1138 	}
1139 
1140 	rintcnt = hda_get_reg_by_offset(sc, HDAC_RINTCNT);
1141 	if (sc->rirb_cnt == rintcnt)
1142 		hda_response_interrupt(sc);
1143 
1144 	return (0);
1145 }
1146 
1147 static int
1148 hda_transfer(struct hda_codec_inst *hci, uint8_t stream, uint8_t dir,
1149     void *buf, size_t count)
1150 {
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;
1156 	uint32_t lpib = 0;
1157 	uint32_t off = 0;
1158 	size_t left = 0;
1159 	uint8_t irq = 0;
1160 
1161 	assert(hci);
1162 	assert(hci->hda);
1163 	assert(buf);
1164 	assert(!(count % HDA_DMA_ACCESS_LEN));
1165 
1166 	if (!stream) {
1167 		DPRINTF("Invalid stream\n\r");
1168 		return (-1);
1169 	}
1170 
1171 	sc = hci->hda;
1172 
1173 	assert(stream < HDA_STREAM_TAGS_CNT);
1174 	stream_ind = sc->stream_map[dir][stream];
1175 
1176 	if (!dir)
1177 		assert(stream_ind < HDA_ISS_NO);
1178 	else
1179 		assert(stream_ind >= HDA_ISS_NO && stream_ind < HDA_IOSS_NO);
1180 
1181 	st = &sc->streams[stream_ind];
1182 	if (!st->run) {
1183 		DPRINTF("Stream 0x%x stopped\n\r", stream);
1184 		return (-1);
1185 	}
1186 
1187 	assert(st->stream == stream);
1188 
1189 	off = hda_get_offset_stream(stream_ind);
1190 
1191 	lpib = hda_get_reg_by_offset(sc, off + HDAC_SDLPIB);
1192 
1193 	bdl = st->bdl;
1194 
1195 	assert(st->be < st->bdl_cnt);
1196 	assert(st->bp < bdl[st->be].len);
1197 
1198 	left = count;
1199 	while (left) {
1200 		bdle_desc = &bdl[st->be];
1201 
1202 		if (dir)
1203 			*(uint32_t *)buf =				\
1204 			    hda_dma_ld_dword(bdle_desc->addr + st->bp);
1205 		else
1206 			hda_dma_st_dword(bdle_desc->addr + st->bp,
1207 					*(uint32_t *)buf);
1208 
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;
1213 
1214 		if (st->bp == bdle_desc->len) {
1215 			st->bp = 0;
1216 			if (bdle_desc->ioc)
1217 				irq = 1;
1218 			st->be++;
1219 			if (st->be == st->bdl_cnt) {
1220 				st->be = 0;
1221 				lpib = 0;
1222 			}
1223 			bdle_desc = &bdl[st->be];
1224 		}
1225 	}
1226 
1227 	hda_set_pib(sc, stream_ind, lpib);
1228 
1229 	if (irq) {
1230 		hda_set_field_by_offset(sc, off + HDAC_SDSTS,
1231 				HDAC_SDSTS_BCIS, HDAC_SDSTS_BCIS);
1232 		hda_update_intr(sc);
1233 	}
1234 
1235 	return (0);
1236 }
1237 
1238 static void
1239 hda_set_pib(struct hda_softc *sc, uint8_t stream_ind, uint32_t pib)
1240 {
1241 	uint32_t off = hda_get_offset_stream(stream_ind);
1242 
1243 	hda_set_reg_by_offset(sc, off + HDAC_SDLPIB, pib);
1244 	/* LPIB Alias */
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;
1249 }
1250 
1251 static uint64_t hda_get_clock_ns(void)
1252 {
1253 	struct timespec ts;
1254 	int err;
1255 
1256 	err = clock_gettime(CLOCK_MONOTONIC, &ts);
1257 	assert(!err);
1258 
1259 	return (ts.tv_sec * 1000000000LL + ts.tv_nsec);
1260 }
1261 
1262 /*
1263  * PCI HDA function definitions
1264  */
1265 static int
1266 pci_hda_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
1267 {
1268 	struct hda_softc *sc = NULL;
1269 
1270 	assert(ctx != NULL);
1271 	assert(pi != NULL);
1272 
1273 	pci_set_cfgdata16(pi, PCIR_VENDOR, INTEL_VENDORID);
1274 	pci_set_cfgdata16(pi, PCIR_DEVICE, HDA_INTEL_82801G);
1275 
1276 	pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_MULTIMEDIA_HDA);
1277 	pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_MULTIMEDIA);
1278 
1279 	/* select the Intel HDA mode */
1280 	pci_set_cfgdata8(pi, PCIR_HDCTL, 0x01);
1281 
1282 	/* allocate one BAR register for the Memory address offsets */
1283 	pci_emul_alloc_bar(pi, 0, PCIBAR_MEM32, HDA_LAST_OFFSET);
1284 
1285 	/* allocate an IRQ pin for our slot */
1286 	pci_lintr_request(pi);
1287 
1288 	sc = hda_init(opts);
1289 	if (!sc)
1290 		return (-1);
1291 
1292 	sc->pci_dev = pi;
1293 	pi->pi_arg = sc;
1294 
1295 	return (0);
1296 }
1297 
1298 static void
1299 pci_hda_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
1300     int baridx, uint64_t offset, int size, uint64_t value)
1301 {
1302 	struct hda_softc *sc = pi->pi_arg;
1303 	int err;
1304 
1305 	assert(sc);
1306 	assert(baridx == 0);
1307 	assert(size <= 4);
1308 
1309 	DPRINTF("offset: 0x%lx value: 0x%lx\n\r", offset, value);
1310 
1311 	err = hda_write(sc, offset, size, value);
1312 	assert(!err);
1313 }
1314 
1315 static uint64_t
1316 pci_hda_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
1317     int baridx, uint64_t offset, int size)
1318 {
1319 	struct hda_softc *sc = pi->pi_arg;
1320 	uint64_t value = 0;
1321 
1322 	assert(sc);
1323 	assert(baridx == 0);
1324 	assert(size <= 4);
1325 
1326 	value = hda_read(sc, offset);
1327 
1328 	DPRINTF("offset: 0x%lx value: 0x%lx\n\r", offset, value);
1329 
1330 	return (value);
1331 }
1332