VirtualBox

Ignore:
Timestamp:
Aug 6, 2024 9:39:44 AM (6 months ago)
Author:
vboxsync
Message:

VMM/ARM: Move the VBox ARMv8 platform descriptor from the end of the address space right after the UEFI region, bugref:10746

The original solution was to avoid as many hardcoded addresses as possible by placing the VBox region descriptor right at the end
of the guest physical address space. This turned out to be a bad idea because on M3 the host maximum physical address width and
guest maxmium physical address width differ so mapping the platform descriptor fails. Also saved states would not be portable if
a saved state is mvoed between systems with different physical address widths.
The solution is to move the platform descriptor right after the UEFI region and move the MMIO region, which grew from top to bottom
to start right after the base RAM region and grow upwards.

File:
1 edited

Legend:

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

    r104386 r105600  
    108108#define VRC()       AssertLogRelMsgReturnStmt(RT_SUCCESS(vrc), ("vrc=%Rrc\n", vrc), RTFdtDestroy(hFdt), vrc)
    109109
    110     /** @todo Find a way to figure it out before CPUM is set up, can't use CPUMGetGuestAddrWidths() and on macOS we need
    111      * access to Hypervisor.framework to query the ID registers (Linux can in theory parse /proc/cpuinfo, no idea for Windows). */
    112     RTGCPHYS GCPhysTopOfAddrSpace = RT_BIT_64(36);
    113 
    114110    /*
    115111     * Get necessary objects and frequently used parameters.
     
    187183    BusAssignmentManager *pBusMgr = mBusMgr = BusAssignmentManager::createInstance(pVMM, chipsetType, IommuType_None);
    188184    ResourceAssignmentManager *pResMgr = ResourceAssignmentManager::createInstance(pVMM, chipsetType, IommuType_None,
    189                                                                                    GCPhysTopOfAddrSpace - sizeof(VBOXPLATFORMARMV8),
    190                                                                                    _1G,             /*GCPhysRam*/
    191                                                                                    128 * _1M,       /*GCPhysMmio32Start*/
    192                                                                                    _1G - 128 * _1M, /*cbMmio32*/
    193                                                                                    32               /*cInterrupts*/);
     185                                                                                   RT_MAX(_1G + cbRam, _4G),                  /*GCPhysMmio*/
     186                                                                                   _1G,                                       /*GCPhysRam*/
     187                                                                                   VBOXPLATFORMARMV8_PHYS_ADDR + _1M,         /*GCPhysMmio32Start*/
     188                                                                                   _1G - (VBOXPLATFORMARMV8_PHYS_ADDR + _1M), /*cbMmio32*/
     189                                                                                   32                                         /*cInterrupts*/);
    194190
    195191    /*
     
    332328
    333329        vrc = RTFdtNodeFinalize(hFdt);                                                      VRC();
     330
     331
     332        /*
     333         * CPUM values.
     334         */
     335        PCFGMNODE pCpum;
     336        InsertConfigNode(pRoot, "CPUM", &pCpum);
    334337
    335338
     
    398401        InsertConfigNode(pResources,    "ArmV8Desc",             &pRes);
    399402        InsertConfigInteger(pRes,       "RegisterAsRom",         1);
    400         InsertConfigInteger(pRes,       "GCPhysLoadAddress",     UINT64_MAX); /* End of physical address space. */
     403        InsertConfigInteger(pRes,       "GCPhysLoadAddress",     VBOXPLATFORMARMV8_PHYS_ADDR);
    401404        InsertConfigString(pRes,        "ResourceId",            "VBoxArmV8Desc");
    402405
     
    613616        RTGCPHYS GCPhysPciMmioEcam, GCPhysPciMmio, GCPhysPciMmio32;
    614617        RTGCPHYS cbPciMmioEcam, cbPciMmio, cbPciMmio32;
    615         hrc = pResMgr->assignMmioRegionAligned("pci-pio",    _64K, _64K,         &GCPhysMmioStart,   &cbMmio);         H();
    616         hrc = pResMgr->assignMmioRegion(       "pci-ecam",   16 * _1M,           &GCPhysPciMmioEcam, &cbPciMmioEcam);  H();
    617         hrc = pResMgr->assignMmioRegion(       "pci-mmio",   _2G,                &GCPhysPciMmio,     &cbPciMmio);      H();
    618         hrc = pResMgr->assignMmio32Region(     "pci-mmio32", (1024 - 128) * _1M, &GCPhysPciMmio32,   &cbPciMmio32);    H();
     618        hrc = pResMgr->assignMmioRegionAligned("pci-pio",    _64K, _64K,                              &GCPhysMmioStart,   &cbMmio);         H();
     619        hrc = pResMgr->assignMmioRegion(       "pci-ecam",   16 * _1M,                                &GCPhysPciMmioEcam, &cbPciMmioEcam);  H();
     620        hrc = pResMgr->assignMmioRegion(       "pci-mmio",   _2G,                                     &GCPhysPciMmio,     &cbPciMmio);      H();
     621        hrc = pResMgr->assignMmio32Region(     "pci-mmio32", _1G - VBOXPLATFORMARMV8_PHYS_ADDR - _1M, &GCPhysPciMmio32,   &cbPciMmio32);    H();
    619622
    620623        InsertConfigNode(pDevices, "pci-generic-ecam",  &pDev);
     
    773776    VBOXPLATFORMARMV8 ArmV8Platform; RT_ZERO(ArmV8Platform);
    774777
     778    /* Make room for the descriptor at the beginning. */
     779    vrc = RTVfsIoStrmZeroFill(hVfsIosDesc, sizeof(ArmV8Platform));
     780    AssertRCReturnStmt(vrc, RTFdtDestroy(hFdt), vrc);
     781
    775782    vrc = RTFdtDumpToVfsIoStrm(hFdt, RTFDTTYPE_DTB, 0 /*fFlags*/, hVfsIosDesc, NULL /*pErrInfo*/);
     783    uint64_t cbFdt = 0;
    776784    if (RT_SUCCESS(vrc))
    777         vrc = RTVfsFileQuerySize(hVfsFileDesc, &ArmV8Platform.cbFdt);
     785    {
     786        vrc = RTVfsFileQuerySize(hVfsFileDesc, &cbFdt);
     787        cbFdt -= sizeof(ArmV8Platform);
     788    }
    778789    AssertRCReturnStmt(vrc, RTFdtDestroy(hFdt), vrc);
    779790
    780     vrc = RTVfsIoStrmZeroFill(hVfsIosDesc, (RTFOFF)(RT_ALIGN_64(ArmV8Platform.cbFdt, _64K) - ArmV8Platform.cbFdt));
     791    vrc = RTVfsIoStrmZeroFill(hVfsIosDesc, (RTFOFF)(RT_ALIGN_64(cbFdt, _64K) - cbFdt));
    781792    AssertRCReturn(vrc, vrc);
    782793
     
    797808    ArmV8Platform.u64PhysAddrRamBase  = GCPhysRam;
    798809    ArmV8Platform.cbRamBase           = cbRam;
    799     ArmV8Platform.u64OffBackFdt       = RT_ALIGN_64(ArmV8Platform.cbFdt, _64K);
    800     ArmV8Platform.cbFdt               = RT_ALIGN_64(ArmV8Platform.cbFdt, _64K);
    801     ArmV8Platform.u64OffBackAcpiXsdp  = 0;
     810    ArmV8Platform.i64OffFdt           = sizeof(ArmV8Platform);
     811    ArmV8Platform.cbFdt               = RT_ALIGN_64(cbFdt, _64K);
     812    ArmV8Platform.i64OffAcpiXsdp      = 0;
    802813    ArmV8Platform.cbAcpiXsdp          = 0;
    803     ArmV8Platform.u64OffBackUefiRom   = GCPhysTopOfAddrSpace - sizeof(ArmV8Platform);
    804     ArmV8Platform.cbUefiRom           = _64M; /** @todo Fixed reservation but the ROM region is usually much smaller. */
    805     ArmV8Platform.u64OffBackMmio      = GCPhysTopOfAddrSpace - sizeof(ArmV8Platform) - GCPhysMmioStart;
     814    ArmV8Platform.i64OffUefiRom       = -128 * _1M;
     815    ArmV8Platform.cbUefiRom           = _64M;
     816    ArmV8Platform.i64OffMmio          = GCPhysMmioStart - _128M;
    806817    ArmV8Platform.cbMmio              = cbMmio;
    807     ArmV8Platform.u64OffBackMmio32    = GCPhysTopOfAddrSpace - sizeof(ArmV8Platform) - GCPhysMmio32Start;
     818    ArmV8Platform.i64OffMmio32        = GCPhysMmio32Start - _128M;
    808819    ArmV8Platform.cbMmio32            = cbMmio32;
    809820
    810821    /* Add the VBox platform descriptor to the resource store. */
    811     vrc = RTVfsIoStrmWrite(hVfsIosDesc, &ArmV8Platform, sizeof(ArmV8Platform), true /*fBlocking*/, NULL /*pcbWritten*/);
     822    vrc = RTVfsIoStrmWriteAt(hVfsIosDesc, 0, &ArmV8Platform, sizeof(ArmV8Platform), true /*fBlocking*/, NULL /*pcbWritten*/);
    812823    RTVfsIoStrmRelease(hVfsIosDesc);
    813824    vrc = mptrResourceStore->i_addItem("resources", "VBoxArmV8Desc", hVfsFileDesc);
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