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 } 1294