VirtualBox

Changeset 89876 in vbox for trunk/src


Ignore:
Timestamp:
Jun 24, 2021 10:02:02 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
145334
Message:

DevHda: Removed the HDA_USE_DMA_ACCESS_HANDLER stuff as it is unlikely to be helpful. Current assumption is that BDLs are owned by the HDA controller when we're running. (What migth've been useful would be to monitor the DMA position buffer.) bugref:9890

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

Legend:

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

    r89874 r89876  
    6262*********************************************************************************************************************************/
    6363//#define HDA_AS_PCI_EXPRESS
    64 
    65 /* Installs a DMA access handler (via PGM callback) to monitor
    66  * HDA's DMA operations, that is, writing / reading audio stream data.
    67  *
    68  * !!! Note: Certain guests are *that* timing sensitive that when enabling  !!!
    69  * !!!       such a handler will mess up audio completely (e.g. Windows 7). !!! */
    70 //#define HDA_USE_DMA_ACCESS_HANDLER
    71 #ifdef HDA_USE_DMA_ACCESS_HANDLER
    72 # include <VBox/vmm/pgm.h>
    73 #endif
    7464
    7565/* Uses the DMA access handler to read the written DMA audio (output) data.
     
    174164    R3PTRTYPE(PAUDMIXSTREAM)           pMixStrm;
    175165} HDADRIVERSTREAM, *PHDADRIVERSTREAM;
    176 
    177 #ifdef HDA_USE_DMA_ACCESS_HANDLER
    178 /**
    179  * Struct for keeping an HDA DMA access handler context.
    180  */
    181 typedef struct HDADMAACCESSHANDLER
    182 {
    183     /** Node for storing this handler in our list in HDASTREAMSTATE. */
    184     RTLISTNODER3            Node;
    185     /** Pointer to stream to which this access handler is assigned to. */
    186     R3PTRTYPE(PHDASTREAM)   pStream;
    187     /** Access handler type handle. */
    188     PGMPHYSHANDLERTYPE      hAccessHandlerType;
    189     /** First address this handler uses. */
    190     RTGCPHYS                GCPhysFirst;
    191     /** Last address this handler uses. */
    192     RTGCPHYS                GCPhysLast;
    193     /** Actual BDLE address to handle. */
    194     RTGCPHYS                BDLEAddr;
    195     /** Actual BDLE buffer size to handle. */
    196     RTGCPHYS                BDLESize;
    197     /** Whether the access handler has been registered or not. */
    198     bool                    fRegistered;
    199     uint8_t                 Padding[3];
    200 } HDADMAACCESSHANDLER, *PHDADMAACCESSHANDLER;
    201 #endif
    202166
    203167/**
     
    345309static int                        hdaR3AddStream(PHDASTATER3 pThisCC, PPDMAUDIOSTREAMCFG pCfg);
    346310static int                        hdaR3RemoveStream(PHDASTATER3 pThisCC, PPDMAUDIOSTREAMCFG pCfg);
    347 # ifdef HDA_USE_DMA_ACCESS_HANDLER
    348 static DECLCALLBACK(VBOXSTRICTRC) hdaR3DmaAccessHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys,
    349                                                         void *pvBuf, size_t cbBuf,
    350                                                         PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser);
    351 # endif
    352311#endif /* IN_RING3 */
    353312/** @} */
     
    16031562    AssertReturn(idxStream < RT_ELEMENTS(pThis->aStreams), VERR_INTERNAL_ERROR_3); /* paranoia^2: Bad g_aHdaRegMap. */
    16041563
    1605 #ifdef HDA_USE_DMA_ACCESS_HANDLER
    1606     if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_OUT)
    1607     {
    1608         /* Try registering the DMA handlers.
    1609          * As we can't be sure in which order LVI + BDL base are set, try registering in both routines. */
    1610         PHDASTREAM pStream = hdaGetStreamFromSD(pThis, idxStream);
    1611         if (   pStream
    1612             && hdaR3StreamRegisterDMAHandlers(pThis, pStream))
    1613             LogFunc(("[SD%RU8] DMA logging enabled\n", pStream->u8SD));
    1614     }
    1615 #endif
    1616 
    16171564    ASSERT_GUEST_LOGREL_MSG(u32Value <= UINT8_MAX, /* Should be covered by the register write mask, but just to make sure. */
    16181565                            ("LVI for stream #%zu must not be bigger than %RU8\n", idxStream, UINT8_MAX - 1));
     
    19851932DECLINLINE(VBOXSTRICTRC) hdaRegWriteSDBDPX(PPDMDEVINS pDevIns, PHDASTATE pThis, uint32_t iReg, uint32_t u32Value, uint8_t uSD)
    19861933{
    1987 #ifndef HDA_USE_DMA_ACCESS_HANDLER
    19881934    RT_NOREF(uSD);
    19891935    return hdaRegWriteU32(pDevIns, pThis, iReg, u32Value);
    1990 #else
    1991 # ifdef IN_RING3
    1992     if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_OUT)
    1993     {
    1994         /* Try registering the DMA handlers.
    1995          * As we can't be sure in which order LVI + BDL base are set, try registering in both routines. */
    1996         PHDASTREAM pStream = hdaGetStreamFromSD(pThis, uSD);
    1997         if (   pStream
    1998             && hdaR3StreamRegisterDMAHandlers(pThis, pStream))
    1999             LogFunc(("[SD%RU8] DMA logging enabled\n", pStream->u8SD));
    2000     }
    2001     return hdaRegWriteU32(pDevIns, pThis, iReg, u32Value);
    2002 # else
    2003     RT_NOREF(pDevIns, pThis, iReg, u32Value, uSD);
    2004     return VINF_IOM_R3_MMIO_WRITE;
    2005 # endif
    2006 #endif
    20071936}
    20081937
     
    27262655}
    27272656
    2728 # ifdef HDA_USE_DMA_ACCESS_HANDLER
    2729 /**
    2730  * HC access handler for the FIFO.
    2731  *
    2732  * @returns VINF_SUCCESS if the handler have carried out the operation.
    2733  * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
    2734  * @param   pVM             VM Handle.
    2735  * @param   pVCpu           The cross context CPU structure for the calling EMT.
    2736  * @param   GCPhys          The physical address the guest is writing to.
    2737  * @param   pvPhys          The HC mapping of that address.
    2738  * @param   pvBuf           What the guest is reading/writing.
    2739  * @param   cbBuf           How much it's reading/writing.
    2740  * @param   enmAccessType   The access type.
    2741  * @param   enmOrigin       Who is making the access.
    2742  * @param   pvUser          User argument.
    2743  */
    2744 static DECLCALLBACK(VBOXSTRICTRC) hdaR3DmaAccessHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys,
    2745                                                         void *pvBuf, size_t cbBuf,
    2746                                                         PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
    2747 {
    2748     RT_NOREF(pVM, pVCpu, pvPhys, pvBuf, enmOrigin);
    2749 
    2750     PHDADMAACCESSHANDLER pHandler = (PHDADMAACCESSHANDLER)pvUser;
    2751     AssertPtr(pHandler);
    2752 
    2753     PHDASTREAM pStream = pHandler->pStream;
    2754     AssertPtr(pStream);
    2755 
    2756     Assert(GCPhys >= pHandler->GCPhysFirst);
    2757     Assert(GCPhys <= pHandler->GCPhysLast);
    2758     Assert(enmAccessType == PGMACCESSTYPE_WRITE);
    2759 
    2760     /* Not within BDLE range? Bail out. */
    2761     if (   (GCPhys         < pHandler->BDLEAddr)
    2762         || (GCPhys + cbBuf > pHandler->BDLEAddr + pHandler->BDLESize))
    2763     {
    2764         return VINF_PGM_HANDLER_DO_DEFAULT;
    2765     }
    2766 
    2767     switch (enmAccessType)
    2768     {
    2769         case PGMACCESSTYPE_WRITE:
    2770         {
    2771 #  ifdef DEBUG
    2772             const uint64_t tsNowNs     = RTTimeNanoTS();
    2773             const uint32_t tsElapsedMs = (tsNowNs - pStream->Dbg.tsWriteSlotBegin) / 1000 / 1000;
    2774 
    2775             uint64_t cWritesHz   = ASMAtomicReadU64(&pStream->Dbg.cWritesHz);
    2776             uint64_t cbWrittenHz = ASMAtomicReadU64(&pStream->Dbg.cbWrittenHz);
    2777 
    2778             if (tsElapsedMs >= (1000 / HDA_TIMER_HZ_DEFAULT))
    2779             {
    2780                 LogFunc(("[SD%RU8] %RU32ms elapsed, cbWritten=%RU64, cWritten=%RU64 -- %RU32 bytes on average per time slot (%zums)\n",
    2781                          pStream->u8SD, tsElapsedMs, cbWrittenHz, cWritesHz,
    2782                          ASMDivU64ByU32RetU32(cbWrittenHz, cWritesHz ? cWritesHz : 1), 1000 / HDA_TIMER_HZ_DEFAULT));
    2783 
    2784                 pStream->Dbg.tsWriteSlotBegin = tsNowNs;
    2785 
    2786                 cWritesHz   = 0;
    2787                 cbWrittenHz = 0;
    2788             }
    2789 
    2790             cWritesHz   += 1;
    2791             cbWrittenHz += cbBuf;
    2792 
    2793             ASMAtomicIncU64(&pStream->Dbg.cWritesTotal);
    2794             ASMAtomicAddU64(&pStream->Dbg.cbWrittenTotal, cbBuf);
    2795 
    2796             ASMAtomicWriteU64(&pStream->Dbg.cWritesHz,   cWritesHz);
    2797             ASMAtomicWriteU64(&pStream->Dbg.cbWrittenHz, cbWrittenHz);
    2798 
    2799             LogFunc(("[SD%RU8] Writing %3zu @ 0x%x (off %zu)\n",
    2800                      pStream->u8SD, cbBuf, GCPhys, GCPhys - pHandler->BDLEAddr));
    2801 
    2802             LogFunc(("[SD%RU8] cWrites=%RU64, cbWritten=%RU64 -> %RU32 bytes on average\n",
    2803                      pStream->u8SD, pStream->Dbg.cWritesTotal, pStream->Dbg.cbWrittenTotal,
    2804                      ASMDivU64ByU32RetU32(pStream->Dbg.cbWrittenTotal, pStream->Dbg.cWritesTotal)));
    2805 #  endif
    2806 
    2807 #  ifdef VBOX_AUDIO_DEBUG_DUMP_PCM_DATA_PATH
    2808             if (pThis->fDebugEnabled)
    2809             {
    2810                 RTFILE fh;
    2811                 RTFileOpen(&fh, VBOX_AUDIO_DEBUG_DUMP_PCM_DATA_PATH "hdaDMAAccessWrite.pcm",
    2812                            RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    2813                 RTFileWrite(fh, pvBuf, cbBuf, NULL);
    2814                 RTFileClose(fh);
    2815             }
    2816 #  endif
    2817 
    2818 #  ifdef HDA_USE_DMA_ACCESS_HANDLER_WRITING
    2819             PRTCIRCBUF pCircBuf = pStream->State.pCircBuf;
    2820             AssertPtr(pCircBuf);
    2821 
    2822             uint8_t *pbBuf = (uint8_t *)pvBuf;
    2823             while (cbBuf)
    2824             {
    2825                 /* Make sure we only copy as much as the stream's FIFO can hold (SDFIFOS, 18.2.39). */
    2826                 void *pvChunk;
    2827                 size_t cbChunk;
    2828                 RTCircBufAcquireWriteBlock(pCircBuf, cbBuf, &pvChunk, &cbChunk);
    2829 
    2830                 if (cbChunk)
    2831                 {
    2832                     memcpy(pvChunk, pbBuf, cbChunk);
    2833 
    2834                     pbBuf  += cbChunk;
    2835                     Assert(cbBuf >= cbChunk);
    2836                     cbBuf  -= cbChunk;
    2837                 }
    2838                 else
    2839                 {
    2840                     //AssertMsg(RTCircBufFree(pCircBuf), ("No more space but still %zu bytes to write\n", cbBuf));
    2841                     break;
    2842                 }
    2843 
    2844                 LogFunc(("[SD%RU8] cbChunk=%zu\n", pStream->u8SD, cbChunk));
    2845 
    2846                 RTCircBufReleaseWriteBlock(pCircBuf, cbChunk);
    2847             }
    2848 #  endif /* HDA_USE_DMA_ACCESS_HANDLER_WRITING */
    2849             break;
    2850         }
    2851 
    2852         default:
    2853             AssertMsgFailed(("Access type not implemented\n"));
    2854             break;
    2855     }
    2856 
    2857     return VINF_PGM_HANDLER_DO_DEFAULT;
    2858 }
    2859 # endif /* HDA_USE_DMA_ACCESS_HANDLER */
    2860 
    28612657/**
    28622658 * Soft reset of the device triggered via GCTL.
     
    35883384            rc2 = hdaR3AddStream(pThisCC, &pStreamShared->State.Cfg);
    35893385            AssertRC(rc2);
    3590 
    3591 #ifdef HDA_USE_DMA_ACCESS_HANDLER
    3592             /* (Re-)install the DMA handler. */
    3593             hdaR3StreamRegisterDMAHandlers(pThis, pStreamShared);
    3594 #endif
    35953386
    35963387            /* Use the LPIB to find the current scheduling position.  If this isn't
  • trunk/src/VBox/Devices/Audio/DevHdaStream.cpp

    r89875 r89876  
    8181    pStreamShared->State.fInReset = false;
    8282    pStreamShared->State.fRunning = false;
    83 # ifdef HDA_USE_DMA_ACCESS_HANDLER
    84     RTListInit(&pStreamR3->State.lstDMAHandlers);
    85 # endif
    8683
    8784    AssertPtr(pStreamR3->pHDAStateR3);
     
    855852    HDA_STREAM_REG(pThis, BDPU,  uSD) = 0;
    856853    HDA_STREAM_REG(pThis, BDPL,  uSD) = 0;
    857 
    858 # ifdef HDA_USE_DMA_ACCESS_HANDLER
    859     hdaR3StreamUnregisterDMAHandlers(pThis, pStream);
    860 # endif
    861854
    862855    /* Assign the default mixer sink to the stream. */
     
    26002593}
    26012594
    2602 
    2603 # ifdef HDA_USE_DMA_ACCESS_HANDLER
    2604 /**
    2605  * Registers access handlers for a stream's BDLE DMA accesses.
    2606  *
    2607  * @returns true if registration was successful, false if not.
    2608  * @param   pStream             HDA stream to register BDLE access handlers for.
    2609  */
    2610 bool hdaR3StreamRegisterDMAHandlers(PHDASTREAM pStream)
    2611 {
    2612     /* At least LVI and the BDL base must be set. */
    2613     if (   !pStreamShared->u16LVI
    2614         || !pStreamShared->u64BDLBase)
    2615     {
    2616         return false;
    2617     }
    2618 
    2619     hdaR3StreamUnregisterDMAHandlers(pStream);
    2620 
    2621     LogFunc(("Registering ...\n"));
    2622 
    2623     int rc = VINF_SUCCESS;
    2624 
    2625     /*
    2626      * Create BDLE ranges.
    2627      */
    2628 
    2629     struct BDLERANGE
    2630     {
    2631         RTGCPHYS uAddr;
    2632         uint32_t uSize;
    2633     } arrRanges[16]; /** @todo Use a define. */
    2634 
    2635     size_t cRanges = 0;
    2636 
    2637     for (uint16_t i = 0; i < pStreamShared->u16LVI + 1; i++)
    2638     {
    2639         HDABDLE BDLE;
    2640         rc = hdaR3BDLEFetch(pDevIns, &BDLE, pStreamShared->u64BDLBase, i /* Index */);
    2641         if (RT_FAILURE(rc))
    2642             break;
    2643 
    2644         bool fAddRange = true;
    2645         BDLERANGE *pRange;
    2646 
    2647         if (cRanges)
    2648         {
    2649             pRange = &arrRanges[cRanges - 1];
    2650 
    2651             /* Is the current range a direct neighbor of the current BLDE? */
    2652             if ((pRange->uAddr + pRange->uSize) == BDLE.Desc.u64BufAddr)
    2653             {
    2654                 /* Expand the current range by the current BDLE's size. */
    2655                 pRange->uSize += BDLE.Desc.u32BufSize;
    2656 
    2657                 /* Adding a new range in this case is not needed anymore. */
    2658                 fAddRange = false;
    2659 
    2660                 LogFunc(("Expanding range %zu by %RU32 (%RU32 total now)\n", cRanges - 1, BDLE.Desc.u32BufSize, pRange->uSize));
    2661             }
    2662         }
    2663 
    2664         /* Do we need to add a new range? */
    2665         if (   fAddRange
    2666             && cRanges < RT_ELEMENTS(arrRanges))
    2667         {
    2668             pRange = &arrRanges[cRanges];
    2669 
    2670             pRange->uAddr = BDLE.Desc.u64BufAddr;
    2671             pRange->uSize = BDLE.Desc.u32BufSize;
    2672 
    2673             LogFunc(("Adding range %zu - 0x%x (%RU32)\n", cRanges, pRange->uAddr, pRange->uSize));
    2674 
    2675             cRanges++;
    2676         }
    2677     }
    2678 
    2679     LogFunc(("%zu ranges total\n", cRanges));
    2680 
    2681     /*
    2682      * Register all ranges as DMA access handlers.
    2683      */
    2684 
    2685     for (size_t i = 0; i < cRanges; i++)
    2686     {
    2687         BDLERANGE *pRange = &arrRanges[i];
    2688 
    2689         PHDADMAACCESSHANDLER pHandler = (PHDADMAACCESSHANDLER)RTMemAllocZ(sizeof(HDADMAACCESSHANDLER));
    2690         if (!pHandler)
    2691         {
    2692             rc = VERR_NO_MEMORY;
    2693             break;
    2694         }
    2695 
    2696         RTListAppend(&pStream->State.lstDMAHandlers, &pHandler->Node);
    2697 
    2698         pHandler->pStream = pStream; /* Save a back reference to the owner. */
    2699 
    2700         char szDesc[32];
    2701         RTStrPrintf(szDesc, sizeof(szDesc), "HDA[SD%RU8 - RANGE%02zu]", pStream->u8SD, i);
    2702 
    2703         int rc2 = PGMR3HandlerPhysicalTypeRegister(PDMDevHlpGetVM(pStream->pHDAState->pDevInsR3), PGMPHYSHANDLERKIND_WRITE,
    2704                                                    hdaDMAAccessHandler,
    2705                                                    NULL, NULL, NULL,
    2706                                                    NULL, NULL, NULL,
    2707                                                    szDesc, &pHandler->hAccessHandlerType);
    2708         AssertRCBreak(rc2);
    2709 
    2710         pHandler->BDLEAddr  = pRange->uAddr;
    2711         pHandler->BDLESize  = pRange->uSize;
    2712 
    2713         /* Get first and last pages of the BDLE range. */
    2714         RTGCPHYS pgFirst = pRange->uAddr & ~PAGE_OFFSET_MASK;
    2715         RTGCPHYS pgLast  = RT_ALIGN(pgFirst + pRange->uSize, PAGE_SIZE);
    2716 
    2717         /* Calculate the region size (in pages). */
    2718         RTGCPHYS regionSize = RT_ALIGN(pgLast - pgFirst, PAGE_SIZE);
    2719 
    2720         pHandler->GCPhysFirst = pgFirst;
    2721         pHandler->GCPhysLast  = pHandler->GCPhysFirst + (regionSize - 1);
    2722 
    2723         LogFunc(("  Registering region '%s': %#RGp - %#RGp (region size: %#zx)\n",
    2724                  szDesc, pHandler->GCPhysFirst, pHandler->GCPhysLast, regionSize));
    2725         LogFunc(("  BDLE @ %#RGp - %#RGp (%#RX32)\n",
    2726                  pHandler->BDLEAddr, pHandler->BDLEAddr + pHandler->BDLESize, pHandler->BDLESize));
    2727 
    2728         rc2 = PGMHandlerPhysicalRegister(PDMDevHlpGetVM(pStream->pHDAState->pDevInsR3),
    2729                                          pHandler->GCPhysFirst, pHandler->GCPhysLast,
    2730                                          pHandler->hAccessHandlerType, pHandler, NIL_RTR0PTR, NIL_RTRCPTR,
    2731                                          szDesc);
    2732         AssertRCBreak(rc2);
    2733 
    2734         pHandler->fRegistered = true;
    2735     }
    2736 
    2737     LogFunc(("Registration ended with rc=%Rrc\n", rc));
    2738 
    2739     return RT_SUCCESS(rc);
    2740 }
    2741 
    2742 /**
    2743  * Unregisters access handlers of a stream's BDLEs.
    2744  *
    2745  * @param   pStream             HDA stream to unregister BDLE access handlers for.
    2746  */
    2747 void hdaR3StreamUnregisterDMAHandlers(PHDASTREAM pStream)
    2748 {
    2749     LogFunc(("\n"));
    2750 
    2751     PHDADMAACCESSHANDLER pHandler, pHandlerNext;
    2752     RTListForEachSafe(&pStream->State.lstDMAHandlers, pHandler, pHandlerNext, HDADMAACCESSHANDLER, Node)
    2753     {
    2754         if (!pHandler->fRegistered) /* Handler not registered? Skip. */
    2755             continue;
    2756 
    2757         LogFunc(("Unregistering 0x%x - 0x%x (%zu)\n",
    2758                  pHandler->GCPhysFirst, pHandler->GCPhysLast, pHandler->GCPhysLast - pHandler->GCPhysFirst));
    2759 
    2760         int rc2 = PGMHandlerPhysicalDeregister(PDMDevHlpGetVM(pStream->pHDAState->pDevInsR3),
    2761                                                pHandler->GCPhysFirst);
    2762         AssertRC(rc2);
    2763 
    2764         RTListNodeRemove(&pHandler->Node);
    2765 
    2766         RTMemFree(pHandler);
    2767         pHandler = NULL;
    2768     }
    2769 
    2770     Assert(RTListIsEmpty(&pStream->State.lstDMAHandlers));
    2771 }
    2772 
    2773 # endif /* HDA_USE_DMA_ACCESS_HANDLER */
    2774 
    27752595#endif /* IN_RING3 */
     2596
  • trunk/src/VBox/Devices/Audio/DevHdaStream.h

    r89874 r89876  
    283283        /** Circular buffer (FIFO) for holding DMA'ed data. */
    284284        R3PTRTYPE(PRTCIRCBUF)   pCircBuf;
    285 #ifdef HDA_USE_DMA_ACCESS_HANDLER
    286         /** List of DMA handlers. */
    287         RTLISTANCHORR3          lstDMAHandlers;
    288 #endif
    289285        /** The mixer sink this stream has registered AIO update callback with.
    290286         * This is NULL till we register it, typically in hdaR3StreamEnable.
     
    347343                                         PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3);
    348344DECLCALLBACK(void)  hdaR3StreamUpdateAsyncIoJob(PPDMDEVINS pDevIns, PAUDMIXSINK pSink, void *pvUser);
    349 # ifdef HDA_USE_DMA_ACCESS_HANDLER
    350 bool                hdaR3StreamRegisterDMAHandlers(PHDASTREAM pStream);
    351 void                hdaR3StreamUnregisterDMAHandlers(PHDASTREAM pStream);
    352 # endif
    353345/** @} */
    354346
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