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