VirtualBox

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

Last change on this file since 106080 was 106080, checked in by vboxsync, 2 months ago

Main: Fixed enabling 3D when selecting supported graphics controllers. bugref:10749

  • 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 106080 2024-09-18 12:38:27Z 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 switch (enmArchitecture)
844 {
845 case PlatformArchitecture_x86:
846 {
847 switch (enmController)
848 {
849#ifdef VBOX_WITH_VMSVGA
850 case GraphicsControllerType_VMSVGA:
851 RT_FALL_THROUGH();
852 case GraphicsControllerType_VBoxSVGA:
853 {
854#if defined(VBOX_WITH_VIDEOHWACCEL) || defined(VBOX_WITH_3D_ACCELERATION) /* Work around zero-sized arrays. */
855 static const GraphicsFeature_T s_aGraphicsFeatures[] =
856 {
857# ifdef VBOX_WITH_VIDEOHWACCEL
858 /* @bugref{9691} -- The legacy VHWA acceleration has been disabled completely. */
859 //GraphicsFeature_Acceleration2DVideo,
860# endif
861# ifdef VBOX_WITH_3D_ACCELERATION
862 GraphicsFeature_Acceleration3D
863# endif
864 };
865 RT_CPP_VECTOR_ASSIGN_ARRAY(vecSupportedGraphicsFeatures, s_aGraphicsFeatures);
866# endif
867 break;
868 }
869#endif /* VBOX_WITH_VMSVGA */
870 case GraphicsControllerType_VBoxVGA:
871 RT_FALL_THROUGH();
872 case GraphicsControllerType_QemuRamFB:
873 {
874 /* None supported. */
875 break;
876 }
877
878 default:
879 /* In case GraphicsControllerType_VBoxSVGA is not available. */
880 break;
881 }
882
883 break;
884 }
885
886 case PlatformArchitecture_ARM:
887 {
888 /* None supported. */
889 break;
890 }
891
892 default:
893 break;
894 }
895
896 return VINF_SUCCESS;
897}
898
899/**
900 * Static helper function to return whether a given graphics feature for a graphics controller is enabled or not.
901 *
902 * @returns \c true if the given feature is supported, or \c false if not.
903 * @param enmArchitecture Platform architecture to query a feature for.
904 * @param enmController Graphics controlller to query a feature for.
905 * @param enmFeature Feature to query.
906 */
907/* static */
908bool PlatformProperties::s_isGraphicsControllerFeatureSupported(PlatformArchitecture_T enmArchitecture,
909 GraphicsControllerType_T enmController,
910 GraphicsFeature_T enmFeature)
911{
912 std::vector<GraphicsFeature_T> vecSupportedGraphicsFeatures;
913 int vrc = PlatformProperties::s_getSupportedGraphicsControllerFeatures(enmArchitecture, enmController,
914 vecSupportedGraphicsFeatures);
915 if (RT_SUCCESS(vrc))
916 return std::find(vecSupportedGraphicsFeatures.begin(),
917 vecSupportedGraphicsFeatures.end(), enmFeature) != vecSupportedGraphicsFeatures.end();
918 return false;
919}
920
921/**
922 * Returns the [minimum, maximum] VRAM range and stride size for a given graphics controller.
923 *
924 * @returns HRESULT
925 * @param aGraphicsControllerType Graphics controller type to return values for.
926 * @param fAccelerate3DEnabled whether 3D acceleration is enabled / disabled for the selected graphics controller.
927 * @param aMinMB Where to return the minimum VRAM (in MB).
928 * @param aMaxMB Where to return the maximum VRAM (in MB).
929 * @param aStrideSizeMB Where to return stride size (in MB). Optional, can be NULL.
930 */
931/* static */
932HRESULT PlatformProperties::s_getSupportedVRAMRange(GraphicsControllerType_T aGraphicsControllerType, BOOL fAccelerate3DEnabled,
933 ULONG *aMinMB, ULONG *aMaxMB, ULONG *aStrideSizeMB)
934{
935 size_t cbMin;
936 size_t cbMax;
937 size_t cbStride = _1M; /* Default stride for all controllers. */
938
939 switch (aGraphicsControllerType)
940 {
941 case GraphicsControllerType_VBoxVGA:
942 {
943 cbMin = VGA_VRAM_MIN;
944 cbMax = VGA_VRAM_MAX;
945 break;
946 }
947
948 case GraphicsControllerType_VMSVGA:
949 RT_FALL_THROUGH();
950 case GraphicsControllerType_VBoxSVGA:
951 {
952 if (fAccelerate3DEnabled)
953 cbMin = VBOX_SVGA_VRAM_MIN_SIZE_3D;
954 else
955 cbMin = VBOX_SVGA_VRAM_MIN_SIZE;
956 /* We don't want to limit ourselves to VBOX_SVGA_VRAM_MAX_SIZE,
957 * so we use VGA_VRAM_MAX for all controllers. */
958 cbMax = VGA_VRAM_MAX;
959 break;
960 }
961
962 case GraphicsControllerType_QemuRamFB:
963 {
964 /* We seem to hardcode 32-bit (4 bytes) as BPP, see RAMFB_BPP in QemuRamfb.c. */
965 cbMin = 4 /* BPP in bytes */ * 16 * 16; /* Values taken from qemu/hw/display/ramfb.c */
966 cbMax = 4 /* BPP in bytes */ * 16000 * 12000; /* Values taken from bochs-vbe.h. */
967 /* Make the maximum value a power of two. */
968 cbMax = RT_BIT_64(ASMBitLastSetU64(cbMax));
969 break;
970 }
971
972 default:
973 return E_INVALIDARG;
974 }
975
976 /* Sanity. We want all max values to be a power of two. */
977 AssertMsg(RT_IS_POWER_OF_TWO(cbMax), ("Maximum VRAM value is not a power of two!\n"));
978
979 /* Convert bytes -> MB, align to stride. */
980 cbMin = (ULONG)(RT_ALIGN_64(cbMin, cbStride) / _1M);
981 cbMax = (ULONG)(RT_ALIGN_64(cbMax, cbStride) / _1M);
982 cbStride = (ULONG)cbStride / _1M;
983
984 /* Finally, clamp the values to our schema definitions before returning. */
985 if (cbMax > SchemaDefs::MaxGuestVRAM)
986 cbMax = SchemaDefs::MaxGuestVRAM;
987
988 *aMinMB = (ULONG)cbMin;
989 *aMaxMB = (ULONG)cbMax;
990 if (aStrideSizeMB)
991 *aStrideSizeMB = (ULONG)cbStride;
992
993 return S_OK;
994}
995
996HRESULT PlatformProperties::getSupportedVRAMRange(GraphicsControllerType_T aGraphicsControllerType, BOOL fAccelerate3DEnabled,
997 ULONG *aMinMB, ULONG *aMaxMB, ULONG *aStrideSizeMB)
998{
999 HRESULT hrc = PlatformProperties::s_getSupportedVRAMRange(aGraphicsControllerType, fAccelerate3DEnabled, aMinMB, aMaxMB,
1000 aStrideSizeMB);
1001 switch (hrc)
1002 {
1003 case VBOX_E_NOT_SUPPORTED:
1004 return setError(VBOX_E_NOT_SUPPORTED, tr("Selected graphics controller not supported in this version"));
1005
1006 case E_INVALIDARG:
1007 return setError(E_INVALIDARG, tr("The graphics controller type (%d) is invalid"), aGraphicsControllerType);
1008
1009 default:
1010 break;
1011 }
1012
1013 return S_OK;
1014}
1015
1016HRESULT PlatformProperties::getSupportedGfxFeaturesForType(GraphicsControllerType_T aGraphicsControllerType,
1017 std::vector<GraphicsFeature_T> &aSupportedGraphicsFeatures)
1018{
1019 int vrc = PlatformProperties::s_getSupportedGraphicsControllerFeatures(mPlatformArchitecture,
1020 aGraphicsControllerType, aSupportedGraphicsFeatures);
1021 if (RT_FAILURE(vrc))
1022 return setError(E_INVALIDARG, tr("The graphics controller type (%d) is invalid"), aGraphicsControllerType);
1023
1024 return S_OK;
1025}
1026
1027HRESULT PlatformProperties::getSupportedAudioControllerTypes(std::vector<AudioControllerType_T> &aSupportedAudioControllerTypes)
1028{
1029 switch (mPlatformArchitecture)
1030 {
1031 case PlatformArchitecture_x86:
1032 {
1033 static const AudioControllerType_T aAudioControllerTypes[] =
1034 {
1035 AudioControllerType_AC97,
1036 AudioControllerType_SB16,
1037 AudioControllerType_HDA,
1038 };
1039 aSupportedAudioControllerTypes.assign(aAudioControllerTypes,
1040 aAudioControllerTypes + RT_ELEMENTS(aAudioControllerTypes));
1041 break;
1042 }
1043
1044 case PlatformArchitecture_ARM:
1045 {
1046 static const AudioControllerType_T aAudioControllerTypes[] =
1047 {
1048 AudioControllerType_AC97,
1049 AudioControllerType_HDA,
1050 };
1051 aSupportedAudioControllerTypes.assign(aAudioControllerTypes,
1052 aAudioControllerTypes + RT_ELEMENTS(aAudioControllerTypes));
1053 break;
1054 }
1055
1056 default:
1057 AssertFailedStmt(aSupportedAudioControllerTypes.clear());
1058 break;
1059 }
1060
1061
1062 return S_OK;
1063}
1064
1065HRESULT PlatformProperties::getSupportedBootDevices(std::vector<DeviceType_T> &aSupportedBootDevices)
1066{
1067 /* Note: This function returns the supported boot devices for the given architecture,
1068 in the default order, to keep it simple for the caller. */
1069
1070 switch (mPlatformArchitecture)
1071 {
1072 case PlatformArchitecture_x86:
1073 {
1074 static const DeviceType_T aBootDevices[] =
1075 {
1076 DeviceType_Floppy,
1077 DeviceType_DVD,
1078 DeviceType_HardDisk,
1079 DeviceType_Network
1080 };
1081 aSupportedBootDevices.assign(aBootDevices,
1082 aBootDevices + RT_ELEMENTS(aBootDevices));
1083 break;
1084 }
1085
1086 case PlatformArchitecture_ARM:
1087 {
1088 static const DeviceType_T aBootDevices[] =
1089 {
1090 DeviceType_DVD,
1091 DeviceType_HardDisk
1092 /** @todo BUGBUG We need to test network booting via PXE on ARM first! */
1093 };
1094 aSupportedBootDevices.assign(aBootDevices,
1095 aBootDevices + RT_ELEMENTS(aBootDevices));
1096 break;
1097 }
1098
1099 default:
1100 AssertFailedStmt(aSupportedBootDevices.clear());
1101 break;
1102 }
1103
1104 return S_OK;
1105}
1106
1107HRESULT PlatformProperties::getSupportedStorageBuses(std::vector<StorageBus_T> &aSupportedStorageBuses)
1108{
1109 switch (mPlatformArchitecture)
1110 {
1111 case PlatformArchitecture_x86:
1112 {
1113 static const StorageBus_T aStorageBuses[] =
1114 {
1115 StorageBus_SATA,
1116 StorageBus_IDE,
1117 StorageBus_SCSI,
1118 StorageBus_Floppy,
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 case PlatformArchitecture_ARM:
1130 {
1131 static const StorageBus_T aStorageBuses[] =
1132 {
1133 StorageBus_VirtioSCSI
1134 };
1135 aSupportedStorageBuses.assign(aStorageBuses,
1136 aStorageBuses + RT_ELEMENTS(aStorageBuses));
1137 break;
1138 }
1139
1140 default:
1141 AssertFailedStmt(aSupportedStorageBuses.clear());
1142 break;
1143 }
1144
1145 return S_OK;
1146}
1147
1148HRESULT PlatformProperties::getSupportedStorageControllerTypes(std::vector<StorageControllerType_T> &aSupportedStorageControllerTypes)
1149{
1150 switch (mPlatformArchitecture)
1151 {
1152 case PlatformArchitecture_x86:
1153 {
1154 static const StorageControllerType_T aStorageControllerTypes[] =
1155 {
1156 StorageControllerType_IntelAhci,
1157 StorageControllerType_PIIX4,
1158 StorageControllerType_PIIX3,
1159 StorageControllerType_ICH6,
1160 StorageControllerType_LsiLogic,
1161 StorageControllerType_BusLogic,
1162 StorageControllerType_I82078,
1163 StorageControllerType_LsiLogicSas,
1164 StorageControllerType_USB,
1165 StorageControllerType_NVMe,
1166 StorageControllerType_VirtioSCSI
1167 };
1168 aSupportedStorageControllerTypes.assign(aStorageControllerTypes,
1169 aStorageControllerTypes + RT_ELEMENTS(aStorageControllerTypes));
1170 break;
1171 }
1172
1173 case PlatformArchitecture_ARM:
1174 {
1175 static const StorageControllerType_T aStorageControllerTypes[] =
1176 {
1177 StorageControllerType_VirtioSCSI
1178 };
1179 aSupportedStorageControllerTypes.assign(aStorageControllerTypes,
1180 aStorageControllerTypes + RT_ELEMENTS(aStorageControllerTypes));
1181 break;
1182 }
1183
1184 default:
1185 AssertFailedStmt(aSupportedStorageControllerTypes.clear());
1186 break;
1187 }
1188
1189 return S_OK;
1190}
1191
1192HRESULT PlatformProperties::getSupportedChipsetTypes(std::vector<ChipsetType_T> &aSupportedChipsetTypes)
1193{
1194 switch (mPlatformArchitecture)
1195 {
1196 case PlatformArchitecture_x86:
1197 {
1198 static const ChipsetType_T aChipsetTypes[] =
1199 {
1200 ChipsetType_PIIX3,
1201 ChipsetType_ICH9
1202 };
1203 aSupportedChipsetTypes.assign(aChipsetTypes,
1204 aChipsetTypes + RT_ELEMENTS(aChipsetTypes));
1205 break;
1206 }
1207
1208 case PlatformArchitecture_ARM:
1209 {
1210 static const ChipsetType_T aChipsetTypes[] =
1211 {
1212 ChipsetType_ARMv8Virtual
1213 };
1214 aSupportedChipsetTypes.assign(aChipsetTypes,
1215 aChipsetTypes + RT_ELEMENTS(aChipsetTypes));
1216 break;
1217 }
1218
1219 default:
1220 AssertFailedStmt(aSupportedChipsetTypes.clear());
1221 break;
1222 }
1223
1224 return S_OK;
1225}
1226
1227HRESULT PlatformProperties::getSupportedIommuTypes(std::vector<IommuType_T> &aSupportedIommuTypes)
1228{
1229 switch (mPlatformArchitecture)
1230 {
1231 case PlatformArchitecture_x86:
1232 {
1233 static const IommuType_T aIommuTypes[] =
1234 {
1235 IommuType_None,
1236 IommuType_Automatic,
1237 IommuType_AMD
1238 /** @todo Add Intel when it's supported. */
1239 };
1240 aSupportedIommuTypes.assign(aIommuTypes,
1241 aIommuTypes + RT_ELEMENTS(aIommuTypes));
1242 break;
1243 }
1244
1245 case PlatformArchitecture_ARM:
1246 {
1247 static const IommuType_T aIommuTypes[] =
1248 {
1249 IommuType_None
1250 };
1251 aSupportedIommuTypes.assign(aIommuTypes,
1252 aIommuTypes + RT_ELEMENTS(aIommuTypes));
1253 break;
1254 }
1255
1256 default:
1257 AssertFailedStmt(aSupportedIommuTypes.clear());
1258 break;
1259 }
1260
1261 return S_OK;
1262}
1263
1264HRESULT PlatformProperties::getSupportedTpmTypes(std::vector<TpmType_T> &aSupportedTpmTypes)
1265{
1266 switch (mPlatformArchitecture)
1267 {
1268 case PlatformArchitecture_x86:
1269 {
1270 static const TpmType_T aTpmTypes[] =
1271 {
1272 TpmType_None,
1273 TpmType_v1_2,
1274 TpmType_v2_0
1275 };
1276 aSupportedTpmTypes.assign(aTpmTypes,
1277 aTpmTypes + RT_ELEMENTS(aTpmTypes));
1278 break;
1279 }
1280
1281 case PlatformArchitecture_ARM:
1282 {
1283 static const TpmType_T aTpmTypes[] =
1284 {
1285 TpmType_None
1286 };
1287 aSupportedTpmTypes.assign(aTpmTypes,
1288 aTpmTypes + RT_ELEMENTS(aTpmTypes));
1289 break;
1290 }
1291
1292 default:
1293 AssertFailedStmt(aSupportedTpmTypes.clear());
1294 break;
1295 }
1296
1297 return S_OK;
1298}
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