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