VirtualBox

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

Last change on this file since 107438 was 107267, checked in by vboxsync, 8 weeks ago

Main/API,UI: bugref:10810 Based on Brent's patch, added UsbNet support into Main API and UI

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 40.6 KB
Line 
1/* $Id: PlatformPropertiesImpl.cpp 107267 2024-12-10 07:37:35Z 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 switch (mPlatformArchitecture)
177 {
178 case PlatformArchitecture_x86:
179 {
180 /* no need to lock, this is const */
181 *count = SchemaDefs::ParallelPortCount;
182 break;
183 }
184
185 case PlatformArchitecture_ARM:
186 default:
187 {
188 *count = 0; /* Not supported. */
189 break;
190 }
191 }
192
193 return S_OK;
194}
195
196HRESULT PlatformProperties::getMaxBootPosition(ULONG *aMaxBootPosition)
197{
198 /* no need to lock, this is const */
199 *aMaxBootPosition = SchemaDefs::MaxBootPosition;
200
201 return S_OK;
202}
203
204HRESULT PlatformProperties::getRawModeSupported(BOOL *aRawModeSupported)
205{
206 *aRawModeSupported = FALSE;
207 return S_OK;
208}
209
210HRESULT PlatformProperties::getExclusiveHwVirt(BOOL *aExclusiveHwVirt)
211{
212 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
213
214 *aExclusiveHwVirt = m->fExclusiveHwVirt;
215
216 /* Makes no sense for guest platform properties, but we return FALSE anyway. */
217 return S_OK;
218}
219
220HRESULT PlatformProperties::setExclusiveHwVirt(BOOL aExclusiveHwVirt)
221{
222 /* Only makes sense when running in VBoxSVC, as this is a pure host setting -- ignored within clients. */
223#ifdef IN_VBOXSVC
224 /* No locking required, as mfIsHost is const. */
225 if (!mfIsHost) /* Ignore setting the attribute if not host properties. */
226 return S_OK;
227
228 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
229 m->fExclusiveHwVirt = !!aExclusiveHwVirt;
230 alock.release();
231
232 // VirtualBox::i_saveSettings() needs vbox write lock
233 AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS);
234 return mParent->i_saveSettings();
235#else /* VBoxC */
236 RT_NOREF(aExclusiveHwVirt);
237 return VBOX_E_NOT_SUPPORTED;
238#endif
239}
240
241/* static */
242ULONG PlatformProperties::s_getMaxNetworkAdapters(ChipsetType_T aChipset)
243{
244 AssertReturn(aChipset != ChipsetType_Null, 0);
245
246 /* no need for locking, no state */
247 switch (aChipset)
248 {
249 case ChipsetType_PIIX3: return 8;
250 case ChipsetType_ICH9: return 36;
251 case ChipsetType_ARMv8Virtual: return 64; /** @todo BUGBUG Put a sane value here. Just a wild guess for now. */
252 case ChipsetType_Null:
253 RT_FALL_THROUGH();
254 default:
255 break;
256 }
257
258 AssertMsgFailedReturn(("Chipset type %#x not handled\n", aChipset), 0);
259}
260
261HRESULT PlatformProperties::getMaxNetworkAdapters(ChipsetType_T aChipset, ULONG *aMaxNetworkAdapters)
262{
263 *aMaxNetworkAdapters = PlatformProperties::s_getMaxNetworkAdapters(aChipset);
264
265 return S_OK;
266}
267
268/* static */
269ULONG PlatformProperties::s_getMaxNetworkAdaptersOfType(ChipsetType_T aChipset, NetworkAttachmentType_T aType)
270{
271 /* no need for locking, no state */
272 uint32_t cMaxNetworkAdapters = PlatformProperties::s_getMaxNetworkAdapters(aChipset);
273
274 switch (aType)
275 {
276 case NetworkAttachmentType_NAT:
277 case NetworkAttachmentType_Internal:
278 case NetworkAttachmentType_NATNetwork:
279 /* chipset default is OK */
280 break;
281 case NetworkAttachmentType_Bridged:
282 /* Maybe use current host interface count here? */
283 break;
284 case NetworkAttachmentType_HostOnly:
285 cMaxNetworkAdapters = RT_MIN(cMaxNetworkAdapters, 8);
286 break;
287 default:
288 AssertMsgFailed(("Unhandled attachment type %d\n", aType));
289 }
290
291 return cMaxNetworkAdapters;
292}
293
294HRESULT PlatformProperties::getMaxNetworkAdaptersOfType(ChipsetType_T aChipset, NetworkAttachmentType_T aType,
295 ULONG *aMaxNetworkAdapters)
296{
297 *aMaxNetworkAdapters = PlatformProperties::s_getMaxNetworkAdaptersOfType(aChipset, aType);
298
299 return S_OK;
300}
301
302HRESULT PlatformProperties::getMaxDevicesPerPortForStorageBus(StorageBus_T aBus,
303 ULONG *aMaxDevicesPerPort)
304{
305 /* no need to lock, this is const */
306 switch (aBus)
307 {
308 case StorageBus_SATA:
309 case StorageBus_SCSI:
310 case StorageBus_SAS:
311 case StorageBus_USB:
312 case StorageBus_PCIe:
313 case StorageBus_VirtioSCSI:
314 {
315 /* SATA and both SCSI controllers only support one device per port. */
316 *aMaxDevicesPerPort = 1;
317 break;
318 }
319 case StorageBus_IDE:
320 case StorageBus_Floppy:
321 {
322 /* The IDE and Floppy controllers support 2 devices. One as master
323 * and one as slave (or floppy drive 0 and 1). */
324 *aMaxDevicesPerPort = 2;
325 break;
326 }
327 default:
328 AssertMsgFailed(("Invalid bus type %d\n", aBus));
329 }
330
331 return S_OK;
332}
333
334HRESULT PlatformProperties::getMinPortCountForStorageBus(StorageBus_T aBus,
335 ULONG *aMinPortCount)
336{
337 /* no need to lock, this is const */
338 switch (aBus)
339 {
340 case StorageBus_SATA:
341 case StorageBus_SAS:
342 case StorageBus_PCIe:
343 case StorageBus_VirtioSCSI:
344 {
345 *aMinPortCount = 1;
346 break;
347 }
348 case StorageBus_SCSI:
349 {
350 *aMinPortCount = 16;
351 break;
352 }
353 case StorageBus_IDE:
354 {
355 *aMinPortCount = 2;
356 break;
357 }
358 case StorageBus_Floppy:
359 {
360 *aMinPortCount = 1;
361 break;
362 }
363 case StorageBus_USB:
364 {
365 *aMinPortCount = 8;
366 break;
367 }
368 default:
369 AssertMsgFailed(("Invalid bus type %d\n", aBus));
370 }
371
372 return S_OK;
373}
374
375HRESULT PlatformProperties::getMaxPortCountForStorageBus(StorageBus_T aBus,
376 ULONG *aMaxPortCount)
377{
378 /* no need to lock, this is const */
379 switch (aBus)
380 {
381 case StorageBus_SATA:
382 {
383 *aMaxPortCount = 30;
384 break;
385 }
386 case StorageBus_SCSI:
387 {
388 *aMaxPortCount = 16;
389 break;
390 }
391 case StorageBus_IDE:
392 {
393 *aMaxPortCount = 2;
394 break;
395 }
396 case StorageBus_Floppy:
397 {
398 *aMaxPortCount = 1;
399 break;
400 }
401 case StorageBus_SAS:
402 case StorageBus_PCIe:
403 {
404 *aMaxPortCount = 255;
405 break;
406 }
407 case StorageBus_USB:
408 {
409 *aMaxPortCount = 8;
410 break;
411 }
412 case StorageBus_VirtioSCSI:
413 {
414 *aMaxPortCount = 256;
415 break;
416 }
417 default:
418 AssertMsgFailed(("Invalid bus type %d\n", aBus));
419 }
420
421 return S_OK;
422}
423
424HRESULT PlatformProperties::getMaxInstancesOfStorageBus(ChipsetType_T aChipset,
425 StorageBus_T aBus,
426 ULONG *aMaxInstances)
427{
428 ULONG cCtrs = 0;
429
430 /* no need to lock, this is const */
431 switch (aBus)
432 {
433 case StorageBus_SATA:
434 case StorageBus_SCSI:
435 case StorageBus_SAS:
436 case StorageBus_PCIe:
437 case StorageBus_VirtioSCSI:
438 cCtrs = aChipset == ChipsetType_ICH9 || aChipset == ChipsetType_ARMv8Virtual ? 8 : 1;
439 break;
440 case StorageBus_USB:
441 case StorageBus_IDE:
442 case StorageBus_Floppy:
443 {
444 cCtrs = 1;
445 break;
446 }
447 default:
448 AssertMsgFailed(("Invalid bus type %d\n", aBus));
449 }
450
451 *aMaxInstances = cCtrs;
452
453 return S_OK;
454}
455
456HRESULT PlatformProperties::getDeviceTypesForStorageBus(StorageBus_T aBus,
457 std::vector<DeviceType_T> &aDeviceTypes)
458{
459 aDeviceTypes.resize(0);
460
461 /* no need to lock, this is const */
462 switch (aBus)
463 {
464 case StorageBus_IDE:
465 case StorageBus_SATA:
466 case StorageBus_SCSI:
467 case StorageBus_SAS:
468 case StorageBus_USB:
469 case StorageBus_VirtioSCSI:
470 {
471 aDeviceTypes.resize(2);
472 aDeviceTypes[0] = DeviceType_DVD;
473 aDeviceTypes[1] = DeviceType_HardDisk;
474 break;
475 }
476 case StorageBus_Floppy:
477 {
478 aDeviceTypes.resize(1);
479 aDeviceTypes[0] = DeviceType_Floppy;
480 break;
481 }
482 case StorageBus_PCIe:
483 {
484 aDeviceTypes.resize(1);
485 aDeviceTypes[0] = DeviceType_HardDisk;
486 break;
487 }
488 default:
489 AssertMsgFailed(("Invalid bus type %d\n", aBus));
490 }
491
492 return S_OK;
493}
494
495HRESULT PlatformProperties::getStorageBusForControllerType(StorageControllerType_T aStorageControllerType,
496 StorageBus_T *aStorageBus)
497{
498 /* no need to lock, this is const */
499 switch (aStorageControllerType)
500 {
501 case StorageControllerType_LsiLogic:
502 case StorageControllerType_BusLogic:
503 *aStorageBus = StorageBus_SCSI;
504 break;
505 case StorageControllerType_IntelAhci:
506 *aStorageBus = StorageBus_SATA;
507 break;
508 case StorageControllerType_PIIX3:
509 case StorageControllerType_PIIX4:
510 case StorageControllerType_ICH6:
511 *aStorageBus = StorageBus_IDE;
512 break;
513 case StorageControllerType_I82078:
514 *aStorageBus = StorageBus_Floppy;
515 break;
516 case StorageControllerType_LsiLogicSas:
517 *aStorageBus = StorageBus_SAS;
518 break;
519 case StorageControllerType_USB:
520 *aStorageBus = StorageBus_USB;
521 break;
522 case StorageControllerType_NVMe:
523 *aStorageBus = StorageBus_PCIe;
524 break;
525 case StorageControllerType_VirtioSCSI:
526 *aStorageBus = StorageBus_VirtioSCSI;
527 break;
528 default:
529 return setError(E_FAIL, tr("Invalid storage controller type %d\n"), aStorageBus);
530 }
531
532 return S_OK;
533}
534
535HRESULT PlatformProperties::getStorageControllerTypesForBus(StorageBus_T aStorageBus,
536 std::vector<StorageControllerType_T> &aStorageControllerTypes)
537{
538 aStorageControllerTypes.resize(0);
539
540 /* no need to lock, this is const */
541 switch (aStorageBus)
542 {
543 case StorageBus_IDE:
544 aStorageControllerTypes.resize(3);
545 aStorageControllerTypes[0] = StorageControllerType_PIIX4;
546 aStorageControllerTypes[1] = StorageControllerType_PIIX3;
547 aStorageControllerTypes[2] = StorageControllerType_ICH6;
548 break;
549 case StorageBus_SATA:
550 aStorageControllerTypes.resize(1);
551 aStorageControllerTypes[0] = StorageControllerType_IntelAhci;
552 break;
553 case StorageBus_SCSI:
554 aStorageControllerTypes.resize(2);
555 aStorageControllerTypes[0] = StorageControllerType_LsiLogic;
556 aStorageControllerTypes[1] = StorageControllerType_BusLogic;
557 break;
558 case StorageBus_Floppy:
559 aStorageControllerTypes.resize(1);
560 aStorageControllerTypes[0] = StorageControllerType_I82078;
561 break;
562 case StorageBus_SAS:
563 aStorageControllerTypes.resize(1);
564 aStorageControllerTypes[0] = StorageControllerType_LsiLogicSas;
565 break;
566 case StorageBus_USB:
567 aStorageControllerTypes.resize(1);
568 aStorageControllerTypes[0] = StorageControllerType_USB;
569 break;
570 case StorageBus_PCIe:
571 aStorageControllerTypes.resize(1);
572 aStorageControllerTypes[0] = StorageControllerType_NVMe;
573 break;
574 case StorageBus_VirtioSCSI:
575 aStorageControllerTypes.resize(1);
576 aStorageControllerTypes[0] = StorageControllerType_VirtioSCSI;
577 break;
578 default:
579 return setError(E_FAIL, tr("Invalid storage bus %d\n"), aStorageBus);
580 }
581
582 return S_OK;
583}
584
585HRESULT PlatformProperties::getStorageControllerHotplugCapable(StorageControllerType_T aControllerType,
586 BOOL *aHotplugCapable)
587{
588 switch (aControllerType)
589 {
590 case StorageControllerType_IntelAhci:
591 case StorageControllerType_USB:
592 *aHotplugCapable = true;
593 break;
594 case StorageControllerType_LsiLogic:
595 case StorageControllerType_LsiLogicSas:
596 case StorageControllerType_BusLogic:
597 case StorageControllerType_NVMe:
598 case StorageControllerType_VirtioSCSI:
599 case StorageControllerType_PIIX3:
600 case StorageControllerType_PIIX4:
601 case StorageControllerType_ICH6:
602 case StorageControllerType_I82078:
603 *aHotplugCapable = false;
604 break;
605 default:
606 AssertMsgFailedReturn(("Invalid controller type %d\n", aControllerType), E_FAIL);
607 }
608
609 return S_OK;
610}
611
612HRESULT PlatformProperties::getMaxInstancesOfUSBControllerType(ChipsetType_T aChipset,
613 USBControllerType_T aType,
614 ULONG *aMaxInstances)
615{
616 NOREF(aChipset);
617 ULONG cCtrs = 0;
618
619 /* no need to lock, this is const */
620 switch (aType)
621 {
622 case USBControllerType_OHCI:
623 case USBControllerType_EHCI:
624 case USBControllerType_XHCI:
625 {
626 cCtrs = 1;
627 break;
628 }
629 default:
630 AssertMsgFailed(("Invalid bus type %d\n", aType));
631 }
632
633 *aMaxInstances = cCtrs;
634
635 return S_OK;
636}
637
638HRESULT PlatformProperties::getSupportedParavirtProviders(std::vector<ParavirtProvider_T> &aSupportedParavirtProviders)
639{
640 static const ParavirtProvider_T aParavirtProviders[] =
641 {
642 ParavirtProvider_None,
643 ParavirtProvider_Default,
644 ParavirtProvider_Legacy,
645 ParavirtProvider_Minimal,
646 ParavirtProvider_HyperV,
647 ParavirtProvider_KVM,
648 };
649 aSupportedParavirtProviders.assign(aParavirtProviders,
650 aParavirtProviders + RT_ELEMENTS(aParavirtProviders));
651 return S_OK;
652}
653
654HRESULT PlatformProperties::getSupportedFirmwareTypes(std::vector<FirmwareType_T> &aSupportedFirmwareTypes)
655{
656 switch (mPlatformArchitecture)
657 {
658 case PlatformArchitecture_x86:
659 {
660 static const FirmwareType_T aFirmwareTypes[] =
661 {
662 FirmwareType_BIOS,
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 case PlatformArchitecture_ARM:
674 {
675 static const FirmwareType_T aFirmwareTypes[] =
676 {
677 FirmwareType_EFI,
678 FirmwareType_EFI32,
679 FirmwareType_EFI64,
680 FirmwareType_EFIDUAL
681 };
682 aSupportedFirmwareTypes.assign(aFirmwareTypes,
683 aFirmwareTypes + RT_ELEMENTS(aFirmwareTypes));
684 break;
685 }
686
687 default:
688 AssertFailedStmt(aSupportedFirmwareTypes.clear());
689 break;
690 }
691
692 return S_OK;
693}
694
695HRESULT PlatformProperties::getSupportedGfxControllerTypes(std::vector<GraphicsControllerType_T> &aSupportedGraphicsControllerTypes)
696{
697 switch (mPlatformArchitecture)
698 {
699 case PlatformArchitecture_x86:
700 {
701 static const GraphicsControllerType_T aGraphicsControllerTypes[] =
702 {
703 GraphicsControllerType_Null,
704 GraphicsControllerType_VBoxVGA,
705 GraphicsControllerType_VBoxSVGA
706#ifdef VBOX_WITH_VMSVGA
707 , GraphicsControllerType_VMSVGA
708#endif
709 };
710 aSupportedGraphicsControllerTypes.assign(aGraphicsControllerTypes + 1 /* Don't include _Null */,
711 aGraphicsControllerTypes + RT_ELEMENTS(aGraphicsControllerTypes));
712 break;
713 }
714
715 case PlatformArchitecture_ARM:
716 {
717 static const GraphicsControllerType_T aGraphicsControllerTypes[] =
718 {
719 GraphicsControllerType_Null,
720 GraphicsControllerType_QemuRamFB
721#ifdef VBOX_WITH_VMSVGA
722 , GraphicsControllerType_VMSVGA
723#endif
724 };
725 aSupportedGraphicsControllerTypes.assign(aGraphicsControllerTypes + 1 /* Don't include _Null */,
726 aGraphicsControllerTypes + RT_ELEMENTS(aGraphicsControllerTypes));
727 break;
728 }
729
730 default:
731 AssertFailedStmt(aSupportedGraphicsControllerTypes.clear());
732 break;
733 }
734
735 return S_OK;
736}
737
738HRESULT PlatformProperties::getSupportedGuestOSTypes(std::vector<ComPtr<IGuestOSType> > &aSupportedGuestOSTypes)
739{
740 /* We only have all supported guest OS types as part of VBoxSVC, not in VBoxC itself. */
741#ifdef IN_VBOXSVC
742 std::vector<PlatformArchitecture_T> vecArchitectures(1 /* Size */, mPlatformArchitecture);
743 return mParent->i_getSupportedGuestOSTypes(vecArchitectures, aSupportedGuestOSTypes);
744#else /* VBoxC */
745 RT_NOREF(aSupportedGuestOSTypes);
746 return VBOX_E_NOT_SUPPORTED;
747#endif
748}
749
750HRESULT PlatformProperties::getSupportedNetAdpPromiscModePols(std::vector<NetworkAdapterPromiscModePolicy_T> &aSupportedNetworkAdapterPromiscModePolicies)
751{
752 static const NetworkAdapterPromiscModePolicy_T aNetworkAdapterPromiscModePolicies[] =
753 {
754 NetworkAdapterPromiscModePolicy_Deny,
755 NetworkAdapterPromiscModePolicy_AllowNetwork,
756 NetworkAdapterPromiscModePolicy_AllowAll
757 };
758
759 aSupportedNetworkAdapterPromiscModePolicies.assign(aNetworkAdapterPromiscModePolicies,
760 aNetworkAdapterPromiscModePolicies + RT_ELEMENTS(aNetworkAdapterPromiscModePolicies));
761 return S_OK;
762}
763
764HRESULT PlatformProperties::getSupportedNetworkAdapterTypes(std::vector<NetworkAdapterType_T> &aSupportedNetworkAdapterTypes)
765{
766 switch (mPlatformArchitecture)
767 {
768 case PlatformArchitecture_x86:
769 {
770 static const NetworkAdapterType_T aNetworkAdapterTypes[] =
771 {
772 NetworkAdapterType_Null,
773 NetworkAdapterType_Am79C970A,
774 NetworkAdapterType_Am79C973
775#ifdef VBOX_WITH_E1000
776 , NetworkAdapterType_I82540EM
777 , NetworkAdapterType_I82543GC
778 , NetworkAdapterType_I82545EM
779#endif
780#ifdef VBOX_WITH_VIRTIO
781 , NetworkAdapterType_Virtio
782#endif
783 , NetworkAdapterType_UsbNet
784 };
785 aSupportedNetworkAdapterTypes.assign(aNetworkAdapterTypes + 1 /* Don't include _Null */,
786 aNetworkAdapterTypes + RT_ELEMENTS(aNetworkAdapterTypes));
787 break;
788 }
789
790 case PlatformArchitecture_ARM:
791 {
792 static const NetworkAdapterType_T aNetworkAdapterTypes[] =
793 {
794 NetworkAdapterType_Null
795#ifdef VBOX_WITH_E1000
796 , NetworkAdapterType_I82540EM
797 , NetworkAdapterType_I82543GC
798 , NetworkAdapterType_I82545EM
799#endif
800#ifdef VBOX_WITH_VIRTIO
801 , NetworkAdapterType_Virtio
802#endif
803 , NetworkAdapterType_UsbNet
804 };
805 aSupportedNetworkAdapterTypes.assign(aNetworkAdapterTypes + 1 /* Don't include _Null */,
806 aNetworkAdapterTypes + RT_ELEMENTS(aNetworkAdapterTypes));
807 break;
808 }
809
810 default:
811 AssertFailedStmt(aSupportedNetworkAdapterTypes.clear());
812 break;
813 }
814
815 return S_OK;
816}
817
818HRESULT PlatformProperties::getSupportedUartTypes(std::vector<UartType_T> &aSupportedUartTypes)
819{
820 static const UartType_T aUartTypes[] =
821 {
822 UartType_U16450,
823 UartType_U16550A,
824 UartType_U16750
825 };
826 aSupportedUartTypes.assign(aUartTypes,
827 aUartTypes + RT_ELEMENTS(aUartTypes));
828 return S_OK;
829}
830
831HRESULT PlatformProperties::getSupportedUSBControllerTypes(std::vector<USBControllerType_T> &aSupportedUSBControllerTypes)
832{
833 static const USBControllerType_T aUSBControllerTypes[] =
834 {
835 USBControllerType_OHCI,
836 USBControllerType_EHCI,
837 USBControllerType_XHCI
838 };
839 aSupportedUSBControllerTypes.assign(aUSBControllerTypes,
840 aUSBControllerTypes + RT_ELEMENTS(aUSBControllerTypes));
841 return S_OK;
842}
843
844/**
845 * Static helper function to return all supported features for a given graphics controller.
846 *
847 * @returns VBox status code.
848 * @param enmArchitecture Platform architecture to query a feature for.
849 * @param enmController Graphics controller to return supported features for.
850 * @param vecSupportedGraphicsFeatures Returned features on success.
851 */
852/* static */
853int PlatformProperties::s_getSupportedGraphicsControllerFeatures(PlatformArchitecture_T enmArchitecture,
854 GraphicsControllerType_T enmController,
855 std::vector<GraphicsFeature_T> &vecSupportedGraphicsFeatures)
856{
857 vecSupportedGraphicsFeatures.clear();
858
859 /* Note! The legacy VHWA acceleration has been disabled completely (see @bugref{9691}). */
860 switch (enmArchitecture)
861 {
862 case PlatformArchitecture_x86:
863 case PlatformArchitecture_ARM:
864 {
865 switch (enmController)
866 {
867 case GraphicsControllerType_VMSVGA:
868 case GraphicsControllerType_VBoxSVGA:
869#ifdef VBOX_WITH_VMSVGA
870# ifdef VBOX_WITH_3D_ACCELERATION
871 vecSupportedGraphicsFeatures.push_back(GraphicsFeature_Acceleration3D);
872# endif
873#endif
874 return VINF_SUCCESS;
875
876 case GraphicsControllerType_VBoxVGA:
877 case GraphicsControllerType_QemuRamFB:
878 /* None supported. */
879 return VINF_SUCCESS;
880
881 /* (no default to get compiler warnings) */
882 case GraphicsControllerType_Null:
883#ifdef VBOX_WITH_XPCOM
884 case GraphicsControllerType_32BitHack:
885#endif
886 break;
887 }
888 break;
889 }
890
891 /* (no default to get compiler warnings) */
892 case PlatformArchitecture_None:
893#ifdef VBOX_WITH_XPCOM
894 case PlatformArchitecture_32BitHack:
895#endif
896 break;
897 }
898 return VERR_INVALID_PARAMETER;
899}
900
901/**
902 * Static helper function to return whether a given graphics feature for a graphics controller is enabled or not.
903 *
904 * @returns \c true if the given feature is supported, or \c false if not.
905 * @param enmArchitecture Platform architecture to query a feature for.
906 * @param enmController Graphics controlller to query a feature for.
907 * @param enmFeature Feature to query.
908 */
909/* static */
910bool PlatformProperties::s_isGraphicsControllerFeatureSupported(PlatformArchitecture_T enmArchitecture,
911 GraphicsControllerType_T enmController,
912 GraphicsFeature_T enmFeature)
913{
914 std::vector<GraphicsFeature_T> vecSupportedGraphicsFeatures;
915 int vrc = PlatformProperties::s_getSupportedGraphicsControllerFeatures(enmArchitecture, enmController,
916 vecSupportedGraphicsFeatures);
917 if (RT_SUCCESS(vrc))
918 return std::find(vecSupportedGraphicsFeatures.begin(),
919 vecSupportedGraphicsFeatures.end(), enmFeature) != vecSupportedGraphicsFeatures.end();
920 return false;
921}
922
923/**
924 * Returns the [minimum, maximum] VRAM range and stride size for a given graphics controller.
925 *
926 * @returns HRESULT
927 * @param aGraphicsControllerType Graphics controller type to return values for.
928 * @param fAccelerate3DEnabled whether 3D acceleration is enabled / disabled for the selected graphics controller.
929 * @param aMinMB Where to return the minimum VRAM (in MB).
930 * @param aMaxMB Where to return the maximum VRAM (in MB).
931 * @param aStrideSizeMB Where to return stride size (in MB). Optional, can be NULL.
932 */
933/* static */
934HRESULT PlatformProperties::s_getSupportedVRAMRange(GraphicsControllerType_T aGraphicsControllerType, BOOL fAccelerate3DEnabled,
935 ULONG *aMinMB, ULONG *aMaxMB, ULONG *aStrideSizeMB)
936{
937 size_t cbMin;
938 size_t cbMax;
939 size_t cbStride = _1M; /* Default stride for all controllers. */
940
941 switch (aGraphicsControllerType)
942 {
943 case GraphicsControllerType_VBoxVGA:
944 {
945 cbMin = VGA_VRAM_MIN;
946 cbMax = VGA_VRAM_MAX;
947 break;
948 }
949
950 case GraphicsControllerType_VMSVGA:
951 case GraphicsControllerType_VBoxSVGA:
952 {
953 if (fAccelerate3DEnabled)
954 cbMin = VBOX_SVGA_VRAM_MIN_SIZE_3D;
955 else
956 cbMin = VBOX_SVGA_VRAM_MIN_SIZE;
957 /* We don't want to limit ourselves to VBOX_SVGA_VRAM_MAX_SIZE,
958 * so we use VGA_VRAM_MAX for all controllers. */
959 cbMax = VGA_VRAM_MAX;
960 break;
961 }
962
963 case GraphicsControllerType_QemuRamFB:
964 {
965 /* We seem to hardcode 32-bit (4 bytes) as BPP, see RAMFB_BPP in QemuRamfb.c. */
966 cbMin = 4 /* BPP in bytes */ * 16 * 16; /* Values taken from qemu/hw/display/ramfb.c */
967 cbMax = 4 /* BPP in bytes */ * 16000 * 12000; /* Values taken from bochs-vbe.h. */
968 /* Make the maximum value a power of two. */
969 cbMax = RT_BIT_64(ASMBitLastSetU64(cbMax));
970 break;
971 }
972
973 default:
974 return E_INVALIDARG;
975 }
976
977 /* Sanity. We want all max values to be a power of two. */
978 AssertMsg(RT_IS_POWER_OF_TWO(cbMax), ("Maximum VRAM value is not a power of two!\n"));
979
980 /* Convert bytes -> MB, align to stride. */
981 cbMin = (ULONG)(RT_ALIGN_64(cbMin, cbStride) / _1M);
982 cbMax = (ULONG)(RT_ALIGN_64(cbMax, cbStride) / _1M);
983 cbStride = (ULONG)cbStride / _1M;
984
985 /* Finally, clamp the values to our schema definitions before returning. */
986 if (cbMax > SchemaDefs::MaxGuestVRAM)
987 cbMax = SchemaDefs::MaxGuestVRAM;
988
989 *aMinMB = (ULONG)cbMin;
990 *aMaxMB = (ULONG)cbMax;
991 if (aStrideSizeMB)
992 *aStrideSizeMB = (ULONG)cbStride;
993
994 return S_OK;
995}
996
997HRESULT PlatformProperties::getSupportedVRAMRange(GraphicsControllerType_T aGraphicsControllerType, BOOL fAccelerate3DEnabled,
998 ULONG *aMinMB, ULONG *aMaxMB, ULONG *aStrideSizeMB)
999{
1000 HRESULT hrc = PlatformProperties::s_getSupportedVRAMRange(aGraphicsControllerType, fAccelerate3DEnabled, aMinMB, aMaxMB,
1001 aStrideSizeMB);
1002 switch (hrc)
1003 {
1004 case VBOX_E_NOT_SUPPORTED:
1005 return setError(VBOX_E_NOT_SUPPORTED, tr("Selected graphics controller not supported in this version"));
1006
1007 case E_INVALIDARG:
1008 return setError(E_INVALIDARG, tr("The graphics controller type (%d) is invalid"), aGraphicsControllerType);
1009
1010 default:
1011 break;
1012 }
1013
1014 return S_OK;
1015}
1016
1017HRESULT PlatformProperties::getSupportedGfxFeaturesForType(GraphicsControllerType_T aGraphicsControllerType,
1018 std::vector<GraphicsFeature_T> &aSupportedGraphicsFeatures)
1019{
1020 int vrc = PlatformProperties::s_getSupportedGraphicsControllerFeatures(mPlatformArchitecture,
1021 aGraphicsControllerType, aSupportedGraphicsFeatures);
1022 if (RT_SUCCESS(vrc))
1023 return S_OK;
1024 return setError(E_INVALIDARG, tr("The graphics controller type (%d) is invalid"), aGraphicsControllerType);
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_SATA,
1134 StorageBus_SCSI,
1135 StorageBus_SAS,
1136 StorageBus_USB,
1137 StorageBus_PCIe,
1138 StorageBus_VirtioSCSI
1139 };
1140 aSupportedStorageBuses.assign(aStorageBuses,
1141 aStorageBuses + RT_ELEMENTS(aStorageBuses));
1142 break;
1143 }
1144
1145 default:
1146 AssertFailedStmt(aSupportedStorageBuses.clear());
1147 break;
1148 }
1149
1150 return S_OK;
1151}
1152
1153HRESULT PlatformProperties::getSupportedStorageControllerTypes(std::vector<StorageControllerType_T> &aSupportedStorageControllerTypes)
1154{
1155 switch (mPlatformArchitecture)
1156 {
1157 case PlatformArchitecture_x86:
1158 {
1159 static const StorageControllerType_T aStorageControllerTypes[] =
1160 {
1161 StorageControllerType_IntelAhci,
1162 StorageControllerType_PIIX4,
1163 StorageControllerType_PIIX3,
1164 StorageControllerType_ICH6,
1165 StorageControllerType_LsiLogic,
1166 StorageControllerType_BusLogic,
1167 StorageControllerType_I82078,
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 case PlatformArchitecture_ARM:
1179 {
1180 static const StorageControllerType_T aStorageControllerTypes[] =
1181 {
1182 StorageControllerType_IntelAhci,
1183 StorageControllerType_LsiLogic,
1184 StorageControllerType_LsiLogicSas,
1185 StorageControllerType_USB,
1186 StorageControllerType_NVMe,
1187 StorageControllerType_VirtioSCSI
1188 };
1189 aSupportedStorageControllerTypes.assign(aStorageControllerTypes,
1190 aStorageControllerTypes + RT_ELEMENTS(aStorageControllerTypes));
1191 break;
1192 }
1193
1194 default:
1195 AssertFailedStmt(aSupportedStorageControllerTypes.clear());
1196 break;
1197 }
1198
1199 return S_OK;
1200}
1201
1202HRESULT PlatformProperties::getSupportedChipsetTypes(std::vector<ChipsetType_T> &aSupportedChipsetTypes)
1203{
1204 switch (mPlatformArchitecture)
1205 {
1206 case PlatformArchitecture_x86:
1207 {
1208 static const ChipsetType_T aChipsetTypes[] =
1209 {
1210 ChipsetType_PIIX3,
1211 ChipsetType_ICH9
1212 };
1213 aSupportedChipsetTypes.assign(aChipsetTypes,
1214 aChipsetTypes + RT_ELEMENTS(aChipsetTypes));
1215 break;
1216 }
1217
1218 case PlatformArchitecture_ARM:
1219 {
1220 static const ChipsetType_T aChipsetTypes[] =
1221 {
1222 ChipsetType_ARMv8Virtual
1223 };
1224 aSupportedChipsetTypes.assign(aChipsetTypes,
1225 aChipsetTypes + RT_ELEMENTS(aChipsetTypes));
1226 break;
1227 }
1228
1229 default:
1230 AssertFailedStmt(aSupportedChipsetTypes.clear());
1231 break;
1232 }
1233
1234 return S_OK;
1235}
1236
1237HRESULT PlatformProperties::getSupportedIommuTypes(std::vector<IommuType_T> &aSupportedIommuTypes)
1238{
1239 switch (mPlatformArchitecture)
1240 {
1241 case PlatformArchitecture_x86:
1242 {
1243 static const IommuType_T aIommuTypes[] =
1244 {
1245 IommuType_None,
1246 IommuType_Automatic,
1247 IommuType_AMD
1248 /** @todo Add Intel when it's supported. */
1249 };
1250 aSupportedIommuTypes.assign(aIommuTypes,
1251 aIommuTypes + RT_ELEMENTS(aIommuTypes));
1252 break;
1253 }
1254
1255 case PlatformArchitecture_ARM:
1256 {
1257 static const IommuType_T aIommuTypes[] =
1258 {
1259 IommuType_None
1260 };
1261 aSupportedIommuTypes.assign(aIommuTypes,
1262 aIommuTypes + RT_ELEMENTS(aIommuTypes));
1263 break;
1264 }
1265
1266 default:
1267 AssertFailedStmt(aSupportedIommuTypes.clear());
1268 break;
1269 }
1270
1271 return S_OK;
1272}
1273
1274HRESULT PlatformProperties::getSupportedTpmTypes(std::vector<TpmType_T> &aSupportedTpmTypes)
1275{
1276 switch (mPlatformArchitecture)
1277 {
1278 case PlatformArchitecture_x86:
1279 {
1280 static const TpmType_T aTpmTypes[] =
1281 {
1282 TpmType_None,
1283 TpmType_v1_2,
1284 TpmType_v2_0
1285 };
1286 aSupportedTpmTypes.assign(aTpmTypes,
1287 aTpmTypes + RT_ELEMENTS(aTpmTypes));
1288 break;
1289 }
1290
1291 case PlatformArchitecture_ARM:
1292 {
1293 static const TpmType_T aTpmTypes[] =
1294 {
1295 TpmType_None,
1296 TpmType_v2_0
1297 };
1298 aSupportedTpmTypes.assign(aTpmTypes,
1299 aTpmTypes + RT_ELEMENTS(aTpmTypes));
1300 break;
1301 }
1302
1303 default:
1304 AssertFailedStmt(aSupportedTpmTypes.clear());
1305 break;
1306 }
1307
1308 return S_OK;
1309}
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