VirtualBox

source: vbox/trunk/src/VBox/Main/src-all/PlatformPropertiesImpl.cpp@ 106624

Last change on this file since 106624 was 106384, checked in by vboxsync, 4 months ago

Main: Code for configuring and enabling nested virtualization support on ARM (M3 based hardware + macOS 15.0 aka Sequioa), bugref:10747

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 40.3 KB
Line 
1/* $Id: PlatformPropertiesImpl.cpp 106384 2024-10-16 13:58:41Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation - Platform properties.
4 */
5
6/*
7 * Copyright (C) 2023-2024 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#define LOG_GROUP LOG_GROUP_MAIN_PLATFORMPROPERTIES
29#include "PlatformPropertiesImpl.h"
30#include "GraphicsAdapterImpl.h" /* For static helper functions. */
31#include "VirtualBoxImpl.h"
32#include "LoggingNew.h"
33#include "Global.h"
34
35#include <algorithm>
36
37#include <iprt/asm.h>
38#include <iprt/cpp/utils.h>
39
40#include <VBox/param.h> /* For VRAM ranges. */
41#include <VBox/settings.h>
42
43// generated header
44#include "SchemaDefs.h"
45
46
47/*
48 * PlatformProperties implementation.
49 */
50PlatformProperties::PlatformProperties()
51 : mParent(NULL)
52 , mPlatformArchitecture(PlatformArchitecture_None)
53 , mfIsHost(false)
54{
55}
56
57PlatformProperties::~PlatformProperties()
58{
59 uninit();
60}
61
62HRESULT PlatformProperties::FinalConstruct()
63{
64 return BaseFinalConstruct();
65}
66
67void PlatformProperties::FinalRelease()
68{
69 uninit();
70
71 BaseFinalRelease();
72}
73
74/**
75 * Initializes platform properties.
76 *
77 * @returns HRESULT
78 * @param aParent Pointer to IVirtualBox parent object (weak).
79 * @param fIsHost Set to \c true if this instance handles platform properties of the host,
80 * or set to \c false for guests (default).
81 */
82HRESULT PlatformProperties::init(VirtualBox *aParent, bool fIsHost /* = false */)
83{
84 /* Enclose the state transition NotReady->InInit->Ready */
85 AutoInitSpan autoInitSpan(this);
86 AssertReturn(autoInitSpan.isOk(), E_FAIL);
87
88 unconst(mParent) = aParent;
89
90 m = new settings::PlatformProperties;
91
92 unconst(mfIsHost) = fIsHost;
93
94 if (mfIsHost)
95 {
96 /* On Windows, macOS and Solaris hosts, HW virtualization use isn't exclusive
97 * by default so that VT-x or AMD-V can be shared with other
98 * hypervisors without requiring user intervention.
99 * NB: See also PlatformProperties constructor in settings.h
100 */
101#if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) || defined(RT_OS_SOLARIS)
102 m->fExclusiveHwVirt = false; /** @todo BUGBUG Applies for MacOS on ARM as well? */
103#else
104 m->fExclusiveHwVirt = true;
105#endif
106 }
107
108 /* Confirm a successful initialization */
109 autoInitSpan.setSucceeded();
110
111 return S_OK;
112}
113
114/**
115 * Sets the platform architecture.
116 *
117 * @returns HRESULT
118 * @param aArchitecture Platform architecture to set.
119 *
120 * @note Usually only called when creating a new machine.
121 */
122HRESULT PlatformProperties::i_setArchitecture(PlatformArchitecture_T aArchitecture)
123{
124 /* sanity */
125 AutoCaller autoCaller(this);
126 AssertComRCReturn(autoCaller.hrc(), autoCaller.hrc());
127
128 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
129
130 mPlatformArchitecture = aArchitecture;
131
132 return S_OK;
133}
134
135/**
136 * Returns the host's platform architecture.
137 *
138 * @returns The host's platform architecture.
139 */
140PlatformArchitecture_T PlatformProperties::s_getHostPlatformArchitecture()
141{
142#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
143 return PlatformArchitecture_x86;
144#elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
145 return PlatformArchitecture_ARM;
146#else
147# error "Port me!"
148 return PlatformArchitecture_None;
149#endif
150}
151
152void PlatformProperties::uninit()
153{
154 /* Enclose the state transition Ready->InUninit->NotReady */
155 AutoUninitSpan autoUninitSpan(this);
156 if (autoUninitSpan.uninitDone())
157 return;
158
159 if (m)
160 {
161 delete m;
162 m = NULL;
163 }
164}
165
166HRESULT PlatformProperties::getSerialPortCount(ULONG *count)
167{
168 /* no need to lock, this is const */
169 *count = SchemaDefs::SerialPortCount;
170
171 return S_OK;
172}
173
174HRESULT PlatformProperties::getParallelPortCount(ULONG *count)
175{
176 /* no need to lock, this is const */
177 *count = SchemaDefs::ParallelPortCount;
178
179 return S_OK;
180}
181
182HRESULT PlatformProperties::getMaxBootPosition(ULONG *aMaxBootPosition)
183{
184 /* no need to lock, this is const */
185 *aMaxBootPosition = SchemaDefs::MaxBootPosition;
186
187 return S_OK;
188}
189
190HRESULT PlatformProperties::getRawModeSupported(BOOL *aRawModeSupported)
191{
192 *aRawModeSupported = FALSE;
193 return S_OK;
194}
195
196HRESULT PlatformProperties::getExclusiveHwVirt(BOOL *aExclusiveHwVirt)
197{
198 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
199
200 *aExclusiveHwVirt = m->fExclusiveHwVirt;
201
202 /* Makes no sense for guest platform properties, but we return FALSE anyway. */
203 return S_OK;
204}
205
206HRESULT PlatformProperties::setExclusiveHwVirt(BOOL aExclusiveHwVirt)
207{
208 /* Only makes sense when running in VBoxSVC, as this is a pure host setting -- ignored within clients. */
209#ifdef IN_VBOXSVC
210 /* No locking required, as mfIsHost is const. */
211 if (!mfIsHost) /* Ignore setting the attribute if not host properties. */
212 return S_OK;
213
214 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
215 m->fExclusiveHwVirt = !!aExclusiveHwVirt;
216 alock.release();
217
218 // VirtualBox::i_saveSettings() needs vbox write lock
219 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
220 return mParent->i_saveSettings();
221#else /* VBoxC */
222 RT_NOREF(aExclusiveHwVirt);
223 return VBOX_E_NOT_SUPPORTED;
224#endif
225}
226
227/* static */
228ULONG PlatformProperties::s_getMaxNetworkAdapters(ChipsetType_T aChipset)
229{
230 AssertReturn(aChipset != ChipsetType_Null, 0);
231
232 /* no need for locking, no state */
233 switch (aChipset)
234 {
235 case ChipsetType_PIIX3: return 8;
236 case ChipsetType_ICH9: return 36;
237 case ChipsetType_ARMv8Virtual: return 64; /** @todo BUGBUG Put a sane value here. Just a wild guess for now. */
238 case ChipsetType_Null:
239 RT_FALL_THROUGH();
240 default:
241 break;
242 }
243
244 AssertMsgFailedReturn(("Chipset type %#x not handled\n", aChipset), 0);
245}
246
247HRESULT PlatformProperties::getMaxNetworkAdapters(ChipsetType_T aChipset, ULONG *aMaxNetworkAdapters)
248{
249 *aMaxNetworkAdapters = PlatformProperties::s_getMaxNetworkAdapters(aChipset);
250
251 return S_OK;
252}
253
254/* static */
255ULONG PlatformProperties::s_getMaxNetworkAdaptersOfType(ChipsetType_T aChipset, NetworkAttachmentType_T aType)
256{
257 /* no need for locking, no state */
258 uint32_t cMaxNetworkAdapters = PlatformProperties::s_getMaxNetworkAdapters(aChipset);
259
260 switch (aType)
261 {
262 case NetworkAttachmentType_NAT:
263 case NetworkAttachmentType_Internal:
264 case NetworkAttachmentType_NATNetwork:
265 /* chipset default is OK */
266 break;
267 case NetworkAttachmentType_Bridged:
268 /* Maybe use current host interface count here? */
269 break;
270 case NetworkAttachmentType_HostOnly:
271 cMaxNetworkAdapters = RT_MIN(cMaxNetworkAdapters, 8);
272 break;
273 default:
274 AssertMsgFailed(("Unhandled attachment type %d\n", aType));
275 }
276
277 return cMaxNetworkAdapters;
278}
279
280HRESULT PlatformProperties::getMaxNetworkAdaptersOfType(ChipsetType_T aChipset, NetworkAttachmentType_T aType,
281 ULONG *aMaxNetworkAdapters)
282{
283 *aMaxNetworkAdapters = PlatformProperties::s_getMaxNetworkAdaptersOfType(aChipset, aType);
284
285 return S_OK;
286}
287
288HRESULT PlatformProperties::getMaxDevicesPerPortForStorageBus(StorageBus_T aBus,
289 ULONG *aMaxDevicesPerPort)
290{
291 /* no need to lock, this is const */
292 switch (aBus)
293 {
294 case StorageBus_SATA:
295 case StorageBus_SCSI:
296 case StorageBus_SAS:
297 case StorageBus_USB:
298 case StorageBus_PCIe:
299 case StorageBus_VirtioSCSI:
300 {
301 /* SATA and both SCSI controllers only support one device per port. */
302 *aMaxDevicesPerPort = 1;
303 break;
304 }
305 case StorageBus_IDE:
306 case StorageBus_Floppy:
307 {
308 /* The IDE and Floppy controllers support 2 devices. One as master
309 * and one as slave (or floppy drive 0 and 1). */
310 *aMaxDevicesPerPort = 2;
311 break;
312 }
313 default:
314 AssertMsgFailed(("Invalid bus type %d\n", aBus));
315 }
316
317 return S_OK;
318}
319
320HRESULT PlatformProperties::getMinPortCountForStorageBus(StorageBus_T aBus,
321 ULONG *aMinPortCount)
322{
323 /* no need to lock, this is const */
324 switch (aBus)
325 {
326 case StorageBus_SATA:
327 case StorageBus_SAS:
328 case StorageBus_PCIe:
329 case StorageBus_VirtioSCSI:
330 {
331 *aMinPortCount = 1;
332 break;
333 }
334 case StorageBus_SCSI:
335 {
336 *aMinPortCount = 16;
337 break;
338 }
339 case StorageBus_IDE:
340 {
341 *aMinPortCount = 2;
342 break;
343 }
344 case StorageBus_Floppy:
345 {
346 *aMinPortCount = 1;
347 break;
348 }
349 case StorageBus_USB:
350 {
351 *aMinPortCount = 8;
352 break;
353 }
354 default:
355 AssertMsgFailed(("Invalid bus type %d\n", aBus));
356 }
357
358 return S_OK;
359}
360
361HRESULT PlatformProperties::getMaxPortCountForStorageBus(StorageBus_T aBus,
362 ULONG *aMaxPortCount)
363{
364 /* no need to lock, this is const */
365 switch (aBus)
366 {
367 case StorageBus_SATA:
368 {
369 *aMaxPortCount = 30;
370 break;
371 }
372 case StorageBus_SCSI:
373 {
374 *aMaxPortCount = 16;
375 break;
376 }
377 case StorageBus_IDE:
378 {
379 *aMaxPortCount = 2;
380 break;
381 }
382 case StorageBus_Floppy:
383 {
384 *aMaxPortCount = 1;
385 break;
386 }
387 case StorageBus_SAS:
388 case StorageBus_PCIe:
389 {
390 *aMaxPortCount = 255;
391 break;
392 }
393 case StorageBus_USB:
394 {
395 *aMaxPortCount = 8;
396 break;
397 }
398 case StorageBus_VirtioSCSI:
399 {
400 *aMaxPortCount = 256;
401 break;
402 }
403 default:
404 AssertMsgFailed(("Invalid bus type %d\n", aBus));
405 }
406
407 return S_OK;
408}
409
410HRESULT PlatformProperties::getMaxInstancesOfStorageBus(ChipsetType_T aChipset,
411 StorageBus_T aBus,
412 ULONG *aMaxInstances)
413{
414 ULONG cCtrs = 0;
415
416 /* no need to lock, this is const */
417 switch (aBus)
418 {
419 case StorageBus_SATA:
420 case StorageBus_SCSI:
421 case StorageBus_SAS:
422 case StorageBus_PCIe:
423 case StorageBus_VirtioSCSI:
424 cCtrs = aChipset == ChipsetType_ICH9 || aChipset == ChipsetType_ARMv8Virtual ? 8 : 1;
425 break;
426 case StorageBus_USB:
427 case StorageBus_IDE:
428 case StorageBus_Floppy:
429 {
430 cCtrs = 1;
431 break;
432 }
433 default:
434 AssertMsgFailed(("Invalid bus type %d\n", aBus));
435 }
436
437 *aMaxInstances = cCtrs;
438
439 return S_OK;
440}
441
442HRESULT PlatformProperties::getDeviceTypesForStorageBus(StorageBus_T aBus,
443 std::vector<DeviceType_T> &aDeviceTypes)
444{
445 aDeviceTypes.resize(0);
446
447 /* no need to lock, this is const */
448 switch (aBus)
449 {
450 case StorageBus_IDE:
451 case StorageBus_SATA:
452 case StorageBus_SCSI:
453 case StorageBus_SAS:
454 case StorageBus_USB:
455 case StorageBus_VirtioSCSI:
456 {
457 aDeviceTypes.resize(2);
458 aDeviceTypes[0] = DeviceType_DVD;
459 aDeviceTypes[1] = DeviceType_HardDisk;
460 break;
461 }
462 case StorageBus_Floppy:
463 {
464 aDeviceTypes.resize(1);
465 aDeviceTypes[0] = DeviceType_Floppy;
466 break;
467 }
468 case StorageBus_PCIe:
469 {
470 aDeviceTypes.resize(1);
471 aDeviceTypes[0] = DeviceType_HardDisk;
472 break;
473 }
474 default:
475 AssertMsgFailed(("Invalid bus type %d\n", aBus));
476 }
477
478 return S_OK;
479}
480
481HRESULT PlatformProperties::getStorageBusForControllerType(StorageControllerType_T aStorageControllerType,
482 StorageBus_T *aStorageBus)
483{
484 /* no need to lock, this is const */
485 switch (aStorageControllerType)
486 {
487 case StorageControllerType_LsiLogic:
488 case StorageControllerType_BusLogic:
489 *aStorageBus = StorageBus_SCSI;
490 break;
491 case StorageControllerType_IntelAhci:
492 *aStorageBus = StorageBus_SATA;
493 break;
494 case StorageControllerType_PIIX3:
495 case StorageControllerType_PIIX4:
496 case StorageControllerType_ICH6:
497 *aStorageBus = StorageBus_IDE;
498 break;
499 case StorageControllerType_I82078:
500 *aStorageBus = StorageBus_Floppy;
501 break;
502 case StorageControllerType_LsiLogicSas:
503 *aStorageBus = StorageBus_SAS;
504 break;
505 case StorageControllerType_USB:
506 *aStorageBus = StorageBus_USB;
507 break;
508 case StorageControllerType_NVMe:
509 *aStorageBus = StorageBus_PCIe;
510 break;
511 case StorageControllerType_VirtioSCSI:
512 *aStorageBus = StorageBus_VirtioSCSI;
513 break;
514 default:
515 return setError(E_FAIL, tr("Invalid storage controller type %d\n"), aStorageBus);
516 }
517
518 return S_OK;
519}
520
521HRESULT PlatformProperties::getStorageControllerTypesForBus(StorageBus_T aStorageBus,
522 std::vector<StorageControllerType_T> &aStorageControllerTypes)
523{
524 aStorageControllerTypes.resize(0);
525
526 /* no need to lock, this is const */
527 switch (aStorageBus)
528 {
529 case StorageBus_IDE:
530 aStorageControllerTypes.resize(3);
531 aStorageControllerTypes[0] = StorageControllerType_PIIX4;
532 aStorageControllerTypes[1] = StorageControllerType_PIIX3;
533 aStorageControllerTypes[2] = StorageControllerType_ICH6;
534 break;
535 case StorageBus_SATA:
536 aStorageControllerTypes.resize(1);
537 aStorageControllerTypes[0] = StorageControllerType_IntelAhci;
538 break;
539 case StorageBus_SCSI:
540 aStorageControllerTypes.resize(2);
541 aStorageControllerTypes[0] = StorageControllerType_LsiLogic;
542 aStorageControllerTypes[1] = StorageControllerType_BusLogic;
543 break;
544 case StorageBus_Floppy:
545 aStorageControllerTypes.resize(1);
546 aStorageControllerTypes[0] = StorageControllerType_I82078;
547 break;
548 case StorageBus_SAS:
549 aStorageControllerTypes.resize(1);
550 aStorageControllerTypes[0] = StorageControllerType_LsiLogicSas;
551 break;
552 case StorageBus_USB:
553 aStorageControllerTypes.resize(1);
554 aStorageControllerTypes[0] = StorageControllerType_USB;
555 break;
556 case StorageBus_PCIe:
557 aStorageControllerTypes.resize(1);
558 aStorageControllerTypes[0] = StorageControllerType_NVMe;
559 break;
560 case StorageBus_VirtioSCSI:
561 aStorageControllerTypes.resize(1);
562 aStorageControllerTypes[0] = StorageControllerType_VirtioSCSI;
563 break;
564 default:
565 return setError(E_FAIL, tr("Invalid storage bus %d\n"), aStorageBus);
566 }
567
568 return S_OK;
569}
570
571HRESULT PlatformProperties::getStorageControllerHotplugCapable(StorageControllerType_T aControllerType,
572 BOOL *aHotplugCapable)
573{
574 switch (aControllerType)
575 {
576 case StorageControllerType_IntelAhci:
577 case StorageControllerType_USB:
578 *aHotplugCapable = true;
579 break;
580 case StorageControllerType_LsiLogic:
581 case StorageControllerType_LsiLogicSas:
582 case StorageControllerType_BusLogic:
583 case StorageControllerType_NVMe:
584 case StorageControllerType_VirtioSCSI:
585 case StorageControllerType_PIIX3:
586 case StorageControllerType_PIIX4:
587 case StorageControllerType_ICH6:
588 case StorageControllerType_I82078:
589 *aHotplugCapable = false;
590 break;
591 default:
592 AssertMsgFailedReturn(("Invalid controller type %d\n", aControllerType), E_FAIL);
593 }
594
595 return S_OK;
596}
597
598HRESULT PlatformProperties::getMaxInstancesOfUSBControllerType(ChipsetType_T aChipset,
599 USBControllerType_T aType,
600 ULONG *aMaxInstances)
601{
602 NOREF(aChipset);
603 ULONG cCtrs = 0;
604
605 /* no need to lock, this is const */
606 switch (aType)
607 {
608 case USBControllerType_OHCI:
609 case USBControllerType_EHCI:
610 case USBControllerType_XHCI:
611 {
612 cCtrs = 1;
613 break;
614 }
615 default:
616 AssertMsgFailed(("Invalid bus type %d\n", aType));
617 }
618
619 *aMaxInstances = cCtrs;
620
621 return S_OK;
622}
623
624HRESULT PlatformProperties::getSupportedParavirtProviders(std::vector<ParavirtProvider_T> &aSupportedParavirtProviders)
625{
626 static const ParavirtProvider_T aParavirtProviders[] =
627 {
628 ParavirtProvider_None,
629 ParavirtProvider_Default,
630 ParavirtProvider_Legacy,
631 ParavirtProvider_Minimal,
632 ParavirtProvider_HyperV,
633 ParavirtProvider_KVM,
634 };
635 aSupportedParavirtProviders.assign(aParavirtProviders,
636 aParavirtProviders + RT_ELEMENTS(aParavirtProviders));
637 return S_OK;
638}
639
640HRESULT PlatformProperties::getSupportedFirmwareTypes(std::vector<FirmwareType_T> &aSupportedFirmwareTypes)
641{
642 switch (mPlatformArchitecture)
643 {
644 case PlatformArchitecture_x86:
645 {
646 static const FirmwareType_T aFirmwareTypes[] =
647 {
648 FirmwareType_BIOS,
649 FirmwareType_EFI,
650 FirmwareType_EFI32,
651 FirmwareType_EFI64,
652 FirmwareType_EFIDUAL
653 };
654 aSupportedFirmwareTypes.assign(aFirmwareTypes,
655 aFirmwareTypes + RT_ELEMENTS(aFirmwareTypes));
656 break;
657 }
658
659 case PlatformArchitecture_ARM:
660 {
661 static const FirmwareType_T aFirmwareTypes[] =
662 {
663 FirmwareType_EFI,
664 FirmwareType_EFI32,
665 FirmwareType_EFI64,
666 FirmwareType_EFIDUAL
667 };
668 aSupportedFirmwareTypes.assign(aFirmwareTypes,
669 aFirmwareTypes + RT_ELEMENTS(aFirmwareTypes));
670 break;
671 }
672
673 default:
674 AssertFailedStmt(aSupportedFirmwareTypes.clear());
675 break;
676 }
677
678 return S_OK;
679}
680
681HRESULT PlatformProperties::getSupportedGfxControllerTypes(std::vector<GraphicsControllerType_T> &aSupportedGraphicsControllerTypes)
682{
683 switch (mPlatformArchitecture)
684 {
685 case PlatformArchitecture_x86:
686 {
687 static const GraphicsControllerType_T aGraphicsControllerTypes[] =
688 {
689 GraphicsControllerType_Null,
690 GraphicsControllerType_VBoxVGA,
691 GraphicsControllerType_VBoxSVGA
692#ifdef VBOX_WITH_VMSVGA
693 , GraphicsControllerType_VMSVGA
694#endif
695 };
696 aSupportedGraphicsControllerTypes.assign(aGraphicsControllerTypes + 1 /* Don't include _Null */,
697 aGraphicsControllerTypes + RT_ELEMENTS(aGraphicsControllerTypes));
698 break;
699 }
700
701 case PlatformArchitecture_ARM:
702 {
703 static const GraphicsControllerType_T aGraphicsControllerTypes[] =
704 {
705 GraphicsControllerType_Null,
706 GraphicsControllerType_QemuRamFB
707#ifdef VBOX_WITH_VMSVGA
708 , GraphicsControllerType_VMSVGA
709#endif
710 };
711 aSupportedGraphicsControllerTypes.assign(aGraphicsControllerTypes + 1 /* Don't include _Null */,
712 aGraphicsControllerTypes + RT_ELEMENTS(aGraphicsControllerTypes));
713 break;
714 }
715
716 default:
717 AssertFailedStmt(aSupportedGraphicsControllerTypes.clear());
718 break;
719 }
720
721 return S_OK;
722}
723
724HRESULT PlatformProperties::getSupportedGuestOSTypes(std::vector<ComPtr<IGuestOSType> > &aSupportedGuestOSTypes)
725{
726 /* We only have all supported guest OS types as part of VBoxSVC, not in VBoxC itself. */
727#ifdef IN_VBOXSVC
728 std::vector<PlatformArchitecture_T> vecArchitectures(1 /* Size */, mPlatformArchitecture);
729 return mParent->i_getSupportedGuestOSTypes(vecArchitectures, aSupportedGuestOSTypes);
730#else /* VBoxC */
731 RT_NOREF(aSupportedGuestOSTypes);
732 return VBOX_E_NOT_SUPPORTED;
733#endif
734}
735
736HRESULT PlatformProperties::getSupportedNetAdpPromiscModePols(std::vector<NetworkAdapterPromiscModePolicy_T> &aSupportedNetworkAdapterPromiscModePolicies)
737{
738 static const NetworkAdapterPromiscModePolicy_T aNetworkAdapterPromiscModePolicies[] =
739 {
740 NetworkAdapterPromiscModePolicy_Deny,
741 NetworkAdapterPromiscModePolicy_AllowNetwork,
742 NetworkAdapterPromiscModePolicy_AllowAll
743 };
744
745 aSupportedNetworkAdapterPromiscModePolicies.assign(aNetworkAdapterPromiscModePolicies,
746 aNetworkAdapterPromiscModePolicies + RT_ELEMENTS(aNetworkAdapterPromiscModePolicies));
747 return S_OK;
748}
749
750HRESULT PlatformProperties::getSupportedNetworkAdapterTypes(std::vector<NetworkAdapterType_T> &aSupportedNetworkAdapterTypes)
751{
752 switch (mPlatformArchitecture)
753 {
754 case PlatformArchitecture_x86:
755 {
756 static const NetworkAdapterType_T aNetworkAdapterTypes[] =
757 {
758 NetworkAdapterType_Null,
759 NetworkAdapterType_Am79C970A,
760 NetworkAdapterType_Am79C973
761#ifdef VBOX_WITH_E1000
762 , NetworkAdapterType_I82540EM
763 , NetworkAdapterType_I82543GC
764 , NetworkAdapterType_I82545EM
765#endif
766#ifdef VBOX_WITH_VIRTIO
767 , NetworkAdapterType_Virtio
768#endif
769 };
770 aSupportedNetworkAdapterTypes.assign(aNetworkAdapterTypes + 1 /* Don't include _Null */,
771 aNetworkAdapterTypes + RT_ELEMENTS(aNetworkAdapterTypes));
772 break;
773 }
774
775 case PlatformArchitecture_ARM:
776 {
777 static const NetworkAdapterType_T aNetworkAdapterTypes[] =
778 {
779 NetworkAdapterType_Null
780#ifdef VBOX_WITH_E1000
781 , NetworkAdapterType_I82540EM
782 , NetworkAdapterType_I82543GC
783 , NetworkAdapterType_I82545EM
784#endif
785#ifdef VBOX_WITH_VIRTIO
786 , NetworkAdapterType_Virtio
787#endif
788 };
789 aSupportedNetworkAdapterTypes.assign(aNetworkAdapterTypes + 1 /* Don't include _Null */,
790 aNetworkAdapterTypes + RT_ELEMENTS(aNetworkAdapterTypes));
791 break;
792 }
793
794 default:
795 AssertFailedStmt(aSupportedNetworkAdapterTypes.clear());
796 break;
797 }
798
799 return S_OK;
800}
801
802HRESULT PlatformProperties::getSupportedUartTypes(std::vector<UartType_T> &aSupportedUartTypes)
803{
804 static const UartType_T aUartTypes[] =
805 {
806 UartType_U16450,
807 UartType_U16550A,
808 UartType_U16750
809 };
810 aSupportedUartTypes.assign(aUartTypes,
811 aUartTypes + RT_ELEMENTS(aUartTypes));
812 return S_OK;
813}
814
815HRESULT PlatformProperties::getSupportedUSBControllerTypes(std::vector<USBControllerType_T> &aSupportedUSBControllerTypes)
816{
817 static const USBControllerType_T aUSBControllerTypes[] =
818 {
819 USBControllerType_OHCI,
820 USBControllerType_EHCI,
821 USBControllerType_XHCI
822 };
823 aSupportedUSBControllerTypes.assign(aUSBControllerTypes,
824 aUSBControllerTypes + RT_ELEMENTS(aUSBControllerTypes));
825 return S_OK;
826}
827
828/**
829 * Static helper function to return all supported features for a given graphics controller.
830 *
831 * @returns VBox status code.
832 * @param enmArchitecture Platform architecture to query a feature for.
833 * @param enmController Graphics controller to return supported features for.
834 * @param vecSupportedGraphicsFeatures Returned features on success.
835 */
836/* static */
837int PlatformProperties::s_getSupportedGraphicsControllerFeatures(PlatformArchitecture_T enmArchitecture,
838 GraphicsControllerType_T enmController,
839 std::vector<GraphicsFeature_T> &vecSupportedGraphicsFeatures)
840{
841 vecSupportedGraphicsFeatures.clear();
842
843 /* Note! The legacy VHWA acceleration has been disabled completely (see @bugref{9691}). */
844 switch (enmArchitecture)
845 {
846 case PlatformArchitecture_x86:
847 case PlatformArchitecture_ARM:
848 {
849 switch (enmController)
850 {
851 case GraphicsControllerType_VMSVGA:
852 case GraphicsControllerType_VBoxSVGA:
853#ifdef VBOX_WITH_VMSVGA
854# ifdef VBOX_WITH_3D_ACCELERATION
855 vecSupportedGraphicsFeatures.push_back(GraphicsFeature_Acceleration3D);
856# endif
857#endif
858 return VINF_SUCCESS;
859
860 case GraphicsControllerType_VBoxVGA:
861 case GraphicsControllerType_QemuRamFB:
862 /* None supported. */
863 return VINF_SUCCESS;
864
865 /* (no default to get compiler warnings) */
866 case GraphicsControllerType_Null:
867#ifdef VBOX_WITH_XPCOM
868 case GraphicsControllerType_32BitHack:
869#endif
870 break;
871 }
872 break;
873 }
874
875 /* (no default to get compiler warnings) */
876 case PlatformArchitecture_None:
877#ifdef VBOX_WITH_XPCOM
878 case PlatformArchitecture_32BitHack:
879#endif
880 break;
881 }
882 return VERR_INVALID_PARAMETER;
883}
884
885/**
886 * Static helper function to return whether a given graphics feature for a graphics controller is enabled or not.
887 *
888 * @returns \c true if the given feature is supported, or \c false if not.
889 * @param enmArchitecture Platform architecture to query a feature for.
890 * @param enmController Graphics controlller to query a feature for.
891 * @param enmFeature Feature to query.
892 */
893/* static */
894bool PlatformProperties::s_isGraphicsControllerFeatureSupported(PlatformArchitecture_T enmArchitecture,
895 GraphicsControllerType_T enmController,
896 GraphicsFeature_T enmFeature)
897{
898 std::vector<GraphicsFeature_T> vecSupportedGraphicsFeatures;
899 int vrc = PlatformProperties::s_getSupportedGraphicsControllerFeatures(enmArchitecture, enmController,
900 vecSupportedGraphicsFeatures);
901 if (RT_SUCCESS(vrc))
902 return std::find(vecSupportedGraphicsFeatures.begin(),
903 vecSupportedGraphicsFeatures.end(), enmFeature) != vecSupportedGraphicsFeatures.end();
904 return false;
905}
906
907/**
908 * Returns the [minimum, maximum] VRAM range and stride size for a given graphics controller.
909 *
910 * @returns HRESULT
911 * @param aGraphicsControllerType Graphics controller type to return values for.
912 * @param fAccelerate3DEnabled whether 3D acceleration is enabled / disabled for the selected graphics controller.
913 * @param aMinMB Where to return the minimum VRAM (in MB).
914 * @param aMaxMB Where to return the maximum VRAM (in MB).
915 * @param aStrideSizeMB Where to return stride size (in MB). Optional, can be NULL.
916 */
917/* static */
918HRESULT PlatformProperties::s_getSupportedVRAMRange(GraphicsControllerType_T aGraphicsControllerType, BOOL fAccelerate3DEnabled,
919 ULONG *aMinMB, ULONG *aMaxMB, ULONG *aStrideSizeMB)
920{
921 size_t cbMin;
922 size_t cbMax;
923 size_t cbStride = _1M; /* Default stride for all controllers. */
924
925 switch (aGraphicsControllerType)
926 {
927 case GraphicsControllerType_VBoxVGA:
928 {
929 cbMin = VGA_VRAM_MIN;
930 cbMax = VGA_VRAM_MAX;
931 break;
932 }
933
934 case GraphicsControllerType_VMSVGA:
935 case GraphicsControllerType_VBoxSVGA:
936 {
937 if (fAccelerate3DEnabled)
938 cbMin = VBOX_SVGA_VRAM_MIN_SIZE_3D;
939 else
940 cbMin = VBOX_SVGA_VRAM_MIN_SIZE;
941 /* We don't want to limit ourselves to VBOX_SVGA_VRAM_MAX_SIZE,
942 * so we use VGA_VRAM_MAX for all controllers. */
943 cbMax = VGA_VRAM_MAX;
944 break;
945 }
946
947 case GraphicsControllerType_QemuRamFB:
948 {
949 /* We seem to hardcode 32-bit (4 bytes) as BPP, see RAMFB_BPP in QemuRamfb.c. */
950 cbMin = 4 /* BPP in bytes */ * 16 * 16; /* Values taken from qemu/hw/display/ramfb.c */
951 cbMax = 4 /* BPP in bytes */ * 16000 * 12000; /* Values taken from bochs-vbe.h. */
952 /* Make the maximum value a power of two. */
953 cbMax = RT_BIT_64(ASMBitLastSetU64(cbMax));
954 break;
955 }
956
957 default:
958 return E_INVALIDARG;
959 }
960
961 /* Sanity. We want all max values to be a power of two. */
962 AssertMsg(RT_IS_POWER_OF_TWO(cbMax), ("Maximum VRAM value is not a power of two!\n"));
963
964 /* Convert bytes -> MB, align to stride. */
965 cbMin = (ULONG)(RT_ALIGN_64(cbMin, cbStride) / _1M);
966 cbMax = (ULONG)(RT_ALIGN_64(cbMax, cbStride) / _1M);
967 cbStride = (ULONG)cbStride / _1M;
968
969 /* Finally, clamp the values to our schema definitions before returning. */
970 if (cbMax > SchemaDefs::MaxGuestVRAM)
971 cbMax = SchemaDefs::MaxGuestVRAM;
972
973 *aMinMB = (ULONG)cbMin;
974 *aMaxMB = (ULONG)cbMax;
975 if (aStrideSizeMB)
976 *aStrideSizeMB = (ULONG)cbStride;
977
978 return S_OK;
979}
980
981HRESULT PlatformProperties::getSupportedVRAMRange(GraphicsControllerType_T aGraphicsControllerType, BOOL fAccelerate3DEnabled,
982 ULONG *aMinMB, ULONG *aMaxMB, ULONG *aStrideSizeMB)
983{
984 HRESULT hrc = PlatformProperties::s_getSupportedVRAMRange(aGraphicsControllerType, fAccelerate3DEnabled, aMinMB, aMaxMB,
985 aStrideSizeMB);
986 switch (hrc)
987 {
988 case VBOX_E_NOT_SUPPORTED:
989 return setError(VBOX_E_NOT_SUPPORTED, tr("Selected graphics controller not supported in this version"));
990
991 case E_INVALIDARG:
992 return setError(E_INVALIDARG, tr("The graphics controller type (%d) is invalid"), aGraphicsControllerType);
993
994 default:
995 break;
996 }
997
998 return S_OK;
999}
1000
1001HRESULT PlatformProperties::getSupportedGfxFeaturesForType(GraphicsControllerType_T aGraphicsControllerType,
1002 std::vector<GraphicsFeature_T> &aSupportedGraphicsFeatures)
1003{
1004 int vrc = PlatformProperties::s_getSupportedGraphicsControllerFeatures(mPlatformArchitecture,
1005 aGraphicsControllerType, aSupportedGraphicsFeatures);
1006 if (RT_SUCCESS(vrc))
1007 return S_OK;
1008 return setError(E_INVALIDARG, tr("The graphics controller type (%d) is invalid"), aGraphicsControllerType);
1009}
1010
1011HRESULT PlatformProperties::getSupportedAudioControllerTypes(std::vector<AudioControllerType_T> &aSupportedAudioControllerTypes)
1012{
1013 switch (mPlatformArchitecture)
1014 {
1015 case PlatformArchitecture_x86:
1016 {
1017 static const AudioControllerType_T aAudioControllerTypes[] =
1018 {
1019 AudioControllerType_AC97,
1020 AudioControllerType_SB16,
1021 AudioControllerType_HDA,
1022 };
1023 aSupportedAudioControllerTypes.assign(aAudioControllerTypes,
1024 aAudioControllerTypes + RT_ELEMENTS(aAudioControllerTypes));
1025 break;
1026 }
1027
1028 case PlatformArchitecture_ARM:
1029 {
1030 static const AudioControllerType_T aAudioControllerTypes[] =
1031 {
1032 AudioControllerType_AC97,
1033 AudioControllerType_HDA,
1034 };
1035 aSupportedAudioControllerTypes.assign(aAudioControllerTypes,
1036 aAudioControllerTypes + RT_ELEMENTS(aAudioControllerTypes));
1037 break;
1038 }
1039
1040 default:
1041 AssertFailedStmt(aSupportedAudioControllerTypes.clear());
1042 break;
1043 }
1044
1045
1046 return S_OK;
1047}
1048
1049HRESULT PlatformProperties::getSupportedBootDevices(std::vector<DeviceType_T> &aSupportedBootDevices)
1050{
1051 /* Note: This function returns the supported boot devices for the given architecture,
1052 in the default order, to keep it simple for the caller. */
1053
1054 switch (mPlatformArchitecture)
1055 {
1056 case PlatformArchitecture_x86:
1057 {
1058 static const DeviceType_T aBootDevices[] =
1059 {
1060 DeviceType_Floppy,
1061 DeviceType_DVD,
1062 DeviceType_HardDisk,
1063 DeviceType_Network
1064 };
1065 aSupportedBootDevices.assign(aBootDevices,
1066 aBootDevices + RT_ELEMENTS(aBootDevices));
1067 break;
1068 }
1069
1070 case PlatformArchitecture_ARM:
1071 {
1072 static const DeviceType_T aBootDevices[] =
1073 {
1074 DeviceType_DVD,
1075 DeviceType_HardDisk
1076 /** @todo BUGBUG We need to test network booting via PXE on ARM first! */
1077 };
1078 aSupportedBootDevices.assign(aBootDevices,
1079 aBootDevices + RT_ELEMENTS(aBootDevices));
1080 break;
1081 }
1082
1083 default:
1084 AssertFailedStmt(aSupportedBootDevices.clear());
1085 break;
1086 }
1087
1088 return S_OK;
1089}
1090
1091HRESULT PlatformProperties::getSupportedStorageBuses(std::vector<StorageBus_T> &aSupportedStorageBuses)
1092{
1093 switch (mPlatformArchitecture)
1094 {
1095 case PlatformArchitecture_x86:
1096 {
1097 static const StorageBus_T aStorageBuses[] =
1098 {
1099 StorageBus_SATA,
1100 StorageBus_IDE,
1101 StorageBus_SCSI,
1102 StorageBus_Floppy,
1103 StorageBus_SAS,
1104 StorageBus_USB,
1105 StorageBus_PCIe,
1106 StorageBus_VirtioSCSI,
1107 };
1108 aSupportedStorageBuses.assign(aStorageBuses,
1109 aStorageBuses + RT_ELEMENTS(aStorageBuses));
1110 break;
1111 }
1112
1113 case PlatformArchitecture_ARM:
1114 {
1115 static const StorageBus_T aStorageBuses[] =
1116 {
1117 StorageBus_SATA,
1118 StorageBus_SCSI,
1119 StorageBus_SAS,
1120 StorageBus_USB,
1121 StorageBus_PCIe,
1122 StorageBus_VirtioSCSI
1123 };
1124 aSupportedStorageBuses.assign(aStorageBuses,
1125 aStorageBuses + RT_ELEMENTS(aStorageBuses));
1126 break;
1127 }
1128
1129 default:
1130 AssertFailedStmt(aSupportedStorageBuses.clear());
1131 break;
1132 }
1133
1134 return S_OK;
1135}
1136
1137HRESULT PlatformProperties::getSupportedStorageControllerTypes(std::vector<StorageControllerType_T> &aSupportedStorageControllerTypes)
1138{
1139 switch (mPlatformArchitecture)
1140 {
1141 case PlatformArchitecture_x86:
1142 {
1143 static const StorageControllerType_T aStorageControllerTypes[] =
1144 {
1145 StorageControllerType_IntelAhci,
1146 StorageControllerType_PIIX4,
1147 StorageControllerType_PIIX3,
1148 StorageControllerType_ICH6,
1149 StorageControllerType_LsiLogic,
1150 StorageControllerType_BusLogic,
1151 StorageControllerType_I82078,
1152 StorageControllerType_LsiLogicSas,
1153 StorageControllerType_USB,
1154 StorageControllerType_NVMe,
1155 StorageControllerType_VirtioSCSI
1156 };
1157 aSupportedStorageControllerTypes.assign(aStorageControllerTypes,
1158 aStorageControllerTypes + RT_ELEMENTS(aStorageControllerTypes));
1159 break;
1160 }
1161
1162 case PlatformArchitecture_ARM:
1163 {
1164 static const StorageControllerType_T aStorageControllerTypes[] =
1165 {
1166 StorageControllerType_IntelAhci,
1167 StorageControllerType_LsiLogic,
1168 StorageControllerType_LsiLogicSas,
1169 StorageControllerType_USB,
1170 StorageControllerType_NVMe,
1171 StorageControllerType_VirtioSCSI
1172 };
1173 aSupportedStorageControllerTypes.assign(aStorageControllerTypes,
1174 aStorageControllerTypes + RT_ELEMENTS(aStorageControllerTypes));
1175 break;
1176 }
1177
1178 default:
1179 AssertFailedStmt(aSupportedStorageControllerTypes.clear());
1180 break;
1181 }
1182
1183 return S_OK;
1184}
1185
1186HRESULT PlatformProperties::getSupportedChipsetTypes(std::vector<ChipsetType_T> &aSupportedChipsetTypes)
1187{
1188 switch (mPlatformArchitecture)
1189 {
1190 case PlatformArchitecture_x86:
1191 {
1192 static const ChipsetType_T aChipsetTypes[] =
1193 {
1194 ChipsetType_PIIX3,
1195 ChipsetType_ICH9
1196 };
1197 aSupportedChipsetTypes.assign(aChipsetTypes,
1198 aChipsetTypes + RT_ELEMENTS(aChipsetTypes));
1199 break;
1200 }
1201
1202 case PlatformArchitecture_ARM:
1203 {
1204 static const ChipsetType_T aChipsetTypes[] =
1205 {
1206 ChipsetType_ARMv8Virtual
1207 };
1208 aSupportedChipsetTypes.assign(aChipsetTypes,
1209 aChipsetTypes + RT_ELEMENTS(aChipsetTypes));
1210 break;
1211 }
1212
1213 default:
1214 AssertFailedStmt(aSupportedChipsetTypes.clear());
1215 break;
1216 }
1217
1218 return S_OK;
1219}
1220
1221HRESULT PlatformProperties::getSupportedIommuTypes(std::vector<IommuType_T> &aSupportedIommuTypes)
1222{
1223 switch (mPlatformArchitecture)
1224 {
1225 case PlatformArchitecture_x86:
1226 {
1227 static const IommuType_T aIommuTypes[] =
1228 {
1229 IommuType_None,
1230 IommuType_Automatic,
1231 IommuType_AMD
1232 /** @todo Add Intel when it's supported. */
1233 };
1234 aSupportedIommuTypes.assign(aIommuTypes,
1235 aIommuTypes + RT_ELEMENTS(aIommuTypes));
1236 break;
1237 }
1238
1239 case PlatformArchitecture_ARM:
1240 {
1241 static const IommuType_T aIommuTypes[] =
1242 {
1243 IommuType_None
1244 };
1245 aSupportedIommuTypes.assign(aIommuTypes,
1246 aIommuTypes + RT_ELEMENTS(aIommuTypes));
1247 break;
1248 }
1249
1250 default:
1251 AssertFailedStmt(aSupportedIommuTypes.clear());
1252 break;
1253 }
1254
1255 return S_OK;
1256}
1257
1258HRESULT PlatformProperties::getSupportedTpmTypes(std::vector<TpmType_T> &aSupportedTpmTypes)
1259{
1260 switch (mPlatformArchitecture)
1261 {
1262 case PlatformArchitecture_x86:
1263 {
1264 static const TpmType_T aTpmTypes[] =
1265 {
1266 TpmType_None,
1267 TpmType_v1_2,
1268 TpmType_v2_0
1269 };
1270 aSupportedTpmTypes.assign(aTpmTypes,
1271 aTpmTypes + RT_ELEMENTS(aTpmTypes));
1272 break;
1273 }
1274
1275 case PlatformArchitecture_ARM:
1276 {
1277 static const TpmType_T aTpmTypes[] =
1278 {
1279 TpmType_None,
1280 TpmType_v2_0
1281 };
1282 aSupportedTpmTypes.assign(aTpmTypes,
1283 aTpmTypes + RT_ELEMENTS(aTpmTypes));
1284 break;
1285 }
1286
1287 default:
1288 AssertFailedStmt(aSupportedTpmTypes.clear());
1289 break;
1290 }
1291
1292 return S_OK;
1293}
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