VirtualBox

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

Last change on this file since 105871 was 105865, checked in by vboxsync, 6 months ago

Main: Added API for querying graphics features (2D Video / 3D Acceleration) of a specific graphics controller for a given platform and revamped the graphics controller attributes for 2D / 3D setters/getters to also use the new graphics features enumeration. Also, the system properties also now contain a dedicated API to query for graphics features (very basic for now, needs to be stuffed out). See SDK changelog for details. Added validation code when setting a specific graphics feature (which we never did before) [build fix]. bugref:10749

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