VirtualBox

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

Last change on this file since 100041 was 100041, checked in by vboxsync, 18 months ago

Main/ConsoleImplConfigArmV8.cpp: A first shot at generating the FDT on the fly for our static VM config so it is usable without the need to have a DTB file around, bugref:10384

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 47.5 KB
Line 
1/* $Id: ConsoleImplConfigArmV8.cpp 100041 2023-06-01 18:25:11Z 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 "ResourceStoreImpl.h"
37#include "Global.h"
38
39// generated header
40#include "SchemaDefs.h"
41
42#include "AutoCaller.h"
43
44#include <iprt/base64.h>
45#include <iprt/buildconfig.h>
46#include <iprt/ctype.h>
47#include <iprt/dir.h>
48#include <iprt/fdt.h>
49#include <iprt/file.h>
50#include <iprt/param.h>
51#include <iprt/path.h>
52#include <iprt/string.h>
53#include <iprt/system.h>
54#if 0 /* enable to play with lots of memory. */
55# include <iprt/env.h>
56#endif
57#include <iprt/stream.h>
58
59#include <VBox/vmm/vmmr3vtable.h>
60#include <VBox/vmm/vmapi.h>
61#include <VBox/err.h>
62#include <VBox/param.h>
63#include <VBox/version.h>
64
65#ifdef VBOX_WITH_EXTPACK
66# include "ExtPackManagerImpl.h"
67#endif
68
69
70/*********************************************************************************************************************************
71* Internal Functions *
72*********************************************************************************************************************************/
73
74/* Darwin compile kludge */
75#undef PVM
76
77#ifdef VBOX_WITH_VIRT_ARMV8
78/**
79 * Worker for configConstructor.
80 *
81 * @return VBox status code.
82 * @param pUVM The user mode VM handle.
83 * @param pVM The cross context VM handle.
84 * @param pVMM The VMM vtable.
85 * @param pAlock The automatic lock instance. This is for when we have
86 * to leave it in order to avoid deadlocks (ext packs and
87 * more).
88 *
89 * @todo This is a big hack at the moment and provides a static VM config to work with, will be adjusted later
90 * on to adhere to the VM config when sorting out the API bits.
91 */
92int Console::i_configConstructorArmV8(PUVM pUVM, PVM pVM, PCVMMR3VTABLE pVMM, AutoWriteLock *pAlock)
93{
94 RT_NOREF(pVM /* when everything is disabled */);
95 VMMDev *pVMMDev = m_pVMMDev; Assert(pVMMDev);
96 ComPtr<IMachine> pMachine = i_machine();
97
98 HRESULT hrc;
99 Utf8Str strTmp;
100 Bstr bstr;
101
102 RTFDT hFdt = NIL_RTFDT;
103 int vrc = RTFdtCreateEmpty(&hFdt);
104 AssertRCReturn(vrc, vrc);
105
106#define H() AssertLogRelMsgReturnStmt(!FAILED(hrc), ("hrc=%Rhrc\n", hrc), RTFdtDestroy(hFdt), VERR_MAIN_CONFIG_CONSTRUCTOR_COM_ERROR)
107#define VRC() AssertLogRelMsgReturnStmt(RT_SUCCESS(vrc), ("vrc=%Rrc\n", vrc), RTFdtDestroy(hFdt), vrc)
108
109
110 /*
111 * Get necessary objects and frequently used parameters.
112 */
113 ComPtr<IVirtualBox> virtualBox;
114 hrc = pMachine->COMGETTER(Parent)(virtualBox.asOutParam()); H();
115
116 ComPtr<IHost> host;
117 hrc = virtualBox->COMGETTER(Host)(host.asOutParam()); H();
118
119 ComPtr<ISystemProperties> systemProperties;
120 hrc = virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam()); H();
121
122 ComPtr<IBIOSSettings> biosSettings;
123 hrc = pMachine->COMGETTER(BIOSSettings)(biosSettings.asOutParam()); H();
124
125 ComPtr<INvramStore> nvramStore;
126 hrc = pMachine->COMGETTER(NonVolatileStore)(nvramStore.asOutParam()); H();
127
128 hrc = pMachine->COMGETTER(HardwareUUID)(bstr.asOutParam()); H();
129 RTUUID HardwareUuid;
130 vrc = RTUuidFromUtf16(&HardwareUuid, bstr.raw());
131 AssertRCReturn(vrc, vrc);
132
133 ULONG cRamMBs;
134 hrc = pMachine->COMGETTER(MemorySize)(&cRamMBs); H();
135 uint64_t const cbRam = cRamMBs * (uint64_t)_1M;
136
137 ULONG cCpus = 1;
138 hrc = pMachine->COMGETTER(CPUCount)(&cCpus); H();
139
140 ULONG ulCpuExecutionCap = 100;
141 hrc = pMachine->COMGETTER(CPUExecutionCap)(&ulCpuExecutionCap); H();
142
143 Bstr osTypeId;
144 hrc = pMachine->COMGETTER(OSTypeId)(osTypeId.asOutParam()); H();
145 LogRel(("Guest OS type: '%s'\n", Utf8Str(osTypeId).c_str()));
146
147 /*
148 * Get root node first.
149 * This is the only node in the tree.
150 */
151 PCFGMNODE pRoot = pVMM->pfnCFGMR3GetRootU(pUVM);
152 Assert(pRoot);
153
154 // catching throws from InsertConfigString and friends.
155 try
156 {
157
158 /*
159 * Set the root (and VMM) level values.
160 */
161 hrc = pMachine->COMGETTER(Name)(bstr.asOutParam()); H();
162 InsertConfigString(pRoot, "Name", bstr);
163 InsertConfigBytes(pRoot, "UUID", &HardwareUuid, sizeof(HardwareUuid));
164 InsertConfigInteger(pRoot, "NumCPUs", cCpus);
165 InsertConfigInteger(pRoot, "CpuExecutionCap", ulCpuExecutionCap);
166 InsertConfigInteger(pRoot, "TimerMillies", 10);
167
168 uint32_t idPHandleIntCtrl = RTFdtPHandleAllocate(hFdt);
169 Assert(idPHandleIntCtrl != UINT32_MAX);
170 uint32_t idPHandleIntCtrlMsi = RTFdtPHandleAllocate(hFdt);
171 Assert(idPHandleIntCtrlMsi != UINT32_MAX);
172 uint32_t idPHandleAbpPClk = RTFdtPHandleAllocate(hFdt);
173 Assert(idPHandleAbpPClk != UINT32_MAX);
174 uint32_t idPHandleGpio = RTFdtPHandleAllocate(hFdt);
175 Assert(idPHandleGpio != UINT32_MAX);
176
177 uint32_t aidPHandleCpus[VMM_MAX_CPU_COUNT];
178 for (uint32_t i = 0; i < cCpus; i++)
179 {
180 aidPHandleCpus[i] = RTFdtPHandleAllocate(hFdt);
181 Assert(aidPHandleCpus[i] != UINT32_MAX);
182 }
183
184 vrc = RTFdtNodePropertyAddU32( hFdt, "interrupt-parent", idPHandleIntCtrl); VRC();
185 vrc = RTFdtNodePropertyAddString(hFdt, "model", "linux,dummy-virt"); VRC();
186 vrc = RTFdtNodePropertyAddU32( hFdt, "#size-cells", 2); VRC();
187 vrc = RTFdtNodePropertyAddU32( hFdt, "#address-cells", 2); VRC();
188 vrc = RTFdtNodePropertyAddString(hFdt, "compatible", "linux,dummy-virt"); VRC();
189
190 /* Configure the Power State Coordination Interface. */
191 vrc = RTFdtNodeAdd(hFdt, "psci"); VRC();
192 vrc = RTFdtNodePropertyAddU32( hFdt, "migrate", 0x84000005); VRC();
193 vrc = RTFdtNodePropertyAddU32( hFdt, "cpu_on", 0x84000003); VRC();
194 vrc = RTFdtNodePropertyAddU32( hFdt, "cpu_off", 0x84000002); VRC();
195 vrc = RTFdtNodePropertyAddU32( hFdt, "cpu_suspend", 0x84000001); VRC();
196 vrc = RTFdtNodePropertyAddString(hFdt, "method", "hvc"); VRC();
197 vrc = RTFdtNodePropertyAddStringList(hFdt, "compatible", 3,
198 "arm,psci-1.0", "arm,psci-0.2", "arm,psci"); VRC();
199 vrc = RTFdtNodeFinalize(hFdt); VRC();
200
201 /* Configure some misc system wide properties. */
202 vrc = RTFdtNodeAdd(hFdt, "chosen"); VRC();
203 vrc = RTFdtNodePropertyAddString(hFdt, "stdout-path", "/pl011@9000000"); VRC();
204 vrc = RTFdtNodeFinalize(hFdt);
205
206 /* Configure the timer and clock. */
207 vrc = RTFdtNodeAdd(hFdt, "timer"); VRC();
208 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "interrupts", 12,
209 0x01, 0x0d, 0x104,
210 0x01, 0x0e, 0x104,
211 0x01, 0x0b, 0x104,
212 0x01, 0x0a, 0x104); VRC();
213 vrc = RTFdtNodePropertyAddEmpty( hFdt, "always-on"); VRC();
214 vrc = RTFdtNodePropertyAddString( hFdt, "compatible", "arm,armv7-timer"); VRC();
215 vrc = RTFdtNodeFinalize(hFdt);
216
217 vrc = RTFdtNodeAdd(hFdt, "apb-clk"); VRC();
218 vrc = RTFdtNodePropertyAddU32( hFdt, "phandle", idPHandleAbpPClk); VRC();
219 vrc = RTFdtNodePropertyAddString( hFdt, "clock-output-names", "clk24mhz"); VRC();
220 vrc = RTFdtNodePropertyAddU32( hFdt, "clock-frequency", 24 * 1000 * 1000); VRC();
221 vrc = RTFdtNodePropertyAddU32( hFdt, "#clock-cells", 0); VRC();
222 vrc = RTFdtNodePropertyAddString( hFdt, "compatible", "fixed-clock"); VRC();
223 vrc = RTFdtNodeFinalize(hFdt);
224
225 /* Configure gpio keys (non functional at the moment). */
226 vrc = RTFdtNodeAdd(hFdt, "gpio-keys"); VRC();
227 vrc = RTFdtNodePropertyAddString(hFdt, "compatible", "gpio-keys"); VRC();
228
229 vrc = RTFdtNodeAdd(hFdt, "poweroff"); VRC();
230 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "gpios", 3, idPHandleGpio, 3, 0); VRC();
231 vrc = RTFdtNodePropertyAddU32( hFdt, "linux,code", 0x74); VRC();
232 vrc = RTFdtNodePropertyAddString( hFdt, "label", "GPIO Key Poweroff"); VRC();
233 vrc = RTFdtNodeFinalize(hFdt); VRC();
234
235 vrc = RTFdtNodeFinalize(hFdt); VRC();
236
237 /*
238 * NEM
239 */
240 PCFGMNODE pNEM;
241 InsertConfigNode(pRoot, "NEM", &pNEM);
242
243 /*
244 * MM values.
245 */
246 PCFGMNODE pMM;
247 InsertConfigNode(pRoot, "MM", &pMM);
248
249 /*
250 * Memory setup.
251 */
252 PCFGMNODE pMem = NULL;
253 InsertConfigNode(pMM, "MemRegions", &pMem);
254
255 PCFGMNODE pMemRegion = NULL;
256 InsertConfigNode(pMem, "Conventional", &pMemRegion);
257 InsertConfigInteger(pMemRegion, "GCPhysStart", 0x40000000);
258 InsertConfigInteger(pMemRegion, "Size", cbRam);
259
260 vrc = RTFdtNodeAddF(hFdt, "memory@%RX32", 0x40000000); VRC();
261 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "reg", 4,
262 0, 0x40000000,
263 (uint32_t)(cbRam >> 32), cbRam & UINT32_MAX); VRC();
264 vrc = RTFdtNodePropertyAddString( hFdt, "device_type", "memory"); VRC();
265 vrc = RTFdtNodeFinalize(hFdt); VRC();
266
267 /* Configure the CPUs in the system, only one socket and cluster at the moment. */
268 vrc = RTFdtNodeAdd(hFdt, "cpus"); VRC();
269 vrc = RTFdtNodePropertyAddU32(hFdt, "#size-cells", 0); VRC();
270 vrc = RTFdtNodePropertyAddU32(hFdt, "#address-cells", 1); VRC();
271
272 vrc = RTFdtNodeAdd(hFdt, "socket0"); VRC();
273 vrc = RTFdtNodeAdd(hFdt, "cluster0"); VRC();
274
275 for (uint32_t i = 0; i < cCpus; i++)
276 {
277 vrc = RTFdtNodeAddF(hFdt, "core%u", i); VRC();
278 vrc = RTFdtNodePropertyAddU32(hFdt, "cpu", aidPHandleCpus[i]); VRC();
279 vrc = RTFdtNodeFinalize(hFdt); VRC();
280 }
281
282 vrc = RTFdtNodeFinalize(hFdt); VRC();
283 vrc = RTFdtNodeFinalize(hFdt); VRC();
284
285 for (uint32_t i = 0; i < cCpus; i++)
286 {
287 vrc = RTFdtNodeAddF(hFdt, "cpu@%u", i); VRC();
288 vrc = RTFdtNodePropertyAddU32(hFdt, "phandle", aidPHandleCpus[i]); VRC();
289 vrc = RTFdtNodePropertyAddU32(hFdt, "reg", 0); VRC();
290 vrc = RTFdtNodePropertyAddString(hFdt, "compatible", "arm,cortex-a15"); VRC();
291 vrc = RTFdtNodePropertyAddString(hFdt, "device_type", "cpu"); VRC();
292 vrc = RTFdtNodeFinalize(hFdt); VRC();
293 }
294
295 vrc = RTFdtNodeFinalize(hFdt); VRC();
296
297
298 /*
299 * PDM config.
300 * Load drivers in VBoxC.[so|dll]
301 */
302 PCFGMNODE pPDM;
303 PCFGMNODE pNode;
304 PCFGMNODE pMod;
305 InsertConfigNode(pRoot, "PDM", &pPDM);
306 InsertConfigNode(pPDM, "Devices", &pNode);
307 InsertConfigNode(pPDM, "Drivers", &pNode);
308 InsertConfigNode(pNode, "VBoxC", &pMod);
309#ifdef VBOX_WITH_XPCOM
310 // VBoxC is located in the components subdirectory
311 char szPathVBoxC[RTPATH_MAX];
312 vrc = RTPathAppPrivateArch(szPathVBoxC, RTPATH_MAX - sizeof("/components/VBoxC")); AssertRC(vrc);
313 strcat(szPathVBoxC, "/components/VBoxC");
314 InsertConfigString(pMod, "Path", szPathVBoxC);
315#else
316 InsertConfigString(pMod, "Path", "VBoxC");
317#endif
318
319
320 /*
321 * Block cache settings.
322 */
323 PCFGMNODE pPDMBlkCache;
324 InsertConfigNode(pPDM, "BlkCache", &pPDMBlkCache);
325
326 /* I/O cache size */
327 ULONG ioCacheSize = 5;
328 hrc = pMachine->COMGETTER(IOCacheSize)(&ioCacheSize); H();
329 InsertConfigInteger(pPDMBlkCache, "CacheSize", ioCacheSize * _1M);
330
331 /*
332 * Bandwidth groups.
333 */
334 ComPtr<IBandwidthControl> bwCtrl;
335
336 hrc = pMachine->COMGETTER(BandwidthControl)(bwCtrl.asOutParam()); H();
337
338 com::SafeIfaceArray<IBandwidthGroup> bwGroups;
339 hrc = bwCtrl->GetAllBandwidthGroups(ComSafeArrayAsOutParam(bwGroups)); H();
340
341 PCFGMNODE pAc;
342 InsertConfigNode(pPDM, "AsyncCompletion", &pAc);
343 PCFGMNODE pAcFile;
344 InsertConfigNode(pAc, "File", &pAcFile);
345 PCFGMNODE pAcFileBwGroups;
346 InsertConfigNode(pAcFile, "BwGroups", &pAcFileBwGroups);
347#ifdef VBOX_WITH_NETSHAPER
348 PCFGMNODE pNetworkShaper;
349 InsertConfigNode(pPDM, "NetworkShaper", &pNetworkShaper);
350 PCFGMNODE pNetworkBwGroups;
351 InsertConfigNode(pNetworkShaper, "BwGroups", &pNetworkBwGroups);
352#endif /* VBOX_WITH_NETSHAPER */
353
354 for (size_t i = 0; i < bwGroups.size(); i++)
355 {
356 Bstr strName;
357 hrc = bwGroups[i]->COMGETTER(Name)(strName.asOutParam()); H();
358 if (strName.isEmpty())
359 return pVMM->pfnVMR3SetError(pUVM, VERR_CFGM_NO_NODE, RT_SRC_POS, N_("No bandwidth group name specified"));
360
361 BandwidthGroupType_T enmType = BandwidthGroupType_Null;
362 hrc = bwGroups[i]->COMGETTER(Type)(&enmType); H();
363 LONG64 cMaxBytesPerSec = 0;
364 hrc = bwGroups[i]->COMGETTER(MaxBytesPerSec)(&cMaxBytesPerSec); H();
365
366 if (enmType == BandwidthGroupType_Disk)
367 {
368 PCFGMNODE pBwGroup;
369 InsertConfigNode(pAcFileBwGroups, Utf8Str(strName).c_str(), &pBwGroup);
370 InsertConfigInteger(pBwGroup, "Max", cMaxBytesPerSec);
371 InsertConfigInteger(pBwGroup, "Start", cMaxBytesPerSec);
372 InsertConfigInteger(pBwGroup, "Step", 0);
373 }
374#ifdef VBOX_WITH_NETSHAPER
375 else if (enmType == BandwidthGroupType_Network)
376 {
377 /* Network bandwidth groups. */
378 PCFGMNODE pBwGroup;
379 InsertConfigNode(pNetworkBwGroups, Utf8Str(strName).c_str(), &pBwGroup);
380 InsertConfigInteger(pBwGroup, "Max", cMaxBytesPerSec);
381 }
382#endif /* VBOX_WITH_NETSHAPER */
383 }
384
385 /*
386 * Devices
387 */
388 PCFGMNODE pDevices = NULL; /* /Devices */
389 PCFGMNODE pDev = NULL; /* /Devices/Dev/ */
390 PCFGMNODE pInst = NULL; /* /Devices/Dev/0/ */
391 PCFGMNODE pCfg = NULL; /* /Devices/Dev/.../Config/ */
392 PCFGMNODE pLunL0 = NULL; /* /Devices/Dev/0/LUN#0/ */
393 PCFGMNODE pLunL1 = NULL; /* /Devices/Dev/0/LUN#0/AttachedDriver/ */
394 PCFGMNODE pLunL1Cfg = NULL; /* /Devices/Dev/0/LUN#0/AttachedDriver/Config */
395
396 InsertConfigNode(pRoot, "Devices", &pDevices);
397
398 InsertConfigNode(pDevices, "efi-armv8", &pDev);
399 InsertConfigNode(pDev, "0", &pInst);
400 InsertConfigNode(pInst, "Config", &pCfg);
401 InsertConfigInteger(pCfg, "GCPhysLoadAddress", 0);
402 InsertConfigString(pCfg, "EfiRom", "VBoxEFIAArch64.fd");
403 InsertConfigInteger(pCfg, "GCPhysFdtAddress", 0x40000000);
404 InsertConfigString(pCfg, "FdtId", "fdt");
405 InsertConfigNode(pInst, "LUN#0", &pLunL0);
406 InsertConfigString(pLunL0, "Driver", "ResourceStore");
407
408 vrc = RTFdtNodeAddF(hFdt, "platform-bus@%RX32", 0x0c000000); VRC();
409 vrc = RTFdtNodePropertyAddU32( hFdt, "interrupt-parent", idPHandleIntCtrl); VRC();
410 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "ranges", 4, 0, 0, 0x0c000000, 0x02000000); VRC();
411 vrc = RTFdtNodePropertyAddU32( hFdt, "#address-cells", 1); VRC();
412 vrc = RTFdtNodePropertyAddU32( hFdt, "#size-cells", 1); VRC();
413 vrc = RTFdtNodePropertyAddStringList(hFdt, "compatible", 2,
414 "qemu,platform", "simple-bus"); VRC();
415 vrc = RTFdtNodeFinalize(hFdt); VRC();
416
417 InsertConfigNode(pDevices, "gic", &pDev);
418 InsertConfigNode(pDev, "0", &pInst);
419 InsertConfigInteger(pInst, "Trusted", 1);
420 InsertConfigNode(pInst, "Config", &pCfg);
421 InsertConfigInteger(pCfg, "DistributorMmioBase", 0x08000000);
422 InsertConfigInteger(pCfg, "RedistributorMmioBase", 0x080a0000);
423
424 vrc = RTFdtNodeAddF(hFdt, "intc@%RX32", 0x08000000); VRC();
425 vrc = RTFdtNodePropertyAddU32( hFdt, "phandle", idPHandleIntCtrl); VRC();
426 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "reg", 8,
427 0, 0x08000000, 0, 0x10000,
428 0, 0x080a0000, 0, 0xf60000); VRC();
429 vrc = RTFdtNodePropertyAddU32( hFdt, "#redistributor-regions", 1); VRC();
430 vrc = RTFdtNodePropertyAddString( hFdt, "compatible", "arm,gic-v3"); VRC();
431 vrc = RTFdtNodePropertyAddEmpty( hFdt, "ranges"); VRC();
432 vrc = RTFdtNodePropertyAddU32( hFdt, "#size-cells", 2); VRC();
433 vrc = RTFdtNodePropertyAddU32( hFdt, "#address-cells", 2); VRC();
434 vrc = RTFdtNodePropertyAddEmpty( hFdt, "interrupt-controller"); VRC();
435 vrc = RTFdtNodePropertyAddU32( hFdt, "#interrupt-cells", 3); VRC();
436
437#if 0
438 vrc = RTFdtNodeAddF(hFdt, "its@%RX32", 0x08080000); VRC();
439 vrc = RTFdtNodePropertyAddU32( hFdt, "phandle", idPHandleIntCtrlMsi); VRC();
440 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "reg", 4, 0, 0x08080000, 0, 0x20000); VRC();
441 vrc = RTFdtNodePropertyAddU32( hFdt, "#msi-cells", 1); VRC();
442 vrc = RTFdtNodePropertyAddEmpty( hFdt, "msi-controller"); VRC();
443 vrc = RTFdtNodePropertyAddString( hFdt, "compatible", "arm,gic-v3-its"); VRC();
444 vrc = RTFdtNodeFinalize(hFdt); VRC();
445#endif
446
447 vrc = RTFdtNodeFinalize(hFdt); VRC();
448
449
450 InsertConfigNode(pDevices, "qemu-fw-cfg", &pDev);
451 InsertConfigNode(pDev, "0", &pInst);
452 InsertConfigNode(pInst, "Config", &pCfg);
453 InsertConfigInteger(pCfg, "MmioSize", 4096);
454 InsertConfigInteger(pCfg, "MmioBase", 0x09020000);
455 InsertConfigInteger(pCfg, "DmaEnabled", 1);
456 InsertConfigInteger(pCfg, "QemuRamfbSupport", 1);
457 InsertConfigNode(pInst, "LUN#0", &pLunL0);
458 InsertConfigString(pLunL0, "Driver", "MainDisplay");
459
460 vrc = RTFdtNodeAddF(hFdt, "fw-cfg@%RX32", 0x09020000); VRC();
461 vrc = RTFdtNodePropertyAddEmpty( hFdt, "dma-coherent"); VRC();
462 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "reg", 4, 0, 0x09020000, 0, 0x18); VRC();
463 vrc = RTFdtNodePropertyAddString( hFdt, "compatible", "qemu,fw-cfg-mmio"); VRC();
464 vrc = RTFdtNodeFinalize(hFdt); VRC();
465
466
467 InsertConfigNode(pDevices, "flash-cfi", &pDev);
468 InsertConfigNode(pDev, "0", &pInst);
469 InsertConfigNode(pInst, "Config", &pCfg);
470 InsertConfigInteger(pCfg, "BaseAddress", 64 * _1M);
471 InsertConfigInteger(pCfg, "Size", 768 * _1K);
472 InsertConfigString(pCfg, "FlashFile", "nvram");
473 /* Attach the NVRAM storage driver. */
474 InsertConfigNode(pInst, "LUN#0", &pLunL0);
475 InsertConfigString(pLunL0, "Driver", "NvramStore");
476
477 vrc = RTFdtNodeAddF(hFdt, "flash@%RX32", 0); VRC();
478 vrc = RTFdtNodePropertyAddU32( hFdt, "bank-width", 4); VRC();
479 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "reg", 8,
480 0, 0, 0, 0x04000000,
481 0, 0x04000000, 0, 0x04000000); VRC();
482 vrc = RTFdtNodePropertyAddString( hFdt, "compatible", "cfi-flash"); VRC();
483 vrc = RTFdtNodeFinalize(hFdt); VRC();
484
485 InsertConfigNode(pDevices, "arm-pl011", &pDev);
486 for (ULONG ulInstance = 0; ulInstance < 1 /** @todo SchemaDefs::SerialPortCount*/; ++ulInstance)
487 {
488 ComPtr<ISerialPort> serialPort;
489 hrc = pMachine->GetSerialPort(ulInstance, serialPort.asOutParam()); H();
490 BOOL fEnabledSerPort = FALSE;
491 if (serialPort)
492 {
493 hrc = serialPort->COMGETTER(Enabled)(&fEnabledSerPort); H();
494 }
495 if (!fEnabledSerPort)
496 {
497 m_aeSerialPortMode[ulInstance] = PortMode_Disconnected;
498 continue;
499 }
500
501 InsertConfigNode(pDev, Utf8StrFmt("%u", ulInstance).c_str(), &pInst);
502 InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
503 InsertConfigNode(pInst, "Config", &pCfg);
504
505 InsertConfigInteger(pCfg, "Irq", 1);
506 InsertConfigInteger(pCfg, "MmioBase", 0x09000000);
507
508 BOOL fServer;
509 hrc = serialPort->COMGETTER(Server)(&fServer); H();
510 hrc = serialPort->COMGETTER(Path)(bstr.asOutParam()); H();
511
512 PortMode_T eHostMode;
513 hrc = serialPort->COMGETTER(HostMode)(&eHostMode); H();
514
515 m_aeSerialPortMode[ulInstance] = eHostMode;
516 if (eHostMode != PortMode_Disconnected)
517 {
518 vrc = i_configSerialPort(pInst, eHostMode, Utf8Str(bstr).c_str(), RT_BOOL(fServer));
519 if (RT_FAILURE(vrc))
520 return vrc;
521 }
522 }
523
524 vrc = RTFdtNodeAddF(hFdt, "pl011@%RX32", 0x09000000); VRC();
525 vrc = RTFdtNodePropertyAddStringList(hFdt, "clock-names", 2, "uartclk", "apb_pclk"); VRC();
526 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "clocks", 2,
527 idPHandleAbpPClk, idPHandleAbpPClk); VRC();
528 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "interrupts", 3, 0x00, 0x01, 0x04); VRC();
529 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "reg", 4, 0, 0x09000000, 0, 0x1000); VRC();
530 vrc = RTFdtNodePropertyAddStringList(hFdt, "compatible", 2,
531 "arm,pl011", "arm,primecell"); VRC();
532 vrc = RTFdtNodeFinalize(hFdt); VRC();
533
534 InsertConfigNode(pDevices, "arm-pl031-rtc", &pDev);
535 InsertConfigNode(pDev, "0", &pInst);
536 InsertConfigNode(pInst, "Config", &pCfg);
537 InsertConfigInteger(pCfg, "Irq", 2);
538 InsertConfigInteger(pCfg, "MmioBase", 0x09010000);
539 vrc = RTFdtNodeAddF(hFdt, "pl032@%RX32", 0x09010000); VRC();
540 vrc = RTFdtNodePropertyAddString( hFdt, "clock-names", "apb_pclk"); VRC();
541 vrc = RTFdtNodePropertyAddU32( hFdt, "clocks", idPHandleAbpPClk); VRC();
542 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "interrupts", 3, 0x00, 0x02, 0x04); VRC();
543 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "reg", 4, 0, 0x09010000, 0, 0x1000); VRC();
544 vrc = RTFdtNodePropertyAddStringList(hFdt, "compatible", 2,
545 "arm,pl031", "arm,primecell"); VRC();
546 vrc = RTFdtNodeFinalize(hFdt); VRC();
547
548 InsertConfigNode(pDevices, "arm-pl061-gpio",&pDev);
549 InsertConfigNode(pDev, "0", &pInst);
550 InsertConfigNode(pInst, "Config", &pCfg);
551 InsertConfigInteger(pCfg, "Irq", 7);
552 InsertConfigInteger(pCfg, "MmioBase", 0x09030000);
553 vrc = RTFdtNodeAddF(hFdt, "pl061@%RX32", 0x09030000); VRC();
554 vrc = RTFdtNodePropertyAddU32( hFdt, "phandle", idPHandleGpio); VRC();
555 vrc = RTFdtNodePropertyAddString( hFdt, "clock-names", "apb_pclk"); VRC();
556 vrc = RTFdtNodePropertyAddU32( hFdt, "clocks", idPHandleAbpPClk); VRC();
557 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "interrupts", 3, 0x00, 0x07, 0x04); VRC();
558 vrc = RTFdtNodePropertyAddEmpty( hFdt, "gpio-controller"); VRC();
559 vrc = RTFdtNodePropertyAddU32( hFdt, "#gpio-cells", 2); VRC();
560 vrc = RTFdtNodePropertyAddStringList(hFdt, "compatible", 2,
561 "arm,pl061", "arm,primecell"); VRC();
562 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "reg", 4, 0, 0x09030000, 0, 0x1000); VRC();
563 vrc = RTFdtNodeFinalize(hFdt); VRC();
564
565 InsertConfigNode(pDevices, "pci-generic-ecam", &pDev);
566 InsertConfigNode(pDev, "0", &pInst);
567 InsertConfigNode(pInst, "Config", &pCfg);
568 InsertConfigInteger(pCfg, "MmioEcamBase", 0x3f000000);
569 InsertConfigInteger(pCfg, "MmioEcamLength", 0x01000000);
570 InsertConfigInteger(pCfg, "MmioPioBase", 0x3eff0000);
571 InsertConfigInteger(pCfg, "MmioPioSize", 0x0000ffff);
572 InsertConfigInteger(pCfg, "IntPinA", 3);
573 InsertConfigInteger(pCfg, "IntPinB", 4);
574 InsertConfigInteger(pCfg, "IntPinC", 5);
575 InsertConfigInteger(pCfg, "IntPinD", 6);
576 vrc = RTFdtNodeAddF(hFdt, "pcie@%RX32", 0x10000000); VRC();
577 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "interrupt-map-mask", 4, 0x1800, 0, 0, 7); VRC();
578 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "interrupt-map", 16 * 10,
579 0x00, 0x00, 0x00, 0x01, idPHandleIntCtrl, 0x00, 0x00, 0x00, 0x03, 0x04,
580 0x00, 0x00, 0x00, 0x02, idPHandleIntCtrl, 0x00, 0x00, 0x00, 0x04, 0x04,
581 0x00, 0x00, 0x00, 0x03, idPHandleIntCtrl, 0x00, 0x00, 0x00, 0x05, 0x04,
582 0x00, 0x00, 0x00, 0x04, idPHandleIntCtrl, 0x00, 0x00, 0x00, 0x06, 0x04,
583 0x800, 0x00, 0x00, 0x01, idPHandleIntCtrl, 0x00, 0x00, 0x00, 0x04, 0x04,
584 0x800, 0x00, 0x00, 0x02, idPHandleIntCtrl, 0x00, 0x00, 0x00, 0x05, 0x04,
585 0x800, 0x00, 0x00, 0x03, idPHandleIntCtrl, 0x00, 0x00, 0x00, 0x06, 0x04,
586 0x800, 0x00, 0x00, 0x04, idPHandleIntCtrl, 0x00, 0x00, 0x00, 0x03, 0x04,
587 0x1000, 0x00, 0x00, 0x01, idPHandleIntCtrl, 0x00, 0x00, 0x00, 0x05, 0x04,
588 0x1000, 0x00, 0x00, 0x02, idPHandleIntCtrl, 0x00, 0x00, 0x00, 0x06, 0x04,
589 0x1000, 0x00, 0x00, 0x03, idPHandleIntCtrl, 0x00, 0x00, 0x00, 0x03, 0x04,
590 0x1000, 0x00, 0x00, 0x04, idPHandleIntCtrl, 0x00, 0x00, 0x00, 0x04, 0x04,
591 0x1800, 0x00, 0x00, 0x01, idPHandleIntCtrl, 0x00, 0x00, 0x00, 0x06, 0x04,
592 0x1800, 0x00, 0x00, 0x02, idPHandleIntCtrl, 0x00, 0x00, 0x00, 0x03, 0x04,
593 0x1800, 0x00, 0x00, 0x03, idPHandleIntCtrl, 0x00, 0x00, 0x00, 0x04, 0x04,
594 0x1800, 0x00, 0x00, 0x04, idPHandleIntCtrl, 0x00, 0x00, 0x00, 0x05, 0x04); VRC();
595 vrc = RTFdtNodePropertyAddU32( hFdt, "#interrupt-cells", 1); VRC();
596 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "ranges", 14,
597 0x1000000, 0, 0, 0, 0x3eff0000, 0, 0x10000,
598 0x2000000, 0, 0x10000000, 0, 0x10000000, 0,
599 0x2eff0000); VRC();
600 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "reg", 4, 0, 0x3f000000, 0, 0x1000000); VRC();
601 /** @todo msi-map */
602 vrc = RTFdtNodePropertyAddEmpty( hFdt, "dma-coherent"); VRC();
603 vrc = RTFdtNodePropertyAddCellsU32(hFdt, "bus-range", 2, 0, 0xf); VRC();
604 vrc = RTFdtNodePropertyAddU32( hFdt, "linux,pci-domain", 0); VRC();
605 vrc = RTFdtNodePropertyAddU32( hFdt, "#size-cells", 2); VRC();
606 vrc = RTFdtNodePropertyAddU32( hFdt, "#address-cells", 3); VRC();
607 vrc = RTFdtNodePropertyAddString( hFdt, "device_type", "pci"); VRC();
608 vrc = RTFdtNodePropertyAddString( hFdt, "compatible", "pci-host-ecam-generic"); VRC();
609 vrc = RTFdtNodeFinalize(hFdt); VRC();
610
611 InsertConfigNode(pDevices, "usb-xhci", &pDev);
612 InsertConfigNode(pDev, "0", &pInst);
613 InsertConfigInteger(pInst, "Trusted", 1);
614 InsertConfigInteger(pInst, "PCIBusNo", 0);
615 InsertConfigInteger(pInst, "PCIDeviceNo", 2);
616 InsertConfigInteger(pInst, "PCIFunctionNo", 0);
617 InsertConfigNode(pInst, "Config", &pCfg);
618 InsertConfigNode(pInst, "LUN#0", &pLunL0);
619 InsertConfigString(pLunL0, "Driver","VUSBRootHub");
620 InsertConfigNode(pInst, "LUN#1", &pLunL0);
621 InsertConfigString(pLunL0, "Driver","VUSBRootHub");
622
623 InsertConfigNode(pDevices, "e1000", &pDev);
624 InsertConfigNode(pDev, "0", &pInst);
625 InsertConfigInteger(pInst, "Trusted", 1);
626 InsertConfigInteger(pInst, "PCIBusNo", 0);
627 InsertConfigInteger(pInst, "PCIDeviceNo", 1);
628 InsertConfigInteger(pInst, "PCIFunctionNo", 0);
629 InsertConfigNode(pInst, "Config", &pCfg);
630 InsertConfigInteger(pCfg, "CableConnected", 1);
631 InsertConfigInteger(pCfg, "LineSpeed", 0);
632 InsertConfigInteger(pCfg, "AdapterType", 0);
633
634 const char *pszMac = "080027ede92c";
635 Assert(strlen(pszMac) == 12);
636 RTMAC Mac;
637 RT_ZERO(Mac);
638 char *pMac = (char*)&Mac;
639 for (uint32_t i = 0; i < 6; ++i)
640 {
641 int c1 = *pszMac++ - '0';
642 if (c1 > 9)
643 c1 -= 7;
644 int c2 = *pszMac++ - '0';
645 if (c2 > 9)
646 c2 -= 7;
647 *pMac++ = (char)(((c1 & 0x0f) << 4) | (c2 & 0x0f));
648 }
649 InsertConfigBytes(pCfg, "MAC", &Mac, sizeof(Mac));
650 InsertConfigNode(pInst, "LUN#0", &pLunL0);
651 InsertConfigString(pLunL0, "Driver", "NAT");
652 InsertConfigNode(pLunL0, "Config", &pLunL1Cfg);
653 InsertConfigString(pLunL1Cfg, "Network", "10.0.2.0/24");
654 InsertConfigString(pLunL1Cfg, "TFTPPrefix", "/Users/vbox/Library/VirtualBox/TFTP");
655 InsertConfigString(pLunL1Cfg, "BootFile", "default.pxe");
656 InsertConfigInteger(pLunL1Cfg, "AliasMode", 0);
657 InsertConfigInteger(pLunL1Cfg, "DNSProxy", 0);
658 InsertConfigInteger(pLunL1Cfg, "LocalhostReachable", 1);
659 InsertConfigInteger(pLunL1Cfg, "PassDomain", 1);
660 InsertConfigInteger(pLunL1Cfg, "UseHostResolver", 0);
661
662 PCFGMNODE pUsb = NULL;
663 InsertConfigNode(pRoot, "USB", &pUsb);
664
665 /*
666 * Storage controllers.
667 */
668 com::SafeIfaceArray<IStorageController> ctrls;
669 PCFGMNODE aCtrlNodes[StorageControllerType_VirtioSCSI + 1] = {};
670 hrc = pMachine->COMGETTER(StorageControllers)(ComSafeArrayAsOutParam(ctrls)); H();
671
672 for (size_t i = 0; i < ctrls.size(); ++i)
673 {
674 DeviceType_T *paLedDevType = NULL;
675
676 StorageControllerType_T enmCtrlType;
677 hrc = ctrls[i]->COMGETTER(ControllerType)(&enmCtrlType); H();
678 AssertRelease((unsigned)enmCtrlType < RT_ELEMENTS(aCtrlNodes)
679 || enmCtrlType == StorageControllerType_USB);
680
681 StorageBus_T enmBus;
682 hrc = ctrls[i]->COMGETTER(Bus)(&enmBus); H();
683
684 Bstr controllerName;
685 hrc = ctrls[i]->COMGETTER(Name)(controllerName.asOutParam()); H();
686
687 ULONG ulInstance = 999;
688 hrc = ctrls[i]->COMGETTER(Instance)(&ulInstance); H();
689
690 BOOL fUseHostIOCache;
691 hrc = ctrls[i]->COMGETTER(UseHostIOCache)(&fUseHostIOCache); H();
692
693 BOOL fBootable;
694 hrc = ctrls[i]->COMGETTER(Bootable)(&fBootable); H();
695
696 PCFGMNODE pCtlInst = NULL;
697 const char *pszCtrlDev = i_storageControllerTypeToStr(enmCtrlType);
698 if (enmCtrlType != StorageControllerType_USB)
699 {
700 /* /Devices/<ctrldev>/ */
701 pDev = aCtrlNodes[enmCtrlType];
702 if (!pDev)
703 {
704 InsertConfigNode(pDevices, pszCtrlDev, &pDev);
705 aCtrlNodes[enmCtrlType] = pDev; /* IDE variants are handled in the switch */
706 }
707
708 /* /Devices/<ctrldev>/<instance>/ */
709 InsertConfigNode(pDev, Utf8StrFmt("%u", ulInstance).c_str(), &pCtlInst);
710
711 /* Device config: /Devices/<ctrldev>/<instance>/<values> & /ditto/Config/<values> */
712 InsertConfigInteger(pCtlInst, "Trusted", 1);
713 InsertConfigNode(pCtlInst, "Config", &pCfg);
714 }
715
716 switch (enmCtrlType)
717 {
718 case StorageControllerType_USB:
719 {
720 if (pUsb)
721 {
722 /*
723 * USB MSDs are handled a bit different as the device instance
724 * doesn't match the storage controller instance but the port.
725 */
726 InsertConfigNode(pUsb, "Msd", &pDev);
727 pCtlInst = pDev;
728 }
729 else
730 return pVMM->pfnVMR3SetError(pUVM, VERR_NOT_FOUND, RT_SRC_POS,
731 N_("There is no USB controller enabled but there\n"
732 "is at least one USB storage device configured for this VM.\n"
733 "To fix this problem either enable the USB controller or remove\n"
734 "the storage device from the VM"));
735 break;
736 }
737
738 case StorageControllerType_IntelAhci:
739 {
740 InsertConfigInteger(pCtlInst, "PCIBusNo", 0);
741 InsertConfigInteger(pCtlInst, "PCIDeviceNo", 3);
742 InsertConfigInteger(pCtlInst, "PCIFunctionNo", 0);
743
744 ULONG cPorts = 0;
745 hrc = ctrls[i]->COMGETTER(PortCount)(&cPorts); H();
746 InsertConfigInteger(pCfg, "PortCount", cPorts);
747 InsertConfigInteger(pCfg, "Bootable", fBootable);
748
749 com::SafeIfaceArray<IMediumAttachment> atts;
750 hrc = pMachine->GetMediumAttachmentsOfController(controllerName.raw(),
751 ComSafeArrayAsOutParam(atts)); H();
752
753 /* Configure the hotpluggable flag for the port. */
754 for (unsigned idxAtt = 0; idxAtt < atts.size(); ++idxAtt)
755 {
756 IMediumAttachment *pMediumAtt = atts[idxAtt];
757
758 LONG lPortNum = 0;
759 hrc = pMediumAtt->COMGETTER(Port)(&lPortNum); H();
760
761 BOOL fHotPluggable = FALSE;
762 hrc = pMediumAtt->COMGETTER(HotPluggable)(&fHotPluggable); H();
763 if (SUCCEEDED(hrc))
764 {
765 PCFGMNODE pPortCfg;
766 char szName[24];
767 RTStrPrintf(szName, sizeof(szName), "Port%d", lPortNum);
768
769 InsertConfigNode(pCfg, szName, &pPortCfg);
770 InsertConfigInteger(pPortCfg, "Hotpluggable", fHotPluggable ? 1 : 0);
771 }
772 }
773 break;
774 }
775 case StorageControllerType_VirtioSCSI:
776 {
777 InsertConfigInteger(pCtlInst, "PCIBusNo", 0);
778 InsertConfigInteger(pCtlInst, "PCIDeviceNo", 3);
779 InsertConfigInteger(pCtlInst, "PCIFunctionNo", 0);
780
781 ULONG cPorts = 0;
782 hrc = ctrls[i]->COMGETTER(PortCount)(&cPorts); H();
783 InsertConfigInteger(pCfg, "NumTargets", cPorts);
784 InsertConfigInteger(pCfg, "Bootable", fBootable);
785
786 /* Attach the status driver */
787 i_attachStatusDriver(pCtlInst, RT_BIT_32(DeviceType_HardDisk) | RT_BIT_32(DeviceType_DVD) /*?*/,
788 cPorts, &paLedDevType, &mapMediumAttachments, pszCtrlDev, ulInstance);
789 break;
790 }
791
792 case StorageControllerType_LsiLogic:
793 case StorageControllerType_BusLogic:
794 case StorageControllerType_PIIX3:
795 case StorageControllerType_PIIX4:
796 case StorageControllerType_ICH6:
797 case StorageControllerType_I82078:
798 case StorageControllerType_LsiLogicSas:
799 case StorageControllerType_NVMe:
800
801 default:
802 AssertLogRelMsgFailedReturn(("invalid storage controller type: %d\n", enmCtrlType), VERR_MAIN_CONFIG_CONSTRUCTOR_IPE);
803 }
804
805 /* Attach the media to the storage controllers. */
806 com::SafeIfaceArray<IMediumAttachment> atts;
807 hrc = pMachine->GetMediumAttachmentsOfController(controllerName.raw(),
808 ComSafeArrayAsOutParam(atts)); H();
809
810 /* Builtin I/O cache - per device setting. */
811 BOOL fBuiltinIOCache = true;
812 hrc = pMachine->COMGETTER(IOCacheEnabled)(&fBuiltinIOCache); H();
813
814 bool fInsertDiskIntegrityDrv = false;
815 Bstr strDiskIntegrityFlag;
816 hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/EnableDiskIntegrityDriver").raw(),
817 strDiskIntegrityFlag.asOutParam());
818 if ( hrc == S_OK
819 && strDiskIntegrityFlag == "1")
820 fInsertDiskIntegrityDrv = true;
821
822 for (size_t j = 0; j < atts.size(); ++j)
823 {
824 IMediumAttachment *pMediumAtt = atts[j];
825 vrc = i_configMediumAttachment(pszCtrlDev,
826 ulInstance,
827 enmBus,
828 !!fUseHostIOCache,
829 enmCtrlType == StorageControllerType_NVMe ? false : !!fBuiltinIOCache,
830 fInsertDiskIntegrityDrv,
831 false /* fSetupMerge */,
832 0 /* uMergeSource */,
833 0 /* uMergeTarget */,
834 pMediumAtt,
835 mMachineState,
836 NULL /* phrc */,
837 false /* fAttachDetach */,
838 false /* fForceUnmount */,
839 false /* fHotplug */,
840 pUVM,
841 pVMM,
842 paLedDevType,
843 NULL /* ppLunL0 */);
844 if (RT_FAILURE(vrc))
845 return vrc;
846 }
847 H();
848 }
849 H();
850
851 InsertConfigNode(pUsb, "HidKeyboard", &pDev);
852 InsertConfigNode(pDev, "0", &pInst);
853 InsertConfigInteger(pInst, "Trusted", 1);
854 InsertConfigNode(pInst, "Config", &pCfg);
855 InsertConfigNode(pInst, "LUN#0", &pLunL0);
856 InsertConfigString(pLunL0, "Driver", "KeyboardQueue");
857 InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
858 InsertConfigString(pLunL1, "Driver", "MainKeyboard");
859
860 InsertConfigNode(pUsb, "HidMouse", &pDev);
861 InsertConfigNode(pDev, "0", &pInst);
862 InsertConfigNode(pInst, "Config", &pCfg);
863 InsertConfigString(pCfg, "Mode", "absolute");
864 InsertConfigNode(pInst, "LUN#0", &pLunL0);
865 InsertConfigString(pLunL0, "Driver", "MouseQueue");
866 InsertConfigNode(pLunL0, "Config", &pCfg);
867 InsertConfigInteger(pCfg, "QueueSize", 128);
868
869 InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
870 InsertConfigString(pLunL1, "Driver", "MainMouse");
871 }
872 catch (ConfigError &x)
873 {
874 RTFdtDestroy(hFdt);
875
876 // InsertConfig threw something:
877 pVMM->pfnVMR3SetError(pUVM, x.m_vrc, RT_SRC_POS, "Caught ConfigError: %Rrc - %s", x.m_vrc, x.what());
878 return x.m_vrc;
879 }
880 catch (HRESULT hrcXcpt)
881 {
882 RTFdtDestroy(hFdt);
883 AssertLogRelMsgFailedReturn(("hrc=%Rhrc\n", hrcXcpt), VERR_MAIN_CONFIG_CONSTRUCTOR_COM_ERROR);
884 }
885
886#ifdef VBOX_WITH_EXTPACK
887 /*
888 * Call the extension pack hooks if everything went well thus far.
889 */
890 if (RT_SUCCESS(vrc))
891 {
892 pAlock->release();
893 vrc = mptrExtPackManager->i_callAllVmConfigureVmmHooks(this, pVM, pVMM);
894 pAlock->acquire();
895 }
896#endif
897
898 /* Finalize the FDT and add it to the resource store. */
899 vrc = RTFdtFinalize(hFdt);
900 AssertRCReturnStmt(vrc, RTFdtDestroy(hFdt), vrc);
901
902 RTVFSFILE hVfsFileFdt = NIL_RTVFSFILE;
903 vrc = RTVfsMemFileCreate(NIL_RTVFSIOSTREAM, 0 /*cbEstimate*/, &hVfsFileFdt);
904 AssertRCReturnStmt(vrc, RTFdtDestroy(hFdt), vrc);
905 RTVFSIOSTREAM hVfsIosFdt = RTVfsFileToIoStream(hVfsFileFdt);
906 AssertRelease(hVfsIosFdt != NIL_RTVFSIOSTREAM);
907
908 vrc = RTFdtDumpToVfsIoStrm(hFdt, RTFDTTYPE_DTB, 0 /*fFlags*/, hVfsIosFdt, NULL /*pErrInfo*/);
909 RTVfsIoStrmRelease(hVfsIosFdt);
910 if (RT_SUCCESS(vrc))
911 vrc = mptrResourceStore->i_addItem("fdt", "fdt", hVfsFileFdt);
912 RTVfsFileRelease(hVfsFileFdt);
913 AssertRCReturnStmt(vrc, RTFdtDestroy(hFdt), vrc);
914
915 /* Dump the DTB for debugging purposes if requested. */
916 Bstr DtbDumpVal;
917 hrc = mMachine->GetExtraData(Bstr("VBoxInternal2/DumpDtb").raw(),
918 DtbDumpVal.asOutParam());
919 if ( hrc == S_OK
920 && DtbDumpVal.isNotEmpty())
921 {
922 vrc = RTFdtDumpToFile(hFdt, RTFDTTYPE_DTB, 0 /*fFlags*/, Utf8Str(DtbDumpVal).c_str(), NULL /*pErrInfo*/);
923 AssertRCReturnStmt(vrc, RTFdtDestroy(hFdt), vrc);
924 }
925
926
927 /*
928 * Apply the CFGM overlay.
929 */
930 if (RT_SUCCESS(vrc))
931 vrc = i_configCfgmOverlay(pRoot, virtualBox, pMachine);
932
933 /*
934 * Dump all extradata API settings tweaks, both global and per VM.
935 */
936 if (RT_SUCCESS(vrc))
937 vrc = i_configDumpAPISettingsTweaks(virtualBox, pMachine);
938
939#undef H
940
941 pAlock->release(); /* Avoid triggering the lock order inversion check. */
942
943 /*
944 * Register VM state change handler.
945 */
946 int vrc2 = pVMM->pfnVMR3AtStateRegister(pUVM, Console::i_vmstateChangeCallback, this);
947 AssertRC(vrc2);
948 if (RT_SUCCESS(vrc))
949 vrc = vrc2;
950
951 /*
952 * Register VM runtime error handler.
953 */
954 vrc2 = pVMM->pfnVMR3AtRuntimeErrorRegister(pUVM, Console::i_atVMRuntimeErrorCallback, this);
955 AssertRC(vrc2);
956 if (RT_SUCCESS(vrc))
957 vrc = vrc2;
958
959 pAlock->acquire();
960
961 LogFlowFunc(("vrc = %Rrc\n", vrc));
962 LogFlowFuncLeave();
963
964 return vrc;
965}
966#endif /* !VBOX_WITH_VIRT_ARMV8 */
967
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