VirtualBox

Changeset 67387 in vbox


Ignore:
Timestamp:
Jun 14, 2017 10:14:06 AM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
116108
Message:

Audio/DevHDA: Forward ported / integrated saved state handling.

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

Legend:

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

    r67376 r67387  
    567567    /** Circular buffer (FIFO) for holding DMA'ed data. */
    568568    R3PTRTYPE(PRTCIRCBUF)   pCircBuf;
    569 # ifdef HDA_USE_DMA_ACCESS_HANDLER
     569    /** Timestamp of the last success DMA data transfer.
     570     *  Used to calculate the time actually elapsed between two transfers. */
     571    uint64_t                uTimerTS;
     572    /** The stream's current configuration.
     573     *  Should match SDFMT. */
     574    PDMAUDIOSTREAMCFG       strmCfg;
     575#ifdef HDA_USE_DMA_ACCESS_HANDLER
    570576    /** List of DMA handlers. */
    571577    RTLISTANCHORR3          lstDMAHandlers;
    572578#endif
     579    /** Unused, padding. */
     580    uint8_t                 Padding1[3];
    573581} HDASTREAMSTATE, *PHDASTREAMSTATE;
    574582
     
    840848    /** Timer ticks per Hz. */
    841849    uint64_t                           cTimerTicks;
     850    /** The current timer expire time (in timer ticks). */
     851    uint64_t                           tsTimerExpire;
    842852    /** Timestamp of the last timer callback (hdaTimer).
    843853     * Used to calculate the time actually elapsed between two timer callbacks. */
     
    11821192
    11831193#ifdef IN_RING3
    1184 /** HDABDLEDESC field descriptors for the v6+ saved state. */
    1185 static SSMFIELD const g_aSSMBDLEDescFields6[] =
     1194/** HDABDLEDESC field descriptors for the v7 saved state. */
     1195static SSMFIELD const g_aSSMBDLEDescFields7[] =
    11861196{
    11871197    SSMFIELD_ENTRY(HDABDLEDESC, u64BufAdr),
     
    11961206    SSMFIELD_ENTRY(HDABDLESTATE, u32BDLIndex),
    11971207    SSMFIELD_ENTRY(HDABDLESTATE, cbBelowFIFOW),
    1198     SSMFIELD_ENTRY_OLD(FIFO, 256),
     1208    SSMFIELD_ENTRY_OLD(FIFO,     HDA_FIFO_MAX), /* Deprecated; now is handled in the stream's circular buffer. */
    11991209    SSMFIELD_ENTRY(HDABDLESTATE, u32BufOff),
    12001210    SSMFIELD_ENTRY_TERM()
    12011211};
    12021212
    1203 /** HDASTREAMSTATE field descriptors for the v6+ saved state. */
     1213/** HDABDLESTATE field descriptors for the v7 saved state. */
     1214static SSMFIELD const g_aSSMBDLEStateFields7[] =
     1215{
     1216    SSMFIELD_ENTRY(HDABDLESTATE, u32BDLIndex),
     1217    SSMFIELD_ENTRY(HDABDLESTATE, cbBelowFIFOW),
     1218    SSMFIELD_ENTRY(HDABDLESTATE, u32BufOff),
     1219    SSMFIELD_ENTRY_TERM()
     1220};
     1221
     1222/** HDASTREAMSTATE field descriptors for the v6 saved state. */
    12041223static SSMFIELD const g_aSSMStreamStateFields6[] =
    12051224{
    1206     SSMFIELD_ENTRY_OLD(cBDLE, 2),
     1225    SSMFIELD_ENTRY_OLD(cBDLE,      sizeof(uint16_t)), /* Deprecated. */
    12071226    SSMFIELD_ENTRY(HDASTREAMSTATE, uCurBDLE),
    1208     SSMFIELD_ENTRY_OLD(fDoStop, 1),
    1209     SSMFIELD_ENTRY_OLD(fActive, 1),
     1227    SSMFIELD_ENTRY_OLD(fStop,      1),                /* Deprecated; see SSMR3PutBool(). */
     1228    SSMFIELD_ENTRY_OLD(fActive,    1),
    12101229    SSMFIELD_ENTRY(HDASTREAMSTATE, fInReset),
     1230    SSMFIELD_ENTRY_TERM()
     1231};
     1232
     1233/** HDASTREAMSTATE field descriptors for the v7 saved state. */
     1234static SSMFIELD const g_aSSMStreamStateFields7[] =
     1235{
     1236    SSMFIELD_ENTRY(HDASTREAMSTATE, uCurBDLE),
     1237    SSMFIELD_ENTRY(HDASTREAMSTATE, fInReset),
     1238    SSMFIELD_ENTRY(HDASTREAMSTATE, uTimerTS),
    12111239    SSMFIELD_ENTRY_TERM()
    12121240};
     
    54215449
    54225450    rc = SSMR3PutStructEx(pSSM, &pStrm->State.BDLE.Desc, sizeof(HDABDLEDESC),
    5423                           0 /*fFlags*/, g_aSSMBDLEDescFields6, NULL);
     5451                          0 /*fFlags*/, g_aSSMBDLEDescFields7, NULL);
    54245452    AssertRCReturn(rc, rc);
    54255453
    54265454    rc = SSMR3PutStructEx(pSSM, &pStrm->State.BDLE.State, sizeof(HDABDLESTATE),
    5427                           0 /*fFlags*/, g_aSSMBDLEStateFields6, NULL);
     5455                          0 /*fFlags*/, g_aSSMBDLEStateFields7, NULL);
    54285456    AssertRCReturn(rc, rc);
    54295457
     
    54785506}
    54795507
    5480 
    5481 /**
    5482  * @callback_method_impl{FNSSMDEVLOADEXEC}
    5483  */
    5484 static DECLCALLBACK(int) hdaLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
    5485 {
    5486     PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    5487 
    5488     Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
    5489 
    5490     LogRel2(("hdaLoadExec: uVersion=%RU32, uPass=0x%x\n", uVersion, uPass));
     5508/**
     5509 * Does required post processing when loading a saved state.
     5510 *
     5511 * @param   pThis               Pointer to HDA state.
     5512 */
     5513static int hdaLoadExecPost(PHDASTATE pThis)
     5514{
     5515    int rc = VINF_SUCCESS;
     5516
     5517    bool fStartTimer = false; /* Whether to resume the device timer. */
    54915518
    54925519    /*
    5493      * Load Codec nodes states.
     5520     * Enable all previously active streams.
    54945521     */
    5495     int rc = hdaCodecLoadState(pThis->pCodec, pSSM, uVersion);
    5496     if (RT_FAILURE(rc))
    5497     {
    5498         LogRel(("HDA: Failed loading codec state (version %RU32, pass 0x%x), rc=%Rrc\n", uVersion, uPass, rc));
    5499         return rc;
    5500     }
     5522    for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++)
     5523    {
     5524        PHDASTREAM pStream = hdaStreamGetFromSD(pThis, i);
     5525        if (pStream)
     5526        {
     5527            hdaStreamEnable(pThis, pStream, false /* fEnable */);
     5528
     5529            bool fActive = RT_BOOL(HDA_STREAM_REG(pThis, CTL, i) & HDA_SDCTL_RUN);
     5530            if (fActive)
     5531            {
     5532                int rc2 = hdaStreamEnable(pThis, pStream, true /* fEnable */);
     5533                AssertRC(rc2);
     5534
     5535#ifdef HDA_USE_DMA_ACCESS_HANDLER
     5536                hdaStreamRegisterDMAHandlers(pThis, pStream);
     5537#endif
     5538                fStartTimer = true;
     5539            }
     5540        }
     5541    }
     5542
     5543#ifndef VBOX_WITH_AUDIO_CALLBACKS
     5544    if (   fStartTimer
     5545        && pThis->pTimer
     5546        && !TMTimerIsActive(pThis->pTimer))
     5547    {
     5548        pThis->tsTimerExpire = TMTimerGet(pThis->pTimer) + pThis->cTimerTicks;
     5549
     5550        /* Resume timer. */
     5551        int rc2 = TMTimerSet(pThis->pTimer, pThis->tsTimerExpire);
     5552        AssertRC(rc2);
     5553    }
     5554#endif
     5555
     5556    LogFlowFuncLeaveRC(rc);
     5557    return rc;
     5558}
     5559
     5560
     5561/**
     5562 * Handles loading of all saved state versions older than the current one.
     5563 *
     5564 * @param   pThis               Pointer to HDA state.
     5565 * @param   pSSM                Pointer to SSM handle.
     5566 * @param   uVersion            Saved state version to load.
     5567 * @param   uPass               Loading stage to handle.
     5568 */
     5569static int hdaLoadExecLegacy(PHDASTATE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
     5570{
     5571    RT_NOREF(uPass);
     5572
     5573    int rc = VINF_SUCCESS;
    55015574
    55025575    /*
     
    55305603        case HDA_SSM_VERSION_4:
    55315604        case HDA_SSM_VERSION_5:
    5532         case HDA_SSM_VERSION:
     5605        case HDA_SSM_VERSION_6:
    55335606            rc = SSMR3GetU32(pSSM, &cRegs); AssertRCReturn(rc, rc);
    55345607            if (cRegs != RT_ELEMENTS(pThis->au32Regs))
     
    55485621    else
    55495622        SSMR3GetMem(pSSM, pThis->au32Regs, sizeof(uint32_t) * cRegs);
     5623
     5624    /* Make sure to update the base addresses first before initializing any streams down below. */
     5625    pThis->u64CORBBase  = RT_MAKE_U64(HDA_REG(pThis, CORBLBASE), HDA_REG(pThis, CORBUBASE));
     5626    pThis->u64RIRBBase  = RT_MAKE_U64(HDA_REG(pThis, RIRBLBASE), HDA_REG(pThis, RIRBUBASE));
     5627    pThis->u64DPBase    = RT_MAKE_U64(HDA_REG(pThis, DPLBASE) & DPBASE_ADDR_MASK, HDA_REG(pThis, DPUBASE));
     5628
     5629    /* Also make sure to update the DMA position bit if this was enabled when saving the state. */
     5630    pThis->fDMAPosition = RT_BOOL(HDA_REG(pThis, DPLBASE) & RT_BIT_32(0));
    55505631
    55515632    /*
     
    55835664        rc = SSMR3Skip(pSSM, sizeof(uint32_t));        /* End marker */     \
    55845665        AssertRCReturn(rc, rc);                                             \
    5585     }                                                                       \
     5666    }
    55865667
    55875668    /*
     
    56275708        }
    56285709
    5629         /* Since v5 we support flexible stream and BDLE counts. */
    5630         case HDA_SSM_VERSION_5:
    5631         case HDA_SSM_VERSION:
     5710#undef HDA_SSM_LOAD_BDLE_STATE_PRE_V5
     5711
     5712        default: /* Since v5 we support flexible stream and BDLE counts. */
    56325713        {
    56335714            uint32_t cStreams;
     
    56415722            for (uint32_t i = 0; i < cStreams; i++)
    56425723            {
    5643                 uint8_t uSD;
    5644                 rc = SSMR3GetU8(pSSM, &uSD);
     5724                uint8_t uStreamID;
     5725                rc = SSMR3GetU8(pSSM, &uStreamID);
    56455726                if (RT_FAILURE(rc))
    56465727                    break;
    56475728
    5648                 PHDASTREAM pStrm = hdaStreamGetFromSD(pThis, uSD);
     5729                PHDASTREAM pStrm = hdaStreamGetFromSD(pThis, uStreamID);
    56495730                HDASTREAM  StreamDummy;
    56505731
    56515732                if (!pStrm)
    56525733                {
    5653                     RT_ZERO(StreamDummy);
    56545734                    pStrm = &StreamDummy;
    5655                     LogRel2(("HDA: Warning: Stream ID=%RU32 not supported, skipping to load ...\n", uSD));
     5735                    LogRel2(("HDA: Warning: Stream ID=%RU32 not supported, skipping to load ...\n", uStreamID));
     5736                }
     5737
     5738                rc = hdaStreamInit(pThis, pStrm, uStreamID);
     5739                if (RT_FAILURE(rc))
     5740                {
     5741                    LogRel(("HDA: Stream #%RU32: Initialization of stream %RU8 failed, rc=%Rrc\n", i, uStreamID, rc));
    56565742                    break;
    56575743                }
    56585744
    5659                 rc = hdaStreamInit(pThis, pStrm, uSD);
    5660                 if (RT_FAILURE(rc))
    5661                 {
    5662                     LogRel(("HDA: Stream #%RU32: Initialization of stream %RU8 failed, rc=%Rrc\n", i, uSD, rc));
    5663                     break;
    5664                 }
     5745                /*
     5746                 * Load BDLEs (Buffer Descriptor List Entries) and DMA counters.
     5747                 */
    56655748
    56665749                if (uVersion == HDA_SSM_VERSION_5)
     
    56695752                    uint16_t cBDLE;
    56705753
    5671                     rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* Begin marker */
     5754                    rc = SSMR3Skip(pSSM, sizeof(uint32_t));         /* Begin marker */
    56725755                    AssertRC(rc);
    56735756                    rc = SSMR3GetU16(pSSM, &cBDLE);                 /* cBDLE */
     
    56815764                    for (uint16_t a = 0; a < cBDLE; a++)
    56825765                    {
    5683                         rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* Begin marker */
     5766                        rc = SSMR3Skip(pSSM, sizeof(uint32_t));     /* Begin marker */
    56845767                        AssertRC(rc);
    5685                         rc = SSMR3GetU32(pSSM, &u32BDLEIndex);  /* u32BDLIndex */
     5768                        rc = SSMR3GetU32(pSSM, &u32BDLEIndex);      /* u32BDLIndex */
    56865769                        AssertRC(rc);
    56875770
     
    57015784                        {
    57025785                            rc = SSMR3Skip(pSSM,   sizeof(uint32_t)      /* cbBelowFIFOW */
    5703                                                  + sizeof(uint8_t) * 256 /* FIFO, deprecated */
     5786                                                 + sizeof(uint8_t) * 256 /* au8FIFO */
    57045787                                                 + sizeof(uint32_t)      /* u32BufOff */
    57055788                                                 + sizeof(uint32_t));    /* End marker */
     
    57155798                        break;
    57165799
    5717                     rc = SSMR3GetStructEx(pSSM, &pStrm->State.BDLE.Desc, sizeof(HDABDLEDESC),
    5718                                           0 /* fFlags */, g_aSSMBDLEDescFields6, NULL);
    5719                     if (RT_FAILURE(rc))
    5720                         break;
     5800                    /* Get HDABDLEDESC. */
     5801                    uint32_t uMarker;
     5802                    rc = SSMR3GetU32(pSSM, &uMarker);      /* Begin marker. */
     5803                    AssertRC(rc);
     5804                    Assert(uMarker == UINT32_C(0x19200102) /* SSMR3STRUCT_BEGIN */);
     5805                    rc = SSMR3GetU64(pSSM, &pStrm->State.BDLE.Desc.u64BufAdr);
     5806                    AssertRC(rc);
     5807                    rc = SSMR3GetU32(pSSM, &pStrm->State.BDLE.Desc.u32BufSize);
     5808                    AssertRC(rc);
     5809                    bool fFlags = false;
     5810                    rc = SSMR3GetBool(pSSM, &fFlags);      /* Saved states < v7 only stored the IOC as boolean flag. */
     5811                    AssertRC(rc);
     5812                    pStrm->State.BDLE.Desc.fFlags = fFlags ? HDA_BDLE_FLAG_IOC : 0;
     5813                    rc = SSMR3GetU32(pSSM, &uMarker);      /* End marker. */
     5814                    AssertRC(rc);
     5815                    Assert(uMarker == UINT32_C(0x19920406) /* SSMR3STRUCT_END */);
    57215816
    57225817                    rc = SSMR3GetStructEx(pSSM, &pStrm->State.BDLE.State, sizeof(HDABDLESTATE),
     
    57245819                    if (RT_FAILURE(rc))
    57255820                        break;
     5821
     5822                    Log2Func(("[SD%RU8] LPIB=%RU32, CBL=%RU32, LVI=%RU32\n",
     5823                              uStreamID,
     5824                              HDA_STREAM_REG(pThis, LPIB, uStreamID), HDA_STREAM_REG(pThis, CBL, uStreamID), HDA_STREAM_REG(pThis, LVI, uStreamID)));
     5825#ifdef LOG_ENABLED
     5826                    hdaBDLEDumpAll(pThis, pStrm->u64BDLBase, pStrm->u16LVI + 1);
     5827#endif
    57265828                }
     5829
     5830                rc = hdaSDFMTToStrmCfg(HDA_STREAM_REG(pThis, FMT, uStreamID), &pStrm->State.strmCfg);
     5831                if (RT_FAILURE(rc))
     5832                {
     5833                    LogRel(("HDA: Stream #%RU8: Loading format failed, rc=%Rrc\n", uStreamID, rc));
     5834                    /* Continue. */
     5835                }
     5836
     5837            } /* for cStreams */
     5838            break;
     5839        } /* default */
     5840    }
     5841
     5842    return rc;
     5843}
     5844
     5845/**
     5846 * @callback_method_impl{FNSSMDEVLOADEXEC}
     5847 */
     5848static DECLCALLBACK(int) hdaLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
     5849{
     5850    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
     5851
     5852    Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
     5853
     5854    LogRel2(("hdaLoadExec: uVersion=%RU32, uPass=0x%x\n", uVersion, uPass));
     5855
     5856    /*
     5857     * Load Codec nodes states.
     5858     */
     5859    int rc = hdaCodecLoadState(pThis->pCodec, pSSM, uVersion);
     5860    if (RT_FAILURE(rc))
     5861    {
     5862        LogRel(("HDA: Failed loading codec state (version %RU32, pass 0x%x), rc=%Rrc\n", uVersion, uPass, rc));
     5863        return rc;
     5864    }
     5865
     5866    if (uVersion < HDA_SSM_VERSION) /* Handle older saved states? */
     5867    {
     5868        rc = hdaLoadExecLegacy(pThis, pSSM, uVersion, uPass);
     5869        if (RT_SUCCESS(rc))
     5870            rc = hdaLoadExecPost(pThis);
     5871
     5872        return rc;
     5873    }
     5874
     5875    /*
     5876     * Load MMIO registers.
     5877     */
     5878    uint32_t cRegs;
     5879    rc = SSMR3GetU32(pSSM, &cRegs); AssertRCReturn(rc, rc);
     5880    if (cRegs != RT_ELEMENTS(pThis->au32Regs))
     5881        LogRel(("HDA: SSM version cRegs is %RU32, expected %RU32\n", cRegs, RT_ELEMENTS(pThis->au32Regs)));
     5882
     5883    if (cRegs >= RT_ELEMENTS(pThis->au32Regs))
     5884    {
     5885        SSMR3GetMem(pSSM, pThis->au32Regs, sizeof(pThis->au32Regs));
     5886        SSMR3Skip(pSSM, sizeof(uint32_t) * (cRegs - RT_ELEMENTS(pThis->au32Regs)));
     5887    }
     5888    else
     5889        SSMR3GetMem(pSSM, pThis->au32Regs, sizeof(uint32_t) * cRegs);
     5890
     5891    /* Make sure to update the base addresses first before initializing any streams down below. */
     5892    pThis->u64CORBBase  = RT_MAKE_U64(HDA_REG(pThis, CORBLBASE), HDA_REG(pThis, CORBUBASE));
     5893    pThis->u64RIRBBase  = RT_MAKE_U64(HDA_REG(pThis, RIRBLBASE), HDA_REG(pThis, RIRBUBASE));
     5894    pThis->u64DPBase    = RT_MAKE_U64(HDA_REG(pThis, DPLBASE) & DPBASE_ADDR_MASK, HDA_REG(pThis, DPUBASE));
     5895
     5896    /* Also make sure to update the DMA position bit if this was enabled when saving the state. */
     5897    pThis->fDMAPosition = RT_BOOL(HDA_REG(pThis, DPLBASE) & RT_BIT_32(0));
     5898
     5899    /*
     5900     * Load controller-specifc internals.
     5901     */
     5902    rc = SSMR3GetU64(pSSM, &pThis->u64BaseTS);
     5903    AssertRC(rc);
     5904
     5905    /*
     5906     * Load streams.
     5907     */
     5908    uint32_t cStreams;
     5909    rc = SSMR3GetU32(pSSM, &cStreams);
     5910    AssertRC(rc);
     5911
     5912    Log2Func(("cStreams=%RU32\n", cStreams));
     5913
     5914    /* Load stream states. */
     5915    for (uint32_t i = 0; i < cStreams; i++)
     5916    {
     5917        uint8_t uStreamID;
     5918        rc = SSMR3GetU8(pSSM, &uStreamID);
     5919        AssertRC(rc);
     5920
     5921        PHDASTREAM pStrm = hdaStreamGetFromSD(pThis, uStreamID);
     5922        HDASTREAM  StreamDummy;
     5923
     5924        if (!pStrm)
     5925        {
     5926            pStrm = &StreamDummy;
     5927            LogRel2(("HDA: Warning: Loading of stream #%RU8 not supported, skipping to load ...\n", uStreamID));
     5928        }
     5929
     5930        rc = hdaStreamInit(pThis, pStrm, uStreamID);
     5931        if (RT_FAILURE(rc))
     5932        {
     5933            LogRel(("HDA: Stream #%RU8: Loading initialization failed, rc=%Rrc\n", uStreamID, rc));
     5934            /* Continue. */
     5935        }
     5936
     5937        /*
     5938         * Load BDLEs (Buffer Descriptor List Entries) and DMA counters.
     5939         */
     5940        rc = SSMR3GetStructEx(pSSM, &pStrm->State, sizeof(HDASTREAMSTATE),
     5941                              0 /* fFlags */, g_aSSMStreamStateFields7,
     5942                              NULL);
     5943        AssertRC(rc);
     5944
     5945        rc = SSMR3GetStructEx(pSSM, &pStrm->State.BDLE.Desc, sizeof(HDABDLEDESC),
     5946                              0 /* fFlags */, g_aSSMBDLEDescFields7, NULL);
     5947        AssertRC(rc);
     5948
     5949        rc = SSMR3GetStructEx(pSSM, &pStrm->State.BDLE.State, sizeof(HDABDLESTATE),
     5950                              0 /* fFlags */, g_aSSMBDLEStateFields7, NULL);
     5951        AssertRC(rc);
     5952
     5953        Log2Func(("[SD%RU8] %R[bdle]\n", pStrm->u8SD, &pStrm->State.BDLE));
     5954
     5955        /*
     5956         * Load internal (FIFO) buffer.
     5957         */
     5958
     5959        uint32_t cbCircBufSize = 0;
     5960        rc = SSMR3GetU32(pSSM, &cbCircBufSize); /* cbCircBuf */
     5961        AssertRC(rc);
     5962
     5963        uint32_t cbCircBufUsed = 0;
     5964        rc = SSMR3GetU32(pSSM, &cbCircBufUsed); /* cbCircBuf */
     5965        AssertRC(rc);
     5966
     5967        if (cbCircBufSize) /* If 0, skip the buffer. */
     5968        {
     5969            /* Paranoia. */
     5970            AssertReleaseMsg(cbCircBufSize <= _1M,
     5971                             ("HDA: Saved state contains bogus DMA buffer size (%RU32) for stream #%RU8",
     5972                              cbCircBufSize, uStreamID));
     5973            AssertReleaseMsg(cbCircBufUsed <= cbCircBufSize,
     5974                             ("HDA: Saved state contains invalid DMA buffer usage (%RU32/%RU32) for stream #%RU8",
     5975                              cbCircBufUsed, cbCircBufSize, uStreamID));
     5976            AssertPtr(pStrm->State.pCircBuf);
     5977
     5978            /* Do we need to cre-create the circular buffer do fit the data size? */
     5979            if (cbCircBufSize != (uint32_t)RTCircBufSize(pStrm->State.pCircBuf))
     5980            {
     5981                RTCircBufDestroy(pStrm->State.pCircBuf);
     5982                pStrm->State.pCircBuf = NULL;
     5983
     5984                rc = RTCircBufCreate(&pStrm->State.pCircBuf, cbCircBufSize);
     5985                AssertRC(rc);
    57275986            }
    5728             break;
    5729         }
    5730 
    5731         default:
    5732             AssertReleaseFailed(); /* Never reached. */
    5733             return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
    5734     }
    5735 
    5736 #undef HDA_SSM_LOAD_BDLE_STATE_PRE_V5
    5737 
    5738     if (RT_SUCCESS(rc))
    5739     {
    5740         pThis->u64CORBBase  = RT_MAKE_U64(HDA_REG(pThis, CORBLBASE), HDA_REG(pThis, CORBUBASE));
    5741         pThis->u64RIRBBase  = RT_MAKE_U64(HDA_REG(pThis, RIRBLBASE), HDA_REG(pThis, RIRBUBASE));
    5742         pThis->u64DPBase    = RT_MAKE_U64(HDA_REG(pThis, DPLBASE),   HDA_REG(pThis, DPUBASE));
    5743 
    5744         /* Also make sure to update the DMA position bit if this was enabled when saving the state. */
    5745         pThis->fDMAPosition = RT_BOOL(pThis->u64DPBase & RT_BIT_64(0));
    5746     }
    5747 
    5748     if (RT_SUCCESS(rc))
    5749     {
    5750         for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++)
    5751         {
    5752             PHDASTREAM pStream = hdaStreamGetFromSD(pThis, i);
    5753             if (pStream)
     5987
     5988            if (   RT_SUCCESS(rc)
     5989                && cbCircBufUsed)
    57545990            {
    5755                 hdaStreamEnable(pThis, pStream, false /* fEnable */);
    5756 
    5757                 bool fActive = RT_BOOL(HDA_STREAM_REG(pThis, CTL, i) & HDA_SDCTL_RUN);
    5758                 if (fActive)
     5991                void  *pvBuf;
     5992                size_t cbBuf;
     5993
     5994                RTCircBufAcquireWriteBlock(pStrm->State.pCircBuf, cbCircBufUsed, &pvBuf, &cbBuf);
     5995
     5996                if (cbBuf)
    57595997                {
    5760                     int rc2 = hdaStreamEnable(pThis, pStream, true /* fEnable */);
    5761                     AssertRC(rc2);
     5998                    rc = SSMR3GetMem(pSSM, pvBuf, cbBuf);
     5999                    AssertRC(rc);
    57626000                }
     6001
     6002                RTCircBufReleaseWriteBlock(pStrm->State.pCircBuf, cbBuf);
     6003
     6004                Assert(cbBuf == cbCircBufUsed);
    57636005            }
    57646006        }
    5765     }
    5766 
    5767     if (RT_FAILURE(rc))
    5768         LogRel(("HDA: Failed loading device state (version %RU32, pass 0x%x), rc=%Rrc\n", uVersion, uPass, rc));
     6007
     6008        Log2Func(("[SD%RU8] LPIB=%RU32, CBL=%RU32, LVI=%RU32\n",
     6009                  uStreamID,
     6010                  HDA_STREAM_REG(pThis, LPIB, uStreamID), HDA_STREAM_REG(pThis, CBL, uStreamID), HDA_STREAM_REG(pThis, LVI, uStreamID)));
     6011#ifdef LOG_ENABLED
     6012        hdaBDLEDumpAll(pThis, pStrm->u64BDLBase, pStrm->u16LVI + 1);
     6013#endif
     6014        /** @todo (Re-)initialize active periods? */
     6015
     6016    } /* for cStreams */
     6017
     6018    rc = hdaLoadExecPost(pThis);
     6019    AssertRC(rc);
    57696020
    57706021    LogFlowFuncLeaveRC(rc);
    57716022    return rc;
    57726023}
    5773 
    57746024
    57756025/* Debug and log type formatters. */
  • trunk/src/VBox/Devices/Audio/HDACodec.h

    r64403 r67387  
    118118int hdaCodecRemoveStream(PHDACODEC pThis, PDMAUDIOMIXERCTL enmMixerCtl);
    119119
    120 #define HDA_SSM_VERSION   6
     120/** Added (Controller): Base time stamp for correctly handling the WALCLK register on resume.
     121  * Added (Streams):    Ring buffer. This is optional and can be skipped if (not) needed.
     122  * Added (Streams):    Struct aSSMStreamStateFields7. */
     123#define HDA_SSM_VERSION   7
     124/** Saves the current BDLE state. */
     125#define HDA_SSM_VERSION_6 6
    121126/** Introduced dynamic number of streams + stream identifiers for serialization.
    122127 *  Bug: Did not save the BDLE states correctly.
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