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