VirtualBox

Changeset 82300 in vbox


Ignore:
Timestamp:
Nov 30, 2019 5:10:05 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
135124
Message:

DevHDA: Converted MMIO region to new style. bugref:9218

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

Legend:

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

    r82257 r82300  
    31413141
    31423142/**
    3143  * @callback_method_impl{FNIOMMMIOREAD, Looks up and calls the appropriate handler.}
     3143 * @callback_method_impl{FNIOMMMIONEWREAD, Looks up and calls the appropriate handler.}
    31443144 *
    31453145 * @note During implementation, we discovered so-called "forgotten" or "hole"
     
    31473147 *       spec.
    31483148 */
    3149 PDMBOTHCBDECL(int) hdaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
     3149static DECLCALLBACK(VBOXSTRICTRC) hdaMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
    31503150{
    31513151    PHDASTATE   pThis  = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);
     
    31573157     * Look up and log.
    31583158     */
    3159     uint32_t        offReg = GCPhysAddr - pThis->MMIOBaseAddr;
    3160     int             idxRegDsc = hdaRegLookup(offReg);    /* Register descriptor index. */
     3159    int             idxRegDsc = hdaRegLookup(off);    /* Register descriptor index. */
    31613160#ifdef LOG_ENABLED
    31623161    unsigned const  cbLog     = cb;
    3163     uint32_t        offRegLog = offReg;
     3162    uint32_t        offRegLog = (uint32_t)off;
    31643163#endif
    31653164
    3166     Log3Func(("offReg=%#x cb=%#x\n", offReg, cb));
    3167     Assert(cb == 4); Assert((offReg & 3) == 0);
     3165    Log3Func(("off=%#x cb=%#x\n", offRegLog, cb));
     3166    Assert(cb == 4); Assert((off & 3) == 0);
    31683167
    31693168    DEVHDA_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_READ);
     
    31733172
    31743173    if (idxRegDsc == -1)
    3175         LogRel(("HDA: Invalid read access @0x%x (bytes=%u)\n", offReg, cb));
     3174        LogRel(("HDA: Invalid read access @0x%x (bytes=%u)\n", (uint32_t)off, cb));
    31763175
    31773176    if (idxRegDsc != -1)
     
    32103209
    32113210                cbLeft -= cbReg;
    3212                 offReg += cbReg;
     3211                off    += cbReg;
    32133212                idxRegDsc++;
    3214             } while (cbLeft > 0 && g_aHdaRegMap[idxRegDsc].offset == offReg);
     3213            } while (cbLeft > 0 && g_aHdaRegMap[idxRegDsc].offset == off);
    32153214
    32163215            if (rc == VINF_SUCCESS)
     
    32293228
    32303229        rc = VINF_IOM_MMIO_UNUSED_FF;
    3231         Log3Func(("\tHole at %x is accessed for read\n", offReg));
     3230        Log3Func(("\tHole at %x is accessed for read\n", offRegLog));
    32323231    }
    32333232
     
    33143313
    33153314/**
    3316  * @callback_method_impl{FNIOMMMIOWRITE, Looks up and calls the appropriate handler.}
    3317  */
    3318 PDMBOTHCBDECL(int) hdaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
     3315 * @callback_method_impl{FNIOMMMIOWNEWRITE,
     3316 *      Looks up and calls the appropriate handler.}
     3317 */
     3318static DECLCALLBACK(VBOXSTRICTRC) hdaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb)
    33193319{
    33203320    PHDASTATE pThis  = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);
     
    33243324
    33253325    /*
    3326      * The behavior of accesses that aren't aligned on natural boundraries is
    3327      * undefined. Just reject them outright.
    3328      */
    3329     /** @todo IOM could check this, it could also split the 8 byte accesses for us. */
    3330     Assert(cb == 1 || cb == 2 || cb == 4 || cb == 8);
    3331     if (GCPhysAddr & (cb - 1))
    3332         return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "misaligned write access: GCPhysAddr=%RGp cb=%u\n", GCPhysAddr, cb);
    3333 
    3334     /*
    33353326     * Look up and log the access.
    33363327     */
    3337     uint32_t    offReg = GCPhysAddr - pThis->MMIOBaseAddr;
    3338     int         idxRegDsc = hdaRegLookup(offReg);
     3328    int         idxRegDsc = hdaRegLookup(off);
    33393329#if defined(IN_RING3) || defined(LOG_ENABLED)
    33403330    uint32_t    idxRegMem = idxRegDsc != -1 ? g_aHdaRegMap[idxRegDsc].mem_idx : UINT32_MAX;
     
    33463336    else if (cb == 8)   u64Value = *(uint64_t const *)pv;
    33473337    else
    3348     {
    3349         u64Value = 0;   /* shut up gcc. */
    3350         AssertReleaseMsgFailed(("%u\n", cb));
    3351     }
     3338        ASSERT_GUEST_MSG_FAILED_RETURN(("cb=%u %.*Rhxs\n", cb, cb, pv),
     3339                                       PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "odd write size: off=%RGp cb=%u\n", off, cb));
     3340
     3341    /*
     3342     * The behavior of accesses that aren't aligned on natural boundraries is
     3343     * undefined. Just reject them outright.
     3344     */
     3345    ASSERT_GUEST_MSG_RETURN((off & (cb - 1)) == 0, ("off=%RGp cb=%u %.*Rhxs\n", off, cb, cb, pv),
     3346                            PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "misaligned write access: off=%RGp cb=%u\n", off, cb));
    33523347
    33533348#ifdef LOG_ENABLED
    33543349    uint32_t const u32LogOldValue = idxRegDsc >= 0 ? pThis->au32Regs[idxRegMem] : UINT32_MAX;
    33553350    if (idxRegDsc == -1)
    3356         Log3Func(("@%#05x u32=%#010x cb=%d\n", offReg, *(uint32_t const *)pv, cb));
    3357     else if (cb == 4)
    3358         Log3Func(("@%#05x u32=%#010x %s\n", offReg, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));
    3359     else if (cb == 2)
    3360         Log3Func(("@%#05x u16=%#06x (%#010x) %s\n", offReg, *(uint16_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));
    3361     else if (cb == 1)
    3362         Log3Func(("@%#05x u8=%#04x (%#010x) %s\n", offReg, *(uint8_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));
    3363 
    3364     if (idxRegDsc >= 0 && g_aHdaRegMap[idxRegDsc].size != cb)
    3365         Log3Func(("\tsize=%RU32 != cb=%u!!\n", g_aHdaRegMap[idxRegDsc].size, cb));
     3351        Log3Func(("@%#05x u32=%#010x cb=%d\n", (uint32_t)off, *(uint32_t const *)pv, cb));
     3352    else
     3353        Log3Func(("@%#05x u%u=%#0*RX64 %s\n", (uint32_t)off, cb * 8, 2 + cb * 2, u64Value, g_aHdaRegMap[idxRegDsc].abbrev));
    33663354#endif
    33673355
     
    33693357     * Try for a direct hit first.
    33703358     */
    3371     if (idxRegDsc != -1 && g_aHdaRegMap[idxRegDsc].size == cb)
     3359    if (idxRegDsc >= 0 && g_aHdaRegMap[idxRegDsc].size == cb)
    33723360    {
    33733361        rc = hdaWriteReg(pDevIns, pThis, idxRegDsc, u64Value, "");
     
    33803368    {
    33813369#ifdef IN_RING3
     3370        if (idxRegDsc >= 0 && g_aHdaRegMap[idxRegDsc].size != cb)
     3371            Log3Func(("\tSize mismatch: %RU32 (reg) vs %u (access)!!\n", g_aHdaRegMap[idxRegDsc].size, cb));
     3372
    33823373        /*
    33833374         * If it's an access beyond the start of the register, shift the input
     
    33863377         * shifting out input values.
    33873378         */
    3388         if (idxRegDsc == -1 && (idxRegDsc = hdaR3RegLookupWithin(offReg)) != -1)
    3389         {
    3390             uint32_t const cbBefore = offReg - g_aHdaRegMap[idxRegDsc].offset; Assert(cbBefore > 0 && cbBefore < 4);
    3391             offReg    -= cbBefore;
     3379        if (idxRegDsc < 0 && (idxRegDsc = hdaR3RegLookupWithin(off)) != -1)
     3380        {
     3381            uint32_t const cbBefore = (uint32_t)off - g_aHdaRegMap[idxRegDsc].offset; Assert(cbBefore > 0 && cbBefore < 4);
     3382            off      -= cbBefore;
    33923383            idxRegMem = g_aHdaRegMap[idxRegDsc].mem_idx;
    33933384            u64Value <<= cbBefore * 8;
     
    34023393        {
    34033394            uint32_t cbReg;
    3404             if (idxRegDsc != -1)
     3395            if (idxRegDsc >= 0)
    34053396            {
    34063397                idxRegMem = g_aHdaRegMap[idxRegDsc].mem_idx;
    3407                 cbReg = g_aHdaRegMap[idxRegDsc].size;
     3398                cbReg     = g_aHdaRegMap[idxRegDsc].size;
    34083399                if (cb < cbReg)
    34093400                {
     
    34203411            else
    34213412            {
    3422                 LogRel(("HDA: Invalid write access @0x%x\n", offReg));
     3413                LogRel(("HDA: Invalid write access @0x%x\n", (uint32_t)off));
    34233414                cbReg = 1;
    34243415            }
     
    34293420
    34303421            /* Advance. */
    3431             offReg += cbReg;
    3432             cb     -= cbReg;
     3422            off += cbReg;
     3423            cb  -= cbReg;
    34333424            u64Value >>= cbReg * 8;
    34343425            if (idxRegDsc == -1)
    3435                 idxRegDsc = hdaRegLookup(offReg);
     3426                idxRegDsc = hdaRegLookup(off);
    34363427            else
    34373428            {
    34383429                idxRegDsc++;
    34393430                if (   (unsigned)idxRegDsc >= RT_ELEMENTS(g_aHdaRegMap)
    3440                     || g_aHdaRegMap[idxRegDsc].offset != offReg)
    3441                 {
     3431                    || g_aHdaRegMap[idxRegDsc].offset != off)
    34423432                    idxRegDsc = -1;
    3443                 }
    34443433            }
    34453434        }
     
    34583447
    34593448#ifdef IN_RING3
    3460 /**
    3461  * @callback_method_impl{FNPCIIOREGIONMAP}
    3462  */
    3463 static DECLCALLBACK(int) hdaR3PciIoRegionMap(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
    3464                                              RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    3465 {
     3449
     3450/* Saved state workers and callbacks. */
     3451
     3452static int hdaR3SaveStream(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, PHDASTREAM pStream)
     3453{
     3454    RT_NOREF(pDevIns);
     3455# ifdef LOG_ENABLED
    34663456    PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);
    3467     RT_NOREF(pPciDev, iRegion, enmType);
    3468 
    3469     Assert(enmType == PCI_ADDRESS_SPACE_MEM);
    3470     Assert(iRegion == 0);
    3471     Assert(pPciDev == pDevIns->apPciDevs[0]);
    3472 
    3473     /*
    3474      * 18.2 of the ICH6 datasheet defines the valid access widths as byte, word, and double word.
    3475      *
    3476      * Let IOM talk DWORDs when reading, saves a lot of complications. On
    3477      * writing though, we have to do it all ourselves because of sideeffects.
    3478      */
    3479     Assert(enmType == PCI_ADDRESS_SPACE_MEM);
    3480     int rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/,
    3481                                      IOMMMIO_FLAGS_READ_DWORD
    3482                                    | IOMMMIO_FLAGS_WRITE_PASSTHRU,
    3483                                    hdaMMIOWrite, hdaMMIORead, "HDA");
    3484 
    3485     if (RT_FAILURE(rc))
    3486         return rc;
    3487 
    3488     if (pThis->fRZEnabled)
    3489     {
    3490         rc = PDMDevHlpMMIORegisterR0(pDevIns, GCPhysAddress, cb, NIL_RTR0PTR /*pvUser*/,
    3491                                      "hdaMMIOWrite", "hdaMMIORead");
    3492         if (RT_FAILURE(rc))
    3493             return rc;
    3494 
    3495         rc = PDMDevHlpMMIORegisterRC(pDevIns, GCPhysAddress, cb, NIL_RTRCPTR /*pvUser*/,
    3496                                      "hdaMMIOWrite", "hdaMMIORead");
    3497         if (RT_FAILURE(rc))
    3498             return rc;
    3499     }
    3500 
    3501     pThis->MMIOBaseAddr = GCPhysAddress;
    3502     return VINF_SUCCESS;
    3503 }
    3504 
    3505 
    3506 /* Saved state workers and callbacks. */
    3507 
    3508 static int hdaR3SaveStream(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, PHDASTREAM pStream)
    3509 {
    3510     RT_NOREF(pDevIns);
    3511 #if defined(LOG_ENABLED)
    3512     PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);
    3513 #endif
     3457# endif
    35143458
    35153459    Log2Func(("[SD%RU8]\n", pStream->u8SD));
     
    49214865    AssertRCReturn(rc, rc);
    49224866
    4923     rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0, 0x4000, PCI_ADDRESS_SPACE_MEM, hdaR3PciIoRegionMap);
     4867    rc = PDMDevHlpPCIIORegionCreateMmio(pDevIns, 0, 0x4000, PCI_ADDRESS_SPACE_MEM, hdaMMIOWrite, hdaMMIORead, NULL /*pvUser*/,
     4868                                        IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_PASSTHRU, "HDA", &pThis->hMmio);
    49244869    AssertRCReturn(rc, rc);
    49254870
     
    52635208}
    52645209
    5265 #endif /* IN_RING3 */
     5210#else  /* !IN_RING3 */
     5211
     5212/**
     5213 * @callback_method_impl{PDMDEVREGR0,pfnConstruct}
     5214 */
     5215static DECLCALLBACK(int) ohciRZConstruct(PPDMDEVINS pDevIns)
     5216{
     5217    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); /* this shall come first */
     5218    PHDASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);
     5219
     5220    int rc = PDMDevHlpMmioSetUpContext(pDevIns, pThis->hMmio, hdaMMIOWrite, hdaMMIORead, NULL /*pvUser*/);
     5221    AssertRCReturn(rc, rc);
     5222
     5223    return VINF_SUCCESS;
     5224}
     5225
     5226#endif /* !IN_RING3 */
    52665227
    52675228/**
  • trunk/src/VBox/Devices/Audio/DevHDA.h

    r81031 r82300  
    109109    /** The base interface for LUN\#0. */
    110110    PDMIBASE                IBase;
    111     RTGCPHYS                MMIOBaseAddr;
    112111    /** The HDA's register set. */
    113112    uint32_t                au32Regs[HDA_NUM_REGS];
     
    196195    uint8_t                 au8Padding3[3];
    197196    HDASTATEDBGINFO         Dbg;
     197
     198    /** PCI Region \#0: 16KB of MMIO stuff. */
     199    IOMMMIOHANDLE           hMmio;
     200
    198201#ifdef VBOX_WITH_STATISTICS
    199202    STAMPROFILE             StatTimer;
Note: See TracChangeset for help on using the changeset viewer.

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