VirtualBox

Changeset 99750 in vbox


Ignore:
Timestamp:
May 11, 2023 1:37:24 PM (19 months ago)
Author:
vboxsync
Message:

Devices/Bus: Started a basic PCI bus implementation suitable for ARMv8, devices are detected by a Linux guest but interrupts don't work right now. The implementation shares most code with ICH9 PCI device, bugref:10445

Location:
trunk/src/VBox/Devices
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Bus/DevPCI.cpp

    r98103 r99750  
    13051305    memset((void *)&pGlobals->auPciApicIrqLevels, 0, sizeof(pGlobals->auPciApicIrqLevels));
    13061306
    1307     pGlobals->PciBus.fTypePiix3  = true;
    1308     pGlobals->PciBus.fTypeIch9   = false;
     1307    pGlobals->PciBus.enmType     = DEVPCIBUSTYPE_PIIX3;
    13091308    pGlobals->PciBus.fPureBridge = false;
    13101309    pGlobals->PciBus.papBridgesR3 = (PPDMPCIDEV *)PDMDevHlpMMHeapAllocZ(pDevIns,
     
    16961695     * Init data and register the PCI bus.
    16971696     */
    1698     pBus->fTypePiix3  = true;
    1699     pBus->fTypeIch9   = false;
    1700     pBus->fPureBridge = true;
     1697    pBus->enmType      = DEVPCIBUSTYPE_PIIX3;
     1698    pBus->fPureBridge  = true;
    17011699    pBus->papBridgesR3 = (PPDMPCIDEV *)PDMDevHlpMMHeapAllocZ(pDevIns, sizeof(PPDMPCIDEV) * RT_ELEMENTS(pBus->apDevices));
    17021700    AssertLogRelReturn(pBus->papBridgesR3, VERR_NO_MEMORY);
  • trunk/src/VBox/Devices/Bus/DevPciIch9.cpp

    r98103 r99750  
    116116#ifdef IN_RING3
    117117static int ich9pciFakePCIBIOS(PPDMDEVINS pDevIns);
    118 DECLINLINE(PPDMPCIDEV) ich9pciFindBridge(PDEVPCIBUS pBus, uint8_t uBus);
    119118static void ich9pciBiosInitAllDevicesOnBus(PPDMDEVINS pDevIns, PDEVPCIROOT pPciRoot, PDEVPCIBUS pBus);
    120119static bool ich9pciBiosInitAllDevicesPrefetchableOnBus(PPDMDEVINS pDevIns, PDEVPCIROOT pPciRoot, PDEVPCIBUS pBus, bool fUse64Bit, bool fDryrun);
     
    342341        {
    343342#ifdef IN_RING3 /** @todo do lookup in R0/RC too! r=klaus don't think that it can work, since the config space access callback only works in R3 */
    344             PPDMPCIDEV pBridgeDevice = ich9pciFindBridge(&pPciRoot->PciBus, pPciAddr->iBus);
     343            PPDMPCIDEV pBridgeDevice = devpciR3FindBridge(&pPciRoot->PciBus, pPciAddr->iBus);
    345344            if (pBridgeDevice)
    346345            {
     
    437436        {
    438437#ifdef IN_RING3 /** @todo do lookup in R0/RC too! r=klaus don't think that it can work, since the config space access callback only works in R3 */
    439             PPDMPCIDEV pBridgeDevice = ich9pciFindBridge(&pPciRoot->PciBus, pPciAddr->iBus);
     438            PPDMPCIDEV pBridgeDevice = devpciR3FindBridge(&pPciRoot->PciBus, pPciAddr->iBus);
    440439            if (pBridgeDevice)
    441440            {
     
    658657 * Emulates writes to configuration space.}
    659658 */
    660 static DECLCALLBACK(VBOXSTRICTRC) ich9pciMcfgMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb)
     659DECL_HIDDEN_CALLBACK(VBOXSTRICTRC) devpciCommonMcfgMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb)
    661660{
    662661    PDEVPCIROOT pPciRoot = PDMINS_2_DATA(pDevIns, PDEVPCIROOT);
     
    700699 * Emulates reads from configuration space.}
    701700 */
    702 static DECLCALLBACK(VBOXSTRICTRC) ich9pciMcfgMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
     701DECL_HIDDEN_CALLBACK(VBOXSTRICTRC) devpciCommonMcfgMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
    703702{
    704703    PDEVPCIROOT pPciRoot = PDMINS_2_DATA(pDevIns, PDEVPCIROOT);
     
    739738
    740739#ifdef IN_RING3
    741 
    742 DECLINLINE(PPDMPCIDEV) ich9pciFindBridge(PDEVPCIBUS pBus, uint8_t uBus)
    743 {
    744     /* Search for a fitting bridge. */
    745     for (uint32_t iBridge = 0; iBridge < pBus->cBridges; iBridge++)
    746     {
    747         /*
    748          * Examine secondary and subordinate bus number.
    749          * If the target bus is in the range we pass the request on to the bridge.
    750          */
    751         PPDMPCIDEV pBridge = pBus->papBridgesR3[iBridge];
    752         AssertMsg(pBridge && pciDevIsPci2PciBridge(pBridge),
    753                   ("Device is not a PCI bridge but on the list of PCI bridges\n"));
    754         /* safe, only needs to go to the config space array */
    755         uint32_t uSecondary   = PDMPciDevGetByte(pBridge, VBOX_PCI_SECONDARY_BUS);
    756         /* safe, only needs to go to the config space array */
    757         uint32_t uSubordinate = PDMPciDevGetByte(pBridge, VBOX_PCI_SUBORDINATE_BUS);
    758         Log3Func(("bus %p, bridge %d: %d in %d..%d\n", pBus, iBridge, uBus, uSecondary, uSubordinate));
    759         if (uBus >= uSecondary && uBus <= uSubordinate)
    760             return pBridge;
    761     }
    762 
    763     /* Nothing found. */
    764     return NULL;
    765 }
    766740
    767741uint32_t devpciR3GetCfg(PPDMPCIDEV pPciDev, int32_t iRegister, int cb)
     
    978952    pPciDev->Int.s.pfnConfigWrite   = NULL;
    979953    pPciDev->Int.s.hMmioMsix        = NIL_IOMMMIOHANDLE;
    980     if (pBus->fTypePiix3 && pPciDev->cbConfig > 256)
     954    if (pBus->enmType == DEVPCIBUSTYPE_PIIX3 && pPciDev->cbConfig > 256)
    981955        pPciDev->cbConfig = 256;
    982956
     
    11761150}
    11771151
    1178 static DECLCALLBACK(int) ich9pciR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
     1152DECL_HIDDEN_CALLBACK(int) devpciR3CommonSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
    11791153{
    11801154    PDEVPCIROOT     pThis = PDMINS_2_DATA(pDevIns, PDEVPCIROOT);
     
    12211195    if (iBus != PDMPciDevGetByte(pDevIns->apPciDevs[0], VBOX_PCI_SECONDARY_BUS))
    12221196    {
    1223         PPDMPCIDEV pBridgeDevice = ich9pciFindBridge(pBus, iBus);
     1197        PPDMPCIDEV pBridgeDevice = devpciR3FindBridge(pBus, iBus);
    12241198        if (pBridgeDevice)
    12251199        {
     
    12611235    if (iBus != PDMPciDevGetByte(pDevIns->apPciDevs[0], VBOX_PCI_SECONDARY_BUS))
    12621236    {
    1263         PPDMPCIDEV pBridgeDevice = ich9pciFindBridge(pBus, iBus);
     1237        PPDMPCIDEV pBridgeDevice = devpciR3FindBridge(pBus, iBus);
    12641238        if (pBridgeDevice)
    12651239        {
     
    17491723}
    17501724
    1751 static DECLCALLBACK(int) ich9pciR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
     1725DECL_HIDDEN_CALLBACK(int) devpciR3CommonLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
    17521726{
    17531727    PDEVPCIROOT     pThis = PDMINS_2_DATA(pDevIns, PDEVPCIROOT);
     
    30793053}
    30803054
     3055static const char *devpciR3InInfoPciBusType(DEVPCIBUSTYPE enmType)
     3056{
     3057    static const char *s_szBusType[] =
     3058    {
     3059        /* 00h */ "INVALID",
     3060        /* 01h */ "PIIX3",
     3061        /* 02h */ "ICH9",
     3062        /* 03h */ "GenericEcam",
     3063        /* 04h */ "?32-bit hack?",
     3064    };
     3065
     3066    if (enmType < RT_ELEMENTS(s_szBusType))
     3067        return s_szBusType[enmType];
     3068    return "?type?";
     3069}
    30813070
    30823071/**
     
    31133102                            pciDevIsPassthrough(pPciDev) ? " (PASSTHROUGH)" : "",
    31143103                            devpciR3GetWord(pPciDev, VBOX_PCI_VENDOR_ID), devpciR3GetWord(pPciDev, VBOX_PCI_DEVICE_ID),
    3115                             pBus->fTypeIch9 ? "ICH9" : pBus->fTypePiix3 ? "PIIX3" : "?type?",
     3104                            devpciR3InInfoPciBusType(pBus->enmType),
    31163105                            pciDevIsMsiCapable(pPciDev)  ? " MSI" : "",
    31173106                            pciDevIsMsixCapable(pPciDev) ? " MSI-X" : ""
     
    33593348    pPciRoot->hIoPortMagic          = NIL_IOMIOPORTHANDLE;
    33603349    pPciRoot->hMmioMcfg             = NIL_IOMMMIOHANDLE;
    3361     pPciRoot->PciBus.fTypePiix3     = false;
    3362     pPciRoot->PciBus.fTypeIch9      = true;
     3350    pPciRoot->PciBus.enmType        = DEVPCIBUSTYPE_GENERIC_ECAM;
    33633351    pPciRoot->PciBus.fPureBridge    = false;
    33643352    pPciRoot->PciBus.papBridgesR3   = (PPDMPCIDEV *)PDMDevHlpMMHeapAllocZ(pDevIns, sizeof(PPDMPCIDEV) * RT_ELEMENTS(pPciRoot->PciBus.apDevices));
     
    34413429    {
    34423430        rc = PDMDevHlpMmioCreateAndMap(pDevIns, pPciRoot->u64PciConfigMMioAddress, pPciRoot->u64PciConfigMMioLength,
    3443                                        ich9pciMcfgMMIOWrite, ich9pciMcfgMMIORead,
     3431                                       devpciCommonMcfgMmioWrite, devpciCommonMcfgMmioRead,
    34443432                                       IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,
    34453433                                       "MCFG ranges", &pPciRoot->hMmioMcfg);
     
    34533441                                sizeof(*pBus) + 16*128, "pgm",
    34543442                                NULL, NULL, NULL,
    3455                                 NULL, ich9pciR3SaveExec, NULL,
    3456                                 NULL, ich9pciR3LoadExec, NULL);
     3443                                NULL, devpciR3CommonSaveExec, NULL,
     3444                                NULL, devpciR3CommonLoadExec, NULL);
    34573445    AssertRCReturn(rc, rc);
    34583446
     
    35723560 * @param   pDevIns     ICH9 bridge (root or PCI-to-PCI) instance.
    35733561 */
    3574 static void ich9pciResetBridge(PPDMDEVINS pDevIns)
     3562DECLHIDDEN(void) devpciR3CommonResetBridge(PPDMDEVINS pDevIns)
    35753563{
    35763564    PDEVPCIBUS pBus = PDMINS_2_DATA(pDevIns, PDEVPCIBUS);
     
    35863574    {
    35873575        if (pBus->papBridgesR3[iBridge])
    3588             ich9pciResetBridge(pBus->papBridgesR3[iBridge]->Int.s.CTX_SUFF(pDevIns));
     3576            devpciR3CommonResetBridge(pBus->papBridgesR3[iBridge]->Int.s.CTX_SUFF(pDevIns));
    35893577    }
    35903578
     
    36103598{
    36113599    /* Reset everything under the root bridge. */
    3612     ich9pciResetBridge(pDevIns);
     3600    devpciR3CommonResetBridge(pDevIns);
    36133601}
    36143602
     
    36783666    PDEVPCIBUS   pBus   = PDMINS_2_DATA(pDevIns, PDEVPCIBUS);
    36793667
    3680     pBus->fTypePiix3  = false;
    3681     pBus->fTypeIch9   = true;
     3668    pBus->enmType     = DEVPCIBUSTYPE_ICH9;
    36823669    pBus->fPureBridge = true;
    36833670    pBusCC->pDevInsR3 = pDevIns;
     
    38593846    if (pPciRoot->hMmioMcfg != NIL_IOMMMIOHANDLE)
    38603847    {
    3861         rc = PDMDevHlpMmioSetUpContext(pDevIns, pPciRoot->hMmioMcfg, ich9pciMcfgMMIOWrite, ich9pciMcfgMMIORead, NULL /*pvUser*/);
     3848        rc = PDMDevHlpMmioSetUpContext(pDevIns, pPciRoot->hMmioMcfg, devpciCommonMcfgMmioWrite, devpciCommonMcfgMmioRead, NULL /*pvUser*/);
    38623849        AssertLogRelRCReturn(rc, rc);
    38633850    }
  • trunk/src/VBox/Devices/Bus/DevPciInternal.h

    r98103 r99750  
    3636#endif
    3737#include <VBox/vmm/pdmdev.h>
     38
     39#include "PciInline.h"
     40
     41
     42/**
     43 * Supported PCI bus types.
     44 */
     45typedef enum DEVPCIBUSTYPE
     46{
     47    /** The usual invalid type. */
     48    DEVPCIBUSTYPE_INVALID = 0,
     49    /** PIIX3 PCI bus type. */
     50    DEVPCIBUSTYPE_PIIX3,
     51    /** ICH9 PCI bus type. */
     52    DEVPCIBUSTYPE_ICH9,
     53    /** Generic ECAM PCI bus type. */
     54    DEVPCIBUSTYPE_GENERIC_ECAM,
     55    /** 32bit blowup. */
     56    DEVPCIBUSTYPE_32BIT_HACK = 0x7fffffff
     57} DEVPCIBUSTYPE;
    3858
    3959
     
    5171    /** Start device number - always zero (only for DevPCI source compat). */
    5272    uint32_t                iDevSearch;
    53     /** Set if PIIX3 type. */
    54     uint32_t                fTypePiix3 : 1;
    55     /** Set if ICH9 type. */
    56     uint32_t                fTypeIch9 : 1;
     73    /** PCI Bus type. */
     74    DEVPCIBUSTYPE           enmType;
    5775    /** Set if this is a pure bridge, i.e. not part of DEVPCIGLOBALS struct. */
    5876    uint32_t                fPureBridge : 1;
    5977    /** Reserved for future config flags. */
    60     uint32_t                uReservedConfigFlags : 29;
     78    uint32_t                uReservedConfigFlags : 31;
    6179
    6280    /** Array of bridges attached to the bus. */
    6381    R3PTRTYPE(PPDMPCIDEV *) papBridgesR3;
    6482    /** Cache line align apDevices. */
    65     uint32_t                au32Alignment1[HC_ARCH_BITS == 32 ? 3 + 8 : 2 + 8];
     83    uint32_t                au32Alignment1[HC_ARCH_BITS == 32 ? 2 + 8 : 8];
    6684    /** Array of PCI devices. We assume 32 slots, each with 8 functions. */
    6785    R3PTRTYPE(PPDMPCIDEV)   apDevices[256];
     
    6987/** Pointer to PCI bus shared instance data. */
    7088typedef DEVPCIBUS *PDEVPCIBUS;
     89AssertCompileMemberAlignment(DEVPCIBUS, apDevices, 64);
     90
    7191
    7292/**
     
    145165    /** Length of PCI config space MMIO region. */
    146166    uint64_t            u64PciConfigMMioLength;
     167    /** Physical address of PCI PIO emulation MMIO region. */
     168    RTGCPHYS            GCPhysMmioPioEmuBase;
     169    /** Length of PCI PIO emulation MMIO region. */
     170    RTGCPHYS            GCPhysMmioPioEmuSize;
     171
    147172
    148173    /** I/O APIC irq levels */
     
    176201    /** The MCFG MMIO region. */
    177202    IOMMMIOHANDLE           hMmioMcfg;
     203    /** The PIO emulation MMIO region. */
     204    IOMMMIOHANDLE           hMmioPioEmu;
    178205
    179206#if 1 /* Will be moved into the BIOS "soon". */
     
    217244                                                            PDEVPCIBUS *ppBus, uint8_t *puDevFnBridge, int *piIrqPinBridge);
    218245
     246DECL_HIDDEN_CALLBACK(VBOXSTRICTRC) devpciCommonMcfgMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb);
     247DECL_HIDDEN_CALLBACK(VBOXSTRICTRC) devpciCommonMcfgMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb);
     248
     249
    219250#ifdef IN_RING3
    220251
     252# ifndef VBOX_DEVICE_STRUCT_TESTCASE
    221253DECLCALLBACK(void) devpciR3InfoPci(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
    222254DECLCALLBACK(void) devpciR3InfoPciIrq(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
     
    243275uint32_t devpciR3GetCfg(PPDMPCIDEV pPciDev, int32_t iRegister, int cb);
    244276void devpciR3SetCfg(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int32_t iRegister, uint32_t u32, int cb);
     277DECLHIDDEN(void) devpciR3CommonResetBridge(PPDMDEVINS pDevIns);
     278DECL_HIDDEN_CALLBACK(int) devpciR3CommonSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
     279DECL_HIDDEN_CALLBACK(int) devpciR3CommonLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
     280
    245281
    246282DECLINLINE(uint8_t) devpciR3GetByte(PPDMPCIDEV pPciDev, int32_t iRegister)
     
    274310}
    275311
     312
     313DECLINLINE(PPDMPCIDEV) devpciR3FindBridge(PDEVPCIBUS pBus, uint8_t uBus)
     314{
     315    /* Search for a fitting bridge. */
     316    for (uint32_t iBridge = 0; iBridge < pBus->cBridges; iBridge++)
     317    {
     318        /*
     319         * Examine secondary and subordinate bus number.
     320         * If the target bus is in the range we pass the request on to the bridge.
     321         */
     322        PPDMPCIDEV pBridge = pBus->papBridgesR3[iBridge];
     323        AssertMsg(pBridge && pciDevIsPci2PciBridge(pBridge),
     324                  ("Device is not a PCI bridge but on the list of PCI bridges\n"));
     325        /* safe, only needs to go to the config space array */
     326        uint32_t uSecondary   = PDMPciDevGetByte(pBridge, VBOX_PCI_SECONDARY_BUS);
     327        /* safe, only needs to go to the config space array */
     328        uint32_t uSubordinate = PDMPciDevGetByte(pBridge, VBOX_PCI_SUBORDINATE_BUS);
     329        Log3Func(("bus %p, bridge %d: %d in %d..%d\n", pBus, iBridge, uBus, uSecondary, uSubordinate));
     330        if (uBus >= uSecondary && uBus <= uSubordinate)
     331            return pBridge;
     332    }
     333
     334    /* Nothing found. */
     335    return NULL;
     336}
     337# endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
     338
    276339#endif /* IN_RING3 */
    277340
  • trunk/src/VBox/Devices/Makefile.kmk

    r99544 r99750  
    921921  VBoxDD_DEFS       += VBOX_VMM_TARGET_ARMV8
    922922  VBoxDD_SOURCES    += \
     923        Bus/DevPciGenericEcam.cpp \
    923924        Misc/DevFlashCFI.cpp \
    924925        Misc/DevPL031.cpp \
  • trunk/src/VBox/Devices/build/VBoxDD.cpp

    r99544 r99750  
    260260    if (RT_FAILURE(rc))
    261261        return rc;
     262
     263    rc = pCallbacks->pfnRegister(pCallbacks, &g_DevicePciGenericEcam);
     264    if (RT_FAILURE(rc))
     265        return rc;
    262266#endif
    263267
  • trunk/src/VBox/Devices/build/VBoxDD.h

    r99544 r99750  
    233233extern const PDMDEVREG g_DevicePl031Rtc;
    234234extern const PDMDEVREG g_DeviceFlashCFI;
     235extern const PDMDEVREG g_DevicePciGenericEcam;
    235236#endif
    236237
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