VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/ConsoleImplConfigArmV8.cpp@ 99927

Last change on this file since 99927 was 99927, checked in by vboxsync, 22 months ago

Devices/EFI,Main: Include EFI firmware images for ARMv8 in VBoxDD2 and provide a basic efi device specific for ARMv8 to get rid of the firmware loading hack by using a dedicated device implementation mapping the image as a ROM into the guest address space, bugref:10400

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.2 KB
Line 
1/* $Id: ConsoleImplConfigArmV8.cpp 99927 2023-05-23 08:05:36Z vboxsync $ */
2/** @file
3 * VBox Console COM Class implementation - VM Configuration Bits for ARMv8.
4 */
5
6/*
7 * Copyright (C) 2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_MAIN_CONSOLE
33#include "LoggingNew.h"
34
35#include "ConsoleImpl.h"
36#include "Global.h"
37
38// generated header
39#include "SchemaDefs.h"
40
41#include "AutoCaller.h"
42
43#include <iprt/base64.h>
44#include <iprt/buildconfig.h>
45#include <iprt/ctype.h>
46#include <iprt/dir.h>
47#include <iprt/file.h>
48#include <iprt/param.h>
49#include <iprt/path.h>
50#include <iprt/string.h>
51#include <iprt/system.h>
52#if 0 /* enable to play with lots of memory. */
53# include <iprt/env.h>
54#endif
55#include <iprt/stream.h>
56
57#include <VBox/vmm/vmmr3vtable.h>
58#include <VBox/vmm/vmapi.h>
59#include <VBox/err.h>
60#include <VBox/param.h>
61#include <VBox/version.h>
62
63#ifdef VBOX_WITH_EXTPACK
64# include "ExtPackManagerImpl.h"
65#endif
66
67
68/*********************************************************************************************************************************
69* Internal Functions *
70*********************************************************************************************************************************/
71
72/* Darwin compile kludge */
73#undef PVM
74
75#ifdef VBOX_WITH_VIRT_ARMV8
76/**
77 * Worker for configConstructor.
78 *
79 * @return VBox status code.
80 * @param pUVM The user mode VM handle.
81 * @param pVM The cross context VM handle.
82 * @param pVMM The VMM vtable.
83 * @param pAlock The automatic lock instance. This is for when we have
84 * to leave it in order to avoid deadlocks (ext packs and
85 * more).
86 *
87 * @todo This is a big hack at the moment and provides a static VM config to work with, will be adjusted later
88 * on to adhere to the VM config when sorting out the API bits.
89 */
90int Console::i_configConstructorArmV8(PUVM pUVM, PVM pVM, PCVMMR3VTABLE pVMM, AutoWriteLock *pAlock)
91{
92 RT_NOREF(pVM /* when everything is disabled */);
93 VMMDev *pVMMDev = m_pVMMDev; Assert(pVMMDev);
94 ComPtr<IMachine> pMachine = i_machine();
95
96 int vrc;
97 HRESULT hrc;
98 Utf8Str strTmp;
99 Bstr bstr;
100
101#define H() AssertLogRelMsgReturn(!FAILED(hrc), ("hrc=%Rhrc\n", hrc), VERR_MAIN_CONFIG_CONSTRUCTOR_COM_ERROR)
102
103 /*
104 * Get necessary objects and frequently used parameters.
105 */
106 ComPtr<IVirtualBox> virtualBox;
107 hrc = pMachine->COMGETTER(Parent)(virtualBox.asOutParam()); H();
108
109 ComPtr<IHost> host;
110 hrc = virtualBox->COMGETTER(Host)(host.asOutParam()); H();
111
112 ComPtr<ISystemProperties> systemProperties;
113 hrc = virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam()); H();
114
115 ComPtr<IBIOSSettings> biosSettings;
116 hrc = pMachine->COMGETTER(BIOSSettings)(biosSettings.asOutParam()); H();
117
118 ComPtr<INvramStore> nvramStore;
119 hrc = pMachine->COMGETTER(NonVolatileStore)(nvramStore.asOutParam()); H();
120
121 hrc = pMachine->COMGETTER(HardwareUUID)(bstr.asOutParam()); H();
122 RTUUID HardwareUuid;
123 vrc = RTUuidFromUtf16(&HardwareUuid, bstr.raw());
124 AssertRCReturn(vrc, vrc);
125
126 ULONG cRamMBs;
127 hrc = pMachine->COMGETTER(MemorySize)(&cRamMBs); H();
128 uint64_t const cbRam = cRamMBs * (uint64_t)_1M;
129
130 ULONG cCpus = 1;
131 hrc = pMachine->COMGETTER(CPUCount)(&cCpus); H();
132
133 ULONG ulCpuExecutionCap = 100;
134 hrc = pMachine->COMGETTER(CPUExecutionCap)(&ulCpuExecutionCap); H();
135
136 Bstr osTypeId;
137 hrc = pMachine->COMGETTER(OSTypeId)(osTypeId.asOutParam()); H();
138 LogRel(("Guest OS type: '%s'\n", Utf8Str(osTypeId).c_str()));
139
140 /*
141 * Get root node first.
142 * This is the only node in the tree.
143 */
144 PCFGMNODE pRoot = pVMM->pfnCFGMR3GetRootU(pUVM);
145 Assert(pRoot);
146
147 // catching throws from InsertConfigString and friends.
148 try
149 {
150
151 /*
152 * Set the root (and VMM) level values.
153 */
154 hrc = pMachine->COMGETTER(Name)(bstr.asOutParam()); H();
155 InsertConfigString(pRoot, "Name", bstr);
156 InsertConfigBytes(pRoot, "UUID", &HardwareUuid, sizeof(HardwareUuid));
157 InsertConfigInteger(pRoot, "NumCPUs", cCpus);
158 InsertConfigInteger(pRoot, "CpuExecutionCap", ulCpuExecutionCap);
159 InsertConfigInteger(pRoot, "TimerMillies", 10);
160
161 /*
162 * NEM
163 */
164 PCFGMNODE pNEM;
165 InsertConfigNode(pRoot, "NEM", &pNEM);
166
167 /*
168 * MM values.
169 */
170 PCFGMNODE pMM;
171 InsertConfigNode(pRoot, "MM", &pMM);
172
173 /*
174 * Memory setup.
175 */
176 PCFGMNODE pMem = NULL;
177 InsertConfigNode(pMM, "MemRegions", &pMem);
178
179 PCFGMNODE pMemRegion = NULL;
180 InsertConfigNode(pMem, "Conventional", &pMemRegion);
181 InsertConfigInteger(pMemRegion, "GCPhysStart", 0x40000000);
182 InsertConfigInteger(pMemRegion, "Size", cbRam);
183
184 /*
185 * PDM config.
186 * Load drivers in VBoxC.[so|dll]
187 */
188 PCFGMNODE pPDM;
189 PCFGMNODE pNode;
190 PCFGMNODE pMod;
191 InsertConfigNode(pRoot, "PDM", &pPDM);
192 InsertConfigNode(pPDM, "Devices", &pNode);
193 InsertConfigNode(pPDM, "Drivers", &pNode);
194 InsertConfigNode(pNode, "VBoxC", &pMod);
195#ifdef VBOX_WITH_XPCOM
196 // VBoxC is located in the components subdirectory
197 char szPathVBoxC[RTPATH_MAX];
198 vrc = RTPathAppPrivateArch(szPathVBoxC, RTPATH_MAX - sizeof("/components/VBoxC")); AssertRC(vrc);
199 strcat(szPathVBoxC, "/components/VBoxC");
200 InsertConfigString(pMod, "Path", szPathVBoxC);
201#else
202 InsertConfigString(pMod, "Path", "VBoxC");
203#endif
204
205
206 /*
207 * Block cache settings.
208 */
209 PCFGMNODE pPDMBlkCache;
210 InsertConfigNode(pPDM, "BlkCache", &pPDMBlkCache);
211
212 /* I/O cache size */
213 ULONG ioCacheSize = 5;
214 hrc = pMachine->COMGETTER(IOCacheSize)(&ioCacheSize); H();
215 InsertConfigInteger(pPDMBlkCache, "CacheSize", ioCacheSize * _1M);
216
217 /*
218 * Bandwidth groups.
219 */
220 ComPtr<IBandwidthControl> bwCtrl;
221
222 hrc = pMachine->COMGETTER(BandwidthControl)(bwCtrl.asOutParam()); H();
223
224 com::SafeIfaceArray<IBandwidthGroup> bwGroups;
225 hrc = bwCtrl->GetAllBandwidthGroups(ComSafeArrayAsOutParam(bwGroups)); H();
226
227 PCFGMNODE pAc;
228 InsertConfigNode(pPDM, "AsyncCompletion", &pAc);
229 PCFGMNODE pAcFile;
230 InsertConfigNode(pAc, "File", &pAcFile);
231 PCFGMNODE pAcFileBwGroups;
232 InsertConfigNode(pAcFile, "BwGroups", &pAcFileBwGroups);
233#ifdef VBOX_WITH_NETSHAPER
234 PCFGMNODE pNetworkShaper;
235 InsertConfigNode(pPDM, "NetworkShaper", &pNetworkShaper);
236 PCFGMNODE pNetworkBwGroups;
237 InsertConfigNode(pNetworkShaper, "BwGroups", &pNetworkBwGroups);
238#endif /* VBOX_WITH_NETSHAPER */
239
240 for (size_t i = 0; i < bwGroups.size(); i++)
241 {
242 Bstr strName;
243 hrc = bwGroups[i]->COMGETTER(Name)(strName.asOutParam()); H();
244 if (strName.isEmpty())
245 return pVMM->pfnVMR3SetError(pUVM, VERR_CFGM_NO_NODE, RT_SRC_POS, N_("No bandwidth group name specified"));
246
247 BandwidthGroupType_T enmType = BandwidthGroupType_Null;
248 hrc = bwGroups[i]->COMGETTER(Type)(&enmType); H();
249 LONG64 cMaxBytesPerSec = 0;
250 hrc = bwGroups[i]->COMGETTER(MaxBytesPerSec)(&cMaxBytesPerSec); H();
251
252 if (enmType == BandwidthGroupType_Disk)
253 {
254 PCFGMNODE pBwGroup;
255 InsertConfigNode(pAcFileBwGroups, Utf8Str(strName).c_str(), &pBwGroup);
256 InsertConfigInteger(pBwGroup, "Max", cMaxBytesPerSec);
257 InsertConfigInteger(pBwGroup, "Start", cMaxBytesPerSec);
258 InsertConfigInteger(pBwGroup, "Step", 0);
259 }
260#ifdef VBOX_WITH_NETSHAPER
261 else if (enmType == BandwidthGroupType_Network)
262 {
263 /* Network bandwidth groups. */
264 PCFGMNODE pBwGroup;
265 InsertConfigNode(pNetworkBwGroups, Utf8Str(strName).c_str(), &pBwGroup);
266 InsertConfigInteger(pBwGroup, "Max", cMaxBytesPerSec);
267 }
268#endif /* VBOX_WITH_NETSHAPER */
269 }
270
271 /*
272 * Devices
273 */
274 PCFGMNODE pDevices = NULL; /* /Devices */
275 PCFGMNODE pDev = NULL; /* /Devices/Dev/ */
276 PCFGMNODE pInst = NULL; /* /Devices/Dev/0/ */
277 PCFGMNODE pCfg = NULL; /* /Devices/Dev/.../Config/ */
278 PCFGMNODE pLunL0 = NULL; /* /Devices/Dev/0/LUN#0/ */
279 PCFGMNODE pLunL1 = NULL; /* /Devices/Dev/0/LUN#0/AttachedDriver/ */
280 PCFGMNODE pLunL1Cfg = NULL; /* /Devices/Dev/0/LUN#0/AttachedDriver/Config */
281
282 InsertConfigNode(pRoot, "Devices", &pDevices);
283
284 InsertConfigNode(pDevices, "efi-armv8", &pDev);
285 InsertConfigNode(pDev, "0", &pInst);
286 InsertConfigNode(pInst, "Config", &pCfg);
287 InsertConfigInteger(pCfg, "GCPhysLoadAddress", 0);
288 InsertConfigString(pCfg, "EfiRom", "VBoxEFIAArch64.fd");
289
290 InsertConfigNode(pDevices, "gic", &pDev);
291 InsertConfigNode(pDev, "0", &pInst);
292 InsertConfigInteger(pInst, "Trusted", 1);
293 InsertConfigNode(pInst, "Config", &pCfg);
294 InsertConfigInteger(pCfg, "DistributorMmioBase", 0x08000000);
295 InsertConfigInteger(pCfg, "RedistributorMmioBase", 0x080a0000);
296
297
298 InsertConfigNode(pDevices, "qemu-fw-cfg", &pDev);
299 InsertConfigNode(pDev, "0", &pInst);
300 InsertConfigNode(pInst, "Config", &pCfg);
301 InsertConfigInteger(pCfg, "MmioSize", 4096);
302 InsertConfigInteger(pCfg, "MmioBase", 0x09020000);
303 InsertConfigInteger(pCfg, "DmaEnabled", 1);
304 InsertConfigInteger(pCfg, "QemuRamfbSupport", 1);
305 InsertConfigNode(pInst, "LUN#0", &pLunL0);
306 InsertConfigString(pLunL0, "Driver", "MainDisplay");
307
308 InsertConfigNode(pDevices, "flash-cfi", &pDev);
309 InsertConfigNode(pDev, "0", &pInst);
310 InsertConfigNode(pInst, "Config", &pCfg);
311 InsertConfigInteger(pCfg, "BaseAddress", 64 * _1M);
312 InsertConfigInteger(pCfg, "Size", 64 * _1M);
313
314 InsertConfigNode(pDevices, "arm-pl011", &pDev);
315 for (ULONG ulInstance = 0; ulInstance < 1 /** @todo SchemaDefs::SerialPortCount*/; ++ulInstance)
316 {
317 ComPtr<ISerialPort> serialPort;
318 hrc = pMachine->GetSerialPort(ulInstance, serialPort.asOutParam()); H();
319 BOOL fEnabledSerPort = FALSE;
320 if (serialPort)
321 {
322 hrc = serialPort->COMGETTER(Enabled)(&fEnabledSerPort); H();
323 }
324 if (!fEnabledSerPort)
325 {
326 m_aeSerialPortMode[ulInstance] = PortMode_Disconnected;
327 continue;
328 }
329
330 InsertConfigNode(pDev, Utf8StrFmt("%u", ulInstance).c_str(), &pInst);
331 InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
332 InsertConfigNode(pInst, "Config", &pCfg);
333
334 InsertConfigInteger(pCfg, "Irq", 1);
335 InsertConfigInteger(pCfg, "MmioBase", 0x09000000);
336
337 BOOL fServer;
338 hrc = serialPort->COMGETTER(Server)(&fServer); H();
339 hrc = serialPort->COMGETTER(Path)(bstr.asOutParam()); H();
340
341 PortMode_T eHostMode;
342 hrc = serialPort->COMGETTER(HostMode)(&eHostMode); H();
343
344 m_aeSerialPortMode[ulInstance] = eHostMode;
345 if (eHostMode != PortMode_Disconnected)
346 {
347 vrc = i_configSerialPort(pInst, eHostMode, Utf8Str(bstr).c_str(), RT_BOOL(fServer));
348 if (RT_FAILURE(vrc))
349 return vrc;
350 }
351 }
352
353 InsertConfigNode(pDevices, "arm-pl031-rtc", &pDev);
354 InsertConfigNode(pDev, "0", &pInst);
355 InsertConfigNode(pInst, "Config", &pCfg);
356 InsertConfigInteger(pCfg, "Irq", 2);
357 InsertConfigInteger(pCfg, "MmioBase", 0x09010000);
358
359 InsertConfigNode(pDevices, "arm-pl061-gpio",&pDev);
360 InsertConfigNode(pDev, "0", &pInst);
361 InsertConfigNode(pInst, "Config", &pCfg);
362 InsertConfigInteger(pCfg, "Irq", 7);
363 InsertConfigInteger(pCfg, "MmioBase", 0x09030000);
364
365 InsertConfigNode(pDevices, "pci-generic-ecam", &pDev);
366 InsertConfigNode(pDev, "0", &pInst);
367 InsertConfigNode(pInst, "Config", &pCfg);
368 InsertConfigInteger(pCfg, "MmioEcamBase", 0x3f000000);
369 InsertConfigInteger(pCfg, "MmioEcamLength", 0x01000000);
370 InsertConfigInteger(pCfg, "MmioPioBase", 0x3eff0000);
371 InsertConfigInteger(pCfg, "MmioPioSize", 0x0000ffff);
372 InsertConfigInteger(pCfg, "IntPinA", 3);
373 InsertConfigInteger(pCfg, "IntPinB", 4);
374 InsertConfigInteger(pCfg, "IntPinC", 5);
375 InsertConfigInteger(pCfg, "IntPinD", 6);
376
377 InsertConfigNode(pDevices, "usb-xhci", &pDev);
378 InsertConfigNode(pDev, "0", &pInst);
379 InsertConfigInteger(pInst, "Trusted", 1);
380 InsertConfigInteger(pInst, "PCIBusNo", 0);
381 InsertConfigInteger(pInst, "PCIDeviceNo", 2);
382 InsertConfigInteger(pInst, "PCIFunctionNo", 0);
383 InsertConfigNode(pInst, "Config", &pCfg);
384 InsertConfigNode(pInst, "LUN#0", &pLunL0);
385 InsertConfigString(pLunL0, "Driver","VUSBRootHub");
386 InsertConfigNode(pInst, "LUN#1", &pLunL0);
387 InsertConfigString(pLunL0, "Driver","VUSBRootHub");
388
389 InsertConfigNode(pDevices, "e1000", &pDev);
390 InsertConfigNode(pDev, "0", &pInst);
391 InsertConfigInteger(pInst, "Trusted", 1);
392 InsertConfigInteger(pInst, "PCIBusNo", 0);
393 InsertConfigInteger(pInst, "PCIDeviceNo", 1);
394 InsertConfigInteger(pInst, "PCIFunctionNo", 0);
395 InsertConfigNode(pInst, "Config", &pCfg);
396 InsertConfigInteger(pCfg, "CableConnected", 1);
397 InsertConfigInteger(pCfg, "LineSpeed", 0);
398 InsertConfigInteger(pCfg, "AdapterType", 0);
399
400 const char *pszMac = "080027ede92c";
401 Assert(strlen(pszMac) == 12);
402 RTMAC Mac;
403 RT_ZERO(Mac);
404 char *pMac = (char*)&Mac;
405 for (uint32_t i = 0; i < 6; ++i)
406 {
407 int c1 = *pszMac++ - '0';
408 if (c1 > 9)
409 c1 -= 7;
410 int c2 = *pszMac++ - '0';
411 if (c2 > 9)
412 c2 -= 7;
413 *pMac++ = (char)(((c1 & 0x0f) << 4) | (c2 & 0x0f));
414 }
415 InsertConfigBytes(pCfg, "MAC", &Mac, sizeof(Mac));
416 InsertConfigNode(pInst, "LUN#0", &pLunL0);
417 InsertConfigString(pLunL0, "Driver", "NAT");
418 InsertConfigNode(pLunL0, "Config", &pLunL1Cfg);
419 InsertConfigString(pLunL1Cfg, "Network", "10.0.2.0/24");
420 InsertConfigString(pLunL1Cfg, "TFTPPrefix", "/Users/vbox/Library/VirtualBox/TFTP");
421 InsertConfigString(pLunL1Cfg, "BootFile", "default.pxe");
422 InsertConfigInteger(pLunL1Cfg, "AliasMode", 0);
423 InsertConfigInteger(pLunL1Cfg, "DNSProxy", 0);
424 InsertConfigInteger(pLunL1Cfg, "LocalhostReachable", 1);
425 InsertConfigInteger(pLunL1Cfg, "PassDomain", 1);
426 InsertConfigInteger(pLunL1Cfg, "UseHostResolver", 0);
427
428 PCFGMNODE pUsb = NULL;
429 InsertConfigNode(pRoot, "USB", &pUsb);
430
431 /*
432 * Storage controllers.
433 */
434 com::SafeIfaceArray<IStorageController> ctrls;
435 PCFGMNODE aCtrlNodes[StorageControllerType_VirtioSCSI + 1] = {};
436 hrc = pMachine->COMGETTER(StorageControllers)(ComSafeArrayAsOutParam(ctrls)); H();
437
438 for (size_t i = 0; i < ctrls.size(); ++i)
439 {
440 DeviceType_T *paLedDevType = NULL;
441
442 StorageControllerType_T enmCtrlType;
443 hrc = ctrls[i]->COMGETTER(ControllerType)(&enmCtrlType); H();
444 AssertRelease((unsigned)enmCtrlType < RT_ELEMENTS(aCtrlNodes)
445 || enmCtrlType == StorageControllerType_USB);
446
447 StorageBus_T enmBus;
448 hrc = ctrls[i]->COMGETTER(Bus)(&enmBus); H();
449
450 Bstr controllerName;
451 hrc = ctrls[i]->COMGETTER(Name)(controllerName.asOutParam()); H();
452
453 ULONG ulInstance = 999;
454 hrc = ctrls[i]->COMGETTER(Instance)(&ulInstance); H();
455
456 BOOL fUseHostIOCache;
457 hrc = ctrls[i]->COMGETTER(UseHostIOCache)(&fUseHostIOCache); H();
458
459 BOOL fBootable;
460 hrc = ctrls[i]->COMGETTER(Bootable)(&fBootable); H();
461
462 PCFGMNODE pCtlInst = NULL;
463 const char *pszCtrlDev = i_storageControllerTypeToStr(enmCtrlType);
464 if (enmCtrlType != StorageControllerType_USB)
465 {
466 /* /Devices/<ctrldev>/ */
467 pDev = aCtrlNodes[enmCtrlType];
468 if (!pDev)
469 {
470 InsertConfigNode(pDevices, pszCtrlDev, &pDev);
471 aCtrlNodes[enmCtrlType] = pDev; /* IDE variants are handled in the switch */
472 }
473
474 /* /Devices/<ctrldev>/<instance>/ */
475 InsertConfigNode(pDev, Utf8StrFmt("%u", ulInstance).c_str(), &pCtlInst);
476
477 /* Device config: /Devices/<ctrldev>/<instance>/<values> & /ditto/Config/<values> */
478 InsertConfigInteger(pCtlInst, "Trusted", 1);
479 InsertConfigNode(pCtlInst, "Config", &pCfg);
480 }
481
482 switch (enmCtrlType)
483 {
484 case StorageControllerType_USB:
485 {
486 if (pUsb)
487 {
488 /*
489 * USB MSDs are handled a bit different as the device instance
490 * doesn't match the storage controller instance but the port.
491 */
492 InsertConfigNode(pUsb, "Msd", &pDev);
493 pCtlInst = pDev;
494 }
495 else
496 return pVMM->pfnVMR3SetError(pUVM, VERR_NOT_FOUND, RT_SRC_POS,
497 N_("There is no USB controller enabled but there\n"
498 "is at least one USB storage device configured for this VM.\n"
499 "To fix this problem either enable the USB controller or remove\n"
500 "the storage device from the VM"));
501 break;
502 }
503
504 case StorageControllerType_LsiLogic:
505 case StorageControllerType_BusLogic:
506 case StorageControllerType_IntelAhci:
507 case StorageControllerType_PIIX3:
508 case StorageControllerType_PIIX4:
509 case StorageControllerType_ICH6:
510 case StorageControllerType_I82078:
511 case StorageControllerType_LsiLogicSas:
512 case StorageControllerType_NVMe:
513 case StorageControllerType_VirtioSCSI:
514 default:
515 AssertLogRelMsgFailedReturn(("invalid storage controller type: %d\n", enmCtrlType), VERR_MAIN_CONFIG_CONSTRUCTOR_IPE);
516 }
517
518 /* Attach the media to the storage controllers. */
519 com::SafeIfaceArray<IMediumAttachment> atts;
520 hrc = pMachine->GetMediumAttachmentsOfController(controllerName.raw(),
521 ComSafeArrayAsOutParam(atts)); H();
522
523 /* Builtin I/O cache - per device setting. */
524 BOOL fBuiltinIOCache = true;
525 hrc = pMachine->COMGETTER(IOCacheEnabled)(&fBuiltinIOCache); H();
526
527 bool fInsertDiskIntegrityDrv = false;
528 Bstr strDiskIntegrityFlag;
529 hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EnableDiskIntegrityDriver").raw(),
530 strDiskIntegrityFlag.asOutParam());
531 if ( hrc == S_OK
532 && strDiskIntegrityFlag == "1")
533 fInsertDiskIntegrityDrv = true;
534
535 for (size_t j = 0; j < atts.size(); ++j)
536 {
537 IMediumAttachment *pMediumAtt = atts[j];
538 vrc = i_configMediumAttachment(pszCtrlDev,
539 ulInstance,
540 enmBus,
541 !!fUseHostIOCache,
542 enmCtrlType == StorageControllerType_NVMe ? false : !!fBuiltinIOCache,
543 fInsertDiskIntegrityDrv,
544 false /* fSetupMerge */,
545 0 /* uMergeSource */,
546 0 /* uMergeTarget */,
547 pMediumAtt,
548 mMachineState,
549 NULL /* phrc */,
550 false /* fAttachDetach */,
551 false /* fForceUnmount */,
552 false /* fHotplug */,
553 pUVM,
554 pVMM,
555 paLedDevType,
556 NULL /* ppLunL0 */);
557 if (RT_FAILURE(vrc))
558 return vrc;
559 }
560 H();
561 }
562 H();
563
564 InsertConfigNode(pUsb, "HidKeyboard", &pDev);
565 InsertConfigNode(pDev, "0", &pInst);
566 InsertConfigInteger(pInst, "Trusted", 1);
567 InsertConfigNode(pInst, "Config", &pCfg);
568 InsertConfigNode(pInst, "LUN#0", &pLunL0);
569 InsertConfigString(pLunL0, "Driver", "KeyboardQueue");
570 InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
571 InsertConfigString(pLunL1, "Driver", "MainKeyboard");
572
573 InsertConfigNode(pUsb, "HidMouse", &pDev);
574 InsertConfigNode(pDev, "0", &pInst);
575 InsertConfigNode(pInst, "Config", &pCfg);
576 InsertConfigString(pCfg, "Mode", "absolute");
577 InsertConfigNode(pInst, "LUN#0", &pLunL0);
578 InsertConfigString(pLunL0, "Driver", "MouseQueue");
579 InsertConfigNode(pLunL0, "Config", &pCfg);
580 InsertConfigInteger(pCfg, "QueueSize", 128);
581
582 InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
583 InsertConfigString(pLunL1, "Driver", "MainMouse");
584 }
585 catch (ConfigError &x)
586 {
587 // InsertConfig threw something:
588 pVMM->pfnVMR3SetError(pUVM, x.m_vrc, RT_SRC_POS, "Caught ConfigError: %Rrc - %s", x.m_vrc, x.what());
589 return x.m_vrc;
590 }
591 catch (HRESULT hrcXcpt)
592 {
593 AssertLogRelMsgFailedReturn(("hrc=%Rhrc\n", hrcXcpt), VERR_MAIN_CONFIG_CONSTRUCTOR_COM_ERROR);
594 }
595
596#ifdef VBOX_WITH_EXTPACK
597 /*
598 * Call the extension pack hooks if everything went well thus far.
599 */
600 if (RT_SUCCESS(vrc))
601 {
602 pAlock->release();
603 vrc = mptrExtPackManager->i_callAllVmConfigureVmmHooks(this, pVM, pVMM);
604 pAlock->acquire();
605 }
606#endif
607
608 /*
609 * Apply the CFGM overlay.
610 */
611 if (RT_SUCCESS(vrc))
612 vrc = i_configCfgmOverlay(pRoot, virtualBox, pMachine);
613
614 /*
615 * Dump all extradata API settings tweaks, both global and per VM.
616 */
617 if (RT_SUCCESS(vrc))
618 vrc = i_configDumpAPISettingsTweaks(virtualBox, pMachine);
619
620#undef H
621
622 pAlock->release(); /* Avoid triggering the lock order inversion check. */
623
624 /*
625 * Register VM state change handler.
626 */
627 int vrc2 = pVMM->pfnVMR3AtStateRegister(pUVM, Console::i_vmstateChangeCallback, this);
628 AssertRC(vrc2);
629 if (RT_SUCCESS(vrc))
630 vrc = vrc2;
631
632 /*
633 * Register VM runtime error handler.
634 */
635 vrc2 = pVMM->pfnVMR3AtRuntimeErrorRegister(pUVM, Console::i_atVMRuntimeErrorCallback, this);
636 AssertRC(vrc2);
637 if (RT_SUCCESS(vrc))
638 vrc = vrc2;
639
640 pAlock->acquire();
641
642 LogFlowFunc(("vrc = %Rrc\n", vrc));
643 LogFlowFuncLeave();
644
645 return vrc;
646}
647#endif /* !VBOX_WITH_VIRT_ARMV8 */
648
Note: See TracBrowser for help on using the repository browser.

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