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