VirtualBox

Changeset 58900 in vbox for trunk/src/VBox/Devices/Audio


Ignore:
Timestamp:
Nov 27, 2015 11:58:18 AM (9 years ago)
Author:
vboxsync
Message:

Audio: Big revamp of the HDA emulation; also introduced (not yet completed) support for audio callbacks for the audio connector interface / backends. Currently still has some noise quirks, work in progress.

Location:
trunk/src/VBox/Devices/Audio
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DevIchHda.cpp

    r58600 r58900  
    3333#include <iprt/asm.h>
    3434#include <iprt/asm-math.h>
     35#include <iprt/list.h>
    3536#ifdef IN_RING3
     37# include <iprt/mem.h>
     38# include <iprt/string.h>
    3639# include <iprt/uuid.h>
    37 # include <iprt/string.h>
    38 # include <iprt/mem.h>
    3940#endif
    40 #include <iprt/list.h>
    4141
    4242#include "VBoxDD.h"
     
    277277#define HDA_RMX_DPUBASE             31
    278278#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)
    280281#define DPBASE_ADDR_MASK            (~(uint64_t)0x7f)
    281282
     
    284285/* Note: sdnum here _MUST_ be stream reg number [0,7]. */
    285286#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)
    286289
    287290#define HDA_REG_SD0CTL              34 /* 0x80 */
     
    303306
    304307#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))
    307311#define HDA_SDCTL_NUM_MASK          0xF
    308312#define HDA_SDCTL_NUM_SHIFT         20
     
    374378#define HDA_RMX_SD7CBL              (HDA_STREAM_RMX_DEF(CBL, 0) + 70)
    375379
    376 
    377380#define HDA_REG_SD0LVI              38 /* 0x8C */
    378381#define HDA_REG_SD1LVI              (HDA_STREAM_REG_DEF(LVI, 0) + 10) /* 0xAC */
     
    410413
    411414/*
    412  * ICH6 datasheet defined limits for FIFOW values (18.2.38)
     415 * ICH6 datasheet defined limits for FIFOW values (18.2.38).
    413416 */
    414417#define HDA_SDFIFOW_8B              0x2
     
    438441 * Other values not listed are not supported.
    439442 */
     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
    440446#define HDA_SDONFIFO_16B            0x0F /* 8-, 16-, 20-, 24-, 32-bit Output Streams */
    441447#define HDA_SDONFIFO_32B            0x1F /* 8-, 16-, 20-, 24-, 32-bit Output Streams */
     
    444450#define HDA_SDONFIFO_192B           0xBF /* 8-, 16-, 20-, 24-, 32-bit Output Streams */
    445451#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 */
    448452#define SDFIFOS(pThis, num)         HDA_REG((pThis), SD(FIFOS, num))
    449453
     
    520524*   Structures and Typedefs                                                                                                      *
    521525*********************************************************************************************************************************/
    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 */
     532typedef 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 */
     551typedef 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 */
     569typedef 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 */
     587typedef 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;
    544609
    545610typedef struct HDAINPUTSTREAM
     
    613678    /** R0 Pointer to the device instance. */
    614679    PPDMDEVINSRC                       pDevInsRC;
    615 
     680    /** Padding for alignment. */
    616681    uint32_t                           u32Padding;
    617 
    618682    /** Pointer to the attached audio driver. */
    619683    R3PTRTYPE(PPDMIBASE)               pDrvBase;
     
    621685    PDMIBASE                           IBase;
    622686    RTGCPHYS                           MMIOBaseAddr;
     687    /** The HDA's register set. */
    623688    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. */
    627696    uint64_t                           u64CORBBase;
     697    /** RIRB buffer base address. */
    628698    uint64_t                           u64RIRBBase;
     699    /** DMA base address.
     700     *  Made out of DPLBASE + DPUBASE (3.3.32 + 3.3.33). */
    629701    uint64_t                           u64DPBase;
    630702    /** Pointer to CORB buffer. */
     
    632704    /** Size in bytes of CORB buffer. */
    633705    uint32_t                           cbCorbBuf;
     706    /** Padding for alignment. */
    634707    uint32_t                           u32Padding2;
    635708    /** Pointer to RIRB buffer. */
     
    639712    /** Indicates if HDA is in reset. */
    640713    bool                               fInReset;
    641     /** Interrupt on completion */
    642     bool                               fCviIoc;
    643714    /** Flag whether the R0 part is enabled. */
    644715    bool                               fR0Enabled;
     
    650721    /** Timer ticks for handling the LUN drivers. */
    651722    uint64_t                           uTicks;
    652 # ifdef VBOX_WITH_STATISTICS
     723#ifdef VBOX_WITH_STATISTICS
     724# ifndef VBOX_WITH_AUDIO_CALLBACKS
    653725    STAMPROFILE                        StatTimer;
     726# endif
    654727    STAMCOUNTER                        StatBytesRead;
    655728    STAMCOUNTER                        StatBytesWritten;
    656 # endif
     729#endif
    657730    /** Pointer to HDA codec to use. */
    658731    R3PTRTYPE(PHDACODEC)               pCodec;
     
    661734        /** List of associated LUN drivers. */
    662735        RTLISTANCHOR                   lstDrv;
     736        /** Padding for alignment. */
    663737        struct
    664738        {
     
    676750    R3PTRTYPE(PAUDMIXSINK)             pSinkMicIn;
    677751    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. */
    680755    uint8_t                            au8Padding[7];
    681756} HDASTATE;
    682757/** Pointer to the ICH Intel HD Audio Controller state. */
    683758typedef HDASTATE *PHDASTATE;
     759
     760#ifdef VBOX_WITH_AUDIO_CALLBACKS
     761typedef struct HDACALLBACKCTX
     762{
     763    PHDASTATE  pThis;
     764    PHDADRIVER pDriver;
     765} HDACALLBACKCTX, *PHDACALLBACKCTX;
     766#endif
    684767
    685768#define ISD0FMT_TO_AUDIO_SELECTOR(pThis) \
     
    695778static FNPDMDEVRESET hdaReset;
    696779
     780/*
     781 * Stubs.
     782 */
    697783static int hdaRegReadUnimpl(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
    698784static int hdaRegWriteUnimpl(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);
     785
     786/*
     787 * Global register set read/write functions.
     788 */
    699789static 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);
    702790static int hdaRegReadINTSTS(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
     791static int hdaRegReadLPIB(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
    703792static int hdaRegReadWALCLK(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
    704793static int hdaRegWriteINTSTS(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);
     
    709798static int hdaRegWriteRIRBWP(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);
    710799static int hdaRegWriteRIRBSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     800static int hdaRegWriteSTATESTS(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);
    711801static int hdaRegWriteIRS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    712802static int hdaRegReadIRS(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
     803static int hdaRegWriteBase(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     804
     805/*
     806 * {IOB}SDn read/write functions.
     807 */
     808static int hdaRegWriteSDCBL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    713809static int hdaRegWriteSDCTL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    714 
    715810static int hdaRegWriteSDSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    716811static int hdaRegWriteSDLVI(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
     
    720815static int hdaRegWriteSDBDPL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
    721816static 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 */
    723821static int hdaRegReadU32(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value);
    724822static int hdaRegWriteU32(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);
     
    730828static int hdaRegWriteU8(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value);
    731829
    732 static DECLCALLBACK(void) hdaTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser);
    733 static int hdaTransfer(PHDASTATE pThis, ENMSOUNDSOURCE enmSrc, uint32_t cbAvail);
     830static void hdaStreamDestroy(PHDASTREAM pStrmSt);
     831
     832static int hdaTransfer(PHDASTATE pThis, ENMSOUNDSOURCE enmSrc, uint32_t *pcbProcessed);
    734833
    735834#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
     835static int hdaBDLEFetch(PHDASTATE pThis, PHDABDLE pBDLE, uint64_t u64BaseDMA, uint16_t u16Entry);
     836# ifdef LOG_ENABLED
     837static void hdaBDLEDumpAll(PHDASTATE pThis, uint64_t u64BaseDMA, uint16_t u16LVI);
     838# endif
     839static void hdaBDLEReset(PHDABDLE pBDLE);
    742840#endif
    743841
     
    747845*********************************************************************************************************************************/
    748846
    749 /* see 302349 p 6.2*/
     847/* see 302349 p 6.2. */
    750848static const struct HDAREGDESC
    751849{
     
    818916    { 0x00080, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24          , hdaRegWriteSDCTL      , IA(SD0CTL)    }, /* Input Stream Descriptor 0 (ICD0) Control */
    819917    { 0x00083, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8           , hdaRegWriteSDSTS      , IA(SD0STS)    }, /* ISD0 Status */
    820     { 0x00084, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32          , hdaRegWriteU32        , IA(SD0LPIB)   }, /* ISD0 Link Position In Buffer */
    821     { 0x00088, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32        , 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 */
    822920    { 0x0008C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI      , IA(SD0LVI)    }, /* ISD0 Last Valid Index */
    823921    { 0x0008E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW    , IA(SD0FIFOW)  }, /* ISD0 FIFO Watermark */
     
    829927    { 0x000A0, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24          , hdaRegWriteSDCTL      , IA(SD1CTL)    }, /* Input Stream Descriptor 1 (ISD1) Control */
    830928    { 0x000A3, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8           , hdaRegWriteSDSTS      , IA(SD1STS)    }, /* ISD1 Status */
    831     { 0x000A4, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32          , hdaRegWriteU32        , IA(SD1LPIB)   }, /* ISD1 Link Position In Buffer */
    832     { 0x000A8, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32        , 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 */
    833931    { 0x000AC, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI      , IA(SD1LVI)    }, /* ISD1 Last Valid Index */
    834932    { 0x000AE, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW    , IA(SD1FIFOW)  }, /* ISD1 FIFO Watermark */
     
    840938    { 0x000C0, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24          , hdaRegWriteSDCTL      , IA(SD2CTL)    }, /* Input Stream Descriptor 2 (ISD2) Control */
    841939    { 0x000C3, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8           , hdaRegWriteSDSTS      , IA(SD2STS)    }, /* ISD2 Status */
    842     { 0x000C4, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32          , hdaRegWriteU32        , IA(SD2LPIB)   }, /* ISD2 Link Position In Buffer */
    843     { 0x000C8, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32        , 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 */
    844942    { 0x000CC, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI      , IA(SD2LVI)    }, /* ISD2 Last Valid Index */
    845943    { 0x000CE, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW    , IA(SD2FIFOW)  }, /* ISD2 FIFO Watermark */
     
    851949    { 0x000E0, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24          , hdaRegWriteSDCTL      , IA(SD3CTL)    }, /* Input Stream Descriptor 3 (ISD3) Control */
    852950    { 0x000E3, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8           , hdaRegWriteSDSTS      , IA(SD3STS)    }, /* ISD3 Status */
    853     { 0x000E4, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32          , hdaRegWriteU32        , IA(SD3LPIB)   }, /* ISD3 Link Position In Buffer */
    854     { 0x000E8, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32        , 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 */
    855953    { 0x000EC, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI      , IA(SD3LVI)    }, /* ISD3 Last Valid Index */
    856954    { 0x000EE, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW    , IA(SD3FIFOW)  }, /* ISD3 FIFO Watermark */
     
    862960    { 0x00100, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24          , hdaRegWriteSDCTL      , OA(SD4CTL)    }, /* Output Stream Descriptor 4 (OSD4) Control */
    863961    { 0x00103, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8           , hdaRegWriteSDSTS      , OA(SD4STS)    }, /* OSD4 Status */
    864     { 0x00104, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32          , hdaRegWriteU32        , OA(SD4LPIB)   }, /* OSD4 Link Position In Buffer */
    865     { 0x00108, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32        , 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 */
    866964    { 0x0010C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI      , OA(SD4LVI)    }, /* OSD4 Last Valid Index */
    867965    { 0x0010E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW    , OA(SD4FIFOW)  }, /* OSD4 FIFO Watermark */
     
    873971    { 0x00120, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24          , hdaRegWriteSDCTL      , OA(SD5CTL)    }, /* Output Stream Descriptor 5 (OSD5) Control */
    874972    { 0x00123, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8           , hdaRegWriteSDSTS      , OA(SD5STS)    }, /* OSD5 Status */
    875     { 0x00124, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32          , hdaRegWriteU32        , OA(SD5LPIB)   }, /* OSD5 Link Position In Buffer */
    876     { 0x00128, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32        , 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 */
    877975    { 0x0012C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI      , OA(SD5LVI)    }, /* OSD5 Last Valid Index */
    878976    { 0x0012E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW    , OA(SD5FIFOW)  }, /* OSD5 FIFO Watermark */
     
    884982    { 0x00140, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24          , hdaRegWriteSDCTL      , OA(SD6CTL)    }, /* Output Stream Descriptor 6 (OSD6) Control */
    885983    { 0x00143, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8           , hdaRegWriteSDSTS      , OA(SD6STS)    }, /* OSD6 Status */
    886     { 0x00144, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32          , hdaRegWriteU32        , OA(SD6LPIB)   }, /* OSD6 Link Position In Buffer */
    887     { 0x00148, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32        , 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 */
    888986    { 0x0014C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI      , OA(SD6LVI)    }, /* OSD6 Last Valid Index */
    889987    { 0x0014E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW    , OA(SD6FIFOW)  }, /* OSD6 FIFO Watermark */
     
    895993    { 0x00160, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24          , hdaRegWriteSDCTL      , OA(SD7CTL)    }, /* Output Stream Descriptor 7 (OSD7) Control */
    896994    { 0x00163, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8           , hdaRegWriteSDSTS      , OA(SD7STS)    }, /* OSD7 Status */
    897     { 0x00164, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32          , hdaRegWriteU32        , OA(SD7LPIB)   }, /* OSD7 Link Position In Buffer */
    898     { 0x00168, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32          , hdaRegWriteU32        , 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 */
    899997    { 0x0016C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16          , hdaRegWriteSDLVI      , OA(SD7LVI)    }, /* OSD7 Last Valid Index */
    900998    { 0x0016E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16          , hdaRegWriteSDFIFOW    , OA(SD7FIFOW)  }, /* OSD7 FIFO Watermark */
     
    9281026
    9291027#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. */
     1029static 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),
    9411035    SSMFIELD_ENTRY_TERM()
    9421036};
    9431037
    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. */
     1039static SSMFIELD const g_aSSMStreamStateFields5[] =
     1040{
     1041    SSMFIELD_ENTRY       (HDASTREAMSTATE, cBDLE),
     1042    SSMFIELD_ENTRY       (HDASTREAMSTATE, uCurBDLE),
     1043    SSMFIELD_ENTRY_IGNORE(HDASTREAMSTATE, paBDLE),
    9561044    SSMFIELD_ENTRY_TERM()
    9571045};
     
    9611049 * 32-bit size indexed masks, i.e. g_afMasks[2 bytes] = 0xffff.
    9621050 */
    963 static uint32_t const   g_afMasks[5] =
     1051static uint32_t const g_afMasks[5] =
    9641052{
    9651053    UINT32_C(0), UINT32_C(0x000000ff), UINT32_C(0x0000ffff), UINT32_C(0x00ffffff), UINT32_C(0xffffffff)
     
    9671055
    9681056#ifdef IN_RING3
    969 DECLINLINE(void) hdaUpdatePosBuf(PHDASTATE pThis, PHDASTREAMTRANSFERDESC pStreamDesc)
    970 {
     1057DECLINLINE(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? */
    9711071    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    }
    9751078}
    9761079#endif
    9771080
    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 */
     1086DECLINLINE(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;
    9861102        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 */
     1118DECLINLINE(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));
    9891131#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 */
     1141DECLINLINE(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 */
     1158DECLINLINE(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 */
     1202DECLINLINE(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
    9901210    return 0;
     1211#endif
    9911212}
    9921213
     
    9961217        (   INTCTL_SX((pThis), num) \
    9971218         && (SDSTS(pThis, num) & HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS)))
     1219
    9981220    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)
    10001224       && (   HDA_REG_FLAG_VALUE(pThis, RIRBSTS, RINTFL)
    10011225           || HDA_REG_FLAG_VALUE(pThis, RIRBSTS, RIRBOIS)
     
    10031227        fIrq = true;
    10041228
     1229    /** @todo Don't hardcode stream numbers here. */
    10051230    if (   IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 0)
    10061231        || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 4))
     1232    {
     1233#ifdef IN_RING3
     1234        LogFunc(("BCIS\n"));
     1235#endif
    10071236        fIrq = true;
     1237    }
    10081238
    10091239    if (HDA_REG_FLAG_VALUE(pThis, INTCTL, GIE))
    10101240    {
    1011         LogFunc(("irq %s\n", fIrq ? "asserted" : "deasserted"));
     1241        LogFunc(("%s\n", fIrq ? "Asserted" : "Deasserted"));
    10121242        PDMDevHlpPCISetIrq(pThis->CTX_SUFF(pDevIns), 0 , fIrq);
    10131243    }
     1244
     1245#undef IS_INTERRUPT_OCCURED_AND_ENABLED
     1246
    10141247    return VINF_SUCCESS;
    10151248}
     
    10921325
    10931326    /*
    1094      * Binary search the
     1327     * Binary search the register map.
    10951328     */
    10961329    int idxEnd  = RT_ELEMENTS(g_aHdaRegMap);
     
    11361369        do
    11371370        {
    1138             LogFunc(("corb%02x: ", i));
     1371            LogFunc(("CORB%02x: ", i));
    11391372            uint8_t j = 0;
    11401373            do
    11411374            {
    1142                 const char *prefix;
     1375                const char *pszPrefix;
    11431376                if ((i + j) == HDA_REG(pThis, CORBRP));
    1144                     prefix = "[R]";
     1377                    pszPrefix = "[R]";
    11451378                else if ((i + j) == HDA_REG(pThis, CORBWP));
    1146                     prefix = "[W]";
     1379                    pszPrefix = "[W]";
    11471380                else
    1148                     prefix = "   "; /* three spaces */
    1149                 LogFunc(("%s%08x", prefix, pThis->pu32CorbBuf[i + j]));
     1381                    pszPrefix = "   "; /* three spaces */
     1382                LogFunc(("%s%08x", pszPrefix, pThis->pu32CorbBuf[i + j]));
    11501383                j++;
    11511384            } while (j < 8);
     
    11641397        uint8_t i = 0;
    11651398        do {
    1166             LogFunc(("rirb%02x: ", i));
     1399            LogFunc(("RIRB%02x: ", i));
    11671400            uint8_t j = 0;
    11681401            do {
     
    11841417static int hdaCORBCmdProcess(PHDASTATE pThis)
    11851418{
    1186     int rc;
    1187     uint8_t corbRp;
    1188     uint8_t corbWp;
    1189     uint8_t rirbWp;
    1190 
    11911419    PFNHDACODECVERBPROCESSOR pfn = (PFNHDACODECVERBPROCESSOR)NULL;
    11921420
    1193     rc = hdaCmdSync(pThis, true);
     1421    int rc = hdaCmdSync(pThis, true);
    11941422    if (RT_FAILURE(rc))
    11951423        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
    11991429    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
    12021432    while (corbRp != corbWp)
    12031433    {
     
    12081438        cmd = pThis->pu32CorbBuf[corbRp];
    12091439
    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);
    12131441        if (RT_SUCCESS(rc))
    12141442        {
    1215             rc = pfn(pThis->pCodec,
    1216                     HDA_CODEC_CMD(cmd, 0 /* LUN */), &resp);
     1443            AssertPtr(pfn);
     1444            rc = pfn(pThis->pCodec, HDA_CODEC_CMD(cmd, 0 /* LUN */), &resp);
    12171445        }
    12181446
    12191447        if (RT_FAILURE(rc))
    12201448            AssertRCReturn(rc, rc);
    1221         Assert(pfn);
    12221449        (rirbWp)++;
    12231450
     
    12301457            return rc;
    12311458        }
     1459
    12321460        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))
    12351464            break;
    12361465    }
     
    12431472    {
    12441473        HDA_REG(pThis, RIRBSTS) |= HDA_REG_FIELD_FLAG_MASK(RIRBSTS,RINTFL);
    1245         pThis->u8Counter = 0;
     1474
     1475        pThis->u8RespIntCnt = 0;
    12461476        rc = hdaProcessInterrupt(pThis);
    12471477    }
     
    12501480    return rc;
    12511481}
     1482
     1483static 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);
    12521518#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
     1538static 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
     1553static 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;
    12641568    /* 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));
    12771584}
    12781585
     
    13321639static int hdaRegReadU32(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value)
    13331640{
    1334     uint32_t    iRegMem = g_aHdaRegMap[iReg].mem_idx;
     1641    uint32_t iRegMem = g_aHdaRegMap[iReg].mem_idx;
    13351642
    13361643    *pu32Value = pThis->au32Regs[iRegMem] & g_aHdaRegMap[iReg].readable;
     
    13401647static int hdaRegWriteU32(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    13411648{
    1342     uint32_t    iRegMem = g_aHdaRegMap[iReg].mem_idx;
     1649    uint32_t iRegMem = g_aHdaRegMap[iReg].mem_idx;
    13431650
    13441651    pThis->au32Regs[iRegMem]  = (u32Value & g_aHdaRegMap[iReg].writable)
     
    13511658    if (u32Value & HDA_REG_FIELD_FLAG_MASK(GCTL, RST))
    13521659    {
    1353         /* exit reset state */
     1660        /* Exit reset state. */
    13541661        HDA_REG(pThis, GCTL) |= HDA_REG_FIELD_FLAG_MASK(GCTL, RST);
    13551662        pThis->fInReset = false;
     
    13581665    {
    13591666#ifdef IN_RING3
    1360         /* enter reset state*/
     1667        /* Enter reset state. */
    13611668        if (   HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA)
    13621669            || HDA_REG_FLAG_VALUE(pThis, RIRBCTL, DMA))
    13631670        {
    13641671            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"));
    13671674        }
    13681675        hdaReset(pThis->CTX_SUFF(pDevIns));
     
    13751682    if (u32Value & HDA_REG_FIELD_FLAG_MASK(GCTL, FSH))
    13761683    {
    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). */
    13801687    }
    13811688    return VINF_SUCCESS;
     
    13991706        || HDA_REG_FLAG_VALUE(pThis, CORBSTS, CMEI)
    14001707        || 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
    14151732    v |= v ? RT_BIT(31) : 0;
     1733
    14161734    *pu32Value = v;
     1735    return VINF_SUCCESS;
     1736}
     1737
     1738static 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;
    14171747    return VINF_SUCCESS;
    14181748}
     
    14291759{
    14301760    if (u32Value & HDA_REG_FIELD_FLAG_MASK(CORBRP, RST))
     1761    {
    14311762        HDA_REG(pThis, CORBRP) = 0;
     1763    }
    14321764#ifndef BIRD_THINKS_CORBRP_IS_MOSTLY_RO
    14331765    else
     
    14421774    int rc = hdaRegWriteU8(pThis, iReg, u32Value);
    14431775    AssertRC(rc);
    1444     if (   HDA_REG(pThis, CORBWP) != HDA_REG(pThis, CORBRP)
     1776    if (   HDA_REG(pThis, CORBWP)                  != HDA_REG(pThis, CORBRP)
    14451777        && HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA) != 0)
     1778    {
    14461779        return hdaCORBCmdProcess(pThis);
     1780    }
    14471781    return rc;
    14481782#else
     
    14761810}
    14771811
     1812static 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
    14781822static int hdaRegWriteSDCTL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    14791823{
    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));
    14841860
    14851861    if (fInReset)
    14861862    {
    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"));
    14931866    }
    14941867    else if (fReset)
    14951868    {
    14961869#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);
    15271875#else
    15281876        return VINF_IOM_R3_MMIO_WRITE;
     
    15321880    {
    15331881#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);
    15391888
    15401889            PHDADRIVER pDrv;
    1541             switch (iReg)
     1890            switch (u8Strm)
    15421891            {
    1543                 case HDA_REG_SD0CTL:
     1892                case 0: /** @todo Use a variable here. Later. */
    15441893                {
    15451894                    RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
     
    15491898                }
    15501899# ifdef VBOX_WITH_HDA_MIC_IN
    1551                 case HDA_REG_SD2CTL:
     1900                case 2: /** @todo Use a variable here. Later. */
    15521901                {
    15531902                    RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
     
    15571906                }
    15581907# endif
    1559                 case HDA_REG_SD4CTL:
     1908                case 4: /** @todo Use a variable here. Later. */
    15601909                {
    15611910                    RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
     
    15691918            }
    15701919        }
     1920
     1921        if (pStrmSt)
     1922        {
     1923            int rc2 = hdaStreamInit(pThis, pStrmSt, u8Strm);
     1924            AssertRC(rc2);
     1925        }
     1926
    15711927#else /* !IN_RING3 */
    15721928        return VINF_IOM_R3_MMIO_WRITE;
     
    15881944static int hdaRegWriteSDLVI(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    15891945{
     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
    15901954    int rc = hdaRegWriteU32(pThis, iReg, u32Value);
    15911955    if (RT_FAILURE(rc))
     
    16061970            return hdaRegWriteU16(pThis, iReg, HDA_SDFIFOW_32B);
    16071971    }
    1608     return VINF_SUCCESS;
     1972    return VINF_SUCCESS; /* Never reached. */
    16091973}
    16101974
    16111975/**
    16121976 * @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).
    16141978 */
    16151979static int hdaRegWriteSDFIFOS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
    16161980{
     1981    /** @todo Only allow updating FIFOS if RUN bit is 0? */
     1982    uint32_t u32FIFOS = 0;
     1983
    16171984    switch (iReg)
    16181985    {
    1619         /* SDInFIFOS is RO, n=0-3 */
     1986        /* SDInFIFOS is RO, n=0-3. */
    16201987        case HDA_REG_SD0FIFOS:
    16211988        case HDA_REG_SD1FIFOS:
    16221989        case HDA_REG_SD2FIFOS:
    16231990        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"));
    16251993            break;
     1994        }
    16261995        case HDA_REG_SD4FIFOS:
    16271996        case HDA_REG_SD5FIFOS:
    16281997        case HDA_REG_SD6FIFOS:
    16291998        case HDA_REG_SD7FIFOS:
     1999        {
    16302000            switch(u32Value)
    16312001            {
     
    16352005                case HDA_SDONFIFO_128B:
    16362006                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. */
    16402011                    LogFunc(("256-bit is unsupported, HDA is switched into 192-bit mode\n"));
     2012                    /* Fall through is intentional. */
    16412013                default:
    1642                     return hdaRegWriteU16(pThis, iReg, HDA_SDONFIFO_192B);
     2014                    u32FIFOS = HDA_SDONFIFO_192B;
     2015                    break;
    16432016            }
     2017
    16442018            break;
     2019        }
    16452020        default:
     2021        {
    16462022            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);
    16472033    }
    16482034
     
    16592045    int rc = VINF_SUCCESS;
    16602046
    1661     uint32_t u32Hz = (u32SdFmt & HDA_SDFMT_BASE_RATE_SHIFT) ? 44100 : 48000;
     2047    uint32_t u32Hz     = (u32SdFmt & HDA_SDFMT_BASE_RATE_SHIFT) ? 44100 : 48000;
    16622048    uint32_t u32HzMult = 1;
    1663     uint32_t u32HzDiv = 1;
     2049    uint32_t u32HzDiv  = 1;
    16642050
    16652051    switch (EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_MULT_MASK, HDA_SDFMT_MULT_SHIFT))
     
    17222108    if (RT_SUCCESS(rc))
    17232109    {
    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;
    17272113        pCfg->enmEndianness = PDMAUDIOHOSTENDIANNESS;
    17282114    }
     
    17302116# undef EXTRACT_VALUE
    17312117
     2118    LogFlowFuncLeaveRC(rc);
    17322119    return rc;
    17332120}
     
    19212308#ifdef IN_RING3
    19222309#ifdef LOG_ENABLED
    1923 static void dump_bd(PHDASTATE pThis, PHDABDLEDESC pBdle, uint64_t u64BaseDMA)
    1924 {
     2310static 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 */
     2354static 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
     2378static 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 */
     2392DECLINLINE(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
     2429DECLINLINE(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
    19252443#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));
    19492449    }
    19502450#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
     2463DECLINLINE(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
     2501DECLINLINE(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
    19722512    /*
    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).
    19742516     */
    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
     2531static 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           )
    21072552        {
    21082553            /**
    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             *
    21102560             * Speech synthesis works fine on Mac Guest if this bit isn't set
    21112561             * but in general sound quality gets worse.
    21122562             */
    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);
    21142564
    21152565            /*
    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.
    21172568             */
    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))
    21192570                hdaProcessInterrupt(pThis);
    21202571        }
    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;
    21242580}
    21252581
     
    21292585 *       but "reports bytes" when all conditions are met (FIFOW).
    21302586 */
    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. */
     2587static 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);
    21362595
    21372596    int rc;
    2138     uint32_t cbTransferred = 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 (!cb2Copy)
    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. */
    21462605        rc = VERR_NO_DATA;
    21472606    }
    21482607    else
    21492608    {
    2150         uint32_t cbRead = 0;
    2151         rc = AudioMixerProcessSinkIn(pSink, AUDMIXOP_BLEND, pBdle->au8HdaBuffer, cb2Copy, &cbRead);
     2609        uint32_t cbReadFromSink = 0;
     2610        rc = AudioMixerProcessSinkIn(pSink, AUDMIXOP_BLEND, pBDLE->State.au8FIFO, cbBuf, &cbReadFromSink);
    21522611        if (RT_SUCCESS(rc))
    21532612        {
    2154             Assert(cbRead);
     2613            Assert(cbReadFromSink);
     2614            Assert(cbReadFromSink == cbBuf);
     2615            Assert(cbReadFromSink <= pBDLE->u32BufSize - pBDLE->State.u32BufOff);
    21552616
    21562617            /*
    2157              * Write the HDA DMA buffer.
     2618             * Write to the BDLE's DMA buffer.
    21582619             */
    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            }
    21682631            else
    21692632            {
    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
    21712638                rc = VERR_NO_DATA;
    21722639            }
     
    21742641    }
    21752642
    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));
    21792647
    21802648    if (RT_SUCCESS(rc))
    2181         *pcbRead = cbTransferred;
     2649    {
     2650        if (pcbRead)
     2651            *pcbRead = cbRead;
     2652    }
    21822653
    21832654    return rc;
    21842655}
    21852656
    2186 static int hdaWriteAudio(PHDASTATE pThis, PHDASTREAMTRANSFERDESC 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);
     2657static 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));
    22002671
    22012672    /*
    2202      * Copy from DMA to the corresponding hdaBuffer (if there are any bytes from the
    2203      * previous unreported transfer we write at offset 'pBdle->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').
    22042675     */
    2205     if (!cb2Copy)
     2676    if (!cbData)
    22062677    {
    22072678        rc = VINF_EOF;
     
    22092680    else
    22102681    {
    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);
    22142689
    22152690#ifdef VBOX_WITH_STATISTICS
    2216         STAM_COUNTER_ADD(&pThis->StatBytesRead, cb2Copy);
     2691        STAM_COUNTER_ADD(&pThis->StatBytesRead, cbData);
    22172692#endif
    2218 
    22192693        /*
    22202694         * Write to audio backend. We should ensure that we have enough bytes to copy to the backend.
    22212695         */
    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;
    22262701
    22272702            PHDADRIVER pDrv;
     
    22302705                if (pDrv->pConnector->pfnIsActiveOut(pDrv->pConnector, pDrv->Out.pStrmOut))
    22312706                {
    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                    }
    22372715                }
    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));
    22432725            }
    22442726
    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);
    22492732        }
    22502733        else
    22512734        {
     2735            pBDLE->State.u32BufOff += cbWritten;
     2736            pBDLE->State.cbBelowFIFOW += cbWritten;
     2737            Assert(pBDLE->State.cbBelowFIFOW <= hdaStreamGetFIFOW(pThis, pStrmSt));
     2738
    22522739            /* 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);
    22542741            rc = VINF_EOF;
    22552742        }
    22562743    }
    22572744
    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);
    22612746
    22622747    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));
    22652754    return rc;
    22662755}
     
    22762765}
    22772766
    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
     2768static DECLCALLBACK(void) hdaCloseIn(PHDASTATE pThis, PDMAUDIORECSOURCE enmRecSource)
    23062769{
    23072770    NOREF(pThis);
     
    23102773}
    23112774
    2312 static DECLCALLBACK(void) hdaDestroyOut(PHDASTATE pThis)
     2775static DECLCALLBACK(void) hdaCloseOut(PHDASTATE pThis)
    23132776{
    23142777    NOREF(pThis);
     
    23162779}
    23172780
    2318 static DECLCALLBACK(int) hdaCreateIn(PHDASTATE pThis,
    2319                                      const char *pszName, PDMAUDIORECSOURCE enmRecSource,
    2320                                      PPDMAUDIOSTREAMCFG pCfg)
     2781static DECLCALLBACK(int) hdaOpenIn(PHDASTATE pThis,
     2782                                   const char *pszName, PDMAUDIORECSOURCE enmRecSource,
     2783                                   PPDMAUDIOSTREAMCFG pCfg)
    23212784{
    23222785    PAUDMIXSINK pSink;
     
    23662829}
    23672830
    2368 static DECLCALLBACK(int) hdaCreateOut(PHDASTATE pThis,
    2369                                       const char *pszName, PPDMAUDIOSTREAMCFG pCfg)
     2831static DECLCALLBACK(int) hdaOpenOut(PHDASTATE pThis,
     2832                                    const char *pszName, PPDMAUDIOSTREAMCFG pCfg)
    23702833{
    23712834    int rc = VINF_SUCCESS;
     
    24062869
    24072870    /* 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;
    24202885    }
    24212886
     
    24262891    return rc;
    24272892}
     2893
     2894#ifndef VBOX_WITH_AUDIO_CALLBACKS
    24282895
    24292896static DECLCALLBACK(void) hdaTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     
    24852952    {
    24862953        Assert(cbOutMin != UINT32_MAX);
    2487         hdaTransfer(pThis, PO_INDEX, cbOutMin); /** @todo Add rc! */
     2954        hdaTransfer(pThis, PO_INDEX, NULL /* pcbProcessed */); /** @todo Add rc! */
    24882955    }
    24892956
     
    24922959     */
    24932960    if (cbInMax)
    2494         hdaTransfer(pThis, PI_INDEX, cbInMax); /** @todo Add rc! */
     2961        hdaTransfer(pThis, PI_INDEX, NULL /* pcbProcessed */); /** @todo Add rc! */
    24952962
    24962963    TMTimerSet(pThis->pTimer, TMTimerGet(pThis->pTimer) + pThis->uTicks);
     
    24992966}
    25002967
    2501 static int hdaTransfer(PHDASTATE pThis,
    2502                        ENMSOUNDSOURCE enmSrc, uint32_t cbAvail)
     2968#else /* VBOX_WITH_AUDIO_CALLBACKS */
     2969
     2970static 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
     2987static 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
     3018static int hdaTransfer(PHDASTATE pThis, ENMSOUNDSOURCE enmSrc, uint32_t *pcbProcessed)
    25033019{
    25043020    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;
    25113026    switch (enmSrc)
    25123027    {
    25133028        case PI_INDEX:
    25143029        {
    2515             u8Strm = 0;
    2516             pBdle = &pThis->StInBdle;
     3030            pStrmSt = &pThis->StrmStLineIn;
    25173031            break;
    25183032        }
     
    25213035        case MC_INDEX:
    25223036        {
    2523             u8Strm = 2;
    2524             pBdle = &pThis->StMicBdle;
     3037            pStrmSt = &pThis->StrmStMicIn;
    25253038            break;
    25263039        }
     
    25283041        case PO_INDEX:
    25293042        {
    2530             u8Strm = 4;
    2531             pBdle = &pThis->StOutBdle;
     3043            pStrmSt = &pThis->StrmStOut;
    25323044            break;
    25333045        }
    25343046
    25353047        default:
     3048        {
    25363049            AssertMsgFailed(("Unknown source index %ld\n", enmSrc));
    25373050            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;
    25633093        switch (enmSrc)
    25643094        {
    25653095            case PI_INDEX:
    2566                 pSink = pThis->pSinkLineIn;
    2567                 rc = hdaReadAudio(pThis, pSink, &StreamDesc, u32CblLimit, &cbAvail, &cbWritten);
     3096                rc = hdaReadAudio(pThis, pStrmSt, pThis->pSinkLineIn, &cbProcessed);
    25683097                break;
    25693098            case PO_INDEX:
    2570                 rc = hdaWriteAudio(pThis, &StreamDesc, u32CblLimit, &cbAvail, &cbWritten);
     3099                rc = hdaWriteAudio(pThis, pStrmSt, &cbProcessed);
    25713100                break;
    25723101#ifdef VBOX_WITH_HDA_MIC_IN
    25733102            case MC_INDEX:
    2574                 pSink = pThis->pSinkMicIn;
    2575                 rc = hdaReadAudio(pThis, pSink, &StreamDesc, u32CblLimit, &cbAvail, &cbWritten);
     3103                rc = hdaReadAudio(pThis, pStrmSt, pThis->pSinkMicIn, &cbProcessed);
    25763104                break;
    25773105#endif
     
    25813109                break;
    25823110        }
    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))
    25903116            break;
    25913117
    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);
    25993139    return rc;
    26003140}
     
    26263166
    26273167    LogFunc(("offReg=%#x cb=%#x\n", offReg, cb));
    2628 #define NEW_READ_CODE
    2629 #ifdef NEW_READ_CODE
    26303168    Assert(cb == 4); Assert((offReg & 3) == 0);
    26313169
    26323170    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"));
    26343172
    26353173    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));
    26373175
    26383176    if (idxRegDsc != -1)
     
    26453183             */
    26463184            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));
    26483186        }
    26493187        else
     
    26613199
    26623200                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));
    26643202                if (rc != VINF_SUCCESS)
    26653203                    break;
     
    26803218    {
    26813219        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    }
    27293222
    27303223    /*
     
    27333226#ifdef LOG_ENABLED
    27343227    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));
    27363229    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));
    27383231    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));
    27403233#endif
    27413234    return rc;
     
    27543247    int rc = g_aHdaRegMap[idxRegDsc].pfnWrite(pThis, idxRegDsc, u32Value);
    27553248    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));
    27573250    return rc;
    27583251}
     
    27903283    {
    27913284        u64Value = 0;   /* shut up gcc. */
    2792         AssertReleaseMsgFailed(("%d\n", cb));
     3285        AssertReleaseMsgFailed(("%u\n", cb));
    27933286    }
    27943287
    27953288#ifdef LOG_ENABLED
    27963289    uint32_t const u32LogOldValue = idxRegDsc >= 0 ? pThis->au32Regs[idxRegMem] : UINT32_MAX;
    2797     uint32_t const offRegLog = offReg;
    2798     int      const idxRegLog = idxRegMem;
    27993290    if (idxRegDsc == -1)
    28003291        LogFunc(("@%#05x u32=%#010x cb=%d\n", offReg, *(uint32_t const *)pv, cb));
     
    28053296    else if (cb == 1)
    28063297        LogFunc(("@%#05x u8=%#04x (%#010x) %s\n", offReg, *(uint8_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));
     3298
    28073299    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));
    28093301#endif
    28103302
    2811 #define NEW_WRITE_CODE
    2812 #ifdef NEW_WRITE_CODE
    28133303    /*
    28143304     * Try for a direct hit first.
     
    28173307    {
    28183308        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
    28213312    }
    28223313    /*
     
    28253316    else
    28263317    {
    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         */
    28313324        if (idxRegDsc == -1 && (idxRegDsc = hdaRegLookupWithin(pThis, offReg)) != -1)
    28323325        {
     
    28363329            u64Value <<= cbBefore * 8;
    28373330            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));
    28403333        }
    28413334
     
    28523345                {
    28533346                    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));
    28563349                }
    28573350                uint32_t u32LogOldVal = pThis->au32Regs[idxRegMem];
    28583351                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]));
    28613353            }
    28623354            else
    28633355            {
    2864                 LogRel(("HDA: Invalid write access @0x%x!\n", offReg));
     3356                LogRel(("HDA: Invalid write access @0x%x\n", offReg));
    28653357                cbReg = 1;
    28663358            }
     
    28703362                break;
    28713363
    2872             /* advance */
     3364            /* Advance. */
    28733365            offReg += cbReg;
    28743366            cb     -= cbReg;
     
    28813373                if (   (unsigned)idxRegDsc >= RT_ELEMENTS(g_aHdaRegMap)
    28823374                    || g_aHdaRegMap[idxRegDsc].offset != offReg)
     3375                {
    28833376                    idxRegDsc = -1;
     3377                }
    28843378            }
    28853379        }
    28863380    }
    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
    29433382    return rc;
    29443383}
     
    29673406    Assert(enmType == PCI_ADDRESS_SPACE_MEM);
    29683407    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,
    29753410                               hdaMMIOWrite, hdaMMIORead, "HDA");
    29763411
     
    30013436/* Saved state callbacks. */
    30023437
     3438static 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
    30033457/**
    30043458 * @callback_method_impl{FNSSMDEVSAVEEXEC}
     
    30083462    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    30093463
    3010     /* Save Codec nodes states */
     3464    /* Save Codec nodes states. */
    30113465    hdaCodecSaveState(pThis->pCodec, pSSM);
    30123466
    3013     /* Save MMIO registers */
     3467    /* Save MMIO registers. */
    30143468    AssertCompile(RT_ELEMENTS(pThis->au32Regs) >= HDA_NREGS_SAVED);
    30153469    SSMR3PutU32(pSSM, RT_ELEMENTS(pThis->au32Regs));
    30163470    SSMR3PutMem(pSSM, pThis->au32Regs, sizeof(pThis->au32Regs));
    30173471
    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;
    30233484}
    30243485
     
    30323493
    30333494    Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
     3495
     3496    LogFlowFunc(("uVersion=%RU32, uPass=%RU32\n", uVersion, uPass));
    30343497
    30353498    /*
     
    30673530            break;
    30683531
     3532        /* Since version 4 we store the register count to stay flexible. */
     3533        case HDA_SSM_VERSION_4:
    30693534        case HDA_SSM_VERSION:
    30703535            rc = SSMR3GetU32(pSSM, &cRegs); AssertRCReturn(rc, rc);
     
    30863551
    30873552    /*
    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).
    30893561     */
    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);                                         \
    30983583
    30993584    /*
    3100      * Update stuff after the state changes.
     3585     * Load BDLEs (Buffer Descriptor List Entries) and DMA counters.
    31013586     */
    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));
    31033688#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));
    31053690#else
    3106     bool fEnableMicIn = fEnableIn; /* Mic In == Line In */
     3691        bool fEnableMicIn = fEnableIn; /* Mic In == Line In */
    31073692#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        }
    31223708    }
    31233709
     
    31333719}
    31343720
    3135 
     3721#ifdef DEBUG
    31363722/* Debug and log type formatters. */
    31373723
     
    31393725 * @callback_method_impl{FNRTSTRFORMATTYPE}
    31403726 */
    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)));
     3727static 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);
    31593736}
    31603737
     
    31623739 * @callback_method_impl{FNRTSTRFORMATTYPE}
    31633740 */
    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);
     3741static 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)));
    31853758}
    31863759
     
    31883761 * @callback_method_impl{FNRTSTRFORMATTYPE}
    31893762 */
    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);
     3763static 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));
    32063770}
    32073771
     
    32093773 * @callback_method_impl{FNRTSTRFORMATTYPE}
    32103774 */
    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)
     3775static 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 */
     3787static 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)
    32163791{
    32173792    uint32_t uSdSts = (uint32_t)(uintptr_t)pvValue;
    32183793    return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
    3219                        "SDSTS(raw: %#0x, fifordy:%RTbool, dese:%RTbool, fifoe:%RTbool, bcis:%RTbool)",
     3794                       "SDSTS(raw:%#0x, fifordy:%RTbool, dese:%RTbool, fifoe:%RTbool, bcis:%RTbool)",
    32203795                       uSdSts,
    32213796                       RT_BOOL(uSdSts & HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY)),
     
    32253800}
    32263801
    3227 
    32283802static int hdaLookUpRegisterByName(PHDASTATE pThis, const char *pszArgs)
    32293803{
     
    32433817    pHlp->pfnPrintf(pHlp, "%s: 0x%x\n", g_aHdaRegMap[iHdaIndex].abbrev, pThis->au32Regs[g_aHdaRegMap[iHdaIndex].mem_idx]);
    32443818}
    3245 
    32463819
    32473820/**
     
    32583831            hdaDbgPrintRegister(pThis, pHlp, iHdaRegisterIndex);
    32593832}
    3260 
    32613833
    32623834static void hdaDbgPrintStream(PHDASTATE pThis, PCDBGFINFOHLP pHlp, int iHdaStrmIndex)
     
    32723844}
    32733845
    3274 
    32753846static int hdaLookUpStreamIndex(PHDASTATE pThis, const char *pszArgs)
    32763847{
     
    32783849    return -1;
    32793850}
    3280 
    32813851
    32823852/**
     
    32943864}
    32953865
    3296 
    32973866/**
    32983867 * @callback_method_impl{FNDBGFHANDLERDEV}
     
    33083877}
    33093878
    3310 
    33113879/**
    33123880 * @callback_method_impl{FNDBGFHANDLERDEV}
     
    33223890}
    33233891
    3324 
    33253892/**
    33263893 * @callback_method_impl{FNDBGFHANDLERDEV}
     
    33353902        pHlp->pfnPrintf(pHlp, "Mixer not available\n");
    33363903}
    3337 
     3904#endif /* DEBUG */
    33383905
    33393906/* PDMIBASE */
     
    33663933{
    33673934    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
     3935
    33683936    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 */
    33753943    HDA_REG(pThis, CORBRP)   = 0x0;
    33763944    HDA_REG(pThis, RIRBWP)   = 0x0;
     
    33903958    }
    33913959
    3392     pThis->cbCorbBuf = 256 * sizeof(uint32_t);
     3960    pThis->cbCorbBuf = 256 * sizeof(uint32_t); /** @todo Use a define here. */
    33933961
    33943962    if (pThis->pu32CorbBuf)
     
    33973965        pThis->pu32CorbBuf = (uint32_t *)RTMemAllocZ(pThis->cbCorbBuf);
    33983966
    3399     pThis->cbRirbBuf = 256 * sizeof(uint64_t);
     3967    pThis->cbRirbBuf = 256 * sizeof(uint64_t); /** @todo Use a define here. */
    34003968    if (pThis->pu64RirbBuf)
    34013969        RT_BZERO(pThis->pu64RirbBuf, pThis->cbRirbBuf);
     
    34053973    pThis->u64BaseTS = PDMDevHlpTMTimeVirtGetNano(pDevIns);
    34063974
    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;
    34123978        if (u8Strm == 0)
    3413             pBdle = &pThis->StInBdle;
     3979            pStrmSt = &pThis->StrmStOut;
    34143980# ifdef VBOX_WITH_HDA_MIC_IN
    34153981        else if (u8Strm == 2)
    3416             pBdle = &pThis->StMicBdle;
     3982            pStrmSt = &pThis->StrmStMicIn;
    34173983# 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        }
    34293994    }
    34303995
     
    34714036    RTMemFree(pThis->pu64RirbBuf);
    34724037    pThis->pu64RirbBuf = NULL;
     4038
     4039    hdaStreamDestroy(&pThis->StrmStLineIn);
     4040    hdaStreamDestroy(&pThis->StrmStMicIn);
     4041    hdaStreamDestroy(&pThis->StrmStOut);
    34734042
    34744043    return VINF_SUCCESS;
     
    35124081        {
    35134082            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;
    35194086
    35204087            /*
     
    37614328
    37624329        /* Audio driver callbacks for multiplexing. */
    3763         pThis->pCodec->pfnDestroyIn  = hdaDestroyIn;
    3764         pThis->pCodec->pfnDestroyOut = hdaDestroyOut;
    3765         pThis->pCodec->pfnCreateIn   = hdaCreateIn;
    3766         pThis->pCodec->pfnCreateOut  = hdaCreateOut;
    3767         pThis->pCodec->pfnReset      = hdaCodecReset;
    3768         pThis->pCodec->pfnSetVolume  = hdaSetVolume;
     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;
    37694336
    37704337        pThis->pCodec->pHDAState = pThis; /* Assign HDA controller state to codec. */
     
    37944361        HDA_REG(pThis, STATESTS) = 0x0;
    37954362
     4363#ifdef DEBUG
    37964364        /*
    37974365         * Debug and string formatter types.
     
    38034371        PDMDevHlpDBGFInfoRegister(pDevIns, "hdamixer",    "HDA mixer state.",                               hdaInfoMixer);
    38044372
    3805         rc = RTStrFormatTypeRegister("sdctl",   hdaFormatStrmCtl,   NULL);
     4373        rc = RTStrFormatTypeRegister("bdle",    hdaDbgFmtBDLE,    NULL);
    38064374        AssertRC(rc);
    3807         rc = RTStrFormatTypeRegister("sdsts",   hdaFormatStrmSts,   NULL);
     4375        rc = RTStrFormatTypeRegister("sdctl",   hdaDbgFmtSDCTL,   NULL);
    38084376        AssertRC(rc);
    3809         rc = RTStrFormatTypeRegister("sdfifos", hdaFormatStrmFifos, NULL);
     4377        rc = RTStrFormatTypeRegister("sdsts",   hdaDbgFmtSDSTS,  NULL);
    38104378        AssertRC(rc);
    3811         rc = RTStrFormatTypeRegister("sdfifow", hdaFormatStrmFifow, NULL);
     4379        rc = RTStrFormatTypeRegister("sdfifos", hdaDbgFmtSDFIFOS, NULL);
    38124380        AssertRC(rc);
    3813     #if 0
    3814         rc = RTStrFormatTypeRegister("sdfmt", printHdaStrmFmt, NULL);
     4381        rc = RTStrFormatTypeRegister("sdfifow", hdaDbgFmtSDFIFOW, NULL);
    38154382        AssertRC(rc);
    3816     #endif
     4383#endif /* DEBUG */
    38174384
    38184385        /*
     
    38474414                                      i - 1, pPrevReg->offset, pPrevReg->size, i + 1, pReg->offset, pReg->size));
    38484415            }
    3849     #if 0
     4416#if 0
    38504417            if ((pReg->offset + pReg->size) & 3)
    38514418            {
     
    38564423                                      i, pReg->offset, pReg->size, i + 1,  pNextReg->offset, pNextReg->size));
    38574424            }
    3858     #endif
    3859 
     4425#endif
    38604426            /* The final entry is a full DWORD, no gaps! Allows shortcuts. */
    38614427            AssertReleaseMsg(pNextReg || ((pReg->offset + pReg->size) & 3) == 0,
     
    38644430    }
    38654431
     4432# ifndef VBOX_WITH_AUDIO_CALLBACKS
    38664433    if (RT_SUCCESS(rc))
    38674434    {
     
    38844451        }
    38854452    }
     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
    38864484
    38874485# ifdef VBOX_WITH_STATISTICS
     
    38914489         * Register statistics.
    38924490         */
     4491#  ifndef VBOX_WITH_AUDIO_CALLBACKS
    38934492        PDMDevHlpSTAMRegister(pDevIns, &pThis->StatTimer,            STAMTYPE_PROFILE, "/Devices/HDA/Timer",             STAMUNIT_TICKS_PER_CALL, "Profiling hdaTimer.");
     4493#  endif
    38944494        PDMDevHlpSTAMRegister(pDevIns, &pThis->StatBytesRead,        STAMTYPE_COUNTER, "/Devices/HDA/BytesRead"   ,      STAMUNIT_BYTES,          "Bytes read from HDA emulation.");
    38954495        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  
    26112611    {
    26122612        case PI_INDEX:
    2613             rc = pThis->pfnCreateIn(pThis->pHDAState, "hda.in", PDMAUDIORECSOURCE_LINE_IN, pCfg);
     2613            rc = pThis->pfnOpenIn(pThis->pHDAState, "hda.in", PDMAUDIORECSOURCE_LINE_IN, pCfg);
    26142614            break;
    26152615
    26162616        case PO_INDEX:
    2617             rc = pThis->pfnCreateOut(pThis->pHDAState, "hda.out", pCfg);
     2617            rc = pThis->pfnOpenOut(pThis->pHDAState, "hda.out", pCfg);
    26182618            break;
    26192619
    26202620#ifdef VBOX_WITH_HDA_MIC_IN
    26212621        case MC_INDEX:
    2622             rc = pThis->pfnCreateIn(pThis->pHDAState, "hda.mc", PDMAUDIORECSOURCE_MIC, pCfg);
     2622            rc = pThis->pfnOpenIn(pThis->pHDAState, "hda.mc", PDMAUDIORECSOURCE_MIC, pCfg);
    26232623            break;
    26242624#endif
     
    26622662            break;
    26632663
     2664        /* Since version 4 a flexible node count is supported. */
     2665        case HDA_SSM_VERSION_4:
    26642666        case HDA_SSM_VERSION:
    26652667        {
  • trunk/src/VBox/Devices/Audio/DevIchHdaCodec.h

    r58600 r58900  
    111111#endif
    112112    /** Callbacks to the HDA controller, mostly used for multiplexing to the various host backends. */
    113     DECLR3CALLBACKMEMBER(void, pfnDestroyIn, (PHDASTATE pThis, PDMAUDIORECSOURCE enmRecSource));
    114     DECLR3CALLBACKMEMBER(void, pfnDestroyOut, (PHDASTATE pThis));
    115     DECLR3CALLBACKMEMBER(int, pfnCreateIn, (PHDASTATE pThis, const char *pszName, PDMAUDIORECSOURCE enmRecSource, PPDMAUDIOSTREAMCFG pCfg));
    116     DECLR3CALLBACKMEMBER(int, pfnCreateOut, (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));
    117117    DECLR3CALLBACKMEMBER(int, pfnSetVolume, (PHDASTATE pThis, ENMSOUNDSOURCE enmSource, bool fMute, uint8_t uVolLeft, uint8_t uVolRight));
    118118    /** Callbacks by codec implementation. */
     
    131131int hdaCodecOpenStream(PHDACODEC pThis, PDMAUDIORECSOURCE enmRecSource, PDMAUDIOSTREAMCFG *pAudioSettings);
    132132
    133 #define HDA_SSM_VERSION   4
     133#define HDA_SSM_VERSION   5
    134134#define HDA_SSM_VERSION_1 1
    135135#define HDA_SSM_VERSION_2 2
    136136#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
    137139
    138140# ifdef VBOX_WITH_HDA_CODEC_EMU
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette