VirtualBox

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

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

Copyright year updates by scm.

  • 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 106061 2024-09-16 14:03:52Z 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_VBoxSVGA:
851 {
852#if defined(VBOX_WITH_VIDEOHWACCEL) || defined(VBOX_WITH_3D_ACCELERATION) /* Work around zero-sized arrays. */
853 static const GraphicsFeature_T s_aGraphicsFeatures[] =
854 {
855# ifdef VBOX_WITH_VIDEOHWACCEL
856 /* @bugref{9691} -- The legacy VHWA acceleration has been disabled completely. */
857 //GraphicsFeature_Acceleration2DVideo,
858# endif
859# ifdef VBOX_WITH_3D_ACCELERATION
860 GraphicsFeature_Acceleration3D
861# endif
862 };
863 RT_CPP_VECTOR_ASSIGN_ARRAY(vecSupportedGraphicsFeatures, s_aGraphicsFeatures);
864# endif
865 break;
866 }
867#endif /* VBOX_WITH_VMSVGA */
868 case GraphicsControllerType_VBoxVGA:
869 RT_FALL_THROUGH();
870 case GraphicsControllerType_QemuRamFB:
871 {
872 /* None supported. */
873 break;
874 }
875
876 default:
877 /* In case GraphicsControllerType_VBoxSVGA is not available. */
878 break;
879 }
880
881 break;
882 }
883
884 case PlatformArchitecture_ARM:
885 {
886 /* None supported. */
887 break;
888 }
889
890 default:
891 break;
892 }
893
894 return VINF_SUCCESS;
895}
896
897/**
898 * Static helper function to return whether a given graphics feature for a graphics controller is enabled or not.
899 *
900 * @returns \c true if the given feature is supported, or \c false if not.
901 * @param enmArchitecture Platform architecture to query a feature for.
902 * @param enmController Graphics controlller to query a feature for.
903 * @param enmFeature Feature to query.
904 */
905/* static */
906bool PlatformProperties::s_isGraphicsControllerFeatureSupported(PlatformArchitecture_T enmArchitecture,
907 GraphicsControllerType_T enmController,
908 GraphicsFeature_T enmFeature)
909{
910 std::vector<GraphicsFeature_T> vecSupportedGraphicsFeatures;
911 int vrc = PlatformProperties::s_getSupportedGraphicsControllerFeatures(enmArchitecture, enmController,
912 vecSupportedGraphicsFeatures);
913 if (RT_SUCCESS(vrc))
914 return std::find(vecSupportedGraphicsFeatures.begin(),
915 vecSupportedGraphicsFeatures.end(), enmFeature) != vecSupportedGraphicsFeatures.end();
916 return false;
917}
918
919/**
920 * Returns the [minimum, maximum] VRAM range and stride size for a given graphics controller.
921 *
922 * @returns HRESULT
923 * @param aGraphicsControllerType Graphics controller type to return values for.
924 * @param fAccelerate3DEnabled whether 3D acceleration is enabled / disabled for the selected graphics controller.
925 * @param aMinMB Where to return the minimum VRAM (in MB).
926 * @param aMaxMB Where to return the maximum VRAM (in MB).
927 * @param aStrideSizeMB Where to return stride size (in MB). Optional, can be NULL.
928 */
929/* static */
930HRESULT PlatformProperties::s_getSupportedVRAMRange(GraphicsControllerType_T aGraphicsControllerType, BOOL fAccelerate3DEnabled,
931 ULONG *aMinMB, ULONG *aMaxMB, ULONG *aStrideSizeMB)
932{
933 size_t cbMin;
934 size_t cbMax;
935 size_t cbStride = _1M; /* Default stride for all controllers. */
936
937 switch (aGraphicsControllerType)
938 {
939 case GraphicsControllerType_VBoxVGA:
940 {
941 cbMin = VGA_VRAM_MIN;
942 cbMax = VGA_VRAM_MAX;
943 break;
944 }
945
946 case GraphicsControllerType_VMSVGA:
947 RT_FALL_THROUGH();
948 case GraphicsControllerType_VBoxSVGA:
949 {
950 if (fAccelerate3DEnabled)
951 cbMin = VBOX_SVGA_VRAM_MIN_SIZE_3D;
952 else
953 cbMin = VBOX_SVGA_VRAM_MIN_SIZE;
954 /* We don't want to limit ourselves to VBOX_SVGA_VRAM_MAX_SIZE,
955 * so we use VGA_VRAM_MAX for all controllers. */
956 cbMax = VGA_VRAM_MAX;
957 break;
958 }
959
960 case GraphicsControllerType_QemuRamFB:
961 {
962 /* We seem to hardcode 32-bit (4 bytes) as BPP, see RAMFB_BPP in QemuRamfb.c. */
963 cbMin = 4 /* BPP in bytes */ * 16 * 16; /* Values taken from qemu/hw/display/ramfb.c */
964 cbMax = 4 /* BPP in bytes */ * 16000 * 12000; /* Values taken from bochs-vbe.h. */
965 /* Make the maximum value a power of two. */
966 cbMax = RT_BIT_64(ASMBitLastSetU64(cbMax));
967 break;
968 }
969
970 default:
971 return E_INVALIDARG;
972 }
973
974 /* Sanity. We want all max values to be a power of two. */
975 AssertMsg(RT_IS_POWER_OF_TWO(cbMax), ("Maximum VRAM value is not a power of two!\n"));
976
977 /* Convert bytes -> MB, align to stride. */
978 cbMin = (ULONG)(RT_ALIGN_64(cbMin, cbStride) / _1M);
979 cbMax = (ULONG)(RT_ALIGN_64(cbMax, cbStride) / _1M);
980 cbStride = (ULONG)cbStride / _1M;
981
982 /* Finally, clamp the values to our schema definitions before returning. */
983 if (cbMax > SchemaDefs::MaxGuestVRAM)
984 cbMax = SchemaDefs::MaxGuestVRAM;
985
986 *aMinMB = (ULONG)cbMin;
987 *aMaxMB = (ULONG)cbMax;
988 if (aStrideSizeMB)
989 *aStrideSizeMB = (ULONG)cbStride;
990
991 return S_OK;
992}
993
994HRESULT PlatformProperties::getSupportedVRAMRange(GraphicsControllerType_T aGraphicsControllerType, BOOL fAccelerate3DEnabled,
995 ULONG *aMinMB, ULONG *aMaxMB, ULONG *aStrideSizeMB)
996{
997 HRESULT hrc = PlatformProperties::s_getSupportedVRAMRange(aGraphicsControllerType, fAccelerate3DEnabled, aMinMB, aMaxMB,
998 aStrideSizeMB);
999 switch (hrc)
1000 {
1001 case VBOX_E_NOT_SUPPORTED:
1002 return setError(VBOX_E_NOT_SUPPORTED, tr("Selected graphics controller not supported in this version"));
1003
1004 case E_INVALIDARG:
1005 return setError(E_INVALIDARG, tr("The graphics controller type (%d) is invalid"), aGraphicsControllerType);
1006
1007 default:
1008 break;
1009 }
1010
1011 return S_OK;
1012}
1013
1014HRESULT PlatformProperties::getSupportedGfxFeaturesForType(GraphicsControllerType_T aGraphicsControllerType,
1015 std::vector<GraphicsFeature_T> &aSupportedGraphicsFeatures)
1016{
1017 int vrc = PlatformProperties::s_getSupportedGraphicsControllerFeatures(mPlatformArchitecture,
1018 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