2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2016 Alex Teaca <iateaca@FreeBSD.org>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
44 #define PCIR_HDCTL 0x40
45 #define INTEL_VENDORID 0x8086
46 #define HDA_INTEL_82801G 0x27d8
48 #define HDA_IOSS_NO 0x08
49 #define HDA_OSS_NO 0x04
50 #define HDA_ISS_NO 0x04
51 #define HDA_CODEC_MAX 0x0f
52 #define HDA_LAST_OFFSET \
53 (0x2084 + ((HDA_ISS_NO) * 0x20) + ((HDA_OSS_NO) * 0x20))
54 #define HDA_SET_REG_TABLE_SZ \
55 (0x80 + ((HDA_ISS_NO) * 0x20) + ((HDA_OSS_NO) * 0x20))
56 #define HDA_CORB_ENTRY_LEN 0x04
57 #define HDA_RIRB_ENTRY_LEN 0x08
58 #define HDA_BDL_ENTRY_LEN 0x10
59 #define HDA_DMA_PIB_ENTRY_LEN 0x08
60 #define HDA_STREAM_TAGS_CNT 0x10
61 #define HDA_STREAM_REGS_BASE 0x80
62 #define HDA_STREAM_REGS_LEN 0x20
64 #define HDA_DMA_ACCESS_LEN (sizeof(uint32_t))
65 #define HDA_BDL_MAX_LEN 0x0100
67 #define HDAC_SDSTS_FIFORDY (1 << 5)
69 #define HDA_RIRBSTS_IRQ_MASK (HDAC_RIRBSTS_RINTFL | HDAC_RIRBSTS_RIRBOIS)
70 #define HDA_STATESTS_IRQ_MASK ((1 << HDA_CODEC_MAX) - 1)
71 #define HDA_SDSTS_IRQ_MASK \
72 (HDAC_SDSTS_DESE | HDAC_SDSTS_FIFOE | HDAC_SDSTS_BCIS)
80 typedef void (*hda_set_reg_handler
)(struct hda_softc
*sc
, uint32_t offset
,
90 struct hda_bdle_desc
{
96 struct hda_codec_cmd_ctl
{
105 struct hda_stream_desc
{
110 /* bp is the no. of bytes transferred in the current bdle */
112 /* be is the no. of bdles transferred in the bdl */
116 struct hda_bdle_desc bdl
[HDA_BDL_MAX_LEN
];
120 struct pci_devinst
*pci_dev
;
121 uint32_t regs
[HDA_LAST_OFFSET
];
125 uint64_t wall_clock_start
;
127 struct hda_codec_cmd_ctl corb
;
128 struct hda_codec_cmd_ctl rirb
;
131 struct hda_codec_inst
*codecs
[HDA_CODEC_MAX
];
133 /* Base Address of the DMA Position Buffer */
136 struct hda_stream_desc streams
[HDA_IOSS_NO
];
137 /* 2 tables for output and input */
138 uint8_t stream_map
[2][HDA_STREAM_TAGS_CNT
];
142 * HDA module function declarations
144 static inline void hda_set_reg_by_offset(struct hda_softc
*sc
, uint32_t offset
,
146 static inline uint32_t hda_get_reg_by_offset(struct hda_softc
*sc
,
148 static inline void hda_set_field_by_offset(struct hda_softc
*sc
,
149 uint32_t offset
, uint32_t mask
, uint32_t value
);
151 static struct hda_softc
*hda_init(nvlist_t
*nvl
);
152 static void hda_update_intr(struct hda_softc
*sc
);
153 static void hda_response_interrupt(struct hda_softc
*sc
);
154 static int hda_codec_constructor(struct hda_softc
*sc
,
155 struct hda_codec_class
*codec
, const char *play
, const char *rec
);
156 static struct hda_codec_class
*hda_find_codec_class(const char *name
);
158 static int hda_send_command(struct hda_softc
*sc
, uint32_t verb
);
159 static int hda_notify_codecs(struct hda_softc
*sc
, uint8_t run
,
160 uint8_t stream
, uint8_t dir
);
161 static void hda_reset(struct hda_softc
*sc
);
162 static void hda_reset_regs(struct hda_softc
*sc
);
163 static void hda_stream_reset(struct hda_softc
*sc
, uint8_t stream_ind
);
164 static int hda_stream_start(struct hda_softc
*sc
, uint8_t stream_ind
);
165 static int hda_stream_stop(struct hda_softc
*sc
, uint8_t stream_ind
);
166 static uint32_t hda_read(struct hda_softc
*sc
, uint32_t offset
);
167 static int hda_write(struct hda_softc
*sc
, uint32_t offset
, uint8_t size
,
170 static inline void hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl
*p
);
171 static int hda_corb_start(struct hda_softc
*sc
);
172 static int hda_corb_run(struct hda_softc
*sc
);
173 static int hda_rirb_start(struct hda_softc
*sc
);
175 static void *hda_dma_get_vaddr(struct hda_softc
*sc
, uint64_t dma_paddr
,
177 static void hda_dma_st_dword(void *dma_vaddr
, uint32_t data
);
178 static uint32_t hda_dma_ld_dword(void *dma_vaddr
);
180 static inline uint8_t hda_get_stream_by_offsets(uint32_t offset
,
182 static inline uint32_t hda_get_offset_stream(uint8_t stream_ind
);
184 static void hda_set_gctl(struct hda_softc
*sc
, uint32_t offset
, uint32_t old
);
185 static void hda_set_statests(struct hda_softc
*sc
, uint32_t offset
,
187 static void hda_set_corbwp(struct hda_softc
*sc
, uint32_t offset
, uint32_t old
);
188 static void hda_set_corbctl(struct hda_softc
*sc
, uint32_t offset
,
190 static void hda_set_rirbctl(struct hda_softc
*sc
, uint32_t offset
,
192 static void hda_set_rirbsts(struct hda_softc
*sc
, uint32_t offset
,
194 static void hda_set_dpiblbase(struct hda_softc
*sc
, uint32_t offset
,
196 static void hda_set_sdctl(struct hda_softc
*sc
, uint32_t offset
, uint32_t old
);
197 static void hda_set_sdctl2(struct hda_softc
*sc
, uint32_t offset
, uint32_t old
);
198 static void hda_set_sdsts(struct hda_softc
*sc
, uint32_t offset
, uint32_t old
);
200 static int hda_signal_state_change(struct hda_codec_inst
*hci
);
201 static int hda_response(struct hda_codec_inst
*hci
, uint32_t response
,
203 static int hda_transfer(struct hda_codec_inst
*hci
, uint8_t stream
,
204 uint8_t dir
, uint8_t *buf
, size_t count
);
206 static void hda_set_pib(struct hda_softc
*sc
, uint8_t stream_ind
, uint32_t pib
);
207 static uint64_t hda_get_clock_ns(void);
210 * PCI HDA function declarations
212 static int pci_hda_init(struct vmctx
*ctx
, struct pci_devinst
*pi
, nvlist_t
*nvl
);
213 static void pci_hda_write(struct vmctx
*ctx
, struct pci_devinst
*pi
,
214 int baridx
, uint64_t offset
, int size
, uint64_t value
);
215 static uint64_t pci_hda_read(struct vmctx
*ctx
, struct pci_devinst
*pi
,
216 int baridx
, uint64_t offset
, int size
);
221 static const hda_set_reg_handler hda_set_reg_table
[] = {
222 [HDAC_GCTL
] = hda_set_gctl
,
223 [HDAC_STATESTS
] = hda_set_statests
,
224 [HDAC_CORBWP
] = hda_set_corbwp
,
225 [HDAC_CORBCTL
] = hda_set_corbctl
,
226 [HDAC_RIRBCTL
] = hda_set_rirbctl
,
227 [HDAC_RIRBSTS
] = hda_set_rirbsts
,
228 [HDAC_DPIBLBASE
] = hda_set_dpiblbase
,
230 #define HDAC_ISTREAM(n, iss, oss) \
231 [_HDAC_ISDCTL(n, iss, oss)] = hda_set_sdctl, \
232 [_HDAC_ISDCTL(n, iss, oss) + 2] = hda_set_sdctl2, \
233 [_HDAC_ISDSTS(n, iss, oss)] = hda_set_sdsts, \
235 #define HDAC_OSTREAM(n, iss, oss) \
236 [_HDAC_OSDCTL(n, iss, oss)] = hda_set_sdctl, \
237 [_HDAC_OSDCTL(n, iss, oss) + 2] = hda_set_sdctl2, \
238 [_HDAC_OSDSTS(n, iss, oss)] = hda_set_sdsts, \
240 HDAC_ISTREAM(0, HDA_ISS_NO, HDA_OSS_NO)
241 HDAC_ISTREAM(1, HDA_ISS_NO
, HDA_OSS_NO
)
242 HDAC_ISTREAM(2, HDA_ISS_NO
, HDA_OSS_NO
)
243 HDAC_ISTREAM(3, HDA_ISS_NO
, HDA_OSS_NO
)
245 HDAC_OSTREAM(0, HDA_ISS_NO
, HDA_OSS_NO
)
246 HDAC_OSTREAM(1, HDA_ISS_NO
, HDA_OSS_NO
)
247 HDAC_OSTREAM(2, HDA_ISS_NO
, HDA_OSS_NO
)
248 HDAC_OSTREAM(3, HDA_ISS_NO
, HDA_OSS_NO
)
250 [HDA_SET_REG_TABLE_SZ
] = NULL
,
253 static const uint16_t hda_corb_sizes
[] = {
254 [HDAC_CORBSIZE_CORBSIZE_2
] = 2,
255 [HDAC_CORBSIZE_CORBSIZE_16
] = 16,
256 [HDAC_CORBSIZE_CORBSIZE_256
] = 256,
257 [HDAC_CORBSIZE_CORBSIZE_MASK
] = 0,
260 static const uint16_t hda_rirb_sizes
[] = {
261 [HDAC_RIRBSIZE_RIRBSIZE_2
] = 2,
262 [HDAC_RIRBSIZE_RIRBSIZE_16
] = 16,
263 [HDAC_RIRBSIZE_RIRBSIZE_256
] = 256,
264 [HDAC_RIRBSIZE_RIRBSIZE_MASK
] = 0,
267 static const struct hda_ops hops
= {
268 .signal
= hda_signal_state_change
,
269 .response
= hda_response
,
270 .transfer
= hda_transfer
,
273 static const struct pci_devemu pci_de_hda
= {
275 .pe_init
= pci_hda_init
,
276 .pe_barwrite
= pci_hda_write
,
277 .pe_barread
= pci_hda_read
279 PCI_EMUL_SET(pci_de_hda
);
281 SET_DECLARE(hda_codec_class_set
, struct hda_codec_class
);
288 * HDA module function definitions
292 hda_set_reg_by_offset(struct hda_softc
*sc
, uint32_t offset
, uint32_t value
)
294 assert(offset
< HDA_LAST_OFFSET
);
295 sc
->regs
[offset
] = value
;
298 static inline uint32_t
299 hda_get_reg_by_offset(struct hda_softc
*sc
, uint32_t offset
)
301 assert(offset
< HDA_LAST_OFFSET
);
302 return sc
->regs
[offset
];
306 hda_set_field_by_offset(struct hda_softc
*sc
, uint32_t offset
,
307 uint32_t mask
, uint32_t value
)
309 uint32_t reg_value
= 0;
311 reg_value
= hda_get_reg_by_offset(sc
, offset
);
314 reg_value
|= (value
& mask
);
316 hda_set_reg_by_offset(sc
, offset
, reg_value
);
319 static struct hda_softc
*
320 hda_init(nvlist_t
*nvl
)
322 struct hda_softc
*sc
= NULL
;
323 struct hda_codec_class
*codec
= NULL
;
330 dbg
= fopen("/tmp/bhyve_hda.log", "w+");
333 sc
= calloc(1, sizeof(*sc
));
340 * TODO search all configured codecs
341 * For now we play with one single codec
343 codec
= hda_find_codec_class("hda_codec");
345 value
= get_config_value_node(nvl
, "play");
349 play
= strdup(value
);
350 value
= get_config_value_node(nvl
, "rec");
355 DPRINTF("play: %s rec: %s", play
, rec
);
356 if (play
!= NULL
|| rec
!= NULL
) {
357 err
= hda_codec_constructor(sc
, codec
, play
, rec
);
368 hda_update_intr(struct hda_softc
*sc
)
370 struct pci_devinst
*pi
= sc
->pci_dev
;
371 uint32_t intctl
= hda_get_reg_by_offset(sc
, HDAC_INTCTL
);
374 uint32_t rirbsts
= 0;
376 uint32_t statests
= 0;
380 /* update the CIS bits */
381 rirbsts
= hda_get_reg_by_offset(sc
, HDAC_RIRBSTS
);
382 if (rirbsts
& (HDAC_RIRBSTS_RINTFL
| HDAC_RIRBSTS_RIRBOIS
))
383 intsts
|= HDAC_INTSTS_CIS
;
385 wakeen
= hda_get_reg_by_offset(sc
, HDAC_WAKEEN
);
386 statests
= hda_get_reg_by_offset(sc
, HDAC_STATESTS
);
387 if (statests
& wakeen
)
388 intsts
|= HDAC_INTSTS_CIS
;
390 /* update the SIS bits */
391 for (i
= 0; i
< HDA_IOSS_NO
; i
++) {
392 off
= hda_get_offset_stream(i
);
393 sdsts
= hda_get_reg_by_offset(sc
, off
+ HDAC_SDSTS
);
394 if (sdsts
& HDAC_SDSTS_BCIS
)
398 /* update the GIS bit */
400 intsts
|= HDAC_INTSTS_GIS
;
402 hda_set_reg_by_offset(sc
, HDAC_INTSTS
, intsts
);
404 if ((intctl
& HDAC_INTCTL_GIE
) && ((intsts
& \
405 ~HDAC_INTSTS_GIS
) & intctl
)) {
407 pci_lintr_assert(pi
);
412 pci_lintr_deassert(pi
);
419 hda_response_interrupt(struct hda_softc
*sc
)
421 uint8_t rirbctl
= hda_get_reg_by_offset(sc
, HDAC_RIRBCTL
);
423 if ((rirbctl
& HDAC_RIRBCTL_RINTCTL
) && sc
->rirb_cnt
) {
425 hda_set_field_by_offset(sc
, HDAC_RIRBSTS
, HDAC_RIRBSTS_RINTFL
,
426 HDAC_RIRBSTS_RINTFL
);
432 hda_codec_constructor(struct hda_softc
*sc
, struct hda_codec_class
*codec
,
433 const char *play
, const char *rec
)
435 struct hda_codec_inst
*hci
= NULL
;
437 if (sc
->codecs_no
>= HDA_CODEC_MAX
)
440 hci
= calloc(1, sizeof(struct hda_codec_inst
));
446 hci
->cad
= sc
->codecs_no
;
449 sc
->codecs
[sc
->codecs_no
++] = hci
;
452 DPRINTF("This codec does not implement the init function");
456 return (codec
->init(hci
, play
, rec
));
459 static struct hda_codec_class
*
460 hda_find_codec_class(const char *name
)
462 struct hda_codec_class
**pdpp
= NULL
, *pdp
= NULL
;
464 SET_FOREACH(pdpp
, hda_codec_class_set
) {
466 if (!strcmp(pdp
->name
, name
)) {
475 hda_send_command(struct hda_softc
*sc
, uint32_t verb
)
477 struct hda_codec_inst
*hci
= NULL
;
478 struct hda_codec_class
*codec
= NULL
;
479 uint8_t cad
= (verb
>> HDA_CMD_CAD_SHIFT
) & 0x0f;
481 hci
= sc
->codecs
[cad
];
485 DPRINTF("cad: 0x%x verb: 0x%x", cad
, verb
);
490 if (!codec
->command
) {
491 DPRINTF("This codec does not implement the command function");
495 return (codec
->command(hci
, verb
));
499 hda_notify_codecs(struct hda_softc
*sc
, uint8_t run
, uint8_t stream
,
502 struct hda_codec_inst
*hci
= NULL
;
503 struct hda_codec_class
*codec
= NULL
;
507 /* Notify each codec */
508 for (i
= 0; i
< sc
->codecs_no
; i
++) {
516 err
= codec
->notify(hci
, run
, stream
, dir
);
522 return (i
== sc
->codecs_no
? (-1) : 0);
526 hda_reset(struct hda_softc
*sc
)
529 struct hda_codec_inst
*hci
= NULL
;
530 struct hda_codec_class
*codec
= NULL
;
534 /* Reset each codec */
535 for (i
= 0; i
< sc
->codecs_no
; i
++) {
546 sc
->wall_clock_start
= hda_get_clock_ns();
550 hda_reset_regs(struct hda_softc
*sc
)
555 DPRINTF("Reset the HDA controller registers ...");
557 memset(sc
->regs
, 0, sizeof(sc
->regs
));
559 hda_set_reg_by_offset(sc
, HDAC_GCAP
,
561 (HDA_ISS_NO
<< HDAC_GCAP_ISS_SHIFT
) |
562 (HDA_OSS_NO
<< HDAC_GCAP_OSS_SHIFT
));
563 hda_set_reg_by_offset(sc
, HDAC_VMAJ
, 0x01);
564 hda_set_reg_by_offset(sc
, HDAC_OUTPAY
, 0x3c);
565 hda_set_reg_by_offset(sc
, HDAC_INPAY
, 0x1d);
566 hda_set_reg_by_offset(sc
, HDAC_CORBSIZE
,
567 HDAC_CORBSIZE_CORBSZCAP_256
| HDAC_CORBSIZE_CORBSIZE_256
);
568 hda_set_reg_by_offset(sc
, HDAC_RIRBSIZE
,
569 HDAC_RIRBSIZE_RIRBSZCAP_256
| HDAC_RIRBSIZE_RIRBSIZE_256
);
571 for (i
= 0; i
< HDA_IOSS_NO
; i
++) {
572 off
= hda_get_offset_stream(i
);
573 hda_set_reg_by_offset(sc
, off
+ HDAC_SDFIFOS
, HDA_FIFO_SIZE
);
578 hda_stream_reset(struct hda_softc
*sc
, uint8_t stream_ind
)
580 struct hda_stream_desc
*st
= &sc
->streams
[stream_ind
];
581 uint32_t off
= hda_get_offset_stream(stream_ind
);
583 DPRINTF("Reset the HDA stream: 0x%x", stream_ind
);
585 /* Reset the Stream Descriptor registers */
586 memset(sc
->regs
+ HDA_STREAM_REGS_BASE
+ off
, 0, HDA_STREAM_REGS_LEN
);
588 /* Reset the Stream Descriptor */
589 memset(st
, 0, sizeof(*st
));
591 hda_set_field_by_offset(sc
, off
+ HDAC_SDSTS
,
592 HDAC_SDSTS_FIFORDY
, HDAC_SDSTS_FIFORDY
);
593 hda_set_field_by_offset(sc
, off
+ HDAC_SDCTL0
,
594 HDAC_SDCTL_SRST
, HDAC_SDCTL_SRST
);
598 hda_stream_start(struct hda_softc
*sc
, uint8_t stream_ind
)
600 struct hda_stream_desc
*st
= &sc
->streams
[stream_ind
];
601 struct hda_bdle_desc
*bdle_desc
= NULL
;
602 struct hda_bdle
*bdle
= NULL
;
604 uint32_t bdl_cnt
= 0;
607 uint64_t bdl_paddr
= 0;
608 void *bdl_vaddr
= NULL
;
609 uint32_t bdle_sz
= 0;
610 uint64_t bdle_addrl
= 0;
611 uint64_t bdle_addrh
= 0;
612 uint64_t bdle_paddr
= 0;
613 void *bdle_vaddr
= NULL
;
614 uint32_t off
= hda_get_offset_stream(stream_ind
);
621 lvi
= hda_get_reg_by_offset(sc
, off
+ HDAC_SDLVI
);
622 bdpl
= hda_get_reg_by_offset(sc
, off
+ HDAC_SDBDPL
);
623 bdpu
= hda_get_reg_by_offset(sc
, off
+ HDAC_SDBDPU
);
626 assert(bdl_cnt
<= HDA_BDL_MAX_LEN
);
628 bdl_paddr
= bdpl
| (bdpu
<< 32);
629 bdl_vaddr
= hda_dma_get_vaddr(sc
, bdl_paddr
,
630 HDA_BDL_ENTRY_LEN
* bdl_cnt
);
632 DPRINTF("Fail to get the guest virtual address");
636 DPRINTF("stream: 0x%x bdl_cnt: 0x%x bdl_paddr: 0x%lx",
637 stream_ind
, bdl_cnt
, bdl_paddr
);
639 st
->bdl_cnt
= bdl_cnt
;
641 bdle
= (struct hda_bdle
*)bdl_vaddr
;
642 for (size_t i
= 0; i
< bdl_cnt
; i
++, bdle
++) {
644 assert(!(bdle_sz
% HDA_DMA_ACCESS_LEN
));
646 bdle_addrl
= bdle
->addrl
;
647 bdle_addrh
= bdle
->addrh
;
649 bdle_paddr
= bdle_addrl
| (bdle_addrh
<< 32);
650 bdle_vaddr
= hda_dma_get_vaddr(sc
, bdle_paddr
, bdle_sz
);
652 DPRINTF("Fail to get the guest virtual address");
656 bdle_desc
= &st
->bdl
[i
];
657 bdle_desc
->addr
= bdle_vaddr
;
658 bdle_desc
->len
= bdle_sz
;
659 bdle_desc
->ioc
= bdle
->ioc
;
661 DPRINTF("bdle: 0x%zx bdle_sz: 0x%x", i
, bdle_sz
);
664 sdctl
= hda_get_reg_by_offset(sc
, off
+ HDAC_SDCTL0
);
665 strm
= (sdctl
>> 20) & 0x0f;
666 dir
= stream_ind
>= HDA_ISS_NO
;
668 DPRINTF("strm: 0x%x, dir: 0x%x", strm
, dir
);
670 sc
->stream_map
[dir
][strm
] = stream_ind
;
676 hda_set_pib(sc
, stream_ind
, 0);
680 hda_notify_codecs(sc
, 1, strm
, dir
);
686 hda_stream_stop(struct hda_softc
*sc
, uint8_t stream_ind
)
688 struct hda_stream_desc
*st
= &sc
->streams
[stream_ind
];
689 uint8_t strm
= st
->stream
;
690 uint8_t dir
= st
->dir
;
692 DPRINTF("stream: 0x%x, strm: 0x%x, dir: 0x%x", stream_ind
, strm
, dir
);
696 hda_notify_codecs(sc
, 0, strm
, dir
);
702 hda_read(struct hda_softc
*sc
, uint32_t offset
)
704 if (offset
== HDAC_WALCLK
)
705 return (24 * (hda_get_clock_ns() - \
706 sc
->wall_clock_start
) / 1000);
708 return (hda_get_reg_by_offset(sc
, offset
));
712 hda_write(struct hda_softc
*sc
, uint32_t offset
, uint8_t size
, uint32_t value
)
714 uint32_t old
= hda_get_reg_by_offset(sc
, offset
);
715 uint32_t masks
[] = {0x00000000, 0x000000ff, 0x0000ffff,
716 0x00ffffff, 0xffffffff};
717 hda_set_reg_handler set_reg_handler
= hda_set_reg_table
[offset
];
719 hda_set_field_by_offset(sc
, offset
, masks
[size
], value
);
722 set_reg_handler(sc
, offset
, old
);
728 hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl
*p
)
731 const char *name
= p
->name
;
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
);
740 hda_corb_start(struct hda_softc
*sc
)
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;
750 corbsize
= hda_get_reg_by_offset(sc
, HDAC_CORBSIZE
) & \
751 HDAC_CORBSIZE_CORBSIZE_MASK
;
752 corb
->size
= hda_corb_sizes
[corbsize
];
755 DPRINTF("Invalid corb size");
759 corblbase
= hda_get_reg_by_offset(sc
, HDAC_CORBLBASE
);
760 corbubase
= hda_get_reg_by_offset(sc
, HDAC_CORBUBASE
);
762 corbpaddr
= corblbase
| (corbubase
<< 32);
763 DPRINTF("CORB dma_paddr: %p", (void *)corbpaddr
);
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");
772 corb
->wp
= hda_get_reg_by_offset(sc
, HDAC_CORBWP
);
773 corb
->rp
= hda_get_reg_by_offset(sc
, HDAC_CORBRP
);
777 hda_print_cmd_ctl_data(corb
);
783 hda_corb_run(struct hda_softc
*sc
)
785 struct hda_codec_cmd_ctl
*corb
= &sc
->corb
;
789 corb
->wp
= hda_get_reg_by_offset(sc
, HDAC_CORBWP
);
791 while (corb
->rp
!= corb
->wp
&& corb
->run
) {
793 corb
->rp
%= corb
->size
;
795 verb
= hda_dma_ld_dword((uint8_t *)corb
->dma_vaddr
+
796 HDA_CORB_ENTRY_LEN
* corb
->rp
);
798 err
= hda_send_command(sc
, verb
);
802 hda_set_reg_by_offset(sc
, HDAC_CORBRP
, corb
->rp
);
805 hda_response_interrupt(sc
);
811 hda_rirb_start(struct hda_softc
*sc
)
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;
821 rirbsize
= hda_get_reg_by_offset(sc
, HDAC_RIRBSIZE
) & \
822 HDAC_RIRBSIZE_RIRBSIZE_MASK
;
823 rirb
->size
= hda_rirb_sizes
[rirbsize
];
826 DPRINTF("Invalid rirb size");
830 rirblbase
= hda_get_reg_by_offset(sc
, HDAC_RIRBLBASE
);
831 rirbubase
= hda_get_reg_by_offset(sc
, HDAC_RIRBUBASE
);
833 rirbpaddr
= rirblbase
| (rirbubase
<< 32);
834 DPRINTF("RIRB dma_paddr: %p", (void *)rirbpaddr
);
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");
843 rirb
->wp
= hda_get_reg_by_offset(sc
, HDAC_RIRBWP
);
848 hda_print_cmd_ctl_data(rirb
);
854 hda_dma_get_vaddr(struct hda_softc
*sc
, uint64_t dma_paddr
, size_t len
)
856 struct pci_devinst
*pi
= sc
->pci_dev
;
860 return (paddr_guest2host(pi
->pi_vmctx
, (uintptr_t)dma_paddr
, len
));
864 hda_dma_st_dword(void *dma_vaddr
, uint32_t data
)
866 *(uint32_t*)dma_vaddr
= data
;
870 hda_dma_ld_dword(void *dma_vaddr
)
872 return (*(uint32_t*)dma_vaddr
);
875 static inline uint8_t
876 hda_get_stream_by_offsets(uint32_t offset
, uint8_t reg_offset
)
878 uint8_t stream_ind
= (offset
- reg_offset
) >> 5;
880 assert(stream_ind
< HDA_IOSS_NO
);
885 static inline uint32_t
886 hda_get_offset_stream(uint8_t stream_ind
)
888 return (stream_ind
<< 5);
892 hda_set_gctl(struct hda_softc
*sc
, uint32_t offset
, uint32_t old __unused
)
894 uint32_t value
= hda_get_reg_by_offset(sc
, offset
);
896 if (!(value
& HDAC_GCTL_CRST
)) {
902 hda_set_statests(struct hda_softc
*sc
, uint32_t offset
, uint32_t old
)
904 uint32_t value
= hda_get_reg_by_offset(sc
, offset
);
906 hda_set_reg_by_offset(sc
, offset
, old
);
908 /* clear the corresponding bits written by the software (guest) */
909 hda_set_field_by_offset(sc
, offset
, value
& HDA_STATESTS_IRQ_MASK
, 0);
915 hda_set_corbwp(struct hda_softc
*sc
, uint32_t offset __unused
,
916 uint32_t old __unused
)
922 hda_set_corbctl(struct hda_softc
*sc
, uint32_t offset
, uint32_t old
)
924 uint32_t value
= hda_get_reg_by_offset(sc
, offset
);
926 struct hda_codec_cmd_ctl
*corb
= NULL
;
928 if (value
& HDAC_CORBCTL_CORBRUN
) {
929 if (!(old
& HDAC_CORBCTL_CORBRUN
)) {
930 err
= hda_corb_start(sc
);
935 memset(corb
, 0, sizeof(*corb
));
942 hda_set_rirbctl(struct hda_softc
*sc
, uint32_t offset
, uint32_t old __unused
)
944 uint32_t value
= hda_get_reg_by_offset(sc
, offset
);
946 struct hda_codec_cmd_ctl
*rirb
= NULL
;
948 if (value
& HDAC_RIRBCTL_RIRBDMAEN
) {
949 err
= hda_rirb_start(sc
);
953 memset(rirb
, 0, sizeof(*rirb
));
958 hda_set_rirbsts(struct hda_softc
*sc
, uint32_t offset
, uint32_t old
)
960 uint32_t value
= hda_get_reg_by_offset(sc
, offset
);
962 hda_set_reg_by_offset(sc
, offset
, old
);
964 /* clear the corresponding bits written by the software (guest) */
965 hda_set_field_by_offset(sc
, offset
, value
& HDA_RIRBSTS_IRQ_MASK
, 0);
971 hda_set_dpiblbase(struct hda_softc
*sc
, uint32_t offset
, uint32_t old
)
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;
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
);
984 dpibpaddr
= dpiblbase
| (dpibubase
<< 32);
985 DPRINTF("DMA Position In Buffer dma_paddr: %p",
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 \
996 DPRINTF("DMA Position In Buffer Reset");
997 sc
->dma_pib_vaddr
= NULL
;
1003 hda_set_sdctl(struct hda_softc
*sc
, uint32_t offset
, uint32_t old
)
1005 uint8_t stream_ind
= hda_get_stream_by_offsets(offset
, HDAC_SDCTL0
);
1006 uint32_t value
= hda_get_reg_by_offset(sc
, offset
);
1009 DPRINTF("stream_ind: 0x%x old: 0x%x value: 0x%x",
1010 stream_ind
, old
, value
);
1012 if (value
& HDAC_SDCTL_SRST
) {
1013 hda_stream_reset(sc
, stream_ind
);
1016 if ((value
& HDAC_SDCTL_RUN
) != (old
& HDAC_SDCTL_RUN
)) {
1017 if (value
& HDAC_SDCTL_RUN
) {
1018 err
= hda_stream_start(sc
, stream_ind
);
1021 err
= hda_stream_stop(sc
, stream_ind
);
1028 hda_set_sdctl2(struct hda_softc
*sc
, uint32_t offset
, uint32_t old __unused
)
1030 uint32_t value
= hda_get_reg_by_offset(sc
, offset
);
1032 hda_set_field_by_offset(sc
, offset
- 2, 0x00ff0000, value
<< 16);
1036 hda_set_sdsts(struct hda_softc
*sc
, uint32_t offset
, uint32_t old
)
1038 uint32_t value
= hda_get_reg_by_offset(sc
, offset
);
1040 hda_set_reg_by_offset(sc
, offset
, old
);
1042 /* clear the corresponding bits written by the software (guest) */
1043 hda_set_field_by_offset(sc
, offset
, value
& HDA_SDSTS_IRQ_MASK
, 0);
1045 hda_update_intr(sc
);
1049 hda_signal_state_change(struct hda_codec_inst
*hci
)
1051 struct hda_softc
*sc
= NULL
;
1052 uint32_t sdiwake
= 0;
1057 DPRINTF("cad: 0x%x", hci
->cad
);
1060 sdiwake
= 1 << hci
->cad
;
1062 hda_set_field_by_offset(sc
, HDAC_STATESTS
, sdiwake
, sdiwake
);
1063 hda_update_intr(sc
);
1069 hda_response(struct hda_codec_inst
*hci
, uint32_t response
, uint8_t unsol
)
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;
1077 assert(hci
->cad
<= HDA_CODEC_MAX
);
1079 response_ex
= hci
->cad
| unsol
;
1088 rirb
->wp
%= rirb
->size
;
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
);
1095 hda_set_reg_by_offset(sc
, HDAC_RIRBWP
, rirb
->wp
);
1100 rintcnt
= hda_get_reg_by_offset(sc
, HDAC_RINTCNT
);
1101 if (sc
->rirb_cnt
== rintcnt
)
1102 hda_response_interrupt(sc
);
1108 hda_transfer(struct hda_codec_inst
*hci
, uint8_t stream
, uint8_t dir
,
1109 uint8_t *buf
, size_t count
)
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;
1124 assert(!(count
% HDA_DMA_ACCESS_LEN
));
1127 DPRINTF("Invalid stream");
1133 assert(stream
< HDA_STREAM_TAGS_CNT
);
1134 stream_ind
= sc
->stream_map
[dir
][stream
];
1137 assert(stream_ind
< HDA_ISS_NO
);
1139 assert(stream_ind
>= HDA_ISS_NO
&& stream_ind
< HDA_IOSS_NO
);
1141 st
= &sc
->streams
[stream_ind
];
1143 DPRINTF("Stream 0x%x stopped", stream
);
1147 assert(st
->stream
== stream
);
1149 off
= hda_get_offset_stream(stream_ind
);
1151 lpib
= hda_get_reg_by_offset(sc
, off
+ HDAC_SDLPIB
);
1155 assert(st
->be
< st
->bdl_cnt
);
1156 assert(st
->bp
< bdl
[st
->be
].len
);
1160 bdle_desc
= &bdl
[st
->be
];
1163 *(uint32_t *)buf
= hda_dma_ld_dword(
1164 (uint8_t *)bdle_desc
->addr
+ st
->bp
);
1166 hda_dma_st_dword((uint8_t *)bdle_desc
->addr
+
1167 st
->bp
, *(uint32_t *)buf
);
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
;
1174 if (st
->bp
== bdle_desc
->len
) {
1179 if (st
->be
== st
->bdl_cnt
) {
1183 bdle_desc
= &bdl
[st
->be
];
1187 hda_set_pib(sc
, stream_ind
, lpib
);
1190 hda_set_field_by_offset(sc
, off
+ HDAC_SDSTS
,
1191 HDAC_SDSTS_BCIS
, HDAC_SDSTS_BCIS
);
1192 hda_update_intr(sc
);
1199 hda_set_pib(struct hda_softc
*sc
, uint8_t stream_ind
, uint32_t pib
)
1201 uint32_t off
= hda_get_offset_stream(stream_ind
);
1203 hda_set_reg_by_offset(sc
, off
+ HDAC_SDLPIB
, pib
);
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
;
1211 static uint64_t hda_get_clock_ns(void)
1216 err
= clock_gettime(CLOCK_MONOTONIC
, &ts
);
1219 return (ts
.tv_sec
* 1000000000LL + ts
.tv_nsec
);
1223 * PCI HDA function definitions
1226 pci_hda_init(struct vmctx
*ctx
, struct pci_devinst
*pi
, nvlist_t
*nvl
)
1228 struct hda_softc
*sc
= NULL
;
1230 assert(ctx
!= NULL
);
1233 pci_set_cfgdata16(pi
, PCIR_VENDOR
, INTEL_VENDORID
);
1234 pci_set_cfgdata16(pi
, PCIR_DEVICE
, HDA_INTEL_82801G
);
1236 pci_set_cfgdata8(pi
, PCIR_SUBCLASS
, PCIS_MULTIMEDIA_HDA
);
1237 pci_set_cfgdata8(pi
, PCIR_CLASS
, PCIC_MULTIMEDIA
);
1239 /* select the Intel HDA mode */
1240 pci_set_cfgdata8(pi
, PCIR_HDCTL
, 0x01);
1242 /* allocate one BAR register for the Memory address offsets */
1243 pci_emul_alloc_bar(pi
, 0, PCIBAR_MEM32
, HDA_LAST_OFFSET
);
1245 /* allocate an IRQ pin for our slot */
1246 pci_lintr_request(pi
);
1259 pci_hda_write(struct vmctx
*ctx __unused
,
1260 struct pci_devinst
*pi
, int baridx
, uint64_t offset
, int size
,
1263 struct hda_softc
*sc
= pi
->pi_arg
;
1267 assert(baridx
== 0);
1270 DPRINTF("offset: 0x%lx value: 0x%lx", offset
, value
);
1272 err
= hda_write(sc
, offset
, size
, value
);
1277 pci_hda_read(struct vmctx
*ctx __unused
,
1278 struct pci_devinst
*pi
, int baridx
, uint64_t offset
, int size
)
1280 struct hda_softc
*sc
= pi
->pi_arg
;
1284 assert(baridx
== 0);
1287 value
= hda_read(sc
, offset
);
1289 DPRINTF("offset: 0x%lx value: 0x%lx", offset
, value
);