VirtualBox

Changeset 99193 in vbox for trunk


Ignore:
Timestamp:
Mar 28, 2023 9:09:30 AM (22 months ago)
Author:
vboxsync
Message:

Devices/DevQemuFwCfg: Add support for the MMIO interface for ARM, bugref:10386

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevQemuFwCfg.cpp

    r98481 r99193  
    9999/** Offset of the low 32bit of the DMA address. */
    100100#define QEMU_FW_CFG_OFF_DMA_LOW                     8
     101
     102
     103/** @name MMIO register offsets.
     104 * @{ */
     105/** Data register offset. */
     106#define QEU_FW_CFG_MMIO_OFF_DATA                    0
     107/** Selector register offset. */
     108#define QEU_FW_CFG_MMIO_OFF_SELECTOR                8
     109/** DMA base address register offset. */
     110#define QEU_FW_CFG_MMIO_OFF_DMA                     16
     111/** @} */
    101112
    102113
     
    572583static int qemuFwCfgItemSelect(PDEVQEMUFWCFG pThis, uint16_t uCfgItem)
    573584{
     585    LogFlowFunc(("uCfgItem=%#x\n", uCfgItem));
     586
    574587    qemuFwCfgR3ItemReset(pThis);
    575588
     
    792805
    793806
     807/* -=-=-=-=-=- MMIO callbacks -=-=-=-=-=- */
     808
     809
     810/**
     811 * @callback_method_impl{FNIOMMMIONEWREAD}
     812 */
     813static DECLCALLBACK(VBOXSTRICTRC) qemuFwCfgMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
     814{
     815    PDEVQEMUFWCFG pThis = PDMDEVINS_2_DATA(pDevIns, PDEVQEMUFWCFG);
     816    RT_NOREF(pvUser);
     817
     818    LogFlowFunc(("%RGp cb=%u\n", off, cb));
     819
     820    AssertReturn(cb <= sizeof(uint64_t), VERR_INVALID_PARAMETER);
     821
     822    VBOXSTRICTRC rc = VINF_SUCCESS;
     823    switch (off)
     824    {
     825        case QEU_FW_CFG_MMIO_OFF_DATA:
     826        {
     827            if (   pThis->cbCfgItemLeft
     828                && pThis->pCfgItem)
     829            {
     830                uint32_t cbRead = 0;
     831                int rc2 = pThis->pCfgItem->pfnRead(pThis, pThis->pCfgItem, pThis->offCfgItemNext, pv,
     832                                                   cb, &cbRead);
     833                if (RT_SUCCESS(rc2))
     834                {
     835                    pThis->offCfgItemNext += cbRead;
     836                    pThis->cbCfgItemLeft  -= cbRead;
     837                }
     838            }
     839            else
     840                rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "offMmio=%#x cb=%d\n", off, cb);
     841            break;
     842        }
     843        case QEU_FW_CFG_MMIO_OFF_SELECTOR:
     844        case QEU_FW_CFG_MMIO_OFF_DMA:
     845            /* Writeonly, ignore. */
     846            break;
     847        default:
     848            rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "offMmio=%#x cb=%d\n", off, cb);
     849            break;
     850    }
     851
     852    return rc;
     853}
     854
     855
     856/**
     857 * @callback_method_impl{FNIOMMMIONEWWRITE}
     858 */
     859static DECLCALLBACK(VBOXSTRICTRC) qemuFwCfgMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb)
     860{
     861    int rc = VINF_SUCCESS;
     862    PDEVQEMUFWCFG pThis = PDMDEVINS_2_DATA(pDevIns, PDEVQEMUFWCFG);
     863    RT_NOREF(pvUser);
     864
     865    LogFlowFunc(("off=%RGp cb=%u\n", off, cb));
     866
     867    switch (off)
     868    {
     869        case QEU_FW_CFG_MMIO_OFF_DATA: /* Readonly, ignore */
     870            break;
     871        case QEU_FW_CFG_MMIO_OFF_SELECTOR:
     872        {
     873            if (cb == sizeof(uint16_t))
     874                qemuFwCfgItemSelect(pThis, *(uint16_t *)pv);
     875            else
     876                rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "offMmio=%#x cb=%d\n", off, cb);
     877            break;
     878        }
     879        case QEU_FW_CFG_MMIO_OFF_DMA:
     880        {
     881            if (cb == sizeof(uint64_t))
     882            {
     883                pThis->GCPhysDma |= ((RTGCPHYS)RT_BE2H_U64(*(uint64_t *)pv));
     884                qemuFwCfgDmaXfer(pThis, pThis->GCPhysDma);
     885                pThis->GCPhysDma = 0;
     886            }
     887            else
     888                rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "offMmio=%#x cb=%d\n", off, cb);
     889            break;
     890        }
     891        default:
     892            rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "offMmio=%#x cb=%d\n", off, cb);
     893            break;
     894    }
     895
     896    LogFlowFunc((" -> rc=%Rrc\n", rc));
     897    return rc;
     898}
     899
     900
    794901/**
    795902 * Sets up the initrd memory file and CPIO filesystem stream for writing.
     
    11731280     */
    11741281    PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "DmaEnabled"
     1282                                           "|MmioBase"
     1283                                           "|MmioSize"
    11751284                                           "|KernelImage"
    11761285                                           "|InitrdImage"
     
    11931302    pThis->hVfsFileInitrd = NIL_RTVFSFILE;
    11941303
     1304    RTGCPHYS GCPhysMmioBase = 0;
     1305    rc = pHlp->pfnCFGMQueryU64(pCfg, "MmioBase", &GCPhysMmioBase);
     1306    if (RT_FAILURE(rc) && rc != VERR_CFGM_VALUE_NOT_FOUND)
     1307        return PDMDEV_SET_ERROR(pDevIns, rc,
     1308                                N_("Configuration error: Failed to get the \"MmioBase\" value"));
     1309    if (rc == VERR_CFGM_VALUE_NOT_FOUND)
     1310    {
     1311        /*
     1312         * Register standard I/O Ports
     1313         */
     1314        IOMIOPORTHANDLE hIoPorts;
     1315        rc = PDMDevHlpIoPortCreateFlagsAndMap(pDevIns, QEMU_FW_CFG_IO_PORT_START, QEMU_FW_CFG_IO_PORT_SIZE, 0 /*fFlags*/,
     1316                                              qemuFwCfgIoPortWrite, qemuFwCfgIoPortRead,
     1317                                              "QEMU firmware configuration", NULL /*paExtDescs*/, &hIoPorts);
     1318        AssertRCReturn(rc, rc);
     1319    }
     1320    else
     1321    {
     1322        uint32_t cbMmio = 0;
     1323        rc = pHlp->pfnCFGMQueryU32(pCfg, "MmioSize", &cbMmio);
     1324        if (RT_FAILURE(rc))
     1325            return PDMDEV_SET_ERROR(pDevIns, rc,
     1326                                    N_("Configuration error: Failed to get the \"MmioSize\" value"));
     1327
     1328        /*
     1329         * Register and map the MMIO region.
     1330         */
     1331        IOMMMIOHANDLE hMmio;
     1332        rc = PDMDevHlpMmioCreateAndMap(pDevIns, GCPhysMmioBase, cbMmio, qemuFwCfgMmioWrite, qemuFwCfgMmioRead,
     1333                                       IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU, "QemuFwCfg", &hMmio);
     1334        AssertRCReturn(rc, rc);
     1335    }
     1336
    11951337    qemuFwCfgR3ItemReset(pThis);
    11961338
     
    11981340    if (RT_FAILURE(rc))
    11991341        return rc; /* Error set. */
    1200 
    1201     /*
    1202      * Register I/O Ports
    1203      */
    1204     IOMIOPORTHANDLE hIoPorts;
    1205     rc = PDMDevHlpIoPortCreateFlagsAndMap(pDevIns, QEMU_FW_CFG_IO_PORT_START, QEMU_FW_CFG_IO_PORT_SIZE, 0 /*fFlags*/,
    1206                                           qemuFwCfgIoPortWrite, qemuFwCfgIoPortRead,
    1207                                           "QEMU firmware configuration", NULL /*paExtDescs*/, &hIoPorts);
    1208     AssertRCReturn(rc, rc);
    12091342
    12101343    return VINF_SUCCESS;
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