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