]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/bhyve/pci_hda.c
ssh: Update to OpenSSH 9.3p2
[FreeBSD/FreeBSD.git] / usr.sbin / bhyve / pci_hda.c
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 __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(DEBUG_HDA_FILE, "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 #if DEBUG_HDA == 1
730 static inline void
731 hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl *p)
732 {
733         DPRINTF("%s size: %d", p->name, p->size);
734         DPRINTF("%s dma_vaddr: %p", p->name, p->dma_vaddr);
735         DPRINTF("%s wp: 0x%x", p->name, p->wp);
736         DPRINTF("%s rp: 0x%x", p->name, p->rp);
737 }
738 #else
739 static inline void
740 hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl *p __unused) {}
741 #endif
742
743 static int
744 hda_corb_start(struct hda_softc *sc)
745 {
746         struct hda_codec_cmd_ctl *corb = &sc->corb;
747         uint8_t corbsize = 0;
748         uint64_t corblbase = 0;
749         uint64_t corbubase = 0;
750         uint64_t corbpaddr = 0;
751
752         corb->name = "CORB";
753
754         corbsize = hda_get_reg_by_offset(sc, HDAC_CORBSIZE) &           \
755                    HDAC_CORBSIZE_CORBSIZE_MASK;
756         corb->size = hda_corb_sizes[corbsize];
757
758         if (!corb->size) {
759                 DPRINTF("Invalid corb size");
760                 return (-1);
761         }
762
763         corblbase = hda_get_reg_by_offset(sc, HDAC_CORBLBASE);
764         corbubase = hda_get_reg_by_offset(sc, HDAC_CORBUBASE);
765
766         corbpaddr = corblbase | (corbubase << 32);
767         DPRINTF("CORB dma_paddr: %p", (void *)corbpaddr);
768
769         corb->dma_vaddr = hda_dma_get_vaddr(sc, corbpaddr,
770                         HDA_CORB_ENTRY_LEN * corb->size);
771         if (!corb->dma_vaddr) {
772                 DPRINTF("Fail to get the guest virtual address");
773                 return (-1);
774         }
775
776         corb->wp = hda_get_reg_by_offset(sc, HDAC_CORBWP);
777         corb->rp = hda_get_reg_by_offset(sc, HDAC_CORBRP);
778
779         corb->run = 1;
780
781         hda_print_cmd_ctl_data(corb);
782
783         return (0);
784 }
785
786 static int
787 hda_corb_run(struct hda_softc *sc)
788 {
789         struct hda_codec_cmd_ctl *corb = &sc->corb;
790         uint32_t verb = 0;
791         int err;
792
793         corb->wp = hda_get_reg_by_offset(sc, HDAC_CORBWP);
794
795         while (corb->rp != corb->wp && corb->run) {
796                 corb->rp++;
797                 corb->rp %= corb->size;
798
799                 verb = hda_dma_ld_dword((uint8_t *)corb->dma_vaddr +
800                     HDA_CORB_ENTRY_LEN * corb->rp);
801
802                 err = hda_send_command(sc, verb);
803                 assert(!err);
804         }
805
806         hda_set_reg_by_offset(sc, HDAC_CORBRP, corb->rp);
807
808         if (corb->run)
809                 hda_response_interrupt(sc);
810
811         return (0);
812 }
813
814 static int
815 hda_rirb_start(struct hda_softc *sc)
816 {
817         struct hda_codec_cmd_ctl *rirb = &sc->rirb;
818         uint8_t rirbsize = 0;
819         uint64_t rirblbase = 0;
820         uint64_t rirbubase = 0;
821         uint64_t rirbpaddr = 0;
822
823         rirb->name = "RIRB";
824
825         rirbsize = hda_get_reg_by_offset(sc, HDAC_RIRBSIZE) &           \
826                    HDAC_RIRBSIZE_RIRBSIZE_MASK;
827         rirb->size = hda_rirb_sizes[rirbsize];
828
829         if (!rirb->size) {
830                 DPRINTF("Invalid rirb size");
831                 return (-1);
832         }
833
834         rirblbase = hda_get_reg_by_offset(sc, HDAC_RIRBLBASE);
835         rirbubase = hda_get_reg_by_offset(sc, HDAC_RIRBUBASE);
836
837         rirbpaddr = rirblbase | (rirbubase << 32);
838         DPRINTF("RIRB dma_paddr: %p", (void *)rirbpaddr);
839
840         rirb->dma_vaddr = hda_dma_get_vaddr(sc, rirbpaddr,
841                         HDA_RIRB_ENTRY_LEN * rirb->size);
842         if (!rirb->dma_vaddr) {
843                 DPRINTF("Fail to get the guest virtual address");
844                 return (-1);
845         }
846
847         rirb->wp = hda_get_reg_by_offset(sc, HDAC_RIRBWP);
848         rirb->rp = 0x0000;
849
850         rirb->run = 1;
851
852         hda_print_cmd_ctl_data(rirb);
853
854         return (0);
855 }
856
857 static void *
858 hda_dma_get_vaddr(struct hda_softc *sc, uint64_t dma_paddr, size_t len)
859 {
860         struct pci_devinst *pi = sc->pci_dev;
861
862         assert(pi);
863
864         return (paddr_guest2host(pi->pi_vmctx, (uintptr_t)dma_paddr, len));
865 }
866
867 static void
868 hda_dma_st_dword(void *dma_vaddr, uint32_t data)
869 {
870         *(uint32_t*)dma_vaddr = data;
871 }
872
873 static uint32_t
874 hda_dma_ld_dword(void *dma_vaddr)
875 {
876         return (*(uint32_t*)dma_vaddr);
877 }
878
879 static inline uint8_t
880 hda_get_stream_by_offsets(uint32_t offset, uint8_t reg_offset)
881 {
882         uint8_t stream_ind = (offset - reg_offset) >> 5;
883
884         assert(stream_ind < HDA_IOSS_NO);
885
886         return (stream_ind);
887 }
888
889 static inline uint32_t
890 hda_get_offset_stream(uint8_t stream_ind)
891 {
892         return (stream_ind << 5);
893 }
894
895 static void
896 hda_set_gctl(struct hda_softc *sc, uint32_t offset, uint32_t old __unused)
897 {
898         uint32_t value = hda_get_reg_by_offset(sc, offset);
899
900         if (!(value & HDAC_GCTL_CRST)) {
901                 hda_reset(sc);
902         }
903 }
904
905 static void
906 hda_set_statests(struct hda_softc *sc, uint32_t offset, uint32_t old)
907 {
908         uint32_t value = hda_get_reg_by_offset(sc, offset);
909
910         hda_set_reg_by_offset(sc, offset, old);
911
912         /* clear the corresponding bits written by the software (guest) */
913         hda_set_field_by_offset(sc, offset, value & HDA_STATESTS_IRQ_MASK, 0);
914
915         hda_update_intr(sc);
916 }
917
918 static void
919 hda_set_corbwp(struct hda_softc *sc, uint32_t offset __unused,
920     uint32_t old __unused)
921 {
922         hda_corb_run(sc);
923 }
924
925 static void
926 hda_set_corbctl(struct hda_softc *sc, uint32_t offset, uint32_t old)
927 {
928         uint32_t value = hda_get_reg_by_offset(sc, offset);
929         int err;
930         struct hda_codec_cmd_ctl *corb = NULL;
931
932         if (value & HDAC_CORBCTL_CORBRUN) {
933                 if (!(old & HDAC_CORBCTL_CORBRUN)) {
934                         err = hda_corb_start(sc);
935                         assert(!err);
936                 }
937         } else {
938                 corb = &sc->corb;
939                 memset(corb, 0, sizeof(*corb));
940         }
941
942         hda_corb_run(sc);
943 }
944
945 static void
946 hda_set_rirbctl(struct hda_softc *sc, uint32_t offset, uint32_t old __unused)
947 {
948         uint32_t value = hda_get_reg_by_offset(sc, offset);
949         int err;
950         struct hda_codec_cmd_ctl *rirb = NULL;
951
952         if (value & HDAC_RIRBCTL_RIRBDMAEN) {
953                 err = hda_rirb_start(sc);
954                 assert(!err);
955         } else {
956                 rirb = &sc->rirb;
957                 memset(rirb, 0, sizeof(*rirb));
958         }
959 }
960
961 static void
962 hda_set_rirbsts(struct hda_softc *sc, uint32_t offset, uint32_t old)
963 {
964         uint32_t value = hda_get_reg_by_offset(sc, offset);
965
966         hda_set_reg_by_offset(sc, offset, old);
967
968         /* clear the corresponding bits written by the software (guest) */
969         hda_set_field_by_offset(sc, offset, value & HDA_RIRBSTS_IRQ_MASK, 0);
970
971         hda_update_intr(sc);
972 }
973
974 static void
975 hda_set_dpiblbase(struct hda_softc *sc, uint32_t offset, uint32_t old)
976 {
977         uint32_t value = hda_get_reg_by_offset(sc, offset);
978         uint64_t dpiblbase = 0;
979         uint64_t dpibubase = 0;
980         uint64_t dpibpaddr = 0;
981
982         if ((value & HDAC_DPLBASE_DPLBASE_DMAPBE) != (old &             \
983                                 HDAC_DPLBASE_DPLBASE_DMAPBE)) {
984                 if (value & HDAC_DPLBASE_DPLBASE_DMAPBE) {
985                         dpiblbase = value & HDAC_DPLBASE_DPLBASE_MASK;
986                         dpibubase = hda_get_reg_by_offset(sc, HDAC_DPIBUBASE);
987
988                         dpibpaddr = dpiblbase | (dpibubase << 32);
989                         DPRINTF("DMA Position In Buffer dma_paddr: %p",
990                             (void *)dpibpaddr);
991
992                         sc->dma_pib_vaddr = hda_dma_get_vaddr(sc, dpibpaddr,
993                                         HDA_DMA_PIB_ENTRY_LEN * HDA_IOSS_NO);
994                         if (!sc->dma_pib_vaddr) {
995                                 DPRINTF("Fail to get the guest \
996                                          virtual address");
997                                 assert(0);
998                         }
999                 } else {
1000                         DPRINTF("DMA Position In Buffer Reset");
1001                         sc->dma_pib_vaddr = NULL;
1002                 }
1003         }
1004 }
1005
1006 static void
1007 hda_set_sdctl(struct hda_softc *sc, uint32_t offset, uint32_t old)
1008 {
1009         uint8_t stream_ind = hda_get_stream_by_offsets(offset, HDAC_SDCTL0);
1010         uint32_t value = hda_get_reg_by_offset(sc, offset);
1011         int err;
1012
1013         DPRINTF("stream_ind: 0x%x old: 0x%x value: 0x%x",
1014             stream_ind, old, value);
1015
1016         if (value & HDAC_SDCTL_SRST) {
1017                 hda_stream_reset(sc, stream_ind);
1018         }
1019
1020         if ((value & HDAC_SDCTL_RUN) != (old & HDAC_SDCTL_RUN)) {
1021                 if (value & HDAC_SDCTL_RUN) {
1022                         err = hda_stream_start(sc, stream_ind);
1023                         assert(!err);
1024                 } else {
1025                         err = hda_stream_stop(sc, stream_ind);
1026                         assert(!err);
1027                 }
1028         }
1029 }
1030
1031 static void
1032 hda_set_sdctl2(struct hda_softc *sc, uint32_t offset, uint32_t old __unused)
1033 {
1034         uint32_t value = hda_get_reg_by_offset(sc, offset);
1035
1036         hda_set_field_by_offset(sc, offset - 2, 0x00ff0000, value << 16);
1037 }
1038
1039 static void
1040 hda_set_sdsts(struct hda_softc *sc, uint32_t offset, uint32_t old)
1041 {
1042         uint32_t value = hda_get_reg_by_offset(sc, offset);
1043
1044         hda_set_reg_by_offset(sc, offset, old);
1045
1046         /* clear the corresponding bits written by the software (guest) */
1047         hda_set_field_by_offset(sc, offset, value & HDA_SDSTS_IRQ_MASK, 0);
1048
1049         hda_update_intr(sc);
1050 }
1051
1052 static int
1053 hda_signal_state_change(struct hda_codec_inst *hci)
1054 {
1055         struct hda_softc *sc = NULL;
1056         uint32_t sdiwake = 0;
1057
1058         assert(hci);
1059         assert(hci->hda);
1060
1061         DPRINTF("cad: 0x%x", hci->cad);
1062
1063         sc = hci->hda;
1064         sdiwake = 1 << hci->cad;
1065
1066         hda_set_field_by_offset(sc, HDAC_STATESTS, sdiwake, sdiwake);
1067         hda_update_intr(sc);
1068
1069         return (0);
1070 }
1071
1072 static int
1073 hda_response(struct hda_codec_inst *hci, uint32_t response, uint8_t unsol)
1074 {
1075         struct hda_softc *sc = NULL;
1076         struct hda_codec_cmd_ctl *rirb = NULL;
1077         uint32_t response_ex = 0;
1078         uint8_t rintcnt = 0;
1079
1080         assert(hci);
1081         assert(hci->cad <= HDA_CODEC_MAX);
1082
1083         response_ex = hci->cad | unsol;
1084
1085         sc = hci->hda;
1086         assert(sc);
1087
1088         rirb = &sc->rirb;
1089
1090         if (rirb->run) {
1091                 rirb->wp++;
1092                 rirb->wp %= rirb->size;
1093
1094                 hda_dma_st_dword((uint8_t *)rirb->dma_vaddr +
1095                     HDA_RIRB_ENTRY_LEN * rirb->wp, response);
1096                 hda_dma_st_dword((uint8_t *)rirb->dma_vaddr +
1097                     HDA_RIRB_ENTRY_LEN * rirb->wp + 0x04, response_ex);
1098
1099                 hda_set_reg_by_offset(sc, HDAC_RIRBWP, rirb->wp);
1100
1101                 sc->rirb_cnt++;
1102         }
1103
1104         rintcnt = hda_get_reg_by_offset(sc, HDAC_RINTCNT);
1105         if (sc->rirb_cnt == rintcnt)
1106                 hda_response_interrupt(sc);
1107
1108         return (0);
1109 }
1110
1111 static int
1112 hda_transfer(struct hda_codec_inst *hci, uint8_t stream, uint8_t dir,
1113     uint8_t *buf, size_t count)
1114 {
1115         struct hda_softc *sc = NULL;
1116         struct hda_stream_desc *st = NULL;
1117         struct hda_bdle_desc *bdl = NULL;
1118         struct hda_bdle_desc *bdle_desc = NULL;
1119         uint8_t stream_ind = 0;
1120         uint32_t lpib = 0;
1121         uint32_t off = 0;
1122         size_t left = 0;
1123         uint8_t irq = 0;
1124
1125         assert(hci);
1126         assert(hci->hda);
1127         assert(buf);
1128         assert(!(count % HDA_DMA_ACCESS_LEN));
1129
1130         if (!stream) {
1131                 DPRINTF("Invalid stream");
1132                 return (-1);
1133         }
1134
1135         sc = hci->hda;
1136
1137         assert(stream < HDA_STREAM_TAGS_CNT);
1138         stream_ind = sc->stream_map[dir][stream];
1139
1140         if (!dir)
1141                 assert(stream_ind < HDA_ISS_NO);
1142         else
1143                 assert(stream_ind >= HDA_ISS_NO && stream_ind < HDA_IOSS_NO);
1144
1145         st = &sc->streams[stream_ind];
1146         if (!st->run) {
1147                 DPRINTF("Stream 0x%x stopped", stream);
1148                 return (-1);
1149         }
1150
1151         assert(st->stream == stream);
1152
1153         off = hda_get_offset_stream(stream_ind);
1154
1155         lpib = hda_get_reg_by_offset(sc, off + HDAC_SDLPIB);
1156
1157         bdl = st->bdl;
1158
1159         assert(st->be < st->bdl_cnt);
1160         assert(st->bp < bdl[st->be].len);
1161
1162         left = count;
1163         while (left) {
1164                 bdle_desc = &bdl[st->be];
1165
1166                 if (dir)
1167                         *(uint32_t *)buf = hda_dma_ld_dword(
1168                             (uint8_t *)bdle_desc->addr + st->bp);
1169                 else
1170                         hda_dma_st_dword((uint8_t *)bdle_desc->addr +
1171                             st->bp, *(uint32_t *)buf);
1172
1173                 buf += HDA_DMA_ACCESS_LEN;
1174                 st->bp += HDA_DMA_ACCESS_LEN;
1175                 lpib += HDA_DMA_ACCESS_LEN;
1176                 left -= HDA_DMA_ACCESS_LEN;
1177
1178                 if (st->bp == bdle_desc->len) {
1179                         st->bp = 0;
1180                         if (bdle_desc->ioc)
1181                                 irq = 1;
1182                         st->be++;
1183                         if (st->be == st->bdl_cnt) {
1184                                 st->be = 0;
1185                                 lpib = 0;
1186                         }
1187                         bdle_desc = &bdl[st->be];
1188                 }
1189         }
1190
1191         hda_set_pib(sc, stream_ind, lpib);
1192
1193         if (irq) {
1194                 hda_set_field_by_offset(sc, off + HDAC_SDSTS,
1195                                 HDAC_SDSTS_BCIS, HDAC_SDSTS_BCIS);
1196                 hda_update_intr(sc);
1197         }
1198
1199         return (0);
1200 }
1201
1202 static void
1203 hda_set_pib(struct hda_softc *sc, uint8_t stream_ind, uint32_t pib)
1204 {
1205         uint32_t off = hda_get_offset_stream(stream_ind);
1206
1207         hda_set_reg_by_offset(sc, off + HDAC_SDLPIB, pib);
1208         /* LPIB Alias */
1209         hda_set_reg_by_offset(sc, 0x2000 + off + HDAC_SDLPIB, pib);
1210         if (sc->dma_pib_vaddr)
1211                 *(uint32_t *)((uint8_t *)sc->dma_pib_vaddr + stream_ind *
1212                     HDA_DMA_PIB_ENTRY_LEN) = pib;
1213 }
1214
1215 static uint64_t hda_get_clock_ns(void)
1216 {
1217         struct timespec ts;
1218         int err;
1219
1220         err = clock_gettime(CLOCK_MONOTONIC, &ts);
1221         assert(!err);
1222
1223         return (ts.tv_sec * 1000000000LL + ts.tv_nsec);
1224 }
1225
1226 /*
1227  * PCI HDA function definitions
1228  */
1229 static int
1230 pci_hda_init(struct pci_devinst *pi, nvlist_t *nvl)
1231 {
1232         struct hda_softc *sc = NULL;
1233
1234         assert(pi != NULL);
1235
1236         pci_set_cfgdata16(pi, PCIR_VENDOR, INTEL_VENDORID);
1237         pci_set_cfgdata16(pi, PCIR_DEVICE, HDA_INTEL_82801G);
1238
1239         pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_MULTIMEDIA_HDA);
1240         pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_MULTIMEDIA);
1241
1242         /* select the Intel HDA mode */
1243         pci_set_cfgdata8(pi, PCIR_HDCTL, 0x01);
1244
1245         /* allocate one BAR register for the Memory address offsets */
1246         pci_emul_alloc_bar(pi, 0, PCIBAR_MEM32, HDA_LAST_OFFSET);
1247
1248         /* allocate an IRQ pin for our slot */
1249         pci_lintr_request(pi);
1250
1251         sc = hda_init(nvl);
1252         if (!sc)
1253                 return (-1);
1254
1255         sc->pci_dev = pi;
1256         pi->pi_arg = sc;
1257
1258         return (0);
1259 }
1260
1261 static void
1262 pci_hda_write(struct pci_devinst *pi, int baridx, uint64_t offset, int size,
1263     uint64_t value)
1264 {
1265         struct hda_softc *sc = pi->pi_arg;
1266         int err;
1267
1268         assert(sc);
1269         assert(baridx == 0);
1270         assert(size <= 4);
1271
1272         DPRINTF("offset: 0x%lx value: 0x%lx", offset, value);
1273
1274         err = hda_write(sc, offset, size, value);
1275         assert(!err);
1276 }
1277
1278 static uint64_t
1279 pci_hda_read(struct pci_devinst *pi, int baridx, uint64_t offset, int size)
1280 {
1281         struct hda_softc *sc = pi->pi_arg;
1282         uint64_t value = 0;
1283
1284         assert(sc);
1285         assert(baridx == 0);
1286         assert(size <= 4);
1287
1288         value = hda_read(sc, offset);
1289
1290         DPRINTF("offset: 0x%lx value: 0x%lx", offset, value);
1291
1292         return (value);
1293 }