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