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