Changeset 58900 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Nov 27, 2015 11:58:18 AM (9 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevIchHda.cpp
r58600 r58900 33 33 #include <iprt/asm.h> 34 34 #include <iprt/asm-math.h> 35 #include <iprt/list.h> 35 36 #ifdef IN_RING3 37 # include <iprt/mem.h> 38 # include <iprt/string.h> 36 39 # include <iprt/uuid.h> 37 # include <iprt/string.h>38 # include <iprt/mem.h>39 40 #endif 40 #include <iprt/list.h>41 41 42 42 #include "VBoxDD.h" … … 277 277 #define HDA_RMX_DPUBASE 31 278 278 #define DPUBASE(pThis) (HDA_REG((pThis), DPUBASE)) 279 #define DPBASE_ENABLED 1 279 /** DMA Position Buffer Enable (3.3.32). */ 280 #define DPBASE_ENABLED RT_BIT(0) 280 281 #define DPBASE_ADDR_MASK (~(uint64_t)0x7f) 281 282 … … 284 285 /* Note: sdnum here _MUST_ be stream reg number [0,7]. */ 285 286 #define HDA_STREAM_REG(pThis, name, sdnum) (HDA_REG_IND((pThis), HDA_REG_SD0##name + (sdnum) * 10)) 287 288 #define HDA_SD_NUM_FROM_REG(pThis, func, reg) ((reg - HDA_STREAM_REG_DEF(func, 0)) / 10) 286 289 287 290 #define HDA_REG_SD0CTL 34 /* 0x80 */ … … 303 306 304 307 #define SD(func, num) SD##num##func 305 #define SDCTL(pThis, num) HDA_REG((pThis), SD(CTL, num)) 306 #define SDCTL_NUM(pThis, num) ((SDCTL((pThis), num) & HDA_REG_FIELD_MASK(SDCTL,NUM)) >> HDA_REG_FIELD_SHIFT(SDCTL, NUM)) 308 309 #define HDA_SDCTL(pThis, num) HDA_REG((pThis), SD(CTL, num)) 310 #define HDA_SDCTL_NUM(pThis, num) ((HDA_SDCTL((pThis), num) & HDA_REG_FIELD_MASK(SDCTL,NUM)) >> HDA_REG_FIELD_SHIFT(SDCTL, NUM)) 307 311 #define HDA_SDCTL_NUM_MASK 0xF 308 312 #define HDA_SDCTL_NUM_SHIFT 20 … … 374 378 #define HDA_RMX_SD7CBL (HDA_STREAM_RMX_DEF(CBL, 0) + 70) 375 379 376 377 380 #define HDA_REG_SD0LVI 38 /* 0x8C */ 378 381 #define HDA_REG_SD1LVI (HDA_STREAM_REG_DEF(LVI, 0) + 10) /* 0xAC */ … … 410 413 411 414 /* 412 * ICH6 datasheet defined limits for FIFOW values (18.2.38) 415 * ICH6 datasheet defined limits for FIFOW values (18.2.38). 413 416 */ 414 417 #define HDA_SDFIFOW_8B 0x2 … … 438 441 * Other values not listed are not supported. 439 442 */ 443 #define HDA_SDINFIFO_120B 0x77 /* 8-, 16-, 20-, 24-, 32-bit Input Streams */ 444 #define HDA_SDINFIFO_160B 0x9F /* 20-, 24-bit Input Streams Streams */ 445 440 446 #define HDA_SDONFIFO_16B 0x0F /* 8-, 16-, 20-, 24-, 32-bit Output Streams */ 441 447 #define HDA_SDONFIFO_32B 0x1F /* 8-, 16-, 20-, 24-, 32-bit Output Streams */ … … 444 450 #define HDA_SDONFIFO_192B 0xBF /* 8-, 16-, 20-, 24-, 32-bit Output Streams */ 445 451 #define HDA_SDONFIFO_256B 0xFF /* 20-, 24-bit Output Streams */ 446 #define HDA_SDINFIFO_120B 0x77 /* 8-, 16-, 20-, 24-, 32-bit Input Streams */447 #define HDA_SDINFIFO_160B 0x9F /* 20-, 24-bit Input Streams Streams */448 452 #define SDFIFOS(pThis, num) HDA_REG((pThis), SD(FIFOS, num)) 449 453 … … 520 524 * Structures and Typedefs * 521 525 *********************************************************************************************************************************/ 522 typedef struct HDABDLEDESC 523 { 524 uint64_t u64BdleCviAddr; 525 uint32_t u32BdleMaxCvi; 526 uint32_t u32BdleCvi; 527 uint32_t u32BdleCviLen; 528 uint32_t u32BdleCviPos; 529 bool fBdleCviIoc; 530 uint32_t cbUnderFifoW; 531 uint8_t au8HdaBuffer[HDA_SDONFIFO_256B + 1]; 532 } HDABDLEDESC, *PHDABDLEDESC; 533 534 typedef struct HDASTREAMTRANSFERDESC 535 { 536 uint64_t u64BaseDMA; 537 uint32_t u32Ctl; 538 uint32_t *pu32Sts; 539 uint8_t u8Strm; 540 uint32_t *pu32Lpib; 541 uint32_t u32Cbl; 542 uint32_t u32Fifos; 543 } HDASTREAMTRANSFERDESC, *PHDASTREAMTRANSFERDESC; 526 527 /** 528 * Internal state of a Buffer Descriptor List Entry (BDLE), 529 * needed to keep track of the data needed for the actual device 530 * emulation. 531 */ 532 typedef struct HDABDLESTATE 533 { 534 /** Own index within the BDL (Buffer Descriptor List). */ 535 uint32_t u32BDLIndex; 536 /** Number of bytes below the stream's FIFO watermark (SDFIFOW). 537 * Used to check if we need fill up the FIFO again. */ 538 uint32_t cbBelowFIFOW; 539 /** The buffer descriptor's internal DMA buffer. */ 540 uint8_t au8FIFO[HDA_SDONFIFO_256B + 1]; 541 /** Current offset in DMA buffer (in bytes).*/ 542 uint32_t u32BufOff; 543 } HDABDLESTATE, *PHDABDLESTATE; 544 545 /** 546 * Buffer Descriptor List Entry (BDLE) (3.6.3). 547 * 548 * Contains only register values which do *not* change until a 549 * stream reset occurs. 550 */ 551 typedef struct HDABDLE 552 { 553 /** Starting address of the actual buffer. Must be 128-bit aligned. */ 554 uint64_t u64BufAdr; 555 /** Size of the actual buffer (in bytes). */ 556 uint32_t u32BufSize; 557 /** Interrupt on completion; the controller will generate 558 * an interrupt when the last byte of the buffer has been 559 * fetched by the DMA engine. */ 560 bool fIntOnCompletion; 561 /** Internal state of this BDLE. 562 * Not part of the actual BDLE registers. */ 563 HDABDLESTATE State; 564 } HDABDLE, *PHDABDLE; 565 566 /** 567 * Internal state of a HDA stream. 568 */ 569 typedef struct HDASTREAMSTATE 570 { 571 /** Number of BDLEs (Buffer Descriptor List Entry). 572 * Should be SDnLVI + 1 usually. */ 573 uint16_t cBDLE; 574 /** Current BDLE to use. Wraps around to 0 if 575 * maximum (cBDLE) is reached. */ 576 uint16_t uCurBDLE; 577 /** Array of BDLEs. */ 578 R3PTRTYPE(PHDABDLE) paBDLE; 579 } HDASTREAMSTATE, *PHDASTREAMSTATE; 580 581 /** 582 * Structure for keeping a HDA stream state. 583 * 584 * Contains only register values which do *not* change until a 585 * stream reset occurs. 586 */ 587 typedef struct HDASTREAM 588 { 589 /** Stream number (SDn). */ 590 uint8_t u8Strm; 591 /** DMA base address (SDnBDPU - SDnBDPL). */ 592 uint64_t u64BaseDMA; 593 /** Cyclic Buffer Length (SDnCBL). 594 * Represents the size of the ring buffer. */ 595 uint32_t u32CBL; 596 /** Format (SDnFMT). */ 597 uint16_t u16FMT; 598 /** FIFO Size (FIFOS). 599 * Maximum number of bytes that may have been DMA'd into 600 * memory but not yet transmitted on the link. 601 * 602 * Must be a power of two. */ 603 uint16_t u16FIFOS; 604 /** Last Valid Index (SDnLVI). */ 605 uint16_t u16LVI; 606 /** Internal state of this stream. */ 607 HDASTREAMSTATE State; 608 } HDASTREAM, *PHDASTREAM; 544 609 545 610 typedef struct HDAINPUTSTREAM … … 613 678 /** R0 Pointer to the device instance. */ 614 679 PPDMDEVINSRC pDevInsRC; 615 680 /** Padding for alignment. */ 616 681 uint32_t u32Padding; 617 618 682 /** Pointer to the attached audio driver. */ 619 683 R3PTRTYPE(PPDMIBASE) pDrvBase; … … 621 685 PDMIBASE IBase; 622 686 RTGCPHYS MMIOBaseAddr; 687 /** The HDA's register set. */ 623 688 uint32_t au32Regs[HDA_NREGS]; 624 HDABDLEDESC StInBdle; 625 HDABDLEDESC StOutBdle; 626 HDABDLEDESC StMicBdle; 689 /** Stream state for line-in. */ 690 HDASTREAM StrmStLineIn; 691 /** Stream state for microphone-in. */ 692 HDASTREAM StrmStMicIn; 693 /** Stream state for output. */ 694 HDASTREAM StrmStOut; 695 /** CORB buffer base address. */ 627 696 uint64_t u64CORBBase; 697 /** RIRB buffer base address. */ 628 698 uint64_t u64RIRBBase; 699 /** DMA base address. 700 * Made out of DPLBASE + DPUBASE (3.3.32 + 3.3.33). */ 629 701 uint64_t u64DPBase; 630 702 /** Pointer to CORB buffer. */ … … 632 704 /** Size in bytes of CORB buffer. */ 633 705 uint32_t cbCorbBuf; 706 /** Padding for alignment. */ 634 707 uint32_t u32Padding2; 635 708 /** Pointer to RIRB buffer. */ … … 639 712 /** Indicates if HDA is in reset. */ 640 713 bool fInReset; 641 /** Interrupt on completion */642 bool fCviIoc;643 714 /** Flag whether the R0 part is enabled. */ 644 715 bool fR0Enabled; … … 650 721 /** Timer ticks for handling the LUN drivers. */ 651 722 uint64_t uTicks; 652 # ifdef VBOX_WITH_STATISTICS 723 #ifdef VBOX_WITH_STATISTICS 724 # ifndef VBOX_WITH_AUDIO_CALLBACKS 653 725 STAMPROFILE StatTimer; 726 # endif 654 727 STAMCOUNTER StatBytesRead; 655 728 STAMCOUNTER StatBytesWritten; 656 # 729 #endif 657 730 /** Pointer to HDA codec to use. */ 658 731 R3PTRTYPE(PHDACODEC) pCodec; … … 661 734 /** List of associated LUN drivers. */ 662 735 RTLISTANCHOR lstDrv; 736 /** Padding for alignment. */ 663 737 struct 664 738 { … … 676 750 R3PTRTYPE(PAUDMIXSINK) pSinkMicIn; 677 751 uint64_t u64BaseTS; 678 /** 1.2.3.4.5.6.7. - someone please tell me what I'm counting! - .8.9.10... */ 679 uint8_t u8Counter; 752 /** Response Interrupt Count (RINTCNT). */ 753 uint8_t u8RespIntCnt; 754 /** Padding for alignment. */ 680 755 uint8_t au8Padding[7]; 681 756 } HDASTATE; 682 757 /** Pointer to the ICH Intel HD Audio Controller state. */ 683 758 typedef HDASTATE *PHDASTATE; 759 760 #ifdef VBOX_WITH_AUDIO_CALLBACKS 761 typedef struct HDACALLBACKCTX 762 { 763 PHDASTATE pThis; 764 PHDADRIVER pDriver; 765 } HDACALLBACKCTX, *PHDACALLBACKCTX; 766 #endif 684 767 685 768 #define ISD0FMT_TO_AUDIO_SELECTOR(pThis) \ … … 695 778 static FNPDMDEVRESET hdaReset; 696 779 780 /* 781 * Stubs. 782 */ 697 783 static int hdaRegReadUnimpl(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 698 784 static int hdaRegWriteUnimpl(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value); 785 786 /* 787 * Global register set read/write functions. 788 */ 699 789 static int hdaRegWriteGCTL(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value); 700 static int hdaRegReadSTATESTS(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);701 static int hdaRegWriteSTATESTS(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);702 790 static int hdaRegReadINTSTS(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 791 static int hdaRegReadLPIB(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 703 792 static int hdaRegReadWALCLK(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 704 793 static int hdaRegWriteINTSTS(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value); … … 709 798 static int hdaRegWriteRIRBWP(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value); 710 799 static int hdaRegWriteRIRBSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 800 static int hdaRegWriteSTATESTS(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value); 711 801 static int hdaRegWriteIRS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 712 802 static int hdaRegReadIRS(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 803 static int hdaRegWriteBase(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 804 805 /* 806 * {IOB}SDn read/write functions. 807 */ 808 static int hdaRegWriteSDCBL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 713 809 static int hdaRegWriteSDCTL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 714 715 810 static int hdaRegWriteSDSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 716 811 static int hdaRegWriteSDLVI(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); … … 720 815 static int hdaRegWriteSDBDPL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 721 816 static int hdaRegWriteSDBDPU(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 722 static int hdaRegWriteBase(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value); 817 818 /* 819 * Generic register read/write functions. 820 */ 723 821 static int hdaRegReadU32(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 724 822 static int hdaRegWriteU32(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value); … … 730 828 static int hdaRegWriteU8(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value); 731 829 732 static DECLCALLBACK(void) hdaTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser); 733 static int hdaTransfer(PHDASTATE pThis, ENMSOUNDSOURCE enmSrc, uint32_t cbAvail); 830 static void hdaStreamDestroy(PHDASTREAM pStrmSt); 831 832 static int hdaTransfer(PHDASTATE pThis, ENMSOUNDSOURCE enmSrc, uint32_t *pcbProcessed); 734 833 735 834 #ifdef IN_RING3 736 DECLINLINE(void) hdaInitTransferDescriptor(PHDASTATE pThis, PHDABDLEDESC pBdle, uint8_t u8Strm, 737 PHDASTREAMTRANSFERDESC pStreamDesc); 738 static void hdaFetchBdle(PHDASTATE pThis, PHDABDLEDESC pBdle, PHDASTREAMTRANSFERDESC pStreamDesc); 739 #ifdef LOG_ENABLED 740 static void dump_bd(PHDASTATE pThis, PHDABDLEDESC pBdle, uint64_t u64BaseDMA); 741 #endif 835 static int hdaBDLEFetch(PHDASTATE pThis, PHDABDLE pBDLE, uint64_t u64BaseDMA, uint16_t u16Entry); 836 # ifdef LOG_ENABLED 837 static void hdaBDLEDumpAll(PHDASTATE pThis, uint64_t u64BaseDMA, uint16_t u16LVI); 838 # endif 839 static void hdaBDLEReset(PHDABDLE pBDLE); 742 840 #endif 743 841 … … 747 845 *********************************************************************************************************************************/ 748 846 749 /* see 302349 p 6.2 */847 /* see 302349 p 6.2. */ 750 848 static const struct HDAREGDESC 751 849 { … … 818 916 { 0x00080, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24 , hdaRegWriteSDCTL , IA(SD0CTL) }, /* Input Stream Descriptor 0 (ICD0) Control */ 819 917 { 0x00083, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8 , hdaRegWriteSDSTS , IA(SD0STS) }, /* ISD0 Status */ 820 { 0x00084, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegRead U32 , hdaRegWriteU32 , IA(SD0LPIB) }, /* ISD0 Link Position In Buffer*/821 { 0x00088, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWrite U32, IA(SD0CBL) }, /* ISD0 Cyclic Buffer Length */918 { 0x00084, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadLPIB , hdaRegWriteUnimpl , IA(SD0LPIB) }, /* ISD0 Link Position In Buffer (RO) */ 919 { 0x00088, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDCBL , IA(SD0CBL) }, /* ISD0 Cyclic Buffer Length */ 822 920 { 0x0008C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , IA(SD0LVI) }, /* ISD0 Last Valid Index */ 823 921 { 0x0008E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , IA(SD0FIFOW) }, /* ISD0 FIFO Watermark */ … … 829 927 { 0x000A0, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24 , hdaRegWriteSDCTL , IA(SD1CTL) }, /* Input Stream Descriptor 1 (ISD1) Control */ 830 928 { 0x000A3, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8 , hdaRegWriteSDSTS , IA(SD1STS) }, /* ISD1 Status */ 831 { 0x000A4, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegRead U32 , hdaRegWriteU32 , IA(SD1LPIB) }, /* ISD1 Link Position In Buffer*/832 { 0x000A8, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWrite U32, IA(SD1CBL) }, /* ISD1 Cyclic Buffer Length */929 { 0x000A4, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadLPIB , hdaRegWriteUnimpl , IA(SD1LPIB) }, /* ISD1 Link Position In Buffer (RO). */ 930 { 0x000A8, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDCBL , IA(SD1CBL) }, /* ISD1 Cyclic Buffer Length */ 833 931 { 0x000AC, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , IA(SD1LVI) }, /* ISD1 Last Valid Index */ 834 932 { 0x000AE, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , IA(SD1FIFOW) }, /* ISD1 FIFO Watermark */ … … 840 938 { 0x000C0, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24 , hdaRegWriteSDCTL , IA(SD2CTL) }, /* Input Stream Descriptor 2 (ISD2) Control */ 841 939 { 0x000C3, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8 , hdaRegWriteSDSTS , IA(SD2STS) }, /* ISD2 Status */ 842 { 0x000C4, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegRead U32 , hdaRegWriteU32 , IA(SD2LPIB) }, /* ISD2 Link Position In Buffer*/843 { 0x000C8, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWrite U32, IA(SD2CBL) }, /* ISD2 Cyclic Buffer Length */940 { 0x000C4, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadLPIB , hdaRegWriteUnimpl , IA(SD2LPIB) }, /* ISD2 Link Position In Buffer (RO) */ 941 { 0x000C8, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDCBL , IA(SD2CBL) }, /* ISD2 Cyclic Buffer Length */ 844 942 { 0x000CC, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , IA(SD2LVI) }, /* ISD2 Last Valid Index */ 845 943 { 0x000CE, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , IA(SD2FIFOW) }, /* ISD2 FIFO Watermark */ … … 851 949 { 0x000E0, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24 , hdaRegWriteSDCTL , IA(SD3CTL) }, /* Input Stream Descriptor 3 (ISD3) Control */ 852 950 { 0x000E3, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8 , hdaRegWriteSDSTS , IA(SD3STS) }, /* ISD3 Status */ 853 { 0x000E4, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegRead U32 , hdaRegWriteU32 , IA(SD3LPIB) }, /* ISD3 Link Position In Buffer*/854 { 0x000E8, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWrite U32, IA(SD3CBL) }, /* ISD3 Cyclic Buffer Length */951 { 0x000E4, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadLPIB , hdaRegWriteUnimpl , IA(SD3LPIB) }, /* ISD3 Link Position In Buffer (RO) */ 952 { 0x000E8, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDCBL , IA(SD3CBL) }, /* ISD3 Cyclic Buffer Length */ 855 953 { 0x000EC, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , IA(SD3LVI) }, /* ISD3 Last Valid Index */ 856 954 { 0x000EE, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , IA(SD3FIFOW) }, /* ISD3 FIFO Watermark */ … … 862 960 { 0x00100, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24 , hdaRegWriteSDCTL , OA(SD4CTL) }, /* Output Stream Descriptor 4 (OSD4) Control */ 863 961 { 0x00103, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8 , hdaRegWriteSDSTS , OA(SD4STS) }, /* OSD4 Status */ 864 { 0x00104, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegRead U32 , hdaRegWriteU32 , OA(SD4LPIB) }, /* OSD4 Link Position In Buffer*/865 { 0x00108, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWrite U32, OA(SD4CBL) }, /* OSD4 Cyclic Buffer Length */962 { 0x00104, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadLPIB , hdaRegWriteUnimpl , OA(SD4LPIB) }, /* OSD4 Link Position In Buffer (RO) */ 963 { 0x00108, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDCBL , OA(SD4CBL) }, /* OSD4 Cyclic Buffer Length */ 866 964 { 0x0010C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , OA(SD4LVI) }, /* OSD4 Last Valid Index */ 867 965 { 0x0010E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , OA(SD4FIFOW) }, /* OSD4 FIFO Watermark */ … … 873 971 { 0x00120, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24 , hdaRegWriteSDCTL , OA(SD5CTL) }, /* Output Stream Descriptor 5 (OSD5) Control */ 874 972 { 0x00123, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8 , hdaRegWriteSDSTS , OA(SD5STS) }, /* OSD5 Status */ 875 { 0x00124, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegRead U32 , hdaRegWriteU32 , OA(SD5LPIB) }, /* OSD5 Link Position In Buffer*/876 { 0x00128, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWrite U32, OA(SD5CBL) }, /* OSD5 Cyclic Buffer Length */973 { 0x00124, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadLPIB , hdaRegWriteUnimpl , OA(SD5LPIB) }, /* OSD5 Link Position In Buffer (RO) */ 974 { 0x00128, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDCBL , OA(SD5CBL) }, /* OSD5 Cyclic Buffer Length */ 877 975 { 0x0012C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , OA(SD5LVI) }, /* OSD5 Last Valid Index */ 878 976 { 0x0012E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , OA(SD5FIFOW) }, /* OSD5 FIFO Watermark */ … … 884 982 { 0x00140, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24 , hdaRegWriteSDCTL , OA(SD6CTL) }, /* Output Stream Descriptor 6 (OSD6) Control */ 885 983 { 0x00143, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8 , hdaRegWriteSDSTS , OA(SD6STS) }, /* OSD6 Status */ 886 { 0x00144, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegRead U32 , hdaRegWriteU32 , OA(SD6LPIB) }, /* OSD6 Link Position In Buffer*/887 { 0x00148, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWrite U32, OA(SD6CBL) }, /* OSD6 Cyclic Buffer Length */984 { 0x00144, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadLPIB , hdaRegWriteUnimpl , OA(SD6LPIB) }, /* OSD6 Link Position In Buffer (RO) */ 985 { 0x00148, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDCBL , OA(SD6CBL) }, /* OSD6 Cyclic Buffer Length */ 888 986 { 0x0014C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , OA(SD6LVI) }, /* OSD6 Last Valid Index */ 889 987 { 0x0014E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , OA(SD6FIFOW) }, /* OSD6 FIFO Watermark */ … … 895 993 { 0x00160, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24 , hdaRegWriteSDCTL , OA(SD7CTL) }, /* Output Stream Descriptor 7 (OSD7) Control */ 896 994 { 0x00163, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8 , hdaRegWriteSDSTS , OA(SD7STS) }, /* OSD7 Status */ 897 { 0x00164, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegRead U32 , hdaRegWriteU32 , OA(SD7LPIB) }, /* OSD7 Link Position In Buffer*/898 { 0x00168, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWrite U32, OA(SD7CBL) }, /* OSD7 Cyclic Buffer Length */995 { 0x00164, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadLPIB , hdaRegWriteUnimpl , OA(SD7LPIB) }, /* OSD7 Link Position In Buffer (RO) */ 996 { 0x00168, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDCBL , OA(SD7CBL) }, /* OSD7 Cyclic Buffer Length */ 899 997 { 0x0016C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , OA(SD7LVI) }, /* OSD7 Last Valid Index */ 900 998 { 0x0016E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , OA(SD7FIFOW) }, /* OSD7 FIFO Watermark */ … … 928 1026 929 1027 #ifdef IN_RING3 930 /** HDABDLEDESC field descriptors the v3+ saved state. */ 931 static SSMFIELD const g_aHdaBDLEDescFields[] = 932 { 933 SSMFIELD_ENTRY( HDABDLEDESC, u64BdleCviAddr), 934 SSMFIELD_ENTRY( HDABDLEDESC, u32BdleMaxCvi), 935 SSMFIELD_ENTRY( HDABDLEDESC, u32BdleCvi), 936 SSMFIELD_ENTRY( HDABDLEDESC, u32BdleCviLen), 937 SSMFIELD_ENTRY( HDABDLEDESC, u32BdleCviPos), 938 SSMFIELD_ENTRY( HDABDLEDESC, fBdleCviIoc), 939 SSMFIELD_ENTRY( HDABDLEDESC, cbUnderFifoW), 940 SSMFIELD_ENTRY( HDABDLEDESC, au8HdaBuffer), 1028 /** HDABDLESTATE field descriptors for the v5+ saved state. */ 1029 static SSMFIELD const g_aSSMBDLEStateFields5[] = 1030 { 1031 SSMFIELD_ENTRY(HDABDLESTATE, u32BDLIndex), 1032 SSMFIELD_ENTRY(HDABDLESTATE, cbBelowFIFOW), 1033 SSMFIELD_ENTRY(HDABDLESTATE, au8FIFO), 1034 SSMFIELD_ENTRY(HDABDLESTATE, u32BufOff), 941 1035 SSMFIELD_ENTRY_TERM() 942 1036 }; 943 1037 944 /** HDABDLEDESC field descriptors the v1 and v2 saved state. */ 945 static SSMFIELD const g_aHdaBDLEDescFieldsOld[] = 946 { 947 SSMFIELD_ENTRY( HDABDLEDESC, u64BdleCviAddr), 948 SSMFIELD_ENTRY( HDABDLEDESC, u32BdleMaxCvi), 949 SSMFIELD_ENTRY( HDABDLEDESC, u32BdleCvi), 950 SSMFIELD_ENTRY( HDABDLEDESC, u32BdleCviLen), 951 SSMFIELD_ENTRY( HDABDLEDESC, u32BdleCviPos), 952 SSMFIELD_ENTRY( HDABDLEDESC, fBdleCviIoc), 953 SSMFIELD_ENTRY_PAD_HC_AUTO(3, 3), 954 SSMFIELD_ENTRY( HDABDLEDESC, cbUnderFifoW), 955 SSMFIELD_ENTRY( HDABDLEDESC, au8HdaBuffer), 1038 /** HDASTREAMSTATE field descriptors for the v5+ saved state. */ 1039 static SSMFIELD const g_aSSMStreamStateFields5[] = 1040 { 1041 SSMFIELD_ENTRY (HDASTREAMSTATE, cBDLE), 1042 SSMFIELD_ENTRY (HDASTREAMSTATE, uCurBDLE), 1043 SSMFIELD_ENTRY_IGNORE(HDASTREAMSTATE, paBDLE), 956 1044 SSMFIELD_ENTRY_TERM() 957 1045 }; … … 961 1049 * 32-bit size indexed masks, i.e. g_afMasks[2 bytes] = 0xffff. 962 1050 */ 963 static uint32_t const 1051 static uint32_t const g_afMasks[5] = 964 1052 { 965 1053 UINT32_C(0), UINT32_C(0x000000ff), UINT32_C(0x0000ffff), UINT32_C(0x00ffffff), UINT32_C(0xffffffff) … … 967 1055 968 1056 #ifdef IN_RING3 969 DECLINLINE(void) hdaUpdatePosBuf(PHDASTATE pThis, PHDASTREAMTRANSFERDESC pStreamDesc) 970 { 1057 DECLINLINE(void) hdaStreamUpdateLPIB(PHDASTATE pThis, PHDASTREAM pStrmSt, uint32_t u32LPIB) 1058 { 1059 AssertPtrReturnVoid(pThis); 1060 AssertPtrReturnVoid(pStrmSt); 1061 1062 Assert(u32LPIB <= pStrmSt->u32CBL); 1063 1064 LogFlowFunc(("uStrm=%RU8, LPIB=%RU32 (DMA Position: %RTbool)\n", 1065 pStrmSt->u8Strm, u32LPIB, RT_BOOL(pThis->u64DPBase & DPBASE_ENABLED))); 1066 1067 /* Update LPIB in any case. */ 1068 HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm) = u32LPIB; 1069 1070 /* Do we need to tell the current DMA position? */ 971 1071 if (pThis->u64DPBase & DPBASE_ENABLED) 972 PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns), 973 (pThis->u64DPBase & DPBASE_ADDR_MASK) + pStreamDesc->u8Strm * 8, 974 pStreamDesc->pu32Lpib, sizeof(uint32_t)); 1072 { 1073 int rc2 = PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns), 1074 (pThis->u64DPBase & DPBASE_ADDR_MASK) + (pStrmSt->u8Strm * 8), 1075 (void *)&u32LPIB, sizeof(uint32_t)); 1076 AssertRC(rc2); 1077 } 975 1078 } 976 1079 #endif 977 1080 978 DECLINLINE(uint32_t) hdaFifoWToSz(PHDASTATE pThis, PHDASTREAMTRANSFERDESC pStreamDesc) 979 { 980 #if 0 981 switch(HDA_STREAM_REG(pThis, FIFOW, pStreamDesc->u8Strm)) 982 { 983 case HDA_SDFIFOW_8B: return 8; 984 case HDA_SDFIFOW_16B: return 16; 985 case HDA_SDFIFOW_32B: return 32; 1081 /** 1082 * Retrieves the number of bytes of a FIFOS register. 1083 * 1084 * @return Number of bytes of a given FIFOS register. 1085 */ 1086 DECLINLINE(uint16_t) hdaSDFIFOSToBytes(uint32_t u32RegFIFOS) 1087 { 1088 uint16_t cb; 1089 switch (u32RegFIFOS) 1090 { 1091 /* Input */ 1092 case HDA_SDINFIFO_120B: cb = 120; break; 1093 case HDA_SDINFIFO_160B: cb = 160; break; 1094 1095 /* Output */ 1096 case HDA_SDONFIFO_16B: cb = 16; break; 1097 case HDA_SDONFIFO_32B: cb = 32; break; 1098 case HDA_SDONFIFO_64B: cb = 64; break; 1099 case HDA_SDONFIFO_128B: cb = 128; break; 1100 case HDA_SDONFIFO_192B: cb = 192; break; 1101 case HDA_SDONFIFO_256B: cb = 256; break; 986 1102 default: 987 AssertMsgFailed(("unsupported value (%x) in SDFIFOW(,%d)\n", HDA_REG_IND(pThis, pStreamDesc->u8Strm), pStreamDesc->u8Strm)); 988 } 1103 { 1104 cb = 0; 1105 AssertMsgFailed(("Wrong FIFO value\n")); 1106 break; 1107 } 1108 } 1109 1110 return cb; 1111 } 1112 1113 /** 1114 * Retrieves the number of bytes of a FIFOW register. 1115 * 1116 * @return Number of bytes of a given FIFOW register. 1117 */ 1118 DECLINLINE(uint8_t) hdaSDFIFOWToBytes(uint32_t u32RegFIFOW) 1119 { 1120 uint32_t cb; 1121 switch (u32RegFIFOW) 1122 { 1123 case HDA_SDFIFOW_8B: cb = 8; break; 1124 case HDA_SDFIFOW_16B: cb = 16; break; 1125 case HDA_SDFIFOW_32B: cb = 32; break; 1126 default: cb = 0; break; 1127 } 1128 1129 #ifdef RT_STRICT 1130 Assert(RT_IS_POWER_OF_TWO(cb)); 989 1131 #endif 1132 return cb; 1133 } 1134 1135 #ifdef IN_RING3 1136 /** 1137 * Returns the current BDLE to use for a stream. 1138 * 1139 * @return BDLE to use, NULL if none found. 1140 */ 1141 DECLINLINE(PHDABDLE) hdaStreamGetCurrentBDLE(PHDASTATE pThis, PHDASTREAM pStrmSt) 1142 { 1143 AssertPtrReturn(pThis, NULL); 1144 AssertPtrReturn(pStrmSt, NULL); 1145 1146 Assert(pStrmSt->State.paBDLE); 1147 Assert(pStrmSt->State.uCurBDLE < pStrmSt->State.cBDLE); 1148 1149 PHDABDLE pBDLE = &pStrmSt->State.paBDLE[pStrmSt->State.uCurBDLE]; 1150 return pBDLE; 1151 } 1152 1153 /** 1154 * Returns the next BDLE to use for a stream. 1155 * 1156 * @return BDLE to use next, NULL if none found. 1157 */ 1158 DECLINLINE(PHDABDLE) hdaStreamGetNextBDLE(PHDASTATE pThis, PHDASTREAM pStrmSt) 1159 { 1160 AssertPtrReturn(pThis, NULL); 1161 AssertPtrReturn(pStrmSt, NULL); 1162 1163 NOREF(pThis); 1164 1165 Assert(pStrmSt->State.paBDLE); 1166 Assert(pStrmSt->State.uCurBDLE < pStrmSt->State.cBDLE); 1167 1168 #ifdef DEBUG 1169 uint32_t uOldBDLE = pStrmSt->State.uCurBDLE; 1170 #endif 1171 1172 pStrmSt->State.uCurBDLE++; 1173 if (pStrmSt->State.uCurBDLE == pStrmSt->State.cBDLE) 1174 { 1175 pStrmSt->State.uCurBDLE = 0; 1176 1177 hdaStreamUpdateLPIB(pThis, pStrmSt, 0); 1178 } 1179 1180 Assert(pStrmSt->State.uCurBDLE < pStrmSt->State.cBDLE); 1181 1182 PHDABDLE pBDLE = &pStrmSt->State.paBDLE[pStrmSt->State.uCurBDLE]; 1183 AssertPtr(pBDLE); 1184 1185 hdaBDLEReset(pBDLE); 1186 1187 #ifdef DEBUG 1188 LogFlowFunc(("uOldBDLE=%RU16, uCurBDLE=%RU16 %R[bdle]\n", uOldBDLE, pStrmSt->State.uCurBDLE, pBDLE)); 1189 #endif 1190 return pBDLE; 1191 } 1192 #endif 1193 1194 /** 1195 * Retrieves the minimum number of bytes accumulated/free in the 1196 * FIFO before the controller will start a fetch/eviction of data. 1197 * 1198 * Uses SDFIFOW (FIFO Watermark Register). 1199 * 1200 * @return Number of bytes accumulated/free in the FIFO. 1201 */ 1202 DECLINLINE(uint8_t) hdaStreamGetFIFOW(PHDASTATE pThis, PHDASTREAM pStrmSt) 1203 { 1204 AssertPtrReturn(pThis, 0); 1205 AssertPtrReturn(pStrmSt, 0); 1206 1207 #ifdef VBOX_HDA_WITH_FIFO 1208 return hdaSDFIFOWToBytes(HDA_STREAM_REG(pThis, FIFOW, pStrmSt->u8Strm)); 1209 #else 990 1210 return 0; 1211 #endif 991 1212 } 992 1213 … … 996 1217 ( INTCTL_SX((pThis), num) \ 997 1218 && (SDSTS(pThis, num) & HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS))) 1219 998 1220 bool fIrq = false; 999 if ( HDA_REG_FLAG_VALUE(pThis, INTCTL, CIE) 1221 1222 if (/* Controller Interrupt Enable (CIE). */ 1223 HDA_REG_FLAG_VALUE(pThis, INTCTL, CIE) 1000 1224 && ( HDA_REG_FLAG_VALUE(pThis, RIRBSTS, RINTFL) 1001 1225 || HDA_REG_FLAG_VALUE(pThis, RIRBSTS, RIRBOIS) … … 1003 1227 fIrq = true; 1004 1228 1229 /** @todo Don't hardcode stream numbers here. */ 1005 1230 if ( IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 0) 1006 1231 || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 4)) 1232 { 1233 #ifdef IN_RING3 1234 LogFunc(("BCIS\n")); 1235 #endif 1007 1236 fIrq = true; 1237 } 1008 1238 1009 1239 if (HDA_REG_FLAG_VALUE(pThis, INTCTL, GIE)) 1010 1240 { 1011 LogFunc((" irq %s\n", fIrq ? "asserted" : "deasserted"));1241 LogFunc(("%s\n", fIrq ? "Asserted" : "Deasserted")); 1012 1242 PDMDevHlpPCISetIrq(pThis->CTX_SUFF(pDevIns), 0 , fIrq); 1013 1243 } 1244 1245 #undef IS_INTERRUPT_OCCURED_AND_ENABLED 1246 1014 1247 return VINF_SUCCESS; 1015 1248 } … … 1092 1325 1093 1326 /* 1094 * Binary search the 1327 * Binary search the register map. 1095 1328 */ 1096 1329 int idxEnd = RT_ELEMENTS(g_aHdaRegMap); … … 1136 1369 do 1137 1370 { 1138 LogFunc((" corb%02x: ", i));1371 LogFunc(("CORB%02x: ", i)); 1139 1372 uint8_t j = 0; 1140 1373 do 1141 1374 { 1142 const char *p refix;1375 const char *pszPrefix; 1143 1376 if ((i + j) == HDA_REG(pThis, CORBRP)); 1144 p refix = "[R]";1377 pszPrefix = "[R]"; 1145 1378 else if ((i + j) == HDA_REG(pThis, CORBWP)); 1146 p refix = "[W]";1379 pszPrefix = "[W]"; 1147 1380 else 1148 p refix = " "; /* three spaces */1149 LogFunc(("%s%08x", p refix, pThis->pu32CorbBuf[i + j]));1381 pszPrefix = " "; /* three spaces */ 1382 LogFunc(("%s%08x", pszPrefix, pThis->pu32CorbBuf[i + j])); 1150 1383 j++; 1151 1384 } while (j < 8); … … 1164 1397 uint8_t i = 0; 1165 1398 do { 1166 LogFunc((" rirb%02x: ", i));1399 LogFunc(("RIRB%02x: ", i)); 1167 1400 uint8_t j = 0; 1168 1401 do { … … 1184 1417 static int hdaCORBCmdProcess(PHDASTATE pThis) 1185 1418 { 1186 int rc;1187 uint8_t corbRp;1188 uint8_t corbWp;1189 uint8_t rirbWp;1190 1191 1419 PFNHDACODECVERBPROCESSOR pfn = (PFNHDACODECVERBPROCESSOR)NULL; 1192 1420 1193 rc = hdaCmdSync(pThis, true);1421 int rc = hdaCmdSync(pThis, true); 1194 1422 if (RT_FAILURE(rc)) 1195 1423 AssertRCReturn(rc, rc); 1196 corbRp = HDA_REG(pThis, CORBRP); 1197 corbWp = HDA_REG(pThis, CORBWP); 1198 rirbWp = HDA_REG(pThis, RIRBWP); 1424 1425 uint8_t corbRp = HDA_REG(pThis, CORBRP); 1426 uint8_t corbWp = HDA_REG(pThis, CORBWP); 1427 uint8_t rirbWp = HDA_REG(pThis, RIRBWP); 1428 1199 1429 Assert((corbWp != corbRp)); 1200 LogFlowFunc(("CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP), 1201 HDA_REG(pThis, CORBWP), HDA_REG(pThis, RIRBWP))); 1430 LogFlowFunc(("CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP), HDA_REG(pThis, CORBWP), HDA_REG(pThis, RIRBWP))); 1431 1202 1432 while (corbRp != corbWp) 1203 1433 { … … 1208 1438 cmd = pThis->pu32CorbBuf[corbRp]; 1209 1439 1210 rc = pThis->pCodec->pfnLookup(pThis->pCodec, 1211 HDA_CODEC_CMD(cmd, 0 /* Codec index */), 1212 &pfn); 1440 rc = pThis->pCodec->pfnLookup(pThis->pCodec, HDA_CODEC_CMD(cmd, 0 /* Codec index */), &pfn); 1213 1441 if (RT_SUCCESS(rc)) 1214 1442 { 1215 rc = pfn(pThis->pCodec,1216 1443 AssertPtr(pfn); 1444 rc = pfn(pThis->pCodec, HDA_CODEC_CMD(cmd, 0 /* LUN */), &resp); 1217 1445 } 1218 1446 1219 1447 if (RT_FAILURE(rc)) 1220 1448 AssertRCReturn(rc, rc); 1221 Assert(pfn);1222 1449 (rirbWp)++; 1223 1450 … … 1230 1457 return rc; 1231 1458 } 1459 1232 1460 pThis->pu64RirbBuf[rirbWp] = resp; 1233 pThis->u8Counter++; 1234 if (pThis->u8Counter == RINTCNT_N(pThis)) 1461 1462 pThis->u8RespIntCnt++; 1463 if (pThis->u8RespIntCnt == RINTCNT_N(pThis)) 1235 1464 break; 1236 1465 } … … 1243 1472 { 1244 1473 HDA_REG(pThis, RIRBSTS) |= HDA_REG_FIELD_FLAG_MASK(RIRBSTS,RINTFL); 1245 pThis->u8Counter = 0; 1474 1475 pThis->u8RespIntCnt = 0; 1246 1476 rc = hdaProcessInterrupt(pThis); 1247 1477 } … … 1250 1480 return rc; 1251 1481 } 1482 1483 static int hdaStreamInit(PHDASTATE pThis, PHDASTREAM pStrmSt, uint8_t u8Strm) 1484 { 1485 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1486 AssertPtrReturn(pStrmSt, VERR_INVALID_POINTER); 1487 1488 pStrmSt->u8Strm = u8Strm; 1489 pStrmSt->u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, u8Strm), 1490 HDA_STREAM_REG(pThis, BDPU, u8Strm)); 1491 pStrmSt->u16LVI = HDA_STREAM_REG(pThis, LVI, u8Strm); 1492 pStrmSt->u32CBL = HDA_STREAM_REG(pThis, CBL, u8Strm); 1493 pStrmSt->u16FIFOS = hdaSDFIFOSToBytes(HDA_STREAM_REG(pThis, FIFOS, u8Strm)); 1494 1495 hdaStreamDestroy(pStrmSt); 1496 1497 int rc = VINF_SUCCESS; 1498 1499 if (pStrmSt->u16LVI) /* Any BDLEs to fetch? */ 1500 { 1501 uint32_t cbBDLE = 0; 1502 1503 pStrmSt->State.cBDLE = pStrmSt->u16LVI + 1; /* See 18.2.37: If LVI is n, then there are n + 1 entries. */ 1504 pStrmSt->State.paBDLE = (PHDABDLE)RTMemAllocZ(sizeof(HDABDLE) * pStrmSt->State.cBDLE); 1505 if (pStrmSt->State.paBDLE) 1506 { 1507 for (uint16_t i = 0; i < pStrmSt->State.cBDLE; i++) 1508 { 1509 rc = hdaBDLEFetch(pThis, &pStrmSt->State.paBDLE[i], pStrmSt->u64BaseDMA, i); 1510 if (RT_FAILURE(rc)) 1511 break; 1512 1513 cbBDLE += pStrmSt->State.paBDLE[i].u32BufSize; 1514 } 1515 1516 #ifdef DEBUG 1517 hdaBDLEDumpAll(pThis, pStrmSt->u64BaseDMA, pStrmSt->State.cBDLE); 1252 1518 #endif 1253 1254 static void hdaStreamReset(PHDASTATE pThis, PHDABDLEDESC pBdle, PHDASTREAMTRANSFERDESC pStreamDesc, uint8_t u8Strm) 1255 { 1256 LogFunc(("reset of stream (%d) started\n", u8Strm)); 1257 Assert(( pThis 1258 && pBdle 1259 && pStreamDesc 1260 && u8Strm <= 7)); 1261 RT_BZERO(pBdle, sizeof(HDABDLEDESC)); 1262 *pStreamDesc->pu32Lpib = 0; 1263 *pStreamDesc->pu32Sts = 0; 1519 if (RT_SUCCESS(rc)) 1520 { 1521 if (pStrmSt->u32CBL != cbBDLE) 1522 LogRel(("HDA: Warning: CBL (%RU32) does not match BDL entries (%RU32); expect sound hickups\n", 1523 pStrmSt->u32CBL, cbBDLE)); 1524 1525 HDA_STREAM_REG(pThis, STS, pStrmSt->u8Strm) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS); 1526 } 1527 } 1528 else 1529 rc = VERR_NO_MEMORY; 1530 } 1531 1532 LogFunc(("[SD%RU8]: DMA=0x%x, LVI=%RU16, CBL=%RU32, FIFOS=%RU16\n", 1533 u8Strm, pStrmSt->u64BaseDMA, pStrmSt->u16LVI, pStrmSt->u32CBL, pStrmSt->u16FIFOS)); 1534 1535 return rc; 1536 } 1537 1538 static void hdaStreamDestroy(PHDASTREAM pStrmSt) 1539 { 1540 AssertPtrReturnVoid(pStrmSt); 1541 1542 if (pStrmSt->State.paBDLE) 1543 { 1544 Assert(pStrmSt->State.cBDLE); 1545 RTMemFree(pStrmSt->State.paBDLE); 1546 pStrmSt->State.paBDLE = NULL; 1547 } 1548 1549 pStrmSt->State.cBDLE = 0; 1550 } 1551 #endif 1552 1553 static void hdaStreamReset(PHDASTATE pThis, PHDASTREAM pStrmSt, uint8_t u8Strm) 1554 { 1555 AssertPtrReturnVoid(pThis); 1556 AssertPtrReturnVoid(pStrmSt); 1557 AssertReturnVoid(u8Strm <= 7); /** @todo Use a define for MAX_STRAEMS! */ 1558 1559 /* 1560 * Initialize stream state. 1561 */ 1562 RT_BZERO(pStrmSt, sizeof(HDASTREAM)); 1563 1564 /* 1565 * Initialize registers. 1566 */ 1567 HDA_STREAM_REG(pThis, STS, u8Strm) = 0; 1264 1568 /* According to the ICH6 datasheet, 0x40000 is the default value for stream descriptor register 23:20 1265 * bits are reserved for stream number 18.2.33, resets SDnCTL except SRCT bit */ 1266 HDA_STREAM_REG(pThis, CTL, u8Strm) = 0x40000 | (HDA_STREAM_REG(pThis, CTL, u8Strm) & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST)); 1267 1268 /* ICH6 defines default values (0x77 for input and 0xBF for output descriptors) of FIFO size. 18.2.39 */ 1269 HDA_STREAM_REG(pThis, FIFOS, u8Strm) = u8Strm < 4 ? HDA_SDINFIFO_120B : HDA_SDONFIFO_192B; 1270 HDA_STREAM_REG(pThis, FIFOW, u8Strm) = u8Strm < 4 ? HDA_SDFIFOW_8B : HDA_SDFIFOW_32B; 1271 HDA_STREAM_REG(pThis, CBL, u8Strm) = 0; 1272 HDA_STREAM_REG(pThis, LVI, u8Strm) = 0; 1273 HDA_STREAM_REG(pThis, FMT, u8Strm) = 0; 1274 HDA_STREAM_REG(pThis, BDPU, u8Strm) = 0; 1275 HDA_STREAM_REG(pThis, BDPL, u8Strm) = 0; 1276 LogFunc(("reset of stream (%d) finished\n", u8Strm)); 1569 * bits are reserved for stream number 18.2.33, resets SDnCTL except SRST bit. */ 1570 HDA_STREAM_REG(pThis, CTL, u8Strm) = 0x40000 | (HDA_STREAM_REG(pThis, CTL, u8Strm) & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST)); 1571 1572 /* ICH6 defines default values (0x77 for input and 0xBF for output descriptors) of FIFO size. 18.2.39. */ 1573 HDA_STREAM_REG(pThis, FIFOS, u8Strm) = u8Strm < 4 ? HDA_SDINFIFO_120B : HDA_SDONFIFO_192B; 1574 /* See 18.2.38: Always defaults to 0x4 (32 bytes). */ 1575 HDA_STREAM_REG(pThis, FIFOW, u8Strm) = HDA_SDFIFOW_32B; 1576 HDA_STREAM_REG(pThis, LPIB, u8Strm) = 0; 1577 HDA_STREAM_REG(pThis, CBL, u8Strm) = 0; 1578 HDA_STREAM_REG(pThis, LVI, u8Strm) = 0; 1579 HDA_STREAM_REG(pThis, FMT, u8Strm) = 0; 1580 HDA_STREAM_REG(pThis, BDPU, u8Strm) = 0; 1581 HDA_STREAM_REG(pThis, BDPL, u8Strm) = 0; 1582 1583 LogFunc(("[SD%RU8] Reset\n", u8Strm)); 1277 1584 } 1278 1585 … … 1332 1639 static int hdaRegReadU32(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value) 1333 1640 { 1334 uint32_t 1641 uint32_t iRegMem = g_aHdaRegMap[iReg].mem_idx; 1335 1642 1336 1643 *pu32Value = pThis->au32Regs[iRegMem] & g_aHdaRegMap[iReg].readable; … … 1340 1647 static int hdaRegWriteU32(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1341 1648 { 1342 uint32_t 1649 uint32_t iRegMem = g_aHdaRegMap[iReg].mem_idx; 1343 1650 1344 1651 pThis->au32Regs[iRegMem] = (u32Value & g_aHdaRegMap[iReg].writable) … … 1351 1658 if (u32Value & HDA_REG_FIELD_FLAG_MASK(GCTL, RST)) 1352 1659 { 1353 /* exit reset state*/1660 /* Exit reset state. */ 1354 1661 HDA_REG(pThis, GCTL) |= HDA_REG_FIELD_FLAG_MASK(GCTL, RST); 1355 1662 pThis->fInReset = false; … … 1358 1665 { 1359 1666 #ifdef IN_RING3 1360 /* enter reset state*/1667 /* Enter reset state. */ 1361 1668 if ( HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA) 1362 1669 || HDA_REG_FLAG_VALUE(pThis, RIRBCTL, DMA)) 1363 1670 { 1364 1671 LogFunc(("HDA enters in reset with DMA(RIRB:%s, CORB:%s)\n", 1365 HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA) ? "on" : "off",1366 HDA_REG_FLAG_VALUE(pThis, RIRBCTL, DMA) ? "on" : "off"));1672 HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA) ? "on" : "off", 1673 HDA_REG_FLAG_VALUE(pThis, RIRBCTL, DMA) ? "on" : "off")); 1367 1674 } 1368 1675 hdaReset(pThis->CTX_SUFF(pDevIns)); … … 1375 1682 if (u32Value & HDA_REG_FIELD_FLAG_MASK(GCTL, FSH)) 1376 1683 { 1377 /* Flush: GSTS:1 set, see 6.2.6*/1378 HDA_REG(pThis, GSTS) |= HDA_REG_FIELD_FLAG_MASK(GSTS, FSH); /* set the flush state*/1379 /* DPLBASE and DPUBASE should be initialized with initial value (see 6.2.6) */1684 /* Flush: GSTS:1 set, see 6.2.6. */ 1685 HDA_REG(pThis, GSTS) |= HDA_REG_FIELD_FLAG_MASK(GSTS, FSH); /* Set the flush state. */ 1686 /* DPLBASE and DPUBASE should be initialized with initial value (see 6.2.6). */ 1380 1687 } 1381 1688 return VINF_SUCCESS; … … 1399 1706 || HDA_REG_FLAG_VALUE(pThis, CORBSTS, CMEI) 1400 1707 || HDA_REG(pThis, STATESTS)) 1401 v |= RT_BIT(30); 1402 #define HDA_IS_STREAM_EVENT(pThis, stream) \ 1403 ( (SDSTS((pThis),stream) & HDA_REG_FIELD_FLAG_MASK(SDSTS, DE)) \ 1404 || (SDSTS((pThis),stream) & HDA_REG_FIELD_FLAG_MASK(SDSTS, FE)) \ 1405 || (SDSTS((pThis),stream) & HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS))) 1406 #define MARK_STREAM(pThis, stream, v) do { (v) |= HDA_IS_STREAM_EVENT((pThis),stream) ? RT_BIT((stream)) : 0; } while(0) 1407 MARK_STREAM(pThis, 0, v); 1408 MARK_STREAM(pThis, 1, v); 1409 MARK_STREAM(pThis, 2, v); 1410 MARK_STREAM(pThis, 3, v); 1411 MARK_STREAM(pThis, 4, v); 1412 MARK_STREAM(pThis, 5, v); 1413 MARK_STREAM(pThis, 6, v); 1414 MARK_STREAM(pThis, 7, v); 1708 { 1709 v |= RT_BIT(30); /* Touch CIS. */ 1710 } 1711 1712 #define HDA_IS_STREAM_EVENT(pThis, num) \ 1713 ( (SDSTS((pThis), num) & HDA_REG_FIELD_FLAG_MASK(SDSTS, DE)) \ 1714 || (SDSTS((pThis), num) & HDA_REG_FIELD_FLAG_MASK(SDSTS, FE)) \ 1715 || (SDSTS((pThis), num) & HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS))) 1716 1717 #define HDA_MARK_STREAM(pThis, num, v) \ 1718 do { (v) |= HDA_IS_STREAM_EVENT((pThis), num) ? RT_BIT((num)) : 0; } while(0) 1719 1720 HDA_MARK_STREAM(pThis, 0, v); 1721 HDA_MARK_STREAM(pThis, 1, v); 1722 HDA_MARK_STREAM(pThis, 2, v); 1723 HDA_MARK_STREAM(pThis, 3, v); 1724 HDA_MARK_STREAM(pThis, 4, v); 1725 HDA_MARK_STREAM(pThis, 5, v); 1726 HDA_MARK_STREAM(pThis, 6, v); 1727 HDA_MARK_STREAM(pThis, 7, v); 1728 1729 #undef HDA_IS_STREAM_EVENT 1730 #undef HDA_MARK_STREAM 1731 1415 1732 v |= v ? RT_BIT(31) : 0; 1733 1416 1734 *pu32Value = v; 1735 return VINF_SUCCESS; 1736 } 1737 1738 static int hdaRegReadLPIB(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value) 1739 { 1740 const uint8_t u8Strm = HDA_SD_NUM_FROM_REG(pThis, LPIB, iReg); 1741 uint32_t u32LPIB = HDA_STREAM_REG(pThis, LPIB, u8Strm); 1742 const uint32_t u32CBL = HDA_STREAM_REG(pThis, CBL, u8Strm); 1743 1744 LogFlowFunc(("[SD%RU8]: LPIB=%RU32, CBL=%RU32\n", u8Strm, u32LPIB, u32CBL)); 1745 1746 *pu32Value = u32LPIB; 1417 1747 return VINF_SUCCESS; 1418 1748 } … … 1429 1759 { 1430 1760 if (u32Value & HDA_REG_FIELD_FLAG_MASK(CORBRP, RST)) 1761 { 1431 1762 HDA_REG(pThis, CORBRP) = 0; 1763 } 1432 1764 #ifndef BIRD_THINKS_CORBRP_IS_MOSTLY_RO 1433 1765 else … … 1442 1774 int rc = hdaRegWriteU8(pThis, iReg, u32Value); 1443 1775 AssertRC(rc); 1444 if ( HDA_REG(pThis, CORBWP) != HDA_REG(pThis, CORBRP)1776 if ( HDA_REG(pThis, CORBWP) != HDA_REG(pThis, CORBRP) 1445 1777 && HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA) != 0) 1778 { 1446 1779 return hdaCORBCmdProcess(pThis); 1780 } 1447 1781 return rc; 1448 1782 #else … … 1476 1810 } 1477 1811 1812 static int hdaRegWriteSDCBL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1813 { 1814 const uint8_t u8Strm = HDA_SD_NUM_FROM_REG(pThis, CBL, iReg); 1815 uint32_t u32LPIB = HDA_STREAM_REG(pThis, LPIB, u8Strm); 1816 1817 LogFlowFunc(("[SD%RU8]: LPIB=%RU32, CBL=%RU32\n", u8Strm, u32LPIB, u32Value)); 1818 1819 return hdaRegWriteU32(pThis, iReg, u32Value); 1820 } 1821 1478 1822 static int hdaRegWriteSDCTL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1479 1823 { 1480 bool fRun = RT_BOOL(u32Value & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 1481 bool fInRun = RT_BOOL(HDA_REG_IND(pThis, iReg) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 1482 bool fReset = RT_BOOL(u32Value & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST)); 1483 bool fInReset = RT_BOOL(HDA_REG_IND(pThis, iReg) & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST)); 1824 bool fRun = RT_BOOL(u32Value & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 1825 bool fInRun = RT_BOOL(HDA_REG_IND(pThis, iReg) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 1826 bool fReset = RT_BOOL(u32Value & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST)); 1827 bool fInReset = RT_BOOL(HDA_REG_IND(pThis, iReg) & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST)); 1828 1829 uint8_t u8Strm = HDA_SD_NUM_FROM_REG(pThis, CTL, iReg); 1830 1831 PHDASTREAM pStrmSt; 1832 switch (u8Strm) 1833 { 1834 case 0: /** @todo Use dynamic indices, based on stream assignment. */ 1835 { 1836 pStrmSt = &pThis->StrmStLineIn; 1837 break; 1838 } 1839 # ifdef VBOX_WITH_HDA_MIC_IN 1840 case 2: /** @todo Use dynamic indices, based on stream assignment. */ 1841 { 1842 pStrmSt = &pThis->StrmStMicIn; 1843 break; 1844 } 1845 # endif 1846 case 4: /** @todo Use dynamic indices, based on stream assignment. */ 1847 { 1848 pStrmSt = &pThis->StrmStOut; 1849 break; 1850 } 1851 1852 default: 1853 { 1854 LogFunc(("Warning: Changing SDCTL on non-attached stream (iReg=0x%x)\n", iReg)); 1855 return hdaRegWriteU24(pThis, iReg, u32Value); /* Write 3 bytes. */ 1856 } 1857 } 1858 1859 LogFunc(("[SD%RU8]: %R[sdctl]\n", u8Strm, u32Value)); 1484 1860 1485 1861 if (fInReset) 1486 1862 { 1487 /* 1488 * Assert!!! Guest is resetting HDA's stream, we're expecting guest will mark stream as exit 1489 * from reset 1490 */ 1491 Assert((!fReset)); 1492 LogFunc(("guest initiated exit of stream reset.\n")); 1863 /* Guest is resetting HDA's stream, we're expecting guest will mark stream as exit. */ 1864 Assert(!fReset); 1865 LogFunc(("Guest initiated exit of stream reset\n")); 1493 1866 } 1494 1867 else if (fReset) 1495 1868 { 1496 1869 #ifdef IN_RING3 1497 /* 1498 * Assert!!! ICH6 datasheet 18.2.33 says that RUN bit should be cleared before initiation of reset. 1499 */ 1500 uint8_t u8Strm = 0; 1501 PHDABDLEDESC pBdle = NULL; 1502 HDASTREAMTRANSFERDESC StreamDesc; 1503 Assert((!fInRun && !fRun)); 1504 switch (iReg) 1505 { 1506 case HDA_REG_SD0CTL: 1507 u8Strm = 0; 1508 pBdle = &pThis->StInBdle; 1509 break; 1510 #ifdef VBOX_WITH_HDA_MIC_IN 1511 case HDA_REG_SD2CTL: 1512 u8Strm = 2; 1513 pBdle = &pThis->StMicBdle; 1514 break; 1515 #endif 1516 case HDA_REG_SD4CTL: 1517 u8Strm = 4; 1518 pBdle = &pThis->StOutBdle; 1519 break; 1520 default: 1521 LogFunc(("changing SRST bit on non-attached stream\n")); 1522 return hdaRegWriteU24(pThis, iReg, u32Value); 1523 } 1524 LogFunc(("guest initiated enter to stream reset.\n")); 1525 hdaInitTransferDescriptor(pThis, pBdle, u8Strm, &StreamDesc); 1526 hdaStreamReset(pThis, pBdle, &StreamDesc, u8Strm); 1870 /* ICH6 datasheet 18.2.33 says that RUN bit should be cleared before initiation of reset. */ 1871 Assert(!fInRun && !fRun); 1872 1873 LogFunc(("Guest initiated enter to stream reset\n")); 1874 hdaStreamReset(pThis, pStrmSt, u8Strm); 1527 1875 #else 1528 1876 return VINF_IOM_R3_MMIO_WRITE; … … 1532 1880 { 1533 1881 #ifdef IN_RING3 1534 /* we enter here to change DMA states only */ 1535 if ( (fInRun && !fRun) 1536 || (fRun && !fInRun)) 1537 { 1538 Assert((!fReset && !fInReset)); 1882 /* 1883 * We enter here to change DMA states only. 1884 */ 1885 if (fInRun != fRun) 1886 { 1887 Assert(!fReset && !fInReset); 1539 1888 1540 1889 PHDADRIVER pDrv; 1541 switch ( iReg)1890 switch (u8Strm) 1542 1891 { 1543 case HDA_REG_SD0CTL:1892 case 0: /** @todo Use a variable here. Later. */ 1544 1893 { 1545 1894 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) … … 1549 1898 } 1550 1899 # ifdef VBOX_WITH_HDA_MIC_IN 1551 case HDA_REG_SD2CTL:1900 case 2: /** @todo Use a variable here. Later. */ 1552 1901 { 1553 1902 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) … … 1557 1906 } 1558 1907 # endif 1559 case HDA_REG_SD4CTL:1908 case 4: /** @todo Use a variable here. Later. */ 1560 1909 { 1561 1910 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) … … 1569 1918 } 1570 1919 } 1920 1921 if (pStrmSt) 1922 { 1923 int rc2 = hdaStreamInit(pThis, pStrmSt, u8Strm); 1924 AssertRC(rc2); 1925 } 1926 1571 1927 #else /* !IN_RING3 */ 1572 1928 return VINF_IOM_R3_MMIO_WRITE; … … 1588 1944 static int hdaRegWriteSDLVI(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1589 1945 { 1946 /* Only can be modified if RUN bit is 0. */ 1947 bool fIsRunning = RT_BOOL(HDA_REG_IND(pThis, iReg) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 1948 if (fIsRunning) 1949 { 1950 AssertMsgFailed(("Cannot write to register when RUN bit is set\n")); 1951 return VINF_SUCCESS; 1952 } 1953 1590 1954 int rc = hdaRegWriteU32(pThis, iReg, u32Value); 1591 1955 if (RT_FAILURE(rc)) … … 1606 1970 return hdaRegWriteU16(pThis, iReg, HDA_SDFIFOW_32B); 1607 1971 } 1608 return VINF_SUCCESS; 1972 return VINF_SUCCESS; /* Never reached. */ 1609 1973 } 1610 1974 1611 1975 /** 1612 1976 * @note This method could be called for changing value on Output Streams 1613 * only (ICH6 datasheet 18.2.39) 1977 * only (ICH6 datasheet 18.2.39). 1614 1978 */ 1615 1979 static int hdaRegWriteSDFIFOS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1616 1980 { 1981 /** @todo Only allow updating FIFOS if RUN bit is 0? */ 1982 uint32_t u32FIFOS = 0; 1983 1617 1984 switch (iReg) 1618 1985 { 1619 /* SDInFIFOS is RO, n=0-3 */1986 /* SDInFIFOS is RO, n=0-3. */ 1620 1987 case HDA_REG_SD0FIFOS: 1621 1988 case HDA_REG_SD1FIFOS: 1622 1989 case HDA_REG_SD2FIFOS: 1623 1990 case HDA_REG_SD3FIFOS: 1624 LogFunc(("Guest tries change value of FIFO size of input stream\n")); 1991 { 1992 LogFunc(("Guest tries to change R/O value of FIFO size of input stream, ignoring\n")); 1625 1993 break; 1994 } 1626 1995 case HDA_REG_SD4FIFOS: 1627 1996 case HDA_REG_SD5FIFOS: 1628 1997 case HDA_REG_SD6FIFOS: 1629 1998 case HDA_REG_SD7FIFOS: 1999 { 1630 2000 switch(u32Value) 1631 2001 { … … 1635 2005 case HDA_SDONFIFO_128B: 1636 2006 case HDA_SDONFIFO_192B: 1637 return hdaRegWriteU16(pThis, iReg, u32Value); 1638 1639 case HDA_SDONFIFO_256B: 2007 u32FIFOS = u32Value; 2008 break; 2009 2010 case HDA_SDONFIFO_256B: /** @todo r=andy Investigate this. */ 1640 2011 LogFunc(("256-bit is unsupported, HDA is switched into 192-bit mode\n")); 2012 /* Fall through is intentional. */ 1641 2013 default: 1642 return hdaRegWriteU16(pThis, iReg, HDA_SDONFIFO_192B); 2014 u32FIFOS = HDA_SDONFIFO_192B; 2015 break; 1643 2016 } 2017 1644 2018 break; 2019 } 1645 2020 default: 2021 { 1646 2022 AssertMsgFailed(("Something weird happened with register lookup routine\n")); 2023 break; 2024 } 2025 } 2026 2027 if (u32FIFOS) 2028 { 2029 LogFunc(("[SD%RU8]: Updating FIFOS to %RU32 bytes\n", 0, hdaSDFIFOSToBytes(u32FIFOS))); 2030 /** @todo Update internal stream state with new FIFOS. */ 2031 2032 return hdaRegWriteU16(pThis, iReg, u32FIFOS); 1647 2033 } 1648 2034 … … 1659 2045 int rc = VINF_SUCCESS; 1660 2046 1661 uint32_t u32Hz = (u32SdFmt & HDA_SDFMT_BASE_RATE_SHIFT) ? 44100 : 48000;2047 uint32_t u32Hz = (u32SdFmt & HDA_SDFMT_BASE_RATE_SHIFT) ? 44100 : 48000; 1662 2048 uint32_t u32HzMult = 1; 1663 uint32_t u32HzDiv = 1;2049 uint32_t u32HzDiv = 1; 1664 2050 1665 2051 switch (EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_MULT_MASK, HDA_SDFMT_MULT_SHIFT)) … … 1722 2108 if (RT_SUCCESS(rc)) 1723 2109 { 1724 pCfg->uHz = u32Hz * u32HzMult / u32HzDiv;1725 pCfg->cChannels = (u32SdFmt & 0xf) + 1;1726 pCfg->enmFormat = enmFmt;2110 pCfg->uHz = u32Hz * u32HzMult / u32HzDiv; 2111 pCfg->cChannels = (u32SdFmt & 0xf) + 1; 2112 pCfg->enmFormat = enmFmt; 1727 2113 pCfg->enmEndianness = PDMAUDIOHOSTENDIANNESS; 1728 2114 } … … 1730 2116 # undef EXTRACT_VALUE 1731 2117 2118 LogFlowFuncLeaveRC(rc); 1732 2119 return rc; 1733 2120 } … … 1921 2308 #ifdef IN_RING3 1922 2309 #ifdef LOG_ENABLED 1923 static void dump_bd(PHDASTATE pThis, PHDABDLEDESC pBdle, uint64_t u64BaseDMA) 1924 { 2310 static void hdaBDLEDumpAll(PHDASTATE pThis, uint64_t u64BaseDMA, uint16_t cBDLE) 2311 { 2312 uint32_t cbBDLE = 0; 2313 2314 for (uint16_t i = 0; i < cBDLE; i++) 2315 { 2316 uint8_t bdle[16]; /** @todo Use a define. */ 2317 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), u64BaseDMA + i * 16, bdle, 16); /** @todo Use a define. */ 2318 2319 uint64_t addr = *(uint64_t *)bdle; 2320 uint32_t len = *(uint32_t *)&bdle[8]; 2321 uint32_t ioc = *(uint32_t *)&bdle[12]; 2322 2323 LogFlowFunc(("#%03d BDLE(adr:0x%llx, size:%RU32, ioc:%RTbool)\n", 2324 i, addr, len, RT_BOOL(ioc & 0x1))); 2325 2326 cbBDLE += len; 2327 } 2328 2329 LogFlowFunc(("Total: %RU32 bytes\n", cbBDLE)); 2330 2331 if (!pThis->u64DPBase) /* No DMA base given? Bail out. */ 2332 return; 2333 2334 for (int i = 0; i < 8; i++) /** @todo Use a define. */ 2335 { 2336 uint32_t uDMACnt; 2337 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), (pThis->u64DPBase & DPBASE_ADDR_MASK) + i * 8, /** @todo Use a define. */ 2338 &uDMACnt, sizeof(&uDMACnt)); 2339 2340 LogFlowFunc(("%s #%02d STREAM(0x%x)\n", 2341 i == HDA_SDCTL_NUM(pThis, 4) || i == HDA_SDCTL_NUM(pThis, 0) ? "*" : " ", i , uDMACnt)); 2342 } 2343 } 2344 #endif 2345 2346 /** 2347 * Fetches a Bundle Descriptor List Entry (BDLE) from the DMA engine. 2348 * 2349 * @param pThis Pointer to HDA state. 2350 * @param pBDLE Where to store the fetched result. 2351 * @param u64BaseDMA Address base of DMA engine to use. 2352 * @param u16Entry BDLE entry to fetch. 2353 */ 2354 static int hdaBDLEFetch(PHDASTATE pThis, PHDABDLE pBDLE, uint64_t u64BaseDMA, uint16_t u16Entry) 2355 { 2356 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2357 AssertPtrReturn(pBDLE, VERR_INVALID_POINTER); 2358 AssertReturn(u64BaseDMA, VERR_INVALID_PARAMETER); 2359 /** @todo Compare u16Entry with LVI. */ 2360 2361 uint8_t uBundleEntry[16]; /** @todo Define a BDLE length. */ 2362 int rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), u64BaseDMA + u16Entry * 16, /** @todo Define a BDLE length. */ 2363 uBundleEntry, RT_ELEMENTS(uBundleEntry)); 2364 if (RT_FAILURE(rc)) 2365 return rc; 2366 2367 pBDLE->State.u32BDLIndex = u16Entry; 2368 pBDLE->u64BufAdr = *(uint64_t *) uBundleEntry; 2369 pBDLE->u32BufSize = *(uint32_t *)&uBundleEntry[8]; 2370 if (pBDLE->u32BufSize < sizeof(uint16_t)) /* Must be at least one word. */ 2371 return VERR_INVALID_STATE; 2372 2373 pBDLE->fIntOnCompletion = (*(uint32_t *)&uBundleEntry[12]) & 0x1; 2374 2375 return VINF_SUCCESS; 2376 } 2377 2378 static void hdaBDLEReset(PHDABDLE pBDLE) 2379 { 2380 AssertPtrReturnVoid(pBDLE); 2381 2382 pBDLE->State.u32BufOff = 0; 2383 pBDLE->State.cbBelowFIFOW = 0; 2384 } 2385 2386 /** 2387 * Returns the number of outstanding stream data bytes which need to be processed 2388 * by the DMA engine assigned to this stream. 2389 * 2390 * @return Number of bytes for the DMA engine to process. 2391 */ 2392 DECLINLINE(uint32_t) hdaStreamGetTransferSize(PHDASTATE pThis, PHDASTREAM pStrmSt) 2393 { 2394 AssertPtrReturn(pThis, 0); 2395 AssertPtrReturn(pStrmSt, 0); 2396 2397 PHDABDLE pBDLE = hdaStreamGetCurrentBDLE(pThis, pStrmSt); 2398 2399 uint32_t cbFree = pStrmSt->u32CBL - HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm); 2400 if (cbFree) 2401 { 2402 /* Limit to the available free space of the current BDLE. */ 2403 cbFree = RT_MIN(cbFree, pBDLE->u32BufSize - pBDLE->State.u32BufOff); 2404 2405 /* Make sure we only copy as much as the stream's FIFO can hold (SDFIFOS, 18.2.39). */ 2406 cbFree = RT_MIN(cbFree, pStrmSt->u16FIFOS); 2407 2408 if (pBDLE->State.cbBelowFIFOW) 2409 { 2410 /* Are we not going to reach (or exceed) the FIFO watermark yet with the data to copy? 2411 * No need to read data from DMA then. */ 2412 if (cbFree > pBDLE->State.cbBelowFIFOW) 2413 { 2414 /* Subtract the amount of bytes that still would fit in the stream's FIFO 2415 * and therefore do not need to be processed by DMA. */ 2416 cbFree -= pBDLE->State.cbBelowFIFOW; 2417 } 2418 } 2419 2420 Log(("HDADEBUG: cb2Copy=%RU32, CVI(len:%RU32, pos:%RU32), CBLL=%RU32, FIFOS=%RU32, Avail=%RU32\n", 2421 cbFree, pBDLE->u32BufSize, pBDLE->State.u32BufOff, pStrmSt->u32CBL - HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm), pStrmSt->u16FIFOS, 0)); 2422 } 2423 2424 LogFlowFunc(("[SD%RU8]: CBL=%RU32, LPIB=%RU32, cbFree=%RU32, %R[bdle]\n", pStrmSt->u8Strm, 2425 pStrmSt->u32CBL, HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm), cbFree, pBDLE)); 2426 return cbFree; 2427 } 2428 2429 DECLINLINE(void) hdaBDLEUpdate(PHDABDLE pBDLE, uint32_t cbData, uint32_t cbProcessed) 2430 { 2431 AssertPtrReturnVoid(pBDLE); 2432 2433 if (!cbData || !cbProcessed) 2434 return; 2435 2436 /* Fewer than cbBelowFIFOW bytes were copied. 2437 * Probably we need to move the buffer, but it is rather hard to imagine a situation 2438 * where it might happen. */ 2439 AssertMsg((cbProcessed == pBDLE->State.cbBelowFIFOW + cbData), /* we assume that we write the entire buffer including unreported bytes */ 2440 ("cbProcessed=%RU32 != pBDLE->State.cbBelowFIFOW=%RU32 + cbData=%RU32\n", 2441 cbProcessed, pBDLE->State.cbBelowFIFOW, cbData)); 2442 1925 2443 #if 0 1926 uint64_t addr; 1927 uint32_t len; 1928 uint32_t ioc; 1929 uint8_t bdle[16]; 1930 uint32_t counter; 1931 uint32_t i; 1932 uint32_t sum = 0; 1933 Assert(pBdle && pBdle->u32BdleMaxCvi); 1934 for (i = 0; i <= pBdle->u32BdleMaxCvi; ++i) 1935 { 1936 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), u64BaseDMA + i*16, bdle, 16); 1937 addr = *(uint64_t *)bdle; 1938 len = *(uint32_t *)&bdle[8]; 1939 ioc = *(uint32_t *)&bdle[12]; 1940 LogFunc(("%s bdle[%d] a:%llx, len:%d, ioc:%d\n", (i == pBdle->u32BdleCvi? "[C]": " "), i, addr, len, ioc & 0x1)); 1941 sum += len; 1942 } 1943 LogFunc(("sum: %d\n", sum)); 1944 for (i = 0; i < 8; ++i) 1945 { 1946 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), (pThis->u64DPBase & DPBASE_ADDR_MASK) + i*8, &counter, sizeof(&counter)); 1947 LogFunc(("%s stream[%d] counter=%x\n", i == SDCTL_NUM(pThis, 4) || i == SDCTL_NUM(pThis, 0)? "[C]": " ", 1948 i , counter)); 2444 if ( pBDLE->State.cbBelowFIFOW 2445 && pBDLE->State.cbBelowFIFOW <= cbWritten) 2446 { 2447 LogFlowFunc(("BDLE(cbUnderFifoW:%RU32, off:%RU32, size:%RU32)\n", 2448 pBDLE->State.cbBelowFIFOW, pBDLE->State.u32BufOff, pBDLE->u32BufSize)); 1949 2449 } 1950 2450 #endif 1951 } 1952 #endif 1953 1954 static void hdaFetchBdle(PHDASTATE pThis, PHDABDLEDESC pBdle, PHDASTREAMTRANSFERDESC pStreamDesc) 1955 { 1956 uint8_t bdle[16]; 1957 Assert(( pStreamDesc->u64BaseDMA 1958 && pBdle 1959 && pBdle->u32BdleMaxCvi)); 1960 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), pStreamDesc->u64BaseDMA + pBdle->u32BdleCvi*16, bdle, 16); 1961 pBdle->u64BdleCviAddr = *(uint64_t *)bdle; 1962 pBdle->u32BdleCviLen = *(uint32_t *)&bdle[8]; 1963 pBdle->fBdleCviIoc = (*(uint32_t *)&bdle[12]) & 0x1; 1964 #ifdef LOG_ENABLED 1965 dump_bd(pThis, pBdle, pStreamDesc->u64BaseDMA); 1966 #endif 1967 } 1968 1969 DECLINLINE(uint32_t) hdaCalculateTransferBufferLength(PHDABDLEDESC pBdle, PHDASTREAMTRANSFERDESC pStreamDesc, 1970 uint32_t u32SoundBackendBufferBytesAvail, uint32_t u32CblLimit) 1971 { 2451 2452 pBDLE->State.cbBelowFIFOW -= RT_MIN(pBDLE->State.cbBelowFIFOW, cbProcessed); 2453 Assert(pBDLE->State.cbBelowFIFOW == 0); 2454 2455 /* We always increment the position of DMA buffer counter because we're always reading 2456 * into an intermediate buffer. */ 2457 pBDLE->State.u32BufOff += cbData; 2458 Assert(pBDLE->State.u32BufOff <= pBDLE->u32BufSize); 2459 2460 LogFlowFunc(("cbData=%RU32, cbProcessed=%RU32, %R[bdle]\n", cbData, cbProcessed, pBDLE)); 2461 } 2462 2463 DECLINLINE(bool) hdaStreamNeedsNextBDLE(PHDASTATE pThis, PHDASTREAM pStrmSt) 2464 { 2465 AssertPtrReturn(pThis, false); 2466 AssertPtrReturn(pStrmSt, false); 2467 2468 PHDABDLE pBDLE = hdaStreamGetCurrentBDLE(pThis, pStrmSt); 2469 uint32_t u32LPIB = HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm); 2470 2471 /* Did we reach the CBL (Cyclic Buffer List) limit? */ 2472 bool fCBLLimitReached = u32LPIB >= pStrmSt->u32CBL; 2473 2474 /* Do we need to use the next BDLE entry? Either because we reached 2475 * the CBL limit or our internal DMA buffer is full. */ 2476 bool fNeedsNextBDLE = ( fCBLLimitReached 2477 || pBDLE->State.u32BufOff >= pBDLE->u32BufSize); 2478 2479 Assert(u32LPIB <= pStrmSt->u32CBL); 2480 Assert(pBDLE->State.u32BufOff <= pBDLE->u32BufSize); 2481 2482 LogFlowFunc(("[SD%RU8]: LPIB=%RU32, CBL=%RU32, fCBLLimitReached=%RTbool, fNeedsNextBDLE=%RTbool, %R[bdle]\n", 2483 pStrmSt->u8Strm, u32LPIB, pStrmSt->u32CBL, fCBLLimitReached, fNeedsNextBDLE, pBDLE)); 2484 2485 if (fCBLLimitReached) 2486 { 2487 /* Reset LPIB register. */ 2488 u32LPIB -= RT_MIN(u32LPIB, pStrmSt->u32CBL); 2489 hdaStreamUpdateLPIB(pThis, pStrmSt, u32LPIB); 2490 } 2491 2492 if (fNeedsNextBDLE) 2493 { 2494 /* Reset current BDLE. */ 2495 hdaBDLEReset(pBDLE); 2496 } 2497 2498 return fNeedsNextBDLE; 2499 } 2500 2501 DECLINLINE(void) hdaStreamTransferUpdate(PHDASTATE pThis, PHDASTREAM pStrmSt, uint32_t cbInc) 2502 { 2503 AssertPtrReturnVoid(pThis); 2504 AssertPtrReturnVoid(pStrmSt); 2505 2506 LogFlowFunc(("[SD%RU8]: cbInc=%RU32\n", pStrmSt->u8Strm, cbInc)); 2507 2508 Assert(cbInc <= pStrmSt->u16FIFOS + 1); 2509 2510 PHDABDLE pBDLE = hdaStreamGetCurrentBDLE(pThis, pStrmSt); 2511 1972 2512 /* 1973 * Number of bytes depends on the current position in buffer (u32BdleCviLen-u32BdleCviPos) 2513 * If we're below the FIFO watermark (SDFIFOW), it's expected that HDA 2514 * doesn't fetch anything via DMA, so just update LPIB. 2515 * (ICH6 datasheet 18.2.38). 1974 2516 */ 1975 Assert((pBdle->u32BdleCviLen >= pBdle->u32BdleCviPos)); /* sanity */ 1976 uint32_t cb2Copy = pBdle->u32BdleCviLen - pBdle->u32BdleCviPos; 1977 /* 1978 * we may increase the counter in range of [0, FIFOS + 1] 1979 */ 1980 cb2Copy = RT_MIN(cb2Copy, pStreamDesc->u32Fifos + 1); 1981 Assert((u32SoundBackendBufferBytesAvail > 0)); 1982 1983 /* sanity check to avoid overriding the backend audio buffer */ 1984 cb2Copy = RT_MIN(cb2Copy, u32SoundBackendBufferBytesAvail); 1985 cb2Copy = RT_MIN(cb2Copy, u32CblLimit); 1986 1987 if (cb2Copy <= pBdle->cbUnderFifoW) 1988 return 0; 1989 cb2Copy -= pBdle->cbUnderFifoW; /* forcibly reserve the amount of unreported bytes to copy */ 1990 return cb2Copy; 1991 } 1992 1993 DECLINLINE(void) hdaBackendWriteTransferReported(PHDABDLEDESC pBdle, uint32_t cbArranged2Copy, uint32_t cbCopied, 1994 uint32_t *pu32DMACursor, uint32_t *pu32BackendBufferCapacity) 1995 { 1996 LogFunc(("cbArranged2Copy: %d, cbCopied: %d, pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n", 1997 cbArranged2Copy, cbCopied, pu32DMACursor ? *pu32DMACursor : 0, pu32BackendBufferCapacity ? *pu32BackendBufferCapacity : 0)); 1998 Assert((cbCopied)); 1999 AssertPtr(pu32DMACursor); 2000 Assert((pu32BackendBufferCapacity && *pu32BackendBufferCapacity)); 2001 /* Assertion!!! Fewer than cbUnderFifoW bytes were copied. 2002 * Probably we need to move the buffer, but it is rather hard to imagine a situation 2003 * where it might happen. 2004 */ 2005 AssertMsg((cbCopied == pBdle->cbUnderFifoW + cbArranged2Copy), /* we assume that we write the entire buffer including unreported bytes */ 2006 ("cbCopied=%RU32 != pBdle->cbUnderFifoW=%RU32 + cbArranged2Copy=%RU32\n", 2007 cbCopied, pBdle->cbUnderFifoW, cbArranged2Copy)); 2008 if ( pBdle->cbUnderFifoW 2009 && pBdle->cbUnderFifoW <= cbCopied) 2010 { 2011 LogFunc(("CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", 2012 pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 2013 } 2014 2015 pBdle->cbUnderFifoW -= RT_MIN(pBdle->cbUnderFifoW, cbCopied); 2016 Assert((!pBdle->cbUnderFifoW)); /* Assert!!! Incorrect assumption */ 2017 2018 /* We always increment the position of DMA buffer counter because we're always reading into an intermediate buffer */ 2019 pBdle->u32BdleCviPos += cbArranged2Copy; 2020 2021 Assert((pBdle->u32BdleCviLen >= pBdle->u32BdleCviPos && *pu32BackendBufferCapacity >= cbCopied)); /* sanity */ 2022 /* We report all bytes (including previously unreported bytes) */ 2023 *pu32DMACursor += cbCopied; 2024 /* Decrease the backend counter by the number of bytes we copied to the backend */ 2025 *pu32BackendBufferCapacity -= cbCopied; 2026 LogFunc(("CVI(pos:%d, len:%d), pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n", 2027 pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, *pu32DMACursor, *pu32BackendBufferCapacity)); 2028 } 2029 2030 DECLINLINE(void) hdaBackendReadTransferReported(PHDABDLEDESC pBdle, uint32_t cbArranged2Copy, uint32_t cbCopied, 2031 uint32_t *pu32DMACursor, uint32_t *pu32BackendBufferCapacity) 2032 { 2033 Assert((cbCopied, cbArranged2Copy)); 2034 *pu32BackendBufferCapacity -= cbCopied; 2035 pBdle->u32BdleCviPos += cbCopied; 2036 LogFunc(("CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 2037 *pu32DMACursor += cbCopied + pBdle->cbUnderFifoW; 2038 pBdle->cbUnderFifoW = 0; 2039 LogFunc(("CVI(pos:%d, len:%d), pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n", 2040 pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, pu32DMACursor ? *pu32DMACursor : 0, pu32BackendBufferCapacity ? *pu32BackendBufferCapacity : 0)); 2041 } 2042 2043 DECLINLINE(void) hdaBackendTransferUnreported(PHDASTATE pThis, PHDABDLEDESC pBdle, PHDASTREAMTRANSFERDESC pStreamDesc, 2044 uint32_t cbCopied, uint32_t *pu32BackendBufferCapacity) 2045 { 2046 LogFunc(("CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 2047 pBdle->u32BdleCviPos += cbCopied; 2048 pBdle->cbUnderFifoW += cbCopied; 2049 /* In case of a read transaction we're always copying from the backend buffer */ 2050 if (pu32BackendBufferCapacity) 2051 *pu32BackendBufferCapacity -= cbCopied; 2052 LogFunc(("CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 2053 Assert((pBdle->cbUnderFifoW <= hdaFifoWToSz(pThis, pStreamDesc))); 2054 } 2055 2056 DECLINLINE(bool) hdaIsTransferCountersOverlapped(PHDASTATE pThis, PHDABDLEDESC pBdle, PHDASTREAMTRANSFERDESC pStreamDesc) 2057 { 2058 bool fOnBufferEdge = ( *pStreamDesc->pu32Lpib == pStreamDesc->u32Cbl 2059 || pBdle->u32BdleCviPos == pBdle->u32BdleCviLen); 2060 2061 Assert((*pStreamDesc->pu32Lpib <= pStreamDesc->u32Cbl)); 2062 2063 if (*pStreamDesc->pu32Lpib == pStreamDesc->u32Cbl) 2064 *pStreamDesc->pu32Lpib -= pStreamDesc->u32Cbl; 2065 hdaUpdatePosBuf(pThis, pStreamDesc); 2066 2067 /* don't touch BdleCvi counter on uninitialized descriptor */ 2068 if ( pBdle->u32BdleCviPos 2069 && pBdle->u32BdleCviPos == pBdle->u32BdleCviLen) 2070 { 2071 pBdle->u32BdleCviPos = 0; 2072 pBdle->u32BdleCvi++; 2073 if (pBdle->u32BdleCvi == pBdle->u32BdleMaxCvi + 1) 2074 pBdle->u32BdleCvi = 0; 2075 } 2076 return fOnBufferEdge; 2077 } 2078 2079 DECLINLINE(void) hdaStreamCounterUpdate(PHDASTATE pThis, PHDABDLEDESC pBdle, PHDASTREAMTRANSFERDESC pStreamDesc, 2080 uint32_t cbInc) 2081 { 2082 /* 2083 * if we're below the FIFO Watermark, it's expected that HDA doesn't fetch anything. 2084 * (ICH6 datasheet 18.2.38) 2085 */ 2086 if (!pBdle->cbUnderFifoW) 2087 { 2088 *pStreamDesc->pu32Lpib += cbInc; 2089 2090 /* 2091 * Assert. The buffer counters should never overlap. 2092 */ 2093 Assert((*pStreamDesc->pu32Lpib <= pStreamDesc->u32Cbl)); 2094 2095 hdaUpdatePosBuf(pThis, pStreamDesc); 2096 } 2097 } 2098 2099 static bool hdaDoNextTransferCycle(PHDASTATE pThis, PHDABDLEDESC pBdle, PHDASTREAMTRANSFERDESC pStreamDesc) 2100 { 2101 bool fDoNextTransferLoop = true; 2102 if ( pBdle->u32BdleCviPos == pBdle->u32BdleCviLen 2103 || *pStreamDesc->pu32Lpib == pStreamDesc->u32Cbl) 2104 { 2105 if ( !pBdle->cbUnderFifoW 2106 && pBdle->fBdleCviIoc) 2517 if (pBDLE->State.cbBelowFIFOW == 0) /* Did we hit (or exceed) the watermark? */ 2518 { 2519 const uint32_t u32LPIB = RT_MIN(HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm) + cbInc, 2520 pStrmSt->u32CBL); 2521 2522 LogFlowFunc(("[SD%RU8]: LPIB: %RU32 -> %RU32, CBL=%RU32\n", 2523 pStrmSt->u8Strm, 2524 HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm), HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm) + cbInc, 2525 pStrmSt->u32CBL)); 2526 2527 hdaStreamUpdateLPIB(pThis, pStrmSt, u32LPIB); 2528 } 2529 } 2530 2531 static bool hdaStreamTransferIsComplete(PHDASTATE pThis, PHDASTREAM pStrmSt) 2532 { 2533 AssertPtrReturn(pThis, true); 2534 AssertPtrReturn(pStrmSt, true); 2535 2536 bool fIsComplete = false; 2537 2538 PHDABDLE pBDLE = hdaStreamGetCurrentBDLE(pThis, pStrmSt); 2539 const uint32_t u32LPIB = HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm); 2540 2541 if ( pBDLE->State.u32BufOff >= pBDLE->u32BufSize 2542 || u32LPIB >= pStrmSt->u32CBL) 2543 { 2544 Assert(pBDLE->State.u32BufOff <= pBDLE->u32BufSize); 2545 Assert(u32LPIB <= pStrmSt->u32CBL); 2546 2547 if (/* IOC (Interrupt On Completion) bit set? */ 2548 pBDLE->fIntOnCompletion 2549 /* All data put into the DMA FIFO? */ 2550 && pBDLE->State.cbBelowFIFOW == 0 2551 ) 2107 2552 { 2108 2553 /** 2109 * @todo - more carefully investigate BCIS flag. 2554 * Set the BCIS (Buffer Completion Interrupt Status) flag as the 2555 * last byte of data for the current descriptor has been fetched 2556 * from memory and put into the DMA FIFO. 2557 * 2558 ** @todo More carefully investigate BCIS flag. 2559 * 2110 2560 * Speech synthesis works fine on Mac Guest if this bit isn't set 2111 2561 * but in general sound quality gets worse. 2112 2562 */ 2113 *pStreamDesc->pu32Sts|= HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS);2563 HDA_STREAM_REG(pThis, STS, pStrmSt->u8Strm) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS); 2114 2564 2115 2565 /* 2116 * we should generate the interrupt if ICE bit of SDCTL register is set. 2566 * If the ICE (IOCE, "Interrupt On Completion Enable") bit of the SDCTL register is set 2567 * we need to generate an interrupt. 2117 2568 */ 2118 if ( pStreamDesc->u32Ctl& HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE))2569 if (HDA_STREAM_REG(pThis, CTL, pStrmSt->u8Strm) & HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE)) 2119 2570 hdaProcessInterrupt(pThis); 2120 2571 } 2121 fDoNextTransferLoop = false; 2122 } 2123 return fDoNextTransferLoop; 2572 2573 fIsComplete = true; 2574 } 2575 2576 LogFlowFunc(("[SD%RU8]: u32LPIB=%RU32, CBL=%RU32, %R[bdle] => %s\n", 2577 pStrmSt->u8Strm, u32LPIB, pStrmSt->u32CBL, pBDLE, fIsComplete ? "COMPLETE" : "INCOMPLETE")); 2578 2579 return fIsComplete; 2124 2580 } 2125 2581 … … 2129 2585 * but "reports bytes" when all conditions are met (FIFOW). 2130 2586 */ 2131 static int hdaReadAudio(PHDASTATE pThis, PAUDMIXSINK pSink, 2132 PHDASTREAMTRANSFERDESC pStreamDesc, 2133 uint32_t u32CblLimit, uint32_t *pcbAvail, uint32_t *pcbRead) 2134 { 2135 PHDABDLEDESC pBdle = &pThis->StInBdle; /** @todo Add support for mic in. */ 2587 static int hdaReadAudio(PHDASTATE pThis, PHDASTREAM pStrmSt, PAUDMIXSINK pSink, uint32_t *pcbRead) 2588 { 2589 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2590 AssertPtrReturn(pStrmSt, VERR_INVALID_POINTER); 2591 AssertPtrReturn(pSink, VERR_INVALID_POINTER); 2592 /* pcbRead is optional. */ 2593 2594 PHDABDLE pBDLE = hdaStreamGetCurrentBDLE(pThis, pStrmSt); 2136 2595 2137 2596 int rc; 2138 uint32_t cb Transferred = 0;2139 2140 LogFlowFunc(("CVI(pos:%d, len:%d)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 2141 2142 uint32_t cb2Copy = hdaCalculateTransferBufferLength(pBdle, pStreamDesc, *pcbAvail, u32CblLimit); 2143 if (!cb 2Copy)2144 { 2145 /* If we enter here we can't report "unreported bits". */2597 uint32_t cbRead = 0; 2598 uint32_t cbBuf = hdaStreamGetTransferSize(pThis, pStrmSt); 2599 2600 LogFlowFunc(("cbBuf=%RU32, %R[bdle]\n", cbBuf, pBDLE)); 2601 2602 if (!cbBuf) 2603 { 2604 /* Nothing to write, bail out. */ 2146 2605 rc = VERR_NO_DATA; 2147 2606 } 2148 2607 else 2149 2608 { 2150 uint32_t cbRead = 0;2151 rc = AudioMixerProcessSinkIn(pSink, AUDMIXOP_BLEND, pB dle->au8HdaBuffer, cb2Copy, &cbRead);2609 uint32_t cbReadFromSink = 0; 2610 rc = AudioMixerProcessSinkIn(pSink, AUDMIXOP_BLEND, pBDLE->State.au8FIFO, cbBuf, &cbReadFromSink); 2152 2611 if (RT_SUCCESS(rc)) 2153 2612 { 2154 Assert(cbRead); 2613 Assert(cbReadFromSink); 2614 Assert(cbReadFromSink == cbBuf); 2615 Assert(cbReadFromSink <= pBDLE->u32BufSize - pBDLE->State.u32BufOff); 2155 2616 2156 2617 /* 2157 * Write t he HDADMA buffer.2618 * Write to the BDLE's DMA buffer. 2158 2619 */ 2159 PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns), 2160 pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, 2161 pBdle->au8HdaBuffer, cbRead); 2162 2163 /* Don't see any reason why cb2Copy would differ from cbRead. */ 2164 Assert((cbRead == cb2Copy && (*pcbAvail) >= cb2Copy)); /* sanity */ 2165 2166 if (pBdle->cbUnderFifoW + cbRead > hdaFifoWToSz(pThis, 0)) 2167 hdaBackendReadTransferReported(pBdle, cb2Copy, cbRead, &cbTransferred, pcbAvail); 2620 rc = PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns), 2621 pBDLE->u64BufAdr + pBDLE->State.u32BufOff, 2622 pBDLE->State.au8FIFO, cbReadFromSink); 2623 AssertRC(rc); 2624 2625 if (pBDLE->State.cbBelowFIFOW + cbReadFromSink > hdaStreamGetFIFOW(pThis, pStrmSt)) 2626 { 2627 pBDLE->State.u32BufOff += cbReadFromSink; 2628 pBDLE->State.cbBelowFIFOW = 0; 2629 //hdaBackendReadTransferReported(pBDLE, cbDMAData, cbRead, &cbRead, pcbAvail); 2630 } 2168 2631 else 2169 2632 { 2170 hdaBackendTransferUnreported(pThis, pBdle, pStreamDesc, cbRead, pcbAvail); 2633 pBDLE->State.u32BufOff += cbReadFromSink; 2634 pBDLE->State.cbBelowFIFOW += cbReadFromSink; 2635 Assert(pBDLE->State.cbBelowFIFOW <= hdaStreamGetFIFOW(pThis, pStrmSt)); 2636 //hdaBackendTransferUnreported(pThis, pBDLE, pStreamDesc, cbRead, pcbAvail); 2637 2171 2638 rc = VERR_NO_DATA; 2172 2639 } … … 2174 2641 } 2175 2642 2176 Assert((cbTransferred <= (SDFIFOS(pThis, 0) + 1))); 2177 LogFunc(("CVI(pos:%RU32, len:%RU32), cbTransferred=%RU32, rc=%Rrc\n", 2178 pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, cbTransferred, rc)); 2643 //Assert(cbRead <= (SDFIFOS(pThis, pStrmSt->u8Strm) + 1)); 2644 2645 LogFunc(("BDLE(off:%RU32, size:%RU32), cbTransferred=%RU32, rc=%Rrc\n", 2646 pBDLE->State.u32BufOff, pBDLE->u32BufSize, cbRead, rc)); 2179 2647 2180 2648 if (RT_SUCCESS(rc)) 2181 *pcbRead = cbTransferred; 2649 { 2650 if (pcbRead) 2651 *pcbRead = cbRead; 2652 } 2182 2653 2183 2654 return rc; 2184 2655 } 2185 2656 2186 static int hdaWriteAudio(PHDASTATE pThis, PHDASTREAM TRANSFERDESC pStreamDesc, uint32_t u32CblLimit,2187 uint32_t *pcbAvail, uint32_t *pcbWritten) 2188 { 2189 PHDABDLEDESC pBdle = &pThis->StOutBdle;2190 2191 int rc = VINF_SUCCESS;2192 2193 uint32_t cbTransferred = 0;2194 uint32_t cbWrittenMin = 0; /* local byte counter, how many bytes copied to backend */2195 2196 LogFunc(("CVI(cvi:%RU32, pos:%RU32, len:%RU32)\n", pBdle->u32BdleCvi, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));2197 2198 /* Local byte counter (on local buffer). */ 2199 uint32_t cb2Copy = hdaCalculateTransferBufferLength(pBdle, pStreamDesc, *pcbAvail, u32CblLimit);2657 static int hdaWriteAudio(PHDASTATE pThis, PHDASTREAM pStrmSt, uint32_t *pcbWritten) 2658 { 2659 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2660 AssertPtrReturn(pStrmSt, VERR_INVALID_POINTER); 2661 AssertPtrReturn(pcbWritten, VERR_INVALID_POINTER); 2662 /* pcbWritten is optional. */ 2663 2664 PHDABDLE pBDLE = hdaStreamGetCurrentBDLE(pThis, pStrmSt); 2665 int rc; 2666 2667 uint32_t cbWritten = 0; 2668 uint32_t cbData = hdaStreamGetTransferSize(pThis, pStrmSt); 2669 2670 LogFlowFunc(("cbData=%RU32, %R[bdle]\n", cbData, pBDLE)); 2200 2671 2201 2672 /* 2202 * Copy from DMA to the corresponding hdaBuffer (if there are any bytes from the2203 * previous unreported transfer we write at offset 'pB dle->cbUnderFifoW').2673 * Copy from DMA to the corresponding stream buffer (if there are any bytes from the 2674 * previous unreported transfer we write at offset 'pBDLE->State.cbUnderFifoW'). 2204 2675 */ 2205 if (!cb 2Copy)2676 if (!cbData) 2206 2677 { 2207 2678 rc = VINF_EOF; … … 2209 2680 else 2210 2681 { 2211 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), 2212 pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, 2213 pBdle->au8HdaBuffer + pBdle->cbUnderFifoW, cb2Copy); 2682 /* 2683 * Read from the current BDLE's DMA buffer. 2684 */ 2685 rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), 2686 pBDLE->u64BufAdr + pBDLE->State.u32BufOff, 2687 pBDLE->State.au8FIFO + pBDLE->State.cbBelowFIFOW, cbData); 2688 AssertRC(rc); 2214 2689 2215 2690 #ifdef VBOX_WITH_STATISTICS 2216 STAM_COUNTER_ADD(&pThis->StatBytesRead, cb 2Copy);2691 STAM_COUNTER_ADD(&pThis->StatBytesRead, cbData); 2217 2692 #endif 2218 2219 2693 /* 2220 2694 * Write to audio backend. We should ensure that we have enough bytes to copy to the backend. 2221 2695 */ 2222 if (cb2Copy + pBdle->cbUnderFifoW >= hdaFifoWToSz(pThis, pStreamDesc)) 2223 { 2224 uint32_t cbWritten; 2225 cbWrittenMin = UINT32_MAX; 2696 uint32_t cbToWrite = cbData + pBDLE->State.cbBelowFIFOW; 2697 if (cbToWrite >= hdaStreamGetFIFOW(pThis, pStrmSt)) 2698 { 2699 uint32_t cbWrittenToStream; 2700 int rc2; 2226 2701 2227 2702 PHDADRIVER pDrv; … … 2230 2705 if (pDrv->pConnector->pfnIsActiveOut(pDrv->pConnector, pDrv->Out.pStrmOut)) 2231 2706 { 2232 int rc2 = pDrv->pConnector->pfnWrite(pDrv->pConnector, pDrv->Out.pStrmOut, 2233 pBdle->au8HdaBuffer, cb2Copy + pBdle->cbUnderFifoW, 2234 &cbWritten); 2235 if (RT_FAILURE(rc2)) 2236 continue; 2707 rc2 = pDrv->pConnector->pfnWrite(pDrv->pConnector, pDrv->Out.pStrmOut, 2708 pBDLE->State.au8FIFO, cbToWrite, &cbWrittenToStream); 2709 if (RT_SUCCESS(rc2)) 2710 { 2711 if (cbWrittenToStream < cbToWrite) /* Lagging behind? */ 2712 LogFlowFunc(("\tLUN#%RU8: Warning: Only written %RU32 / %RU32 bytes, expect lags\n", 2713 pDrv->uLUN, cbWrittenToStream, cbToWrite)); 2714 } 2237 2715 } 2238 else /* Stream disabled, just assume all was copied. */ 2239 cbWritten = cb2Copy; 2240 2241 cbWrittenMin = RT_MIN(cbWrittenMin, cbWritten); 2242 LogFlowFunc(("\tLUN#%RU8: cbWritten=%RU32, cWrittenMin=%RU32\n", pDrv->uLUN, cbWritten, cbWrittenMin)); 2716 else /* Stream disabled, not fatal. */ 2717 { 2718 cbWrittenToStream = 0; 2719 rc2 = VERR_NOT_AVAILABLE; 2720 /* Keep going. */ 2721 } 2722 2723 LogFlowFunc(("\tLUN#%RU8: cbToWrite=%RU32, cbWrittenToStream=%RU32, rc=%Rrc\n", 2724 pDrv->uLUN, cbToWrite, cbWrittenToStream, rc2)); 2243 2725 } 2244 2726 2245 if (cbWrittenMin == UINT32_MAX) 2246 cbWrittenMin = 0; 2247 2248 hdaBackendWriteTransferReported(pBdle, cb2Copy, cbWrittenMin, &cbTransferred, pcbAvail); 2727 /* Always report all data as being written; 2728 * backends who were not able to catch up have to deal with it themselves. */ 2729 cbWritten = cbToWrite; 2730 2731 hdaBDLEUpdate(pBDLE, cbData, cbWritten); 2249 2732 } 2250 2733 else 2251 2734 { 2735 pBDLE->State.u32BufOff += cbWritten; 2736 pBDLE->State.cbBelowFIFOW += cbWritten; 2737 Assert(pBDLE->State.cbBelowFIFOW <= hdaStreamGetFIFOW(pThis, pStrmSt)); 2738 2252 2739 /* Not enough bytes to be processed and reported, we'll try our luck next time around. */ 2253 hdaBackendTransferUnreported(pThis, pBdle, pStreamDesc, cb2Copy, NULL);2740 //hdaBackendTransferUnreported(pThis, pBDLE, pStreamDesc, cbAvail, NULL); 2254 2741 rc = VINF_EOF; 2255 2742 } 2256 2743 } 2257 2744 2258 Assert(cbTransferred <= SDFIFOS(pThis, 4) + 1); 2259 LogFunc(("CVI(pos:%RU32, len:%RU32, cbTransferred:%RU32), rc=%Rrc\n", 2260 pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, cbTransferred, rc)); 2745 Assert(cbWritten <= pStrmSt->u16FIFOS + 1); 2261 2746 2262 2747 if (RT_SUCCESS(rc)) 2263 *pcbWritten = cbTransferred; 2264 2748 { 2749 if (pcbWritten) 2750 *pcbWritten = cbWritten; 2751 } 2752 2753 LogFunc(("Returning cbWritten=%RU32, rc=%Rrc\n", cbWritten, rc)); 2265 2754 return rc; 2266 2755 } … … 2276 2765 } 2277 2766 2278 DECLINLINE(void) hdaInitTransferDescriptor(PHDASTATE pThis, PHDABDLEDESC pBdle, uint8_t u8Strm, 2279 PHDASTREAMTRANSFERDESC pStreamDesc) 2280 { 2281 Assert(pThis); Assert(pBdle); Assert(pStreamDesc); Assert(u8Strm <= 7); 2282 2283 RT_BZERO(pStreamDesc, sizeof(HDASTREAMTRANSFERDESC)); 2284 pStreamDesc->u8Strm = u8Strm; 2285 pStreamDesc->u32Ctl = HDA_STREAM_REG(pThis, CTL, u8Strm); 2286 pStreamDesc->u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, u8Strm), 2287 HDA_STREAM_REG(pThis, BDPU, u8Strm)); 2288 pStreamDesc->pu32Lpib = &HDA_STREAM_REG(pThis, LPIB, u8Strm); 2289 pStreamDesc->pu32Sts = &HDA_STREAM_REG(pThis, STS, u8Strm); 2290 pStreamDesc->u32Cbl = HDA_STREAM_REG(pThis, CBL, u8Strm); 2291 pStreamDesc->u32Fifos = HDA_STREAM_REG(pThis, FIFOS, u8Strm); 2292 2293 pBdle->u32BdleMaxCvi = HDA_STREAM_REG(pThis, LVI, u8Strm); 2294 2295 #ifdef LOG_ENABLED 2296 if ( pBdle 2297 && pBdle->u32BdleMaxCvi) 2298 { 2299 LogFunc(("Initialization of transfer descriptor:\n")); 2300 dump_bd(pThis, pBdle, pStreamDesc->u64BaseDMA); 2301 } 2302 #endif 2303 } 2304 2305 static DECLCALLBACK(void) hdaDestroyIn(PHDASTATE pThis, PDMAUDIORECSOURCE enmRecSource) 2767 2768 static DECLCALLBACK(void) hdaCloseIn(PHDASTATE pThis, PDMAUDIORECSOURCE enmRecSource) 2306 2769 { 2307 2770 NOREF(pThis); … … 2310 2773 } 2311 2774 2312 static DECLCALLBACK(void) hda DestroyOut(PHDASTATE pThis)2775 static DECLCALLBACK(void) hdaCloseOut(PHDASTATE pThis) 2313 2776 { 2314 2777 NOREF(pThis); … … 2316 2779 } 2317 2780 2318 static DECLCALLBACK(int) hda CreateIn(PHDASTATE pThis,2319 2320 2781 static DECLCALLBACK(int) hdaOpenIn(PHDASTATE pThis, 2782 const char *pszName, PDMAUDIORECSOURCE enmRecSource, 2783 PPDMAUDIOSTREAMCFG pCfg) 2321 2784 { 2322 2785 PAUDMIXSINK pSink; … … 2366 2829 } 2367 2830 2368 static DECLCALLBACK(int) hda CreateOut(PHDASTATE pThis,2369 2831 static DECLCALLBACK(int) hdaOpenOut(PHDASTATE pThis, 2832 const char *pszName, PPDMAUDIOSTREAMCFG pCfg) 2370 2833 { 2371 2834 int rc = VINF_SUCCESS; … … 2406 2869 2407 2870 /* Convert the audio source to corresponding sink. */ 2408 switch (enmSource) { 2409 case PO_INDEX: 2410 pSink = pThis->pSinkOutput; 2411 break; 2412 case PI_INDEX: 2413 pSink = pThis->pSinkLineIn; 2414 break; 2415 case MC_INDEX: 2416 pSink = pThis->pSinkMicIn; 2417 break; 2418 default: 2419 AssertFailedReturn(VERR_INVALID_PARAMETER); 2871 switch (enmSource) 2872 { 2873 case PO_INDEX: 2874 pSink = pThis->pSinkOutput; 2875 break; 2876 case PI_INDEX: 2877 pSink = pThis->pSinkLineIn; 2878 break; 2879 case MC_INDEX: 2880 pSink = pThis->pSinkMicIn; 2881 break; 2882 default: 2883 AssertFailedReturn(VERR_INVALID_PARAMETER); 2884 break; 2420 2885 } 2421 2886 … … 2426 2891 return rc; 2427 2892 } 2893 2894 #ifndef VBOX_WITH_AUDIO_CALLBACKS 2428 2895 2429 2896 static DECLCALLBACK(void) hdaTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) … … 2485 2952 { 2486 2953 Assert(cbOutMin != UINT32_MAX); 2487 hdaTransfer(pThis, PO_INDEX, cbOutMin); /** @todo Add rc! */2954 hdaTransfer(pThis, PO_INDEX, NULL /* pcbProcessed */); /** @todo Add rc! */ 2488 2955 } 2489 2956 … … 2492 2959 */ 2493 2960 if (cbInMax) 2494 hdaTransfer(pThis, PI_INDEX, cbInMax); /** @todo Add rc! */2961 hdaTransfer(pThis, PI_INDEX, NULL /* pcbProcessed */); /** @todo Add rc! */ 2495 2962 2496 2963 TMTimerSet(pThis->pTimer, TMTimerGet(pThis->pTimer) + pThis->uTicks); … … 2499 2966 } 2500 2967 2501 static int hdaTransfer(PHDASTATE pThis, 2502 ENMSOUNDSOURCE enmSrc, uint32_t cbAvail) 2968 #else /* VBOX_WITH_AUDIO_CALLBACKS */ 2969 2970 static DECLCALLBACK(int) hdaCallbackInput(PDMAUDIOCALLBACKTYPE enmType, void *pvCtx, size_t cbCtx, void *pvUser, size_t cbUser) 2971 { 2972 Assert(enmType == PDMAUDIOCALLBACKTYPE_INPUT); 2973 AssertPtrReturn(pvCtx, VERR_INVALID_POINTER); 2974 AssertReturn(cbCtx, VERR_INVALID_PARAMETER); 2975 AssertPtrReturn(pvUser, VERR_INVALID_POINTER); 2976 AssertReturn(cbUser, VERR_INVALID_PARAMETER); 2977 2978 PHDACALLBACKCTX pCtx = (PHDACALLBACKCTX)pvCtx; 2979 AssertReturn(cbCtx == sizeof(HDACALLBACKCTX), VERR_INVALID_PARAMETER); 2980 2981 PPDMAUDIOCALLBACKDATAIN pData = (PPDMAUDIOCALLBACKDATAIN)pvUser; 2982 AssertReturn(cbUser == sizeof(PDMAUDIOCALLBACKDATAIN), VERR_INVALID_PARAMETER); 2983 2984 return hdaTransfer(pCtx->pThis, PI_INDEX, &pData->cbOutRead); 2985 } 2986 2987 static DECLCALLBACK(int) hdaCallbackOutput(PDMAUDIOCALLBACKTYPE enmType, void *pvCtx, size_t cbCtx, void *pvUser, size_t cbUser) 2988 { 2989 Assert(enmType == PDMAUDIOCALLBACKTYPE_OUTPUT); 2990 AssertPtrReturn(pvCtx, VERR_INVALID_POINTER); 2991 AssertReturn(cbCtx, VERR_INVALID_PARAMETER); 2992 AssertPtrReturn(pvUser, VERR_INVALID_POINTER); 2993 AssertReturn(cbUser, VERR_INVALID_PARAMETER); 2994 2995 PHDACALLBACKCTX pCtx = (PHDACALLBACKCTX)pvCtx; 2996 AssertReturn(cbCtx == sizeof(HDACALLBACKCTX), VERR_INVALID_PARAMETER); 2997 2998 PPDMAUDIOCALLBACKDATAOUT pData = (PPDMAUDIOCALLBACKDATAOUT)pvUser; 2999 AssertReturn(cbUser == sizeof(PDMAUDIOCALLBACKDATAOUT), VERR_INVALID_PARAMETER); 3000 3001 PHDASTATE pThis = pCtx->pThis; 3002 3003 int rc = hdaTransfer(pCtx->pThis, PO_INDEX, &pData->cbOutWritten); 3004 if ( RT_SUCCESS(rc) 3005 && pData->cbOutWritten) 3006 { 3007 PHDADRIVER pDrv; 3008 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 3009 { 3010 uint32_t cSamplesPlayed; 3011 int rc2 = pDrv->pConnector->pfnPlayOut(pDrv->pConnector, &cSamplesPlayed); 3012 LogFlowFunc(("LUN#%RU8: cSamplesPlayed=%RU32, rc=%Rrc\n", pDrv->uLUN, cSamplesPlayed, rc2)); 3013 } 3014 } 3015 } 3016 #endif /* VBOX_WITH_AUDIO_CALLBACKS */ 3017 3018 static int hdaTransfer(PHDASTATE pThis, ENMSOUNDSOURCE enmSrc, uint32_t *pcbProcessed) 2503 3019 { 2504 3020 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2505 2506 LogFlowFunc(("pThis=%p, cbAvail=%RU32\n", pThis, cbAvail)); 2507 2508 uint8_t u8Strm; 2509 PHDABDLEDESC pBdle; 2510 3021 /* pcbProcessed is optional. */ 3022 3023 LogFlowFunc(("enmSrc=%RU32\n", enmSrc)); 3024 3025 PHDASTREAM pStrmSt; 2511 3026 switch (enmSrc) 2512 3027 { 2513 3028 case PI_INDEX: 2514 3029 { 2515 u8Strm = 0; 2516 pBdle = &pThis->StInBdle; 3030 pStrmSt = &pThis->StrmStLineIn; 2517 3031 break; 2518 3032 } … … 2521 3035 case MC_INDEX: 2522 3036 { 2523 u8Strm = 2; 2524 pBdle = &pThis->StMicBdle; 3037 pStrmSt = &pThis->StrmStMicIn; 2525 3038 break; 2526 3039 } … … 2528 3041 case PO_INDEX: 2529 3042 { 2530 u8Strm = 4; 2531 pBdle = &pThis->StOutBdle; 3043 pStrmSt = &pThis->StrmStOut; 2532 3044 break; 2533 3045 } 2534 3046 2535 3047 default: 3048 { 2536 3049 AssertMsgFailed(("Unknown source index %ld\n", enmSrc)); 2537 3050 return VERR_NOT_SUPPORTED; 2538 } 2539 2540 HDASTREAMTRANSFERDESC StreamDesc; 2541 hdaInitTransferDescriptor(pThis, pBdle, u8Strm, &StreamDesc); 2542 2543 int rc = VINF_EOF; 2544 while (cbAvail) 2545 { 2546 Assert( (StreamDesc.u32Ctl & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)) 2547 && cbAvail 2548 && StreamDesc.u64BaseDMA); 2549 2550 /* Fetch the Buffer Descriptor Entry (BDE). */ 2551 if (hdaIsTransferCountersOverlapped(pThis, pBdle, &StreamDesc)) 2552 hdaFetchBdle(pThis, pBdle, &StreamDesc); 2553 2554 *StreamDesc.pu32Sts |= HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY); 2555 Assert((StreamDesc.u32Cbl >= (*StreamDesc.pu32Lpib))); /* sanity */ 2556 uint32_t u32CblLimit = StreamDesc.u32Cbl - (*StreamDesc.pu32Lpib); 2557 Assert((u32CblLimit > hdaFifoWToSz(pThis, &StreamDesc))); 2558 2559 LogFunc(("CBL=%RU32, LPIB=%RU32\n", StreamDesc.u32Cbl, *StreamDesc.pu32Lpib)); 2560 2561 PAUDMIXSINK pSink; 2562 uint32_t cbWritten = 0; 3051 } 3052 } 3053 3054 if (pStrmSt->State.cBDLE == 0) /* No buffers available? */ 3055 { 3056 LogFlowFunc(("[SD%RU8] No buffers available\n", pStrmSt->u8Strm)); 3057 3058 if (pcbProcessed) 3059 *pcbProcessed = 0; 3060 return VINF_SUCCESS; 3061 } 3062 AssertPtr(pStrmSt->State.paBDLE); 3063 3064 /* Is this stream running? */ 3065 const bool fIsRunning = RT_BOOL(HDA_STREAM_REG(pThis, CTL, pStrmSt->u8Strm) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 3066 if (!fIsRunning) 3067 { 3068 LogFlowFunc(("[SD%RU8]: Stream not running\n", pStrmSt->u8Strm)); 3069 3070 if (pcbProcessed) 3071 *pcbProcessed = 0; 3072 return VINF_SUCCESS; 3073 } 3074 3075 Assert(pStrmSt->u8Strm <= 7); /** @todo Use a define for MAX_STRAEMS! */ 3076 Assert(pStrmSt->u64BaseDMA); 3077 Assert(pStrmSt->u32CBL); 3078 3079 int rc; 3080 uint32_t cbProcessedTotal = 0; 3081 bool fIsComplete = false; 3082 3083 do 3084 { 3085 /* Do we need to fetch the next Buffer Descriptor Entry (BDLE)? */ 3086 if (hdaStreamNeedsNextBDLE(pThis, pStrmSt)) 3087 hdaStreamGetNextBDLE(pThis, pStrmSt); 3088 3089 /* Set the FIFORDY bit on the stream while doing the transfer. */ 3090 HDA_STREAM_REG(pThis, STS, pStrmSt->u8Strm) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY); 3091 3092 uint32_t cbProcessed; 2563 3093 switch (enmSrc) 2564 3094 { 2565 3095 case PI_INDEX: 2566 pSink = pThis->pSinkLineIn; 2567 rc = hdaReadAudio(pThis, pSink, &StreamDesc, u32CblLimit, &cbAvail, &cbWritten); 3096 rc = hdaReadAudio(pThis, pStrmSt, pThis->pSinkLineIn, &cbProcessed); 2568 3097 break; 2569 3098 case PO_INDEX: 2570 rc = hdaWriteAudio(pThis, &StreamDesc, u32CblLimit, &cbAvail, &cbWritten);3099 rc = hdaWriteAudio(pThis, pStrmSt, &cbProcessed); 2571 3100 break; 2572 3101 #ifdef VBOX_WITH_HDA_MIC_IN 2573 3102 case MC_INDEX: 2574 pSink = pThis->pSinkMicIn; 2575 rc = hdaReadAudio(pThis, pSink, &StreamDesc, u32CblLimit, &cbAvail, &cbWritten); 3103 rc = hdaReadAudio(pThis, pStrmSt, pThis->pSinkMicIn, &cbProcessed); 2576 3104 break; 2577 3105 #endif … … 2581 3109 break; 2582 3110 } 2583 Assert(cbWritten <= StreamDesc.u32Fifos + 1); 2584 *StreamDesc.pu32Sts &= ~HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY); 2585 2586 /* Process end of buffer condition. */ 2587 hdaStreamCounterUpdate(pThis, pBdle, &StreamDesc, cbWritten); 2588 2589 if (!hdaDoNextTransferCycle(pThis, pBdle, &StreamDesc)) 3111 3112 /* Remove the FIFORDY bit again. */ 3113 HDA_STREAM_REG(pThis, STS, pStrmSt->u8Strm) &= ~HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY); 3114 3115 if (RT_FAILURE(rc)) 2590 3116 break; 2591 3117 2592 if ( RT_FAILURE(rc) 2593 || rc == VINF_EOF) /* All data processed? */ 2594 { 2595 break; 2596 } 2597 } 2598 3118 hdaStreamTransferUpdate(pThis, pStrmSt, cbProcessed); 3119 3120 cbProcessedTotal += cbProcessed; 3121 3122 LogFlowFunc(("cbProcessed=%RU32, cbProcessedTotal=%RU32, rc=%Rrc\n", cbProcessed, cbProcessedTotal, rc)); 3123 3124 if (rc == VINF_EOF) 3125 fIsComplete = true; 3126 3127 if (!fIsComplete) 3128 fIsComplete = hdaStreamTransferIsComplete(pThis, pStrmSt); 3129 3130 } while (!fIsComplete); 3131 3132 if (RT_SUCCESS(rc)) 3133 { 3134 if (pcbProcessed) 3135 *pcbProcessed = cbProcessedTotal; 3136 } 3137 3138 LogFlowFuncLeaveRC(rc); 2599 3139 return rc; 2600 3140 } … … 2626 3166 2627 3167 LogFunc(("offReg=%#x cb=%#x\n", offReg, cb)); 2628 #define NEW_READ_CODE2629 #ifdef NEW_READ_CODE2630 3168 Assert(cb == 4); Assert((offReg & 3) == 0); 2631 3169 2632 3170 if (pThis->fInReset && idxRegDsc != HDA_REG_GCTL) 2633 LogFunc((" access to registers except GCTL is blocked while reset\n"));3171 LogFunc(("\tAccess to registers except GCTL is blocked while reset\n")); 2634 3172 2635 3173 if (idxRegDsc == -1) 2636 LogRel((" Invalid read access @0x%x(of bytes:%d)\n", offReg, cb));3174 LogRel(("HDA: Invalid read access @0x%x (bytes=%d)\n", offReg, cb)); 2637 3175 2638 3176 if (idxRegDsc != -1) … … 2645 3183 */ 2646 3184 rc = g_aHdaRegMap[idxRegDsc].pfnRead(pThis, idxRegDsc, (uint32_t *)pv); 2647 LogFunc((" read %s => %x (%Rrc)\n", g_aHdaRegMap[idxRegDsc].abbrev, *(uint32_t *)pv, rc));3185 LogFunc(("\tRead %s => %x (%Rrc)\n", g_aHdaRegMap[idxRegDsc].abbrev, *(uint32_t *)pv, rc)); 2648 3186 } 2649 3187 else … … 2661 3199 2662 3200 rc = g_aHdaRegMap[idxRegDsc].pfnRead(pThis, idxRegDsc, &u32Tmp); 2663 LogFunc((" read %s[%db] => %x (%Rrc)*\n", g_aHdaRegMap[idxRegDsc].abbrev, cbReg, u32Tmp, rc));3201 LogFunc(("\tRead %s[%db] => %x (%Rrc)*\n", g_aHdaRegMap[idxRegDsc].abbrev, cbReg, u32Tmp, rc)); 2664 3202 if (rc != VINF_SUCCESS) 2665 3203 break; … … 2680 3218 { 2681 3219 rc = VINF_IOM_MMIO_UNUSED_FF; 2682 LogFunc(("hole at %x is accessed for read\n", offReg)); 2683 } 2684 #else 2685 if (idxRegDsc != -1) 2686 { 2687 /** @todo r=bird: Accesses crossing register boundraries aren't handled 2688 * right from what I can tell? If they are, please explain 2689 * what the rules are. */ 2690 uint32_t mask = 0; 2691 uint32_t shift = (g_aHdaRegMap[idxRegDsc].offset - offReg) % sizeof(uint32_t) * 8; 2692 uint32_t u32Value = 0; 2693 switch(cb) 2694 { 2695 case 1: mask = 0x000000ff; break; 2696 case 2: mask = 0x0000ffff; break; 2697 case 4: 2698 /* 18.2 of the ICH6 datasheet defines the valid access widths as byte, word, and double word */ 2699 case 8: 2700 mask = 0xffffffff; 2701 cb = 4; 2702 break; 2703 } 2704 #if 0 2705 /* Cross-register access. Mac guest hits this assert doing assumption 4 byte access to 3 byte registers e.g. {I,O}SDnCTL 2706 */ 2707 //Assert((cb <= g_aHdaRegMap[idxRegDsc].size - (offReg - g_aHdaRegMap[idxRegDsc].offset))); 2708 if (cb > g_aHdaRegMap[idxRegDsc].size - (offReg - g_aHdaRegMap[idxRegDsc].offset)) 2709 { 2710 int off = cb - (g_aHdaRegMap[idxRegDsc].size - (offReg - g_aHdaRegMap[idxRegDsc].offset)); 2711 rc = hdaMMIORead(pDevIns, pvUser, GCPhysAddr + cb - off, (char *)pv + cb - off, off); 2712 if (RT_FAILURE(rc)) 2713 AssertRCReturn (rc, rc); 2714 } 2715 //Assert(((offReg - g_aHdaRegMap[idxRegDsc].offset) == 0)); 2716 #endif 2717 mask <<= shift; 2718 rc = g_aHdaRegMap[idxRegDsc].pfnRead(pThis, idxRegDsc, &u32Value); 2719 *(uint32_t *)pv |= (u32Value & mask); 2720 LogFunc(("read %s[%x/%x]\n", g_aHdaRegMap[idxRegDsc].abbrev, u32Value, *(uint32_t *)pv)); 2721 } 2722 else 2723 { 2724 *(uint32_t *)pv = 0xFF; 2725 LogFunc(("hole at %x is accessed for read\n", offReg)); 2726 rc = VINF_SUCCESS; 2727 } 2728 #endif 3220 LogFunc(("\tHole at %x is accessed for read\n", offReg)); 3221 } 2729 3222 2730 3223 /* … … 2733 3226 #ifdef LOG_ENABLED 2734 3227 if (cbLog == 4) 2735 LogFunc((" @%#05x -> %#010x %Rrc\n", offRegLog, *(uint32_t *)pv, rc));3228 LogFunc(("\tReturning @%#05x -> %#010x %Rrc\n", offRegLog, *(uint32_t *)pv, rc)); 2736 3229 else if (cbLog == 2) 2737 LogFunc((" @%#05x -> %#06x %Rrc\n", offRegLog, *(uint16_t *)pv, rc));3230 LogFunc(("\tReturning @%#05x -> %#06x %Rrc\n", offRegLog, *(uint16_t *)pv, rc)); 2738 3231 else if (cbLog == 1) 2739 LogFunc((" @%#05x -> %#04x %Rrc\n", offRegLog, *(uint8_t *)pv, rc));3232 LogFunc(("\tReturning @%#05x -> %#04x %Rrc\n", offRegLog, *(uint8_t *)pv, rc)); 2740 3233 #endif 2741 3234 return rc; … … 2754 3247 int rc = g_aHdaRegMap[idxRegDsc].pfnWrite(pThis, idxRegDsc, u32Value); 2755 3248 LogFunc(("write %#x -> %s[%db]; %x => %x%s\n", u32Value, g_aHdaRegMap[idxRegDsc].abbrev, 2756 g_aHdaRegMap[idxRegDsc].size, u32CurValue, pThis->au32Regs[idxRegMem], pszLog));3249 g_aHdaRegMap[idxRegDsc].size, u32CurValue, pThis->au32Regs[idxRegMem], pszLog)); 2757 3250 return rc; 2758 3251 } … … 2790 3283 { 2791 3284 u64Value = 0; /* shut up gcc. */ 2792 AssertReleaseMsgFailed(("% d\n", cb));3285 AssertReleaseMsgFailed(("%u\n", cb)); 2793 3286 } 2794 3287 2795 3288 #ifdef LOG_ENABLED 2796 3289 uint32_t const u32LogOldValue = idxRegDsc >= 0 ? pThis->au32Regs[idxRegMem] : UINT32_MAX; 2797 uint32_t const offRegLog = offReg;2798 int const idxRegLog = idxRegMem;2799 3290 if (idxRegDsc == -1) 2800 3291 LogFunc(("@%#05x u32=%#010x cb=%d\n", offReg, *(uint32_t const *)pv, cb)); … … 2805 3296 else if (cb == 1) 2806 3297 LogFunc(("@%#05x u8=%#04x (%#010x) %s\n", offReg, *(uint8_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev)); 3298 2807 3299 if (idxRegDsc >= 0 && g_aHdaRegMap[idxRegDsc].size != cb) 2808 LogFunc((" size=%d != cb=%d!!\n", g_aHdaRegMap[idxRegDsc].size, cb));3300 LogFunc(("\tsize=%RU32 != cb=%u!!\n", g_aHdaRegMap[idxRegDsc].size, cb)); 2809 3301 #endif 2810 3302 2811 #define NEW_WRITE_CODE2812 #ifdef NEW_WRITE_CODE2813 3303 /* 2814 3304 * Try for a direct hit first. … … 2817 3307 { 2818 3308 rc = hdaWriteReg(pThis, idxRegDsc, u64Value, ""); 2819 LogFunc(("@%#05x %#x -> %#x\n", offRegLog, u32LogOldValue, 2820 idxRegLog != -1 ? pThis->au32Regs[idxRegLog] : UINT32_MAX)); 3309 #ifdef LOG_ENABLED 3310 LogFunc(("\t%#x -> %#x\n", u32LogOldValue, idxRegMem != UINT32_MAX ? pThis->au32Regs[idxRegMem] : UINT32_MAX)); 3311 #endif 2821 3312 } 2822 3313 /* … … 2825 3316 else 2826 3317 { 2827 /* If it's an access beyond the start of the register, shift the input 2828 value and fill in missing bits. Natural alignment rules means we 2829 will only see 1 or 2 byte accesses of this kind, so no risk of 2830 shifting out input values. */ 3318 /* 3319 * If it's an access beyond the start of the register, shift the input 3320 * value and fill in missing bits. Natural alignment rules means we 3321 * will only see 1 or 2 byte accesses of this kind, so no risk of 3322 * shifting out input values. 3323 */ 2831 3324 if (idxRegDsc == -1 && (idxRegDsc = hdaRegLookupWithin(pThis, offReg)) != -1) 2832 3325 { … … 2836 3329 u64Value <<= cbBefore * 8; 2837 3330 u64Value |= pThis->au32Regs[idxRegMem] & g_afMasks[cbBefore]; 2838 LogFunc((" Within register, supplied %u leading bits: %#llx -> %#llx ...\n",2839 cbBefore * 8, ~g_afMasks[cbBefore] & u64Value, u64Value));3331 LogFunc(("\tWithin register, supplied %u leading bits: %#llx -> %#llx ...\n", 3332 cbBefore * 8, ~g_afMasks[cbBefore] & u64Value, u64Value)); 2840 3333 } 2841 3334 … … 2852 3345 { 2853 3346 u64Value |= pThis->au32Regs[idxRegMem] & g_afMasks[cbReg] & ~g_afMasks[cb]; 2854 LogFunc((" Supplying missing bits (%#x): %#llx -> %#llx ...\n",2855 g_afMasks[cbReg] & ~g_afMasks[cb], u64Value & g_afMasks[cb], u64Value));3347 LogFunc(("\tSupplying missing bits (%#x): %#llx -> %#llx ...\n", 3348 g_afMasks[cbReg] & ~g_afMasks[cb], u64Value & g_afMasks[cb], u64Value)); 2856 3349 } 2857 3350 uint32_t u32LogOldVal = pThis->au32Regs[idxRegMem]; 2858 3351 rc = hdaWriteReg(pThis, idxRegDsc, u64Value, "*"); 2859 LogFunc(("@%#05x %#x -> %#x\n", offRegLog, u32LogOldVal, 2860 pThis->au32Regs[idxRegMem])); 3352 LogFunc(("\t%#x -> %#x\n", u32LogOldVal, pThis->au32Regs[idxRegMem])); 2861 3353 } 2862 3354 else 2863 3355 { 2864 LogRel(("HDA: Invalid write access @0x%x !\n", offReg));3356 LogRel(("HDA: Invalid write access @0x%x\n", offReg)); 2865 3357 cbReg = 1; 2866 3358 } … … 2870 3362 break; 2871 3363 2872 /* advance*/3364 /* Advance. */ 2873 3365 offReg += cbReg; 2874 3366 cb -= cbReg; … … 2881 3373 if ( (unsigned)idxRegDsc >= RT_ELEMENTS(g_aHdaRegMap) 2882 3374 || g_aHdaRegMap[idxRegDsc].offset != offReg) 3375 { 2883 3376 idxRegDsc = -1; 3377 } 2884 3378 } 2885 3379 } 2886 3380 } 2887 #else 2888 if (idxRegDsc != -1) 2889 { 2890 /** @todo r=bird: This looks like code for handling unaligned register 2891 * accesses. If it isn't, then add a comment explaining what you're 2892 * trying to do here. OTOH, if it is then it has the following 2893 * issues: 2894 * -# You're calculating the wrong new value for the register. 2895 * -# You're not handling cross register accesses. Imagine a 2896 * 4-byte write starting at CORBCTL, or a 8-byte write. 2897 * 2898 * PS! consider dropping the 'offset' argument to pfnWrite/pfnRead as 2899 * nobody seems to be using it and it just adds complexity when reading 2900 * the code. 2901 * 2902 */ 2903 uint32_t u32CurValue = pThis->au32Regs[idxRegMem]; 2904 uint32_t u32NewValue; 2905 uint32_t mask; 2906 switch (cb) 2907 { 2908 case 1: 2909 u32NewValue = *(uint8_t const *)pv; 2910 mask = 0xff; 2911 break; 2912 case 2: 2913 u32NewValue = *(uint16_t const *)pv; 2914 mask = 0xffff; 2915 break; 2916 case 4: 2917 case 8: 2918 /* 18.2 of the ICH6 datasheet defines the valid access widths as byte, word, and double word */ 2919 u32NewValue = *(uint32_t const *)pv; 2920 mask = 0xffffffff; 2921 cb = 4; 2922 break; 2923 default: 2924 AssertFailedReturn(VERR_INTERNAL_ERROR_4); /* shall not happen. */ 2925 } 2926 /* cross-register access, see corresponding comment in hdaMMIORead */ 2927 uint32_t shift = (g_aHdaRegMap[idxRegDsc].offset - offReg) % sizeof(uint32_t) * 8; 2928 mask <<= shift; 2929 u32NewValue <<= shift; 2930 u32NewValue &= mask; 2931 u32NewValue |= (u32CurValue & ~mask); 2932 2933 rc = g_aHdaRegMap[idxRegDsc].pfnWrite(pThis, idxRegDsc, u32NewValue); 2934 LogFunc(("write %s:(%x) %x => %x\n", g_aHdaRegMap[idxRegDsc].abbrev, u32NewValue, 2935 u32CurValue, pThis->au32Regs[idxRegMem])); 2936 } 2937 else 2938 rc = VINF_SUCCESS; 2939 2940 LogFunc(("@%#05x %#x -> %#x\n", offRegLog, u32LogOldValue, 2941 idxRegLog != -1 ? pThis->au32Regs[idxRegLog] : UINT32_MAX)); 2942 #endif 3381 2943 3382 return rc; 2944 3383 } … … 2967 3406 Assert(enmType == PCI_ADDRESS_SPACE_MEM); 2968 3407 rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/, 2969 #ifdef NEW_READ_CODE 2970 IOMMMIO_FLAGS_READ_DWORD | 2971 #else 2972 IOMMMIO_FLAGS_READ_PASSTHRU | 2973 #endif 2974 IOMMMIO_FLAGS_WRITE_PASSTHRU, 3408 IOMMMIO_FLAGS_READ_DWORD 3409 | IOMMMIO_FLAGS_WRITE_PASSTHRU, 2975 3410 hdaMMIOWrite, hdaMMIORead, "HDA"); 2976 3411 … … 3001 3436 /* Saved state callbacks. */ 3002 3437 3438 static int hdaSaveStream(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, PHDASTREAM pStrm) 3439 { 3440 /* Save stream ID. */ 3441 int rc = SSMR3PutU8(pSSM, pStrm->u8Strm); 3442 AssertRCReturn(rc, rc); 3443 Assert(pStrm->u8Strm <= 7); /** @todo Use a define. */ 3444 3445 rc = SSMR3PutStructEx(pSSM, &pStrm->State, sizeof(HDASTREAMSTATE), 0 /*fFlags*/, g_aSSMStreamStateFields5, NULL); 3446 AssertRCReturn(rc, rc); 3447 3448 for (uint32_t i = 0; i < pStrm->State.cBDLE; i++) 3449 { 3450 rc = SSMR3PutStructEx(pSSM, &pStrm->State.paBDLE[i], sizeof(HDABDLE), 0 /*fFlags*/, g_aSSMBDLEStateFields5, NULL); 3451 AssertRCReturn(rc, rc); 3452 } 3453 3454 return rc; 3455 } 3456 3003 3457 /** 3004 3458 * @callback_method_impl{FNSSMDEVSAVEEXEC} … … 3008 3462 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); 3009 3463 3010 /* Save Codec nodes states */3464 /* Save Codec nodes states. */ 3011 3465 hdaCodecSaveState(pThis->pCodec, pSSM); 3012 3466 3013 /* Save MMIO registers */3467 /* Save MMIO registers. */ 3014 3468 AssertCompile(RT_ELEMENTS(pThis->au32Regs) >= HDA_NREGS_SAVED); 3015 3469 SSMR3PutU32(pSSM, RT_ELEMENTS(pThis->au32Regs)); 3016 3470 SSMR3PutMem(pSSM, pThis->au32Regs, sizeof(pThis->au32Regs)); 3017 3471 3018 /* Save HDA dma counters */ 3019 SSMR3PutStructEx(pSSM, &pThis->StOutBdle, sizeof(pThis->StOutBdle), 0 /*fFlags*/, g_aHdaBDLEDescFields, NULL); 3020 SSMR3PutStructEx(pSSM, &pThis->StMicBdle, sizeof(pThis->StMicBdle), 0 /*fFlags*/, g_aHdaBDLEDescFields, NULL); 3021 SSMR3PutStructEx(pSSM, &pThis->StInBdle, sizeof(pThis->StInBdle), 0 /*fFlags*/, g_aHdaBDLEDescFields, NULL); 3022 return VINF_SUCCESS; 3472 /* Save number of streams. */ 3473 SSMR3PutU32(pSSM, 3); 3474 3475 /* Save stream states. */ 3476 int rc = hdaSaveStream(pDevIns, pSSM, &pThis->StrmStOut); 3477 AssertRCReturn(rc, rc); 3478 rc = hdaSaveStream(pDevIns, pSSM, &pThis->StrmStMicIn); 3479 AssertRCReturn(rc, rc); 3480 rc = hdaSaveStream(pDevIns, pSSM, &pThis->StrmStLineIn); 3481 AssertRCReturn(rc, rc); 3482 3483 return rc; 3023 3484 } 3024 3485 … … 3032 3493 3033 3494 Assert(uPass == SSM_PASS_FINAL); NOREF(uPass); 3495 3496 LogFlowFunc(("uVersion=%RU32, uPass=%RU32\n", uVersion, uPass)); 3034 3497 3035 3498 /* … … 3067 3530 break; 3068 3531 3532 /* Since version 4 we store the register count to stay flexible. */ 3533 case HDA_SSM_VERSION_4: 3069 3534 case HDA_SSM_VERSION: 3070 3535 rc = SSMR3GetU32(pSSM, &cRegs); AssertRCReturn(rc, rc); … … 3086 3551 3087 3552 /* 3088 * Load HDA DMA counters. 3553 * Note: Saved states < v5 store LVI (u32BdleMaxCvi) for 3554 * *every* BDLE state, whereas it only needs to be stored 3555 * *once* for every stream. Most of the BDLE state we can 3556 * get out of the registers anyway, so just ignore those values. 3557 * 3558 * Also, only the current BDLE was saved, regardless whether 3559 * there were more than one (and there are at least two entries, 3560 * according to the spec). 3089 3561 */ 3090 uint32_t fFlags = uVersion <= HDA_SSM_VERSION_2 ? SSMSTRUCT_FLAGS_MEM_BAND_AID_RELAXED : 0; 3091 PCSSMFIELD paFields = uVersion <= HDA_SSM_VERSION_2 ? g_aHdaBDLEDescFieldsOld : g_aHdaBDLEDescFields; 3092 rc = SSMR3GetStructEx(pSSM, &pThis->StOutBdle, sizeof(pThis->StOutBdle), fFlags, paFields, NULL); 3093 AssertRCReturn(rc, rc); 3094 rc = SSMR3GetStructEx(pSSM, &pThis->StMicBdle, sizeof(pThis->StMicBdle), fFlags, paFields, NULL); 3095 AssertRCReturn(rc, rc); 3096 rc = SSMR3GetStructEx(pSSM, &pThis->StInBdle, sizeof(pThis->StInBdle), fFlags, paFields, NULL); 3097 AssertRCReturn(rc, rc); 3562 #define HDA_SSM_LOAD_BDLE_STATE_PRE_V5(v, x) \ 3563 rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* Begin marker */ \ 3564 AssertRCReturn(rc, rc); \ 3565 rc = SSMR3Skip(pSSM, sizeof(uint64_t)); /* u64BdleCviAddr */ \ 3566 AssertRCReturn(rc, rc); \ 3567 rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* u32BdleMaxCvi */ \ 3568 AssertRCReturn(rc, rc); \ 3569 rc = SSMR3GetU32(pSSM, &x->u32BDLIndex); /* u32BdleCvi */ \ 3570 AssertRCReturn(rc, rc); \ 3571 rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* u32BdleCviLen */ \ 3572 AssertRCReturn(rc, rc); \ 3573 rc = SSMR3GetU32(pSSM, &x->u32BufOff); /* u32BdleCviPos */ \ 3574 AssertRCReturn(rc, rc); \ 3575 rc = SSMR3Skip(pSSM, sizeof(uint8_t)); /* fBdleCviIoc */ \ 3576 AssertRCReturn(rc, rc); \ 3577 rc = SSMR3GetU32(pSSM, &x->cbBelowFIFOW); /* cbUnderFifoW */ \ 3578 AssertRCReturn(rc, rc); \ 3579 rc = SSMR3GetMem(pSSM, &x->au8FIFO, sizeof(x->au8FIFO)); \ 3580 AssertRCReturn(rc, rc); \ 3581 rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* End marker */ \ 3582 AssertRCReturn(rc, rc); \ 3098 3583 3099 3584 /* 3100 * Update stuff after the state changes.3585 * Load BDLEs (Buffer Descriptor List Entries) and DMA counters. 3101 3586 */ 3102 bool fEnableIn = RT_BOOL(SDCTL(pThis, 0) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 3587 HDABDLESTATE StateBDLEDummy; 3588 3589 switch (uVersion) 3590 { 3591 case HDA_SSM_VERSION_1: 3592 case HDA_SSM_VERSION_2: 3593 case HDA_SSM_VERSION_3: 3594 case HDA_SSM_VERSION_4: 3595 { 3596 /* Only load the internal states. 3597 * The rest will be initialized from the saved registers later. */ 3598 3599 /* Note: Only the *current* BDLE for a stream was saved! */ 3600 3601 /* Output */ 3602 rc = hdaStreamInit(pThis, &pThis->StrmStOut, 4 /* Stream number, hardcoded */); 3603 AssertRCBreak(rc); 3604 HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, ( pThis->StrmStOut.State.cBDLE 3605 ? &pThis->StrmStOut.State.paBDLE[0].State : &StateBDLEDummy)); 3606 /* Microphone-In */ 3607 rc = hdaStreamInit(pThis, &pThis->StrmStMicIn, 2 /* Stream number, hardcoded */); 3608 AssertRCBreak(rc); 3609 HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, ( pThis->StrmStMicIn.State.cBDLE 3610 ? &pThis->StrmStMicIn.State.paBDLE[0].State : &StateBDLEDummy)); 3611 /* Line-In */ 3612 rc = hdaStreamInit(pThis, &pThis->StrmStLineIn, 0 /* Stream number, hardcoded */); 3613 AssertRCBreak(rc); 3614 HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, ( pThis->StrmStLineIn.State.cBDLE 3615 ? &pThis->StrmStLineIn.State.paBDLE[0].State : &StateBDLEDummy)); 3616 break; 3617 } 3618 3619 /* Since v5 we support flexible stream and BDLE counts. */ 3620 case HDA_SSM_VERSION: 3621 { 3622 uint32_t cStreams; 3623 rc = SSMR3GetU32(pSSM, &cStreams); 3624 AssertRCBreak(rc); 3625 3626 /* Load stream states. */ 3627 for (uint32_t i = 0; i < cStreams; i++) 3628 { 3629 uint8_t uStreamID; 3630 rc = SSMR3GetU8(pSSM, &uStreamID); 3631 AssertRCBreak(rc); 3632 3633 PHDASTREAM pStrm; 3634 HDASTREAM StreamDummy; 3635 3636 switch (uStreamID) 3637 { 3638 case 0: /** @todo Use a define. */ 3639 pStrm = &pThis->StrmStLineIn; 3640 break; 3641 3642 case 2: /** @todo Use a define. */ 3643 pStrm = &pThis->StrmStMicIn; 3644 break; 3645 3646 case 4: /** @todo Use a define. */ 3647 pStrm = &pThis->StrmStOut; 3648 break; 3649 3650 default: 3651 pStrm = &StreamDummy; 3652 break; 3653 } 3654 3655 rc = SSMR3GetStructEx(pSSM, &pStrm->State, sizeof(HDASTREAMSTATE), 0 /* fFlags */, g_aSSMStreamStateFields5, NULL); 3656 AssertRCBreak(rc); 3657 3658 rc = hdaStreamInit(pThis, pStrm, uStreamID); 3659 AssertRCBreak(rc); 3660 3661 /* Load BDLE states. */ 3662 for (uint32_t a = 0; a < pStrm->State.cBDLE; a++) 3663 { 3664 rc = SSMR3GetStructEx(pSSM, &pStrm->State.paBDLE[a].State, sizeof(HDABDLESTATE), 3665 0 /* fFlags */, g_aSSMBDLEStateFields5, NULL); 3666 AssertRCBreak(rc); 3667 } 3668 3669 /* Destroy dummy again. */ 3670 if (pStrm == &StreamDummy) 3671 hdaStreamDestroy(pStrm); 3672 } 3673 break; 3674 } 3675 3676 default: 3677 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; 3678 } 3679 3680 #undef HDA_SSM_LOAD_BDLE_STATE_PRE_V5 3681 3682 if (RT_SUCCESS(rc)) 3683 { 3684 /* 3685 * Update stuff after the state changes. 3686 */ 3687 bool fEnableIn = RT_BOOL(HDA_SDCTL(pThis, 0) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 3103 3688 #ifdef VBOX_WITH_HDA_MIC_IN 3104 bool fEnableMicIn = RT_BOOL(SDCTL(pThis, 2) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));3689 bool fEnableMicIn = RT_BOOL(HDA_SDCTL(pThis, 2) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 3105 3690 #else 3106 bool fEnableMicIn = fEnableIn; /* Mic In == Line In */3691 bool fEnableMicIn = fEnableIn; /* Mic In == Line In */ 3107 3692 #endif 3108 bool fEnableOut = RT_BOOL(SDCTL(pThis, 4) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 3109 3110 PHDADRIVER pDrv; 3111 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 3112 { 3113 rc = pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->LineIn.pStrmIn, fEnableIn); 3114 if (RT_FAILURE(rc)) 3115 break; 3116 rc = pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->MicIn.pStrmIn, fEnableMicIn); 3117 if (RT_FAILURE(rc)) 3118 break; 3119 rc = pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->Out.pStrmOut, fEnableOut); 3120 if (RT_FAILURE(rc)) 3121 break; 3693 bool fEnableOut = RT_BOOL(HDA_SDCTL(pThis, 4) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 3694 3695 PHDADRIVER pDrv; 3696 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 3697 { 3698 rc = pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->LineIn.pStrmIn, fEnableIn); 3699 if (RT_FAILURE(rc)) 3700 break; 3701 rc = pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->MicIn.pStrmIn, fEnableMicIn); 3702 if (RT_FAILURE(rc)) 3703 break; 3704 rc = pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->Out.pStrmOut, fEnableOut); 3705 if (RT_FAILURE(rc)) 3706 break; 3707 } 3122 3708 } 3123 3709 … … 3133 3719 } 3134 3720 3135 3721 #ifdef DEBUG 3136 3722 /* Debug and log type formatters. */ 3137 3723 … … 3139 3725 * @callback_method_impl{FNRTSTRFORMATTYPE} 3140 3726 */ 3141 static DECLCALLBACK(size_t) 3142 hdaFormatStrmCtl(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, 3143 const char *pszType, void const *pvValue, 3144 int cchWidth, int cchPrecision, unsigned fFlags, 3145 void *pvUser) 3146 { 3147 uint32_t sdCtl = (uint32_t)(uintptr_t)pvValue; 3148 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, 3149 "SDCTL(raw: %#x, strm:%#x, dir:%RTbool, tp:%RTbool strip:%x, deie:%RTbool, ioce:%RTbool, run:%RTbool, srst:%RTbool)", 3150 sdCtl, 3151 (sdCtl & HDA_REG_FIELD_MASK(SDCTL, NUM)) >> HDA_SDCTL_NUM_SHIFT, 3152 RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, DIR)), 3153 RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, TP)), 3154 (sdCtl & HDA_REG_FIELD_MASK(SDCTL, STRIPE)) >> HDA_SDCTL_STRIPE_SHIFT, 3155 RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, DEIE)), 3156 RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE)), 3157 RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)), 3158 RT_BOOL(sdCtl & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST))); 3727 static DECLCALLBACK(size_t) hdaDbgFmtBDLE(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, 3728 const char *pszType, void const *pvValue, 3729 int cchWidth, int cchPrecision, unsigned fFlags, 3730 void *pvUser) 3731 { 3732 PHDABDLE pBDLE = (PHDABDLE)pvValue; 3733 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, 3734 "BDLE(idx:%RU32, off:%RU32, fifow:%RU32, DMA[%RU32 bytes @ 0x%x])", 3735 pBDLE->State.u32BDLIndex, pBDLE->State.u32BufOff, pBDLE->State.cbBelowFIFOW, pBDLE->u32BufSize, pBDLE->u64BufAdr); 3159 3736 } 3160 3737 … … 3162 3739 * @callback_method_impl{FNRTSTRFORMATTYPE} 3163 3740 */ 3164 static DECLCALLBACK(size_t) 3165 hdaFormatStrmFifos(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, 3166 const char *pszType, void const *pvValue, 3167 int cchWidth, int cchPrecision, unsigned fFlags, 3168 void *pvUser) 3169 { 3170 uint32_t uSdFifos = (uint32_t)(uintptr_t)pvValue; 3171 uint32_t cb; 3172 switch (uSdFifos) 3173 { 3174 case HDA_SDONFIFO_16B: cb = 16; break; 3175 case HDA_SDONFIFO_32B: cb = 32; break; 3176 case HDA_SDONFIFO_64B: cb = 64; break; 3177 case HDA_SDONFIFO_128B: cb = 128; break; 3178 case HDA_SDONFIFO_192B: cb = 192; break; 3179 case HDA_SDONFIFO_256B: cb = 256; break; 3180 case HDA_SDINFIFO_120B: cb = 120; break; 3181 case HDA_SDINFIFO_160B: cb = 160; break; 3182 default: cb = 0; break; 3183 } 3184 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "SDFIFOS(raw: %#x, sdfifos:%u B)", uSdFifos, cb); 3741 static DECLCALLBACK(size_t) hdaDbgFmtSDCTL(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, 3742 const char *pszType, void const *pvValue, 3743 int cchWidth, int cchPrecision, unsigned fFlags, 3744 void *pvUser) 3745 { 3746 uint32_t uSDCTL = (uint32_t)(uintptr_t)pvValue; 3747 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, 3748 "SDCTL(raw:%#x, DIR:%s, TP:%RTbool, STRIPE:%x, DEIE:%RTbool, FEIE:%RTbool, IOCE:%RTbool, RUN:%RTbool, RESET:%RTbool)", 3749 uSDCTL, 3750 (uSDCTL & HDA_REG_FIELD_FLAG_MASK(SDCTL, DIR)) ? "OUT" : "IN", 3751 RT_BOOL(uSDCTL & HDA_REG_FIELD_FLAG_MASK(SDCTL, TP)), 3752 (uSDCTL & HDA_REG_FIELD_MASK(SDCTL, STRIPE)) >> HDA_SDCTL_STRIPE_SHIFT, 3753 RT_BOOL(uSDCTL & HDA_REG_FIELD_FLAG_MASK(SDCTL, DEIE)), 3754 RT_BOOL(uSDCTL & HDA_REG_FIELD_FLAG_MASK(SDCTL, FEIE)), 3755 RT_BOOL(uSDCTL & HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE)), 3756 RT_BOOL(uSDCTL & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)), 3757 RT_BOOL(uSDCTL & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST))); 3185 3758 } 3186 3759 … … 3188 3761 * @callback_method_impl{FNRTSTRFORMATTYPE} 3189 3762 */ 3190 static DECLCALLBACK(size_t) 3191 hdaFormatStrmFifow(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, 3192 const char *pszType, void const *pvValue, 3193 int cchWidth, int cchPrecision, unsigned fFlags, 3194 void *pvUser) 3195 { 3196 uint32_t uSdFifos = (uint32_t)(uintptr_t)pvValue; 3197 uint32_t cb; 3198 switch (uSdFifos) 3199 { 3200 case HDA_SDFIFOW_8B: cb = 8; break; 3201 case HDA_SDFIFOW_16B: cb = 16; break; 3202 case HDA_SDFIFOW_32B: cb = 32; break; 3203 default: cb = 0; break; 3204 } 3205 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "SDFIFOW(raw: %#0x, sdfifow:%d B)", uSdFifos, cb); 3763 static DECLCALLBACK(size_t) hdaDbgFmtSDFIFOS(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, 3764 const char *pszType, void const *pvValue, 3765 int cchWidth, int cchPrecision, unsigned fFlags, 3766 void *pvUser) 3767 { 3768 uint32_t uSDFIFOS = (uint32_t)(uintptr_t)pvValue; 3769 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "SDFIFOS(raw:%#x, sdfifos:%RU8 B)", uSDFIFOS, hdaSDFIFOSToBytes(uSDFIFOS)); 3206 3770 } 3207 3771 … … 3209 3773 * @callback_method_impl{FNRTSTRFORMATTYPE} 3210 3774 */ 3211 static DECLCALLBACK(size_t) 3212 hdaFormatStrmSts(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, 3213 const char *pszType, void const *pvValue, 3214 int cchWidth, int cchPrecision, unsigned fFlags, 3215 void *pvUser) 3775 static DECLCALLBACK(size_t) hdaDbgFmtSDFIFOW(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, 3776 const char *pszType, void const *pvValue, 3777 int cchWidth, int cchPrecision, unsigned fFlags, 3778 void *pvUser) 3779 { 3780 uint32_t uSDFIFOW = (uint32_t)(uintptr_t)pvValue; 3781 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "SDFIFOW(raw: %#0x, sdfifow:%d B)", uSDFIFOW, hdaSDFIFOWToBytes(uSDFIFOW)); 3782 } 3783 3784 /** 3785 * @callback_method_impl{FNRTSTRFORMATTYPE} 3786 */ 3787 static DECLCALLBACK(size_t) hdaDbgFmtSDSTS(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, 3788 const char *pszType, void const *pvValue, 3789 int cchWidth, int cchPrecision, unsigned fFlags, 3790 void *pvUser) 3216 3791 { 3217 3792 uint32_t uSdSts = (uint32_t)(uintptr_t)pvValue; 3218 3793 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, 3219 "SDSTS(raw: 3794 "SDSTS(raw:%#0x, fifordy:%RTbool, dese:%RTbool, fifoe:%RTbool, bcis:%RTbool)", 3220 3795 uSdSts, 3221 3796 RT_BOOL(uSdSts & HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY)), … … 3225 3800 } 3226 3801 3227 3228 3802 static int hdaLookUpRegisterByName(PHDASTATE pThis, const char *pszArgs) 3229 3803 { … … 3243 3817 pHlp->pfnPrintf(pHlp, "%s: 0x%x\n", g_aHdaRegMap[iHdaIndex].abbrev, pThis->au32Regs[g_aHdaRegMap[iHdaIndex].mem_idx]); 3244 3818 } 3245 3246 3819 3247 3820 /** … … 3258 3831 hdaDbgPrintRegister(pThis, pHlp, iHdaRegisterIndex); 3259 3832 } 3260 3261 3833 3262 3834 static void hdaDbgPrintStream(PHDASTATE pThis, PCDBGFINFOHLP pHlp, int iHdaStrmIndex) … … 3272 3844 } 3273 3845 3274 3275 3846 static int hdaLookUpStreamIndex(PHDASTATE pThis, const char *pszArgs) 3276 3847 { … … 3278 3849 return -1; 3279 3850 } 3280 3281 3851 3282 3852 /** … … 3294 3864 } 3295 3865 3296 3297 3866 /** 3298 3867 * @callback_method_impl{FNDBGFHANDLERDEV} … … 3308 3877 } 3309 3878 3310 3311 3879 /** 3312 3880 * @callback_method_impl{FNDBGFHANDLERDEV} … … 3322 3890 } 3323 3891 3324 3325 3892 /** 3326 3893 * @callback_method_impl{FNDBGFHANDLERDEV} … … 3335 3902 pHlp->pfnPrintf(pHlp, "Mixer not available\n"); 3336 3903 } 3337 3904 #endif /* DEBUG */ 3338 3905 3339 3906 /* PDMIBASE */ … … 3366 3933 { 3367 3934 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); 3935 3368 3936 HDA_REG(pThis, GCAP) = HDA_MAKE_GCAP(4,4,0,0,1); /* see 6.2.1 */ 3369 HDA_REG(pThis, VMIN) = 0x00; /* see 6.2.2 */3370 HDA_REG(pThis, VMAJ) = 0x01; /* see 6.2.3 */3371 HDA_REG(pThis, OUTPAY) = 0x003C; /* see 6.2.4 */3372 HDA_REG(pThis, INPAY) = 0x001D; /* see 6.2.5 */3373 HDA_REG(pThis, CORBSIZE) = 0x42; /* see 6.2.1 */3374 HDA_REG(pThis, RIRBSIZE) = 0x42; /* see 6.2.1 */3937 HDA_REG(pThis, VMIN) = 0x00; /* see 6.2.2 */ 3938 HDA_REG(pThis, VMAJ) = 0x01; /* see 6.2.3 */ 3939 HDA_REG(pThis, OUTPAY) = 0x003C; /* see 6.2.4 */ 3940 HDA_REG(pThis, INPAY) = 0x001D; /* see 6.2.5 */ 3941 HDA_REG(pThis, CORBSIZE) = 0x42; /* see 6.2.1 */ 3942 HDA_REG(pThis, RIRBSIZE) = 0x42; /* see 6.2.1 */ 3375 3943 HDA_REG(pThis, CORBRP) = 0x0; 3376 3944 HDA_REG(pThis, RIRBWP) = 0x0; … … 3390 3958 } 3391 3959 3392 pThis->cbCorbBuf = 256 * sizeof(uint32_t); 3960 pThis->cbCorbBuf = 256 * sizeof(uint32_t); /** @todo Use a define here. */ 3393 3961 3394 3962 if (pThis->pu32CorbBuf) … … 3397 3965 pThis->pu32CorbBuf = (uint32_t *)RTMemAllocZ(pThis->cbCorbBuf); 3398 3966 3399 pThis->cbRirbBuf = 256 * sizeof(uint64_t); 3967 pThis->cbRirbBuf = 256 * sizeof(uint64_t); /** @todo Use a define here. */ 3400 3968 if (pThis->pu64RirbBuf) 3401 3969 RT_BZERO(pThis->pu64RirbBuf, pThis->cbRirbBuf); … … 3405 3973 pThis->u64BaseTS = PDMDevHlpTMTimeVirtGetNano(pDevIns); 3406 3974 3407 HDABDLEDESC StEmptyBdle; 3408 for (uint8_t u8Strm = 0; u8Strm < 8; ++u8Strm) 3409 { 3410 HDASTREAMTRANSFERDESC StreamDesc; 3411 PHDABDLEDESC pBdle = NULL; 3975 for (uint8_t u8Strm = 0; u8Strm < 8; u8Strm++) /** @todo Use a define here. */ 3976 { 3977 PHDASTREAM pStrmSt = NULL; 3412 3978 if (u8Strm == 0) 3413 p Bdle = &pThis->StInBdle;3979 pStrmSt = &pThis->StrmStOut; 3414 3980 # ifdef VBOX_WITH_HDA_MIC_IN 3415 3981 else if (u8Strm == 2) 3416 p Bdle = &pThis->StMicBdle;3982 pStrmSt = &pThis->StrmStMicIn; 3417 3983 # endif 3418 else if(u8Strm == 4) 3419 pBdle = &pThis->StOutBdle; 3420 else 3421 { 3422 RT_ZERO(StEmptyBdle); 3423 pBdle = &StEmptyBdle; 3424 } 3425 hdaInitTransferDescriptor(pThis, pBdle, u8Strm, &StreamDesc); 3426 /* hdaStreamReset prevents changing the SRST bit, so we force it to zero here. */ 3427 HDA_STREAM_REG(pThis, CTL, u8Strm) = 0; 3428 hdaStreamReset(pThis, pBdle, &StreamDesc, u8Strm); 3984 else if (u8Strm == 4) 3985 pStrmSt = &pThis->StrmStLineIn; 3986 3987 if (pStrmSt) 3988 { 3989 /* hdaStreamReset prevents changing the SRST bit, so we force it to zero here. */ 3990 HDA_STREAM_REG(pThis, CTL, u8Strm) = 0; 3991 3992 hdaStreamReset(pThis, pStrmSt, u8Strm); 3993 } 3429 3994 } 3430 3995 … … 3471 4036 RTMemFree(pThis->pu64RirbBuf); 3472 4037 pThis->pu64RirbBuf = NULL; 4038 4039 hdaStreamDestroy(&pThis->StrmStLineIn); 4040 hdaStreamDestroy(&pThis->StrmStMicIn); 4041 hdaStreamDestroy(&pThis->StrmStOut); 3473 4042 3474 4043 return VINF_SUCCESS; … … 3512 4081 { 3513 4082 pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR); 3514 AssertMsg(pDrv->pConnector != NULL, 3515 ("Configuration error: LUN#%u has no host audio interface, rc=%Rrc\n", 3516 uLUN, rc)); 3517 pDrv->pHDAState = pThis; 3518 pDrv->uLUN = uLUN; 4083 AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN#%u has no host audio interface, rc=%Rrc\n", uLUN, rc)); 4084 pDrv->pHDAState = pThis; 4085 pDrv->uLUN = uLUN; 3519 4086 3520 4087 /* … … 3761 4328 3762 4329 /* Audio driver callbacks for multiplexing. */ 3763 pThis->pCodec->pfn DestroyIn = hdaDestroyIn;3764 pThis->pCodec->pfn DestroyOut = hdaDestroyOut;3765 pThis->pCodec->pfn CreateIn = hdaCreateIn;3766 pThis->pCodec->pfn CreateOut = hdaCreateOut;3767 pThis->pCodec->pfnReset 3768 pThis->pCodec->pfnSetVolume 4330 pThis->pCodec->pfnCloseIn = hdaCloseIn; 4331 pThis->pCodec->pfnCloseOut = hdaCloseOut; 4332 pThis->pCodec->pfnOpenIn = hdaOpenIn; 4333 pThis->pCodec->pfnOpenOut = hdaOpenOut; 4334 pThis->pCodec->pfnReset = hdaCodecReset; 4335 pThis->pCodec->pfnSetVolume = hdaSetVolume; 3769 4336 3770 4337 pThis->pCodec->pHDAState = pThis; /* Assign HDA controller state to codec. */ … … 3794 4361 HDA_REG(pThis, STATESTS) = 0x0; 3795 4362 4363 #ifdef DEBUG 3796 4364 /* 3797 4365 * Debug and string formatter types. … … 3803 4371 PDMDevHlpDBGFInfoRegister(pDevIns, "hdamixer", "HDA mixer state.", hdaInfoMixer); 3804 4372 3805 rc = RTStrFormatTypeRegister(" sdctl", hdaFormatStrmCtl,NULL);4373 rc = RTStrFormatTypeRegister("bdle", hdaDbgFmtBDLE, NULL); 3806 4374 AssertRC(rc); 3807 rc = RTStrFormatTypeRegister("sd sts", hdaFormatStrmSts, NULL);4375 rc = RTStrFormatTypeRegister("sdctl", hdaDbgFmtSDCTL, NULL); 3808 4376 AssertRC(rc); 3809 rc = RTStrFormatTypeRegister("sd fifos", hdaFormatStrmFifos,NULL);4377 rc = RTStrFormatTypeRegister("sdsts", hdaDbgFmtSDSTS, NULL); 3810 4378 AssertRC(rc); 3811 rc = RTStrFormatTypeRegister("sdfifo w", hdaFormatStrmFifow, NULL);4379 rc = RTStrFormatTypeRegister("sdfifos", hdaDbgFmtSDFIFOS, NULL); 3812 4380 AssertRC(rc); 3813 #if 0 3814 rc = RTStrFormatTypeRegister("sdfmt", printHdaStrmFmt, NULL); 4381 rc = RTStrFormatTypeRegister("sdfifow", hdaDbgFmtSDFIFOW, NULL); 3815 4382 AssertRC(rc); 3816 #endif 4383 #endif /* DEBUG */ 3817 4384 3818 4385 /* … … 3847 4414 i - 1, pPrevReg->offset, pPrevReg->size, i + 1, pReg->offset, pReg->size)); 3848 4415 } 3849 4416 #if 0 3850 4417 if ((pReg->offset + pReg->size) & 3) 3851 4418 { … … 3856 4423 i, pReg->offset, pReg->size, i + 1, pNextReg->offset, pNextReg->size)); 3857 4424 } 3858 #endif 3859 4425 #endif 3860 4426 /* The final entry is a full DWORD, no gaps! Allows shortcuts. */ 3861 4427 AssertReleaseMsg(pNextReg || ((pReg->offset + pReg->size) & 3) == 0, … … 3864 4430 } 3865 4431 4432 # ifndef VBOX_WITH_AUDIO_CALLBACKS 3866 4433 if (RT_SUCCESS(rc)) 3867 4434 { … … 3884 4451 } 3885 4452 } 4453 # else 4454 if (RT_SUCCESS(rc)) 4455 { 4456 PHDADRIVER pDrv; 4457 RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node) 4458 { 4459 /* Only register primary driver. 4460 * The device emulation does the output multiplexing then. */ 4461 if (pDrv->Flags != PDMAUDIODRVFLAG_PRIMARY) 4462 continue; 4463 4464 PDMAUDIOCALLBACK AudioCallbacks[2]; 4465 4466 HDACALLBACKCTX Ctx = { pThis, pDrv }; 4467 4468 AudioCallbacks[0].enmType = PDMAUDIOCALLBACKTYPE_INPUT; 4469 AudioCallbacks[0].pfnCallback = hdaCallbackInput; 4470 AudioCallbacks[0].pvCtx = &Ctx; 4471 AudioCallbacks[0].cbCtx = sizeof(HDACALLBACKCTX); 4472 4473 AudioCallbacks[1].enmType = PDMAUDIOCALLBACKTYPE_OUTPUT; 4474 AudioCallbacks[1].pfnCallback = hdaCallbackOutput; 4475 AudioCallbacks[1].pvCtx = &Ctx; 4476 AudioCallbacks[1].cbCtx = sizeof(HDACALLBACKCTX); 4477 4478 rc = pDrv->pConnector->pfnRegisterCallbacks(pDrv->pConnector, AudioCallbacks, RT_ELEMENTS(AudioCallbacks)); 4479 if (RT_FAILURE(rc)) 4480 break; 4481 } 4482 } 4483 # endif 3886 4484 3887 4485 # ifdef VBOX_WITH_STATISTICS … … 3891 4489 * Register statistics. 3892 4490 */ 4491 # ifndef VBOX_WITH_AUDIO_CALLBACKS 3893 4492 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatTimer, STAMTYPE_PROFILE, "/Devices/HDA/Timer", STAMUNIT_TICKS_PER_CALL, "Profiling hdaTimer."); 4493 # endif 3894 4494 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatBytesRead, STAMTYPE_COUNTER, "/Devices/HDA/BytesRead" , STAMUNIT_BYTES, "Bytes read from HDA emulation."); 3895 4495 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatBytesWritten, STAMTYPE_COUNTER, "/Devices/HDA/BytesWritten", STAMUNIT_BYTES, "Bytes written to HDA emulation."); -
trunk/src/VBox/Devices/Audio/DevIchHdaCodec.cpp
r58600 r58900 2611 2611 { 2612 2612 case PI_INDEX: 2613 rc = pThis->pfn CreateIn(pThis->pHDAState, "hda.in", PDMAUDIORECSOURCE_LINE_IN, pCfg);2613 rc = pThis->pfnOpenIn(pThis->pHDAState, "hda.in", PDMAUDIORECSOURCE_LINE_IN, pCfg); 2614 2614 break; 2615 2615 2616 2616 case PO_INDEX: 2617 rc = pThis->pfn CreateOut(pThis->pHDAState, "hda.out", pCfg);2617 rc = pThis->pfnOpenOut(pThis->pHDAState, "hda.out", pCfg); 2618 2618 break; 2619 2619 2620 2620 #ifdef VBOX_WITH_HDA_MIC_IN 2621 2621 case MC_INDEX: 2622 rc = pThis->pfn CreateIn(pThis->pHDAState, "hda.mc", PDMAUDIORECSOURCE_MIC, pCfg);2622 rc = pThis->pfnOpenIn(pThis->pHDAState, "hda.mc", PDMAUDIORECSOURCE_MIC, pCfg); 2623 2623 break; 2624 2624 #endif … … 2662 2662 break; 2663 2663 2664 /* Since version 4 a flexible node count is supported. */ 2665 case HDA_SSM_VERSION_4: 2664 2666 case HDA_SSM_VERSION: 2665 2667 { -
trunk/src/VBox/Devices/Audio/DevIchHdaCodec.h
r58600 r58900 111 111 #endif 112 112 /** Callbacks to the HDA controller, mostly used for multiplexing to the various host backends. */ 113 DECLR3CALLBACKMEMBER(void, pfn DestroyIn, (PHDASTATE pThis, PDMAUDIORECSOURCE enmRecSource));114 DECLR3CALLBACKMEMBER(void, pfn DestroyOut, (PHDASTATE pThis));115 DECLR3CALLBACKMEMBER(int, pfn CreateIn, (PHDASTATE pThis, const char *pszName, PDMAUDIORECSOURCE enmRecSource, PPDMAUDIOSTREAMCFG pCfg));116 DECLR3CALLBACKMEMBER(int, pfn CreateOut, (PHDASTATE pThis, const char *pszName, PPDMAUDIOSTREAMCFG pCfg));113 DECLR3CALLBACKMEMBER(void, pfnCloseIn, (PHDASTATE pThis, PDMAUDIORECSOURCE enmRecSource)); 114 DECLR3CALLBACKMEMBER(void, pfnCloseOut, (PHDASTATE pThis)); 115 DECLR3CALLBACKMEMBER(int, pfnOpenIn, (PHDASTATE pThis, const char *pszName, PDMAUDIORECSOURCE enmRecSource, PPDMAUDIOSTREAMCFG pCfg)); 116 DECLR3CALLBACKMEMBER(int, pfnOpenOut, (PHDASTATE pThis, const char *pszName, PPDMAUDIOSTREAMCFG pCfg)); 117 117 DECLR3CALLBACKMEMBER(int, pfnSetVolume, (PHDASTATE pThis, ENMSOUNDSOURCE enmSource, bool fMute, uint8_t uVolLeft, uint8_t uVolRight)); 118 118 /** Callbacks by codec implementation. */ … … 131 131 int hdaCodecOpenStream(PHDACODEC pThis, PDMAUDIORECSOURCE enmRecSource, PDMAUDIOSTREAMCFG *pAudioSettings); 132 132 133 #define HDA_SSM_VERSION 4133 #define HDA_SSM_VERSION 5 134 134 #define HDA_SSM_VERSION_1 1 135 135 #define HDA_SSM_VERSION_2 2 136 136 #define HDA_SSM_VERSION_3 3 137 /* Since this version the number of MMIO registers can be flexible. */ 138 #define HDA_SSM_VERSION_4 4 137 139 138 140 # ifdef VBOX_WITH_HDA_CODEC_EMU
Note:
See TracChangeset
for help on using the changeset viewer.