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