VirtualBox

Ignore:
Timestamp:
Nov 12, 2024 12:09:04 PM (2 months ago)
Author:
vboxsync
Message:

Main/ResourceAssignmentManager: Rewrite to accomodate for the fact that Windows guests have several requirements on where devices are located (TPM needs to be at fixed 0xfed40000, PL061 GPIO driver doesn't support 64bit MMIO, the GIC re-disitributor emulated by Hyper-V requires 128KiB of MMIO space rather than the 64KiB we currently reserve). This will break saved state compatibility (whether we want to restore this functionality is up for discussion), bugref:10732

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/ConsoleImplConfigArmV8.cpp

    r106476 r106957  
    187187
    188188    BusAssignmentManager *pBusMgr = mBusMgr = BusAssignmentManager::createInstance(pVMM, chipsetType, IommuType_None);
    189     ResourceAssignmentManager *pResMgr = ResourceAssignmentManager::createInstance(pVMM, chipsetType, IommuType_None,
    190                                                                                    RT_MAX(_1G + cbRam, _4G),                  /*GCPhysMmio*/
    191                                                                                    _1G,                                       /*GCPhysRam*/
    192                                                                                    VBOXPLATFORMARMV8_PHYS_ADDR + _1M,         /*GCPhysMmio32Start*/
    193                                                                                    _1G - (VBOXPLATFORMARMV8_PHYS_ADDR + _1M), /*cbMmio32*/
    194                                                                                    32                                         /*cInterrupts*/);
     189    ResourceAssignmentManager *pResMgr = ResourceAssignmentManager::createInstance(pVMM, chipsetType, IommuType_None, 32 /*cInterrupts*/,
     190                                                                                   _4G); /* Start looking for free MMIO regions at 4GiB downwards. */
    195191    SystemTableBuilder *pSysTblsBldAcpi = NULL;
    196192
     
    211207    Assert(pRoot);
    212208
    213     RTGCPHYS GCPhysRam = NIL_RTGCPHYS;
     209    /*
     210     * The VBox platform descriptor, FDT and ACPI tables will reside at the end of the 4GiB
     211     * address space and we reserve 2MiB for those.
     212     */
     213    RTGCPHYS cbPlatformDesc     = _2M;
     214    RTGCPHYS GCPhysPlatformDesc = VBOXPLATFORMARMV8_PHYS_ADDR - (cbPlatformDesc - _64K);
     215
     216    RTGCPHYS GCPhysRamBase = 128 * _1M;
     217    RTGCPHYS cbRamBase     = RT_MIN(cbRam, _4G - _512M - 128 * _1M);
     218
     219    RTGCPHYS GCPhysFw = 0;
     220    RTGCPHYS cbFw     = _64M;
    214221
    215222    // catching throws from InsertConfigString and friends.
     
    281288        vrc = RTFdtNodePropertyAddU32(     hFdt, "phandle", idPHandleAbpPClk);              VRC();
    282289        vrc = RTFdtNodePropertyAddString(  hFdt, "clock-output-names", "clk24mhz");         VRC();
    283         vrc = RTFdtNodePropertyAddU32(     hFdt, "clock-frequency",    24 * 1000 * 1000);  VRC();
     290        vrc = RTFdtNodePropertyAddU32(     hFdt, "clock-frequency",    ASMReadCntFrqEl0()); VRC();
    284291        vrc = RTFdtNodePropertyAddU32(     hFdt, "#clock-cells",       0);                  VRC();
    285292        vrc = RTFdtNodePropertyAddString(  hFdt, "compatible",         "fixed-clock");      VRC();
     
    304311        InsertConfigNode(pMM, "MemRegions", &pMem);
    305312
    306         hrc = pResMgr->assignRamRegion("Conventional", cbRam, &GCPhysRam);                  H();
     313        /*
     314         * Windows requires the TPM to be available at 0xfed40000 so reserve this region first, even
     315         * if no TPM is configured.
     316         */
     317        RTGCPHYS GCPhysTpm = 0xfed40000;
     318        RTGCPHYS cbTpm     = 0x5000 + 0x1000; /* TPM + PPI region. */
     319        hrc = pResMgr->assignFixedMmioRegion("tpm", GCPhysTpm, cbTpm);                              H();
     320
     321        /*
     322         * The firmware ROM will start at the beginning of the address space and span 64MiB
     323         * After that comes the flash and spans another 64MiB (even if the real size is smaller).
     324         */
     325        hrc = pResMgr->assignFixedRomRegion("firmware", GCPhysFw, cbFw);                            H();
     326
     327        RTGCPHYS GCPhysFlash = _64M;
     328        RTGCPHYS cbFlash     = _64M;
     329        hrc = pResMgr->assignFixedMmioRegion("flash", GCPhysFlash, cbFlash);                        H();
     330
     331        hrc = pResMgr->assignFixedRomRegion("platform-tables", GCPhysPlatformDesc, cbPlatformDesc); H();
     332
     333        /*
     334         * The base RAM will start at 128MiB (end of flash region) and goes up to 4GiB - 512MiB
     335         * (for the MMIO hole).
     336         * If more RAM is configured the high region will start at 4GiB.
     337         */
     338        hrc = pResMgr->assignFixedRamRegion("RAM Base", GCPhysRamBase, cbRamBase);                  H();
    307339
    308340        PCFGMNODE pMemRegion = NULL;
    309         InsertConfigNode(pMem, "Conventional", &pMemRegion);
    310         InsertConfigInteger(pMemRegion, "GCPhysStart", GCPhysRam);
    311         InsertConfigInteger(pMemRegion, "Size", cbRam);
    312 
    313         vrc = RTFdtNodeAddF(hFdt, "memory@%RGp", GCPhysRam);                                VRC();
    314         vrc = RTFdtNodePropertyAddCellsU64(hFdt, "reg", 2, GCPhysRam, cbRam);               VRC();
     341        InsertConfigNode(pMem, "Base", &pMemRegion);
     342        InsertConfigInteger(pMemRegion, "GCPhysStart", GCPhysRamBase);
     343        InsertConfigInteger(pMemRegion, "Size", cbRamBase);
     344
     345        vrc = RTFdtNodeAddF(hFdt, "memory@%RGp", GCPhysRamBase);                            VRC();
     346        vrc = RTFdtNodePropertyAddCellsU64(hFdt, "reg", 2, GCPhysRamBase, cbRamBase);       VRC();
    315347        vrc = RTFdtNodePropertyAddString(  hFdt, "device_type",      "memory");             VRC();
    316348        vrc = RTFdtNodeFinalize(hFdt);                                                      VRC();
     
    318350        if (pSysTblsBldAcpi)
    319351        {
    320             vrc = pSysTblsBldAcpi->addMemory(GCPhysRam, cbRam);
     352            vrc = pSysTblsBldAcpi->addMemory(GCPhysRamBase, cbRamBase);
    321353            VRC();
     354        }
     355
     356        if (cbRamBase < cbRam)
     357        {
     358            RTGCPHYS GCPhysRamHigh = _4G;
     359            RTGCPHYS cbRamHigh     = cbRam - cbRamBase;
     360
     361            hrc = pResMgr->assignFixedRamRegion("RAM High", GCPhysRamHigh, cbRamHigh);        H();
     362
     363            InsertConfigNode(pMem, "High", &pMemRegion);
     364            InsertConfigInteger(pMemRegion, "GCPhysStart", GCPhysRamHigh);
     365            InsertConfigInteger(pMemRegion, "Size", cbRamHigh);
     366
     367            vrc = RTFdtNodeAddF(hFdt, "memory@%RGp", GCPhysRamHigh);                        VRC();
     368            vrc = RTFdtNodePropertyAddCellsU64(hFdt, "reg", 2, GCPhysRamHigh, cbRamHigh);   VRC();
     369            vrc = RTFdtNodePropertyAddString(  hFdt, "device_type",      "memory");         VRC();
     370            vrc = RTFdtNodeFinalize(hFdt);                                                  VRC();
     371
     372            if (pSysTblsBldAcpi)
     373            {
     374                vrc = pSysTblsBldAcpi->addMemory(GCPhysRamHigh, cbRamHigh);
     375                VRC();
     376            }
    322377        }
    323378
     
    440495        InsertConfigNode(pResources,    "ArmV8Desc",             &pRes);
    441496        InsertConfigInteger(pRes,       "RegisterAsRom",         1);
    442         InsertConfigInteger(pRes,       "GCPhysLoadAddress",     VBOXPLATFORMARMV8_PHYS_ADDR);
     497        InsertConfigInteger(pRes,       "GCPhysLoadAddress",     GCPhysPlatformDesc);
    443498        InsertConfigString(pRes,        "ResourceId",            "VBoxArmV8Desc");
    444499
     
    447502         */
    448503        RTGCPHYS GCPhysIntcDist;
     504        RTGCPHYS GCPhysIntcIts;
     505        RTGCPHYS cbMmioIntcDist;
     506        RTGCPHYS cbMmioIntcIts;
    449507        RTGCPHYS GCPhysIntcReDist;
    450         RTGCPHYS cbMmioIntcDist;
    451508        RTGCPHYS cbMmioIntcReDist;
    452509
    453         /* Each vCPU needs on re-distributor, this would allow for up to 256 vCPUs in the future. */
    454         hrc = pResMgr->assignMmioRegion("gic", 256 * _64K, &GCPhysIntcReDist, &cbMmioIntcReDist);       H();
    455         hrc = pResMgr->assignMmioRegion("gic", _64K, &GCPhysIntcDist, &cbMmioIntcDist);                 H();
    456 
    457 #ifndef RT_OS_LINUX
     510        /* Allow for up to 256 vCPUs in the future without changing the address space layout. */
     511        hrc = pResMgr->assignMmioRegion("gic", _64K + 256 * _128K, &GCPhysIntcDist, &cbMmioIntcDist);     H();
     512        GCPhysIntcReDist = GCPhysIntcDist + _64K;
     513        cbMmioIntcReDist = 256 * _128K;
     514        cbMmioIntcDist = _64K;
     515
     516        hrc = pResMgr->assignMmioRegion("gic-its", 2 * _64K, &GCPhysIntcIts, &cbMmioIntcIts);             H();
     517
     518#ifdef RT_OS_DARWIN
    458519        InsertConfigNode(pDevices, "gic",                   &pDev);
    459520#else
    460         /* On Linux we default to the KVM in-kernel GIC for now. */
     521        /* On Linux we default to the KVM in-kernel GIC and on Windows we are forced to the Hyper-V GIC for now. */
    461522        InsertConfigNode(pDevices, "gic-nem",               &pDev);
    462523#endif
     
    466527        InsertConfigInteger(pCfg,  "DistributorMmioBase",   GCPhysIntcDist);
    467528        InsertConfigInteger(pCfg,  "RedistributorMmioBase", GCPhysIntcReDist);
     529        InsertConfigInteger(pCfg,  "ItsMmioBase",           GCPhysIntcIts);
    468530
    469531        vrc = RTFdtNodeAddF(hFdt, "intc@%RGp", GCPhysIntcDist);                                         VRC();
    470532        vrc = RTFdtNodePropertyAddU32(     hFdt, "phandle",          idPHandleIntCtrl);                 VRC();
    471533        vrc = RTFdtNodePropertyAddCellsU64(hFdt, "reg", 4,
    472                                            GCPhysIntcDist, cbMmioIntcDist,      /* Distributor */
     534                                           GCPhysIntcDist, cbMmioIntcDist,       /* Distributor */
    473535                                           GCPhysIntcReDist, cbMmioIntcReDist); /* Re-Distributor */    VRC();
    474536        vrc = RTFdtNodePropertyAddU32(     hFdt, "#redistributor-regions", 1);                          VRC();
     
    500562
    501563        /*
    502          * Configure the perofrmance monitoring unit.
     564         * Configure the performance monitoring unit.
    503565         */
    504566        /** @todo Make this configurable and enable as default for Windows VMs because they assume a working PMU
     
    542604        InsertConfigNode(pDev,     "0",            &pInst);
    543605        InsertConfigNode(pInst,    "Config",        &pCfg);
    544         InsertConfigInteger(pCfg,  "BaseAddress",  64 * _1M);
     606        InsertConfigInteger(pCfg,  "BaseAddress",  GCPhysFlash);
    545607        InsertConfigInteger(pCfg,  "Size",        768 * _1K);
    546608        InsertConfigString(pCfg,   "FlashFile",   "nvram");
     
    552614        vrc = RTFdtNodePropertyAddU32(     hFdt, "bank-width", 4);                          VRC();
    553615        vrc = RTFdtNodePropertyAddCellsU64(hFdt, "reg", 4,
    554                                            0,          0x04000000,  /* First region (EFI). */
    555                                            0x04000000, 0x04000000); /* Second region (NVRAM). */ VRC();
     616                                           GCPhysFw,    cbFw,     /* First region (EFI). */
     617                                           GCPhysFlash, cbFlash); /* Second region (NVRAM). */ VRC();
    556618        vrc = RTFdtNodePropertyAddString(  hFdt, "compatible", "cfi-flash");                VRC();
    557619        vrc = RTFdtNodeFinalize(hFdt);                                                      VRC();
     
    638700        vrc = RTFdtNodeFinalize(hFdt);                                                      VRC();
    639701
    640         /* Configure gpio keys. */
     702        /* Configure gpio keys (The Windows GPIO PL061 driver doesn't like 64-bit MMIO addresses...). */
    641703        hrc = pResMgr->assignSingleInterrupt("arm-pl061-gpio", &iIrq);                      H();
    642         hrc = pResMgr->assignMmioRegion("arm-pl061-gpio", _4K, &GCPhysMmioStart, &cbMmio);  H();
     704        hrc = pResMgr->assignMmio32Region("arm-pl061-gpio", _4K, &GCPhysMmioStart, &cbMmio);  H();
    643705        InsertConfigNode(pDevices, "arm-pl061-gpio",&pDev);
    644706        InsertConfigNode(pDev,     "0",            &pInst);
     
    660722        if (pSysTblsBldAcpi)
    661723        {
    662             vrc = pSysTblsBldAcpi->addMmioDevice("arm-pl061-gpio", 0, GCPhysMmioStart, _4K, iIrq);
     724            vrc = pSysTblsBldAcpi->addMmioDevice("arm-pl061-gpio", 0, GCPhysMmioStart, cbMmio, iIrq);
    663725            VRC();
    664726        }
     
    687749        vrc = RTFdtNodeFinalize(hFdt);                                                      VRC();
    688750
    689         hrc = pResMgr->assignInterrupts("pci-generic-ecam", 4 /*cInterrupts*/, &iIrq);      H();
    690         uint32_t aPinIrqs[] = { iIrq, iIrq + 1, iIrq + 2, iIrq + 3 };
    691         RTGCPHYS GCPhysPciMmioEcam, GCPhysPciMmio, GCPhysPciMmio32;
    692         RTGCPHYS cbPciMmioEcam, cbPciMmio, cbPciMmio32;
    693         hrc = pResMgr->assignMmioRegionAligned("pci-pio",    _64K, _64K,                              &GCPhysMmioStart,   &cbMmio);         H();
    694         hrc = pResMgr->assignMmioRegion(       "pci-ecam",   16 * _1M,                                &GCPhysPciMmioEcam, &cbPciMmioEcam);  H();
    695         hrc = pResMgr->assignMmioRegion(       "pci-mmio",   _2G,                                     &GCPhysPciMmio,     &cbPciMmio);      H();
    696         hrc = pResMgr->assignMmio32Region(     "pci-mmio32", _1G - VBOXPLATFORMARMV8_PHYS_ADDR - _1M, &GCPhysPciMmio32,   &cbPciMmio32);    H();
    697 
    698         InsertConfigNode(pDevices, "pci-generic-ecam",  &pDev);
    699         InsertConfigNode(pDev,     "0",            &pInst);
    700         InsertConfigNode(pInst,    "Config",        &pCfg);
    701         InsertConfigInteger(pCfg,  "MmioEcamBase",   GCPhysPciMmioEcam);
    702         InsertConfigInteger(pCfg,  "MmioEcamLength", cbPciMmioEcam);
    703         InsertConfigInteger(pCfg,  "MmioPioBase",    GCPhysMmioStart);
    704         InsertConfigInteger(pCfg,  "MmioPioSize",    cbMmio);
    705         InsertConfigInteger(pCfg,  "IntPinA",        aPinIrqs[0]);
    706         InsertConfigInteger(pCfg,  "IntPinB",        aPinIrqs[1]);
    707         InsertConfigInteger(pCfg,  "IntPinC",        aPinIrqs[2]);
    708         InsertConfigInteger(pCfg,  "IntPinD",        aPinIrqs[3]);
    709         vrc = RTFdtNodeAddF(hFdt, "pcie@%RGp", GCPhysPciMmio);                              VRC();
    710         vrc = RTFdtNodePropertyAddCellsU32(hFdt, "interrupt-map-mask", 4, 0xf800, 0, 0, 7); VRC();
    711 
    712         uint32_t aIrqCells[32 * 4 * 10]; RT_ZERO(aIrqCells); /* Maximum of 32 devices on the root bus, each supporting 4 interrupts (INTA# ... INTD#). */
    713         uint32_t *pau32IrqCell = &aIrqCells[0];
    714         uint32_t iIrqPinSwizzle = 0;
    715 
    716         for (uint32_t i = 0; i < 32; i++)
    717         {
    718             for (uint32_t iIrqPin = 0; iIrqPin < 4; iIrqPin++)
    719             {
    720                 pau32IrqCell[0] = i << 11; /* The dev part, composed as dev.fn. */
    721                 pau32IrqCell[1] = 0;
    722                 pau32IrqCell[2] = 0;
    723                 pau32IrqCell[3] = iIrqPin + 1;
    724                 pau32IrqCell[4] = idPHandleIntCtrl;
    725                 pau32IrqCell[5] = 0;
    726                 pau32IrqCell[6] = 0;
    727                 pau32IrqCell[7] = 0;
    728                 pau32IrqCell[8] = aPinIrqs[(iIrqPinSwizzle + iIrqPin) % RT_ELEMENTS(aPinIrqs)];
    729                 pau32IrqCell[9] = 0x04;
    730                 pau32IrqCell += 10;
    731             }
    732 
    733             iIrqPinSwizzle++;
    734         }
    735 
    736         vrc = RTFdtNodePropertyAddCellsU32AsArray(hFdt, "interrupt-map", RT_ELEMENTS(aIrqCells), &aIrqCells[0]);
    737         vrc = RTFdtNodePropertyAddU32(     hFdt, "#interrupt-cells", 1);                        VRC();
    738         vrc = RTFdtNodePropertyAddCellsU32(hFdt, "ranges", 21,
    739                                            0x1000000, 0, 0,
    740                                            GCPhysMmioStart >> 32, GCPhysMmioStart, cbMmio >> 32, cbMmio,
    741                                            0x2000000, GCPhysPciMmio32 >> 32, GCPhysPciMmio32, GCPhysPciMmio32 >> 32, GCPhysPciMmio32,
    742                                            cbPciMmio32 >> 32, cbPciMmio32,
    743                                            0x3000000, GCPhysPciMmio >> 32, GCPhysPciMmio, GCPhysPciMmio >> 32, GCPhysPciMmio,
    744                                            cbPciMmio >> 32, cbPciMmio);                         VRC();
    745         vrc = RTFdtNodePropertyAddCellsU64(hFdt, "reg", 2, GCPhysPciMmioEcam, cbPciMmioEcam);   VRC();
    746         /** @todo msi-map */
    747         vrc = RTFdtNodePropertyAddEmpty(   hFdt, "dma-coherent");                               VRC();
    748         vrc = RTFdtNodePropertyAddCellsU32(hFdt, "bus-range", 2, 0, 0xf);                       VRC();
    749         vrc = RTFdtNodePropertyAddU32(     hFdt, "linux,pci-domain", 0);                        VRC();
    750         vrc = RTFdtNodePropertyAddU32(     hFdt, "#size-cells", 2);                             VRC();
    751         vrc = RTFdtNodePropertyAddU32(     hFdt, "#address-cells", 3);                          VRC();
    752         vrc = RTFdtNodePropertyAddString(  hFdt, "device_type", "pci");                         VRC();
    753         vrc = RTFdtNodePropertyAddString(  hFdt, "compatible", "pci-host-ecam-generic");        VRC();
    754         vrc = RTFdtNodeFinalize(hFdt);                                                          VRC();
    755 
    756         if (pSysTblsBldAcpi)
    757         {
    758             vrc = pSysTblsBldAcpi->configurePcieRootBus("pci-generic-ecam", aPinIrqs, GCPhysMmioStart, GCPhysPciMmioEcam,
    759                                                         cbPciMmioEcam, GCPhysMmioStart, cbMmio, GCPhysPciMmio32, cbPciMmio32);
    760             VRC();
    761         }
    762 
    763751#if defined(VBOX_WITH_TPM)
    764752        /*
     
    773761        {
    774762            hrc = pResMgr->assignSingleInterrupt("tpm", &iIrq);                               H();
    775             hrc = pResMgr->assignMmioRegion("tpm", 5 * _1K, &GCPhysMmioStart, &cbMmio);       H();
    776763
    777764            InsertConfigNode(pDevices, "tpm", &pDev);
     
    779766            InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
    780767            InsertConfigNode(pInst,    "Config", &pCfg);
    781             InsertConfigInteger(pCfg,  "MmioBase", GCPhysMmioStart);
     768            InsertConfigInteger(pCfg,  "MmioBase", GCPhysTpm);
    782769            InsertConfigInteger(pCfg,  "Irq",      iIrq);
    783             //InsertConfigInteger(pCfg,  "Crb",      1); /* boolean */
     770            InsertConfigInteger(pCfg,  "Crb",      1); /* boolean */
    784771
    785772            InsertConfigNode(pInst,    "LUN#0", &pLunL0);
     
    811798            }
    812799
    813             vrc = RTFdtNodeAddF(hFdt, "tpm@%RGp", GCPhysMmioStart);                           VRC();
     800            vrc = RTFdtNodeAddF(hFdt, "tpm@%RGp", GCPhysTpm);                                   VRC();
    814801            vrc = RTFdtNodePropertyAddCellsU32(hFdt, "interrupts", 3, 0x00, iIrq, 0x04);        VRC();
    815             vrc = RTFdtNodePropertyAddCellsU64(hFdt, "reg", 2, GCPhysMmioStart, cbMmio);        VRC();
     802            vrc = RTFdtNodePropertyAddCellsU64(hFdt, "reg", 2, GCPhysTpm, cbTpm);               VRC();
    816803            vrc = RTFdtNodePropertyAddStringList(hFdt, "compatible", 1, "tcg,tpm-tis-mmio");    VRC();
    817804            vrc = RTFdtNodeFinalize(hFdt);                                                      VRC();
     
    819806            if (pSysTblsBldAcpi)
    820807            {
    821                 vrc = pSysTblsBldAcpi->configureTpm2(false /*fCrb*/, GCPhysMmioStart, cbMmio, iIrq);
     808                vrc = pSysTblsBldAcpi->configureTpm2(true /*fCrb*/, GCPhysTpm, cbTpm, iIrq);
    822809                VRC();
    823810            }
    824811
    825 #if 0
    826812            /* Add the device for the physical presence interface. */
    827813            InsertConfigNode(   pDevices, "tpm-ppi",  &pDev);
     
    829815            InsertConfigInteger(pInst,    "Trusted",  1); /* boolean */
    830816            InsertConfigNode(   pInst,    "Config",   &pCfg);
    831             InsertConfigInteger(pCfg,     "MmioBase", TPM_PPI_MMIO_BASE_DEFAULT);
     817            InsertConfigInteger(pCfg,     "MmioBase", GCPhysTpm + 0x5000);
     818        }
    832819#endif
    833         }
    834 #endif
     820
     821        hrc = pResMgr->assignInterrupts("pci-generic-ecam", 4 /*cInterrupts*/, &iIrq);      H();
     822        uint32_t aPinIrqs[] = { iIrq, iIrq + 1, iIrq + 2, iIrq + 3 };
     823        RTGCPHYS GCPhysPciMmioEcam, GCPhysPciMmio, GCPhysPciMmio32;
     824        RTGCPHYS cbPciMmioEcam, cbPciMmio, cbPciMmio32;
     825
     826        hrc = pResMgr->assignMmioRegionAligned("pci-pio",    _64K, _64K, &GCPhysMmioStart,   &cbMmio, false /*fOnly32Bit*/); H();
     827        hrc = pResMgr->assignMmioRegion(       "pci-ecam",   16 * _1M,   &GCPhysPciMmioEcam, &cbPciMmioEcam);              H();
     828        hrc = pResMgr->assignMmioRegion(       "pci-mmio",   _2G,        &GCPhysPciMmio,     &cbPciMmio);                  H();
     829        hrc = pResMgr->assignMmio32Region(     "pci-mmio32", _256M,      &GCPhysPciMmio32,   &cbPciMmio32);                H();
     830
     831        InsertConfigNode(pDevices, "pci-generic-ecam",  &pDev);
     832        InsertConfigNode(pDev,     "0",            &pInst);
     833        InsertConfigNode(pInst,    "Config",        &pCfg);
     834        InsertConfigInteger(pCfg,  "MmioEcamBase",   GCPhysPciMmioEcam);
     835        InsertConfigInteger(pCfg,  "MmioEcamLength", cbPciMmioEcam);
     836        InsertConfigInteger(pCfg,  "MmioPioBase",    GCPhysMmioStart);
     837        InsertConfigInteger(pCfg,  "MmioPioSize",    cbMmio);
     838        InsertConfigInteger(pCfg,  "IntPinA",        aPinIrqs[0]);
     839        InsertConfigInteger(pCfg,  "IntPinB",        aPinIrqs[1]);
     840        InsertConfigInteger(pCfg,  "IntPinC",        aPinIrqs[2]);
     841        InsertConfigInteger(pCfg,  "IntPinD",        aPinIrqs[3]);
     842        vrc = RTFdtNodeAddF(hFdt, "pcie@%RGp", GCPhysPciMmio);                              VRC();
     843        vrc = RTFdtNodePropertyAddCellsU32(hFdt, "interrupt-map-mask", 4, 0xf800, 0, 0, 7); VRC();
     844
     845        uint32_t aIrqCells[32 * 4 * 10]; RT_ZERO(aIrqCells); /* Maximum of 32 devices on the root bus, each supporting 4 interrupts (INTA# ... INTD#). */
     846        uint32_t *pau32IrqCell = &aIrqCells[0];
     847        uint32_t iIrqPinSwizzle = 0;
     848
     849        for (uint32_t i = 0; i < 32; i++)
     850        {
     851            for (uint32_t iIrqPin = 0; iIrqPin < 4; iIrqPin++)
     852            {
     853                pau32IrqCell[0] = i << 11; /* The dev part, composed as dev.fn. */
     854                pau32IrqCell[1] = 0;
     855                pau32IrqCell[2] = 0;
     856                pau32IrqCell[3] = iIrqPin + 1;
     857                pau32IrqCell[4] = idPHandleIntCtrl;
     858                pau32IrqCell[5] = 0;
     859                pau32IrqCell[6] = 0;
     860                pau32IrqCell[7] = 0;
     861                pau32IrqCell[8] = aPinIrqs[(iIrqPinSwizzle + iIrqPin) % RT_ELEMENTS(aPinIrqs)];
     862                pau32IrqCell[9] = 0x04;
     863                pau32IrqCell += 10;
     864            }
     865
     866            iIrqPinSwizzle++;
     867        }
     868
     869        vrc = RTFdtNodePropertyAddCellsU32AsArray(hFdt, "interrupt-map", RT_ELEMENTS(aIrqCells), &aIrqCells[0]);
     870        vrc = RTFdtNodePropertyAddU32(     hFdt, "#interrupt-cells", 1);                        VRC();
     871        vrc = RTFdtNodePropertyAddCellsU32(hFdt, "ranges", 21,
     872                                           0x1000000, 0, 0,
     873                                           GCPhysMmioStart >> 32, GCPhysMmioStart, cbMmio >> 32, cbMmio,
     874                                           0x2000000, GCPhysPciMmio32 >> 32, GCPhysPciMmio32, GCPhysPciMmio32 >> 32, GCPhysPciMmio32,
     875                                           cbPciMmio32 >> 32, cbPciMmio32,
     876                                           0x3000000, GCPhysPciMmio >> 32, GCPhysPciMmio, GCPhysPciMmio >> 32, GCPhysPciMmio,
     877                                           cbPciMmio >> 32, cbPciMmio);                         VRC();
     878        vrc = RTFdtNodePropertyAddCellsU64(hFdt, "reg", 2, GCPhysPciMmioEcam, cbPciMmioEcam);   VRC();
     879        /** @todo msi-map */
     880        vrc = RTFdtNodePropertyAddEmpty(   hFdt, "dma-coherent");                               VRC();
     881        vrc = RTFdtNodePropertyAddCellsU32(hFdt, "bus-range", 2, 0, 0xf);                       VRC();
     882        vrc = RTFdtNodePropertyAddU32(     hFdt, "linux,pci-domain", 0);                        VRC();
     883        vrc = RTFdtNodePropertyAddU32(     hFdt, "#size-cells", 2);                             VRC();
     884        vrc = RTFdtNodePropertyAddU32(     hFdt, "#address-cells", 3);                          VRC();
     885        vrc = RTFdtNodePropertyAddString(  hFdt, "device_type", "pci");                         VRC();
     886        vrc = RTFdtNodePropertyAddString(  hFdt, "compatible", "pci-host-ecam-generic");        VRC();
     887        vrc = RTFdtNodeFinalize(hFdt);                                                          VRC();
     888
     889        if (pSysTblsBldAcpi)
     890        {
     891            vrc = pSysTblsBldAcpi->configurePcieRootBus("pci-generic-ecam", aPinIrqs, GCPhysMmioStart, GCPhysPciMmioEcam,
     892                                                        cbPciMmioEcam, GCPhysMmioStart, cbMmio, GCPhysPciMmio32, cbPciMmio32);
     893            VRC();
     894        }
    835895
    836896        /*
     
    931991    VBOXPLATFORMARMV8 ArmV8Platform; RT_ZERO(ArmV8Platform);
    932992
    933     /* Make room for the descriptor at the beginning. */
    934     vrc = RTVfsIoStrmZeroFill(hVfsIosDesc, sizeof(ArmV8Platform));
    935     AssertRCReturnStmt(vrc, RTFdtDestroy(hFdt), vrc);
    936 
    937993    vrc = RTFdtDumpToVfsIoStrm(hFdt, RTFDTTYPE_DTB, 0 /*fFlags*/, hVfsIosDesc, NULL /*pErrInfo*/);
    938994    uint64_t cbFdt = 0;
    939995    if (RT_SUCCESS(vrc))
    940     {
    941996        vrc = RTVfsFileQuerySize(hVfsFileDesc, &cbFdt);
    942         cbFdt -= sizeof(ArmV8Platform);
    943     }
    944997    AssertRCReturnStmt(vrc, RTFdtDestroy(hFdt), vrc);
    945998
    946999    vrc = RTVfsIoStrmZeroFill(hVfsIosDesc, (RTFOFF)(RT_ALIGN_64(cbFdt, _64K) - cbFdt));
    9471000    AssertRCReturn(vrc, vrc);
     1001
     1002    cbFdt = RT_ALIGN_64(cbFdt, _64K);
    9481003
    9491004    RTGCPHYS GCPhysMmioStart;
     
    9621017    if (pSysTblsBldAcpi)
    9631018    {
    964         vrc = pSysTblsBldAcpi->finishTables(VBOXPLATFORMARMV8_PHYS_ADDR + sizeof(ArmV8Platform) + RT_ALIGN_64(cbFdt, _64K),
     1019        vrc = pSysTblsBldAcpi->finishTables(GCPhysPlatformDesc + cbFdt,
    9651020                                            hVfsIosDesc, &GCPhysXsdp, &cbAcpiXsdp, &cbAcpi);
    9661021        AssertRCReturn(vrc, vrc);
    967         Assert(GCPhysXsdp > VBOXPLATFORMARMV8_PHYS_ADDR);
     1022        Assert(   GCPhysXsdp > GCPhysPlatformDesc
     1023               && GCPhysXsdp < VBOXPLATFORMARMV8_PHYS_ADDR);
    9681024
    9691025        /* Dump the ACPI table for debugging purposes if requested. */
     
    9821038        vrc = RTVfsIoStrmZeroFill(hVfsIosDesc, (RTFOFF)(RT_ALIGN_64(cbAcpi, _64K) - cbAcpi));
    9831039        AssertRCReturn(vrc, vrc);
     1040
     1041        cbAcpi = RT_ALIGN_64(cbAcpi, _64K);
    9841042    }
     1043
     1044    /* Fill the room until the end where the platform descriptor lives. */
     1045    vrc = RTVfsIoStrmZeroFill(hVfsIosDesc, cbPlatformDesc - sizeof(ArmV8Platform) - cbFdt - cbAcpi);
     1046    AssertRCReturnStmt(vrc, RTFdtDestroy(hFdt), vrc);
     1047
     1048    RTGCPHYS GCPhysMmio    = 0;
     1049    RTGCPHYS cbMmioAbove4G = 0;
     1050    pResMgr->queryMmioRegion(&GCPhysMmio, &cbMmioAbove4G);
    9851051
    9861052    ArmV8Platform.u32Magic            = VBOXPLATFORMARMV8_MAGIC;
     
    9881054    ArmV8Platform.cbDesc              = sizeof(ArmV8Platform);
    9891055    ArmV8Platform.fFlags              = 0;
    990     ArmV8Platform.u64PhysAddrRamBase  = GCPhysRam;
    991     ArmV8Platform.cbRamBase           = cbRam;
    992     ArmV8Platform.i64OffFdt           = sizeof(ArmV8Platform);
    993     ArmV8Platform.cbFdt               = RT_ALIGN_64(cbFdt, _64K);
     1056    ArmV8Platform.u64PhysAddrRamBase  = GCPhysRamBase;
     1057    ArmV8Platform.cbRamBase           = cbRamBase;
     1058    ArmV8Platform.i64OffFdt           = (int64_t)GCPhysPlatformDesc - VBOXPLATFORMARMV8_PHYS_ADDR;
     1059    ArmV8Platform.cbFdt               = cbFdt;
    9941060    if (cbAcpi)
    9951061    {
    996         ArmV8Platform.i64OffAcpi      = sizeof(ArmV8Platform) + RT_ALIGN_64(cbFdt, _64K);
    997         ArmV8Platform.cbAcpi          = RT_ALIGN_64(cbAcpi, _64K);
    998         ArmV8Platform.i64OffAcpiXsdp  = GCPhysXsdp - VBOXPLATFORMARMV8_PHYS_ADDR;
     1062        ArmV8Platform.i64OffAcpi      = (int64_t)(GCPhysPlatformDesc + cbFdt) - VBOXPLATFORMARMV8_PHYS_ADDR;
     1063        ArmV8Platform.cbAcpi          = cbAcpi;
     1064        ArmV8Platform.i64OffAcpiXsdp  = (int64_t)GCPhysXsdp - VBOXPLATFORMARMV8_PHYS_ADDR;
    9991065        ArmV8Platform.cbAcpiXsdp      = cbAcpiXsdp;
    10001066    }
    1001     ArmV8Platform.i64OffUefiRom       = -128 * _1M;
     1067    ArmV8Platform.i64OffUefiRom       = (int64_t)GCPhysFw - VBOXPLATFORMARMV8_PHYS_ADDR;
    10021068    ArmV8Platform.cbUefiRom           = _64M;
    1003     ArmV8Platform.i64OffMmio          = GCPhysMmioStart - _128M;
    1004     ArmV8Platform.cbMmio              = cbMmio;
    1005     ArmV8Platform.i64OffMmio32        = GCPhysMmio32Start - _128M;
    1006     ArmV8Platform.cbMmio32            = cbMmio32;
     1069    ArmV8Platform.i64OffMmio          = GCPhysMmio ? (int64_t)GCPhysMmio - VBOXPLATFORMARMV8_PHYS_ADDR : 0;
     1070    ArmV8Platform.cbMmio              = cbMmioAbove4G;
     1071    ArmV8Platform.i64OffMmio32        = (int64_t)(_4G - _512M) - VBOXPLATFORMARMV8_PHYS_ADDR;
     1072    ArmV8Platform.cbMmio32            = _512M - _2M; /* Just assign the whole MMIO hole (except for the platform descriptor region). */
    10071073
    10081074    /* Add the VBox platform descriptor to the resource store. */
    1009     vrc = RTVfsIoStrmWriteAt(hVfsIosDesc, 0, &ArmV8Platform, sizeof(ArmV8Platform), true /*fBlocking*/, NULL /*pcbWritten*/);
     1075    vrc = RTVfsIoStrmWrite(hVfsIosDesc, &ArmV8Platform, sizeof(ArmV8Platform), true /*fBlocking*/, NULL /*pcbWritten*/);
    10101076    RTVfsIoStrmRelease(hVfsIosDesc);
    10111077    vrc = mptrResourceStore->i_addItem("resources", "VBoxArmV8Desc", hVfsFileDesc);
     
    10241090    }
    10251091
     1092    pResMgr->dumpMemoryRegionsToReleaseLog();
     1093
    10261094    delete pResMgr; /* Delete the address/interrupt assignment manager. */
    10271095
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