VirtualBox

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

Last change on this file since 107017 was 107017, checked in by vboxsync, 3 months ago

Main: Expose different parallel port counts in PlatformProperties::getParallelPortCount(). ​bugref:10384

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 40.5 KB
Line 
1/* $Id: PlatformPropertiesImpl.cpp 107017 2024-11-15 15:07:41Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation - Platform properties.
4 */
5
6/*
7 * Copyright (C) 2023-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#define LOG_GROUP LOG_GROUP_MAIN_PLATFORMPROPERTIES
29#include "PlatformPropertiesImpl.h"
30#include "GraphicsAdapterImpl.h" /* For static helper functions. */
31#include "VirtualBoxImpl.h"
32#include "LoggingNew.h"
33#include "Global.h"
34
35#include <algorithm>
36
37#include <iprt/asm.h>
38#include <iprt/cpp/utils.h>
39
40#include <VBox/param.h> /* For VRAM ranges. */
41#include <VBox/settings.h>
42
43// generated header
44#include "SchemaDefs.h"
45
46
47/*
48 * PlatformProperties implementation.
49 */
50PlatformProperties::PlatformProperties()
51 : mParent(NULL)
52 , mPlatformArchitecture(PlatformArchitecture_None)
53 , mfIsHost(false)
54{
55}
56
57PlatformProperties::~PlatformProperties()
58{
59 uninit();
60}
61
62HRESULT PlatformProperties::FinalConstruct()
63{
64 return BaseFinalConstruct();
65}
66
67void PlatformProperties::FinalRelease()
68{
69 uninit();
70
71 BaseFinalRelease();
72}
73
74/**
75 * Initializes platform properties.
76 *
77 * @returns HRESULT
78 * @param aParent Pointer to IVirtualBox parent object (weak).
79 * @param fIsHost Set to \c true if this instance handles platform properties of the host,
80 * or set to \c false for guests (default).
81 */
82HRESULT PlatformProperties::init(VirtualBox *aParent, bool fIsHost /* = false */)
83{
84 /* Enclose the state transition NotReady->InInit->Ready */
85 AutoInitSpan autoInitSpan(this);
86 AssertReturn(autoInitSpan.isOk(), E_FAIL);
87
88 unconst(mParent) = aParent;
89
90 m = new settings::PlatformProperties;
91
92 unconst(mfIsHost) = fIsHost;
93
94 if (mfIsHost)
95 {
96 /* On Windows, macOS and Solaris hosts, HW virtualization use isn't exclusive
97 * by default so that VT-x or AMD-V can be shared with other
98 * hypervisors without requiring user intervention.
99 * NB: See also PlatformProperties constructor in settings.h
100 */
101#if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) || defined(RT_OS_SOLARIS)
102 m->fExclusiveHwVirt = false; /** @todo BUGBUG Applies for MacOS on ARM as well? */
103#else
104 m->fExclusiveHwVirt = true;
105#endif
106 }
107
108 /* Confirm a successful initialization */
109 autoInitSpan.setSucceeded();
110
111 return S_OK;
112}
113
114/**
115 * Sets the platform architecture.
116 *
117 * @returns HRESULT
118 * @param aArchitecture Platform architecture to set.
119 *
120 * @note Usually only called when creating a new machine.
121 */
122HRESULT PlatformProperties::i_setArchitecture(PlatformArchitecture_T aArchitecture)
123{
124 /* sanity */
125 AutoCaller autoCaller(this);
126 AssertComRCReturn(autoCaller.hrc(), autoCaller.hrc());
127
128 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
129
130 mPlatformArchitecture = aArchitecture;
131
132 return S_OK;
133}
134
135/**
136 * Returns the host's platform architecture.
137 *
138 * @returns The host's platform architecture.
139 */
140PlatformArchitecture_T PlatformProperties::s_getHostPlatformArchitecture()
141{
142#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
143 return PlatformArchitecture_x86;
144#elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
145 return PlatformArchitecture_ARM;
146#else
147# error "Port me!"
148 return PlatformArchitecture_None;
149#endif
150}
151
152void PlatformProperties::uninit()
153{
154 /* Enclose the state transition Ready->InUninit->NotReady */
155 AutoUninitSpan autoUninitSpan(this);
156 if (autoUninitSpan.uninitDone())
157 return;
158
159 if (m)
160 {
161 delete m;
162 m = NULL;
163 }
164}
165
166HRESULT PlatformProperties::getSerialPortCount(ULONG *count)
167{
168 /* no need to lock, this is const */
169 *count = SchemaDefs::SerialPortCount;
170
171 return S_OK;
172}
173
174HRESULT PlatformProperties::getParallelPortCount(ULONG *count)
175{
176 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 };
784 aSupportedNetworkAdapterTypes.assign(aNetworkAdapterTypes + 1 /* Don't include _Null */,
785 aNetworkAdapterTypes + RT_ELEMENTS(aNetworkAdapterTypes));
786 break;
787 }
788
789 case PlatformArchitecture_ARM:
790 {
791 static const NetworkAdapterType_T aNetworkAdapterTypes[] =
792 {
793 NetworkAdapterType_Null
794#ifdef VBOX_WITH_E1000
795 , NetworkAdapterType_I82540EM
796 , NetworkAdapterType_I82543GC
797 , NetworkAdapterType_I82545EM
798#endif
799#ifdef VBOX_WITH_VIRTIO
800 , NetworkAdapterType_Virtio
801#endif
802 };
803 aSupportedNetworkAdapterTypes.assign(aNetworkAdapterTypes + 1 /* Don't include _Null */,
804 aNetworkAdapterTypes + RT_ELEMENTS(aNetworkAdapterTypes));
805 break;
806 }
807
808 default:
809 AssertFailedStmt(aSupportedNetworkAdapterTypes.clear());
810 break;
811 }
812
813 return S_OK;
814}
815
816HRESULT PlatformProperties::getSupportedUartTypes(std::vector<UartType_T> &aSupportedUartTypes)
817{
818 static const UartType_T aUartTypes[] =
819 {
820 UartType_U16450,
821 UartType_U16550A,
822 UartType_U16750
823 };
824 aSupportedUartTypes.assign(aUartTypes,
825 aUartTypes + RT_ELEMENTS(aUartTypes));
826 return S_OK;
827}
828
829HRESULT PlatformProperties::getSupportedUSBControllerTypes(std::vector<USBControllerType_T> &aSupportedUSBControllerTypes)
830{
831 static const USBControllerType_T aUSBControllerTypes[] =
832 {
833 USBControllerType_OHCI,
834 USBControllerType_EHCI,
835 USBControllerType_XHCI
836 };
837 aSupportedUSBControllerTypes.assign(aUSBControllerTypes,
838 aUSBControllerTypes + RT_ELEMENTS(aUSBControllerTypes));
839 return S_OK;
840}
841
842/**
843 * Static helper function to return all supported features for a given graphics controller.
844 *
845 * @returns VBox status code.
846 * @param enmArchitecture Platform architecture to query a feature for.
847 * @param enmController Graphics controller to return supported features for.
848 * @param vecSupportedGraphicsFeatures Returned features on success.
849 */
850/* static */
851int PlatformProperties::s_getSupportedGraphicsControllerFeatures(PlatformArchitecture_T enmArchitecture,
852 GraphicsControllerType_T enmController,
853 std::vector<GraphicsFeature_T> &vecSupportedGraphicsFeatures)
854{
855 vecSupportedGraphicsFeatures.clear();
856
857 /* Note! The legacy VHWA acceleration has been disabled completely (see @bugref{9691}). */
858 switch (enmArchitecture)
859 {
860 case PlatformArchitecture_x86:
861 case PlatformArchitecture_ARM:
862 {
863 switch (enmController)
864 {
865 case GraphicsControllerType_VMSVGA:
866 case GraphicsControllerType_VBoxSVGA:
867#ifdef VBOX_WITH_VMSVGA
868# ifdef VBOX_WITH_3D_ACCELERATION
869 vecSupportedGraphicsFeatures.push_back(GraphicsFeature_Acceleration3D);
870# endif
871#endif
872 return VINF_SUCCESS;
873
874 case GraphicsControllerType_VBoxVGA:
875 case GraphicsControllerType_QemuRamFB:
876 /* None supported. */
877 return VINF_SUCCESS;
878
879 /* (no default to get compiler warnings) */
880 case GraphicsControllerType_Null:
881#ifdef VBOX_WITH_XPCOM
882 case GraphicsControllerType_32BitHack:
883#endif
884 break;
885 }
886 break;
887 }
888
889 /* (no default to get compiler warnings) */
890 case PlatformArchitecture_None:
891#ifdef VBOX_WITH_XPCOM
892 case PlatformArchitecture_32BitHack:
893#endif
894 break;
895 }
896 return VERR_INVALID_PARAMETER;
897}
898
899/**
900 * Static helper function to return whether a given graphics feature for a graphics controller is enabled or not.
901 *
902 * @returns \c true if the given feature is supported, or \c false if not.
903 * @param enmArchitecture Platform architecture to query a feature for.
904 * @param enmController Graphics controlller to query a feature for.
905 * @param enmFeature Feature to query.
906 */
907/* static */
908bool PlatformProperties::s_isGraphicsControllerFeatureSupported(PlatformArchitecture_T enmArchitecture,
909 GraphicsControllerType_T enmController,
910 GraphicsFeature_T enmFeature)
911{
912 std::vector<GraphicsFeature_T> vecSupportedGraphicsFeatures;
913 int vrc = PlatformProperties::s_getSupportedGraphicsControllerFeatures(enmArchitecture, enmController,
914 vecSupportedGraphicsFeatures);
915 if (RT_SUCCESS(vrc))
916 return std::find(vecSupportedGraphicsFeatures.begin(),
917 vecSupportedGraphicsFeatures.end(), enmFeature) != vecSupportedGraphicsFeatures.end();
918 return false;
919}
920
921/**
922 * Returns the [minimum, maximum] VRAM range and stride size for a given graphics controller.
923 *
924 * @returns HRESULT
925 * @param aGraphicsControllerType Graphics controller type to return values for.
926 * @param fAccelerate3DEnabled whether 3D acceleration is enabled / disabled for the selected graphics controller.
927 * @param aMinMB Where to return the minimum VRAM (in MB).
928 * @param aMaxMB Where to return the maximum VRAM (in MB).
929 * @param aStrideSizeMB Where to return stride size (in MB). Optional, can be NULL.
930 */
931/* static */
932HRESULT PlatformProperties::s_getSupportedVRAMRange(GraphicsControllerType_T aGraphicsControllerType, BOOL fAccelerate3DEnabled,
933 ULONG *aMinMB, ULONG *aMaxMB, ULONG *aStrideSizeMB)
934{
935 size_t cbMin;
936 size_t cbMax;
937 size_t cbStride = _1M; /* Default stride for all controllers. */
938
939 switch (aGraphicsControllerType)
940 {
941 case GraphicsControllerType_VBoxVGA:
942 {
943 cbMin = VGA_VRAM_MIN;
944 cbMax = VGA_VRAM_MAX;
945 break;
946 }
947
948 case GraphicsControllerType_VMSVGA:
949 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(mPlatformArchitecture,
1019 aGraphicsControllerType, aSupportedGraphicsFeatures);
1020 if (RT_SUCCESS(vrc))
1021 return S_OK;
1022 return setError(E_INVALIDARG, tr("The graphics controller type (%d) is invalid"), aGraphicsControllerType);
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_SATA,
1132 StorageBus_SCSI,
1133 StorageBus_SAS,
1134 StorageBus_USB,
1135 StorageBus_PCIe,
1136 StorageBus_VirtioSCSI
1137 };
1138 aSupportedStorageBuses.assign(aStorageBuses,
1139 aStorageBuses + RT_ELEMENTS(aStorageBuses));
1140 break;
1141 }
1142
1143 default:
1144 AssertFailedStmt(aSupportedStorageBuses.clear());
1145 break;
1146 }
1147
1148 return S_OK;
1149}
1150
1151HRESULT PlatformProperties::getSupportedStorageControllerTypes(std::vector<StorageControllerType_T> &aSupportedStorageControllerTypes)
1152{
1153 switch (mPlatformArchitecture)
1154 {
1155 case PlatformArchitecture_x86:
1156 {
1157 static const StorageControllerType_T aStorageControllerTypes[] =
1158 {
1159 StorageControllerType_IntelAhci,
1160 StorageControllerType_PIIX4,
1161 StorageControllerType_PIIX3,
1162 StorageControllerType_ICH6,
1163 StorageControllerType_LsiLogic,
1164 StorageControllerType_BusLogic,
1165 StorageControllerType_I82078,
1166 StorageControllerType_LsiLogicSas,
1167 StorageControllerType_USB,
1168 StorageControllerType_NVMe,
1169 StorageControllerType_VirtioSCSI
1170 };
1171 aSupportedStorageControllerTypes.assign(aStorageControllerTypes,
1172 aStorageControllerTypes + RT_ELEMENTS(aStorageControllerTypes));
1173 break;
1174 }
1175
1176 case PlatformArchitecture_ARM:
1177 {
1178 static const StorageControllerType_T aStorageControllerTypes[] =
1179 {
1180 StorageControllerType_IntelAhci,
1181 StorageControllerType_LsiLogic,
1182 StorageControllerType_LsiLogicSas,
1183 StorageControllerType_USB,
1184 StorageControllerType_NVMe,
1185 StorageControllerType_VirtioSCSI
1186 };
1187 aSupportedStorageControllerTypes.assign(aStorageControllerTypes,
1188 aStorageControllerTypes + RT_ELEMENTS(aStorageControllerTypes));
1189 break;
1190 }
1191
1192 default:
1193 AssertFailedStmt(aSupportedStorageControllerTypes.clear());
1194 break;
1195 }
1196
1197 return S_OK;
1198}
1199
1200HRESULT PlatformProperties::getSupportedChipsetTypes(std::vector<ChipsetType_T> &aSupportedChipsetTypes)
1201{
1202 switch (mPlatformArchitecture)
1203 {
1204 case PlatformArchitecture_x86:
1205 {
1206 static const ChipsetType_T aChipsetTypes[] =
1207 {
1208 ChipsetType_PIIX3,
1209 ChipsetType_ICH9
1210 };
1211 aSupportedChipsetTypes.assign(aChipsetTypes,
1212 aChipsetTypes + RT_ELEMENTS(aChipsetTypes));
1213 break;
1214 }
1215
1216 case PlatformArchitecture_ARM:
1217 {
1218 static const ChipsetType_T aChipsetTypes[] =
1219 {
1220 ChipsetType_ARMv8Virtual
1221 };
1222 aSupportedChipsetTypes.assign(aChipsetTypes,
1223 aChipsetTypes + RT_ELEMENTS(aChipsetTypes));
1224 break;
1225 }
1226
1227 default:
1228 AssertFailedStmt(aSupportedChipsetTypes.clear());
1229 break;
1230 }
1231
1232 return S_OK;
1233}
1234
1235HRESULT PlatformProperties::getSupportedIommuTypes(std::vector<IommuType_T> &aSupportedIommuTypes)
1236{
1237 switch (mPlatformArchitecture)
1238 {
1239 case PlatformArchitecture_x86:
1240 {
1241 static const IommuType_T aIommuTypes[] =
1242 {
1243 IommuType_None,
1244 IommuType_Automatic,
1245 IommuType_AMD
1246 /** @todo Add Intel when it's supported. */
1247 };
1248 aSupportedIommuTypes.assign(aIommuTypes,
1249 aIommuTypes + RT_ELEMENTS(aIommuTypes));
1250 break;
1251 }
1252
1253 case PlatformArchitecture_ARM:
1254 {
1255 static const IommuType_T aIommuTypes[] =
1256 {
1257 IommuType_None
1258 };
1259 aSupportedIommuTypes.assign(aIommuTypes,
1260 aIommuTypes + RT_ELEMENTS(aIommuTypes));
1261 break;
1262 }
1263
1264 default:
1265 AssertFailedStmt(aSupportedIommuTypes.clear());
1266 break;
1267 }
1268
1269 return S_OK;
1270}
1271
1272HRESULT PlatformProperties::getSupportedTpmTypes(std::vector<TpmType_T> &aSupportedTpmTypes)
1273{
1274 switch (mPlatformArchitecture)
1275 {
1276 case PlatformArchitecture_x86:
1277 {
1278 static const TpmType_T aTpmTypes[] =
1279 {
1280 TpmType_None,
1281 TpmType_v1_2,
1282 TpmType_v2_0
1283 };
1284 aSupportedTpmTypes.assign(aTpmTypes,
1285 aTpmTypes + RT_ELEMENTS(aTpmTypes));
1286 break;
1287 }
1288
1289 case PlatformArchitecture_ARM:
1290 {
1291 static const TpmType_T aTpmTypes[] =
1292 {
1293 TpmType_None,
1294 TpmType_v2_0
1295 };
1296 aSupportedTpmTypes.assign(aTpmTypes,
1297 aTpmTypes + RT_ELEMENTS(aTpmTypes));
1298 break;
1299 }
1300
1301 default:
1302 AssertFailedStmt(aSupportedTpmTypes.clear());
1303 break;
1304 }
1305
1306 return S_OK;
1307}
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