VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/PlatformImpl.cpp@ 107597

Last change on this file since 107597 was 107530, checked in by vboxsync, 3 weeks ago

src/VBox/Main/src-server/PlatformImpl.cpp: Fixed warnings found by Parfait (uninitialized attributes). jiraref:VBP-1424

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.6 KB
Line 
1/* $Id: PlatformImpl.cpp 107530 2025-01-08 15:37:57Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation - Platform settings.
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_PLATFORM
29#include "PlatformImpl.h"
30#ifdef VBOX_WITH_VIRT_ARMV8
31# include "PlatformARMImpl.h"
32#endif
33#include "PlatformX86Impl.h"
34#include "PlatformPropertiesImpl.h"
35#include "MachineImpl.h"
36#include "LoggingNew.h"
37
38#include "AutoStateDep.h"
39
40#include <iprt/cpp/utils.h>
41
42#include <VBox/settings.h>
43
44
45struct Platform::Data
46{
47 Data() { }
48
49 ComObjPtr<Platform> pPeer;
50
51 // use the XML settings structure in the members for simplicity
52 Backupable<settings::Platform> bd;
53};
54
55
56/*
57 * Platform implementation.
58 */
59Platform::Platform()
60 : mParent(NULL)
61 , m(NULL)
62{
63}
64
65Platform::~Platform()
66{
67 uninit();
68}
69
70HRESULT Platform::FinalConstruct()
71{
72 return BaseFinalConstruct();
73}
74
75void Platform::FinalRelease()
76{
77 uninit();
78
79 BaseFinalRelease();
80}
81
82HRESULT Platform::init(Machine *aParent)
83{
84 /* Enclose the state transition NotReady->InInit->Ready */
85 AutoInitSpan autoInitSpan(this);
86 AssertReturn(autoInitSpan.isOk(), E_FAIL);
87
88 /* Share the parent weakly */
89 unconst(mParent) = aParent;
90
91 m = new Data();
92
93 m->bd.allocate();
94
95 /* Allocates architecture-dependent stuff.
96 * Note: We ignore the return value here, as the machine object expects a working platform object.
97 We always want a working platform object, no matter if we support the current platform architecture or not. */
98 i_initArchitecture(m->bd->architectureType);
99
100 /* Confirm a successful initialization */
101 autoInitSpan.setSucceeded();
102
103 LogFlowThisFuncLeave();
104 return S_OK;
105}
106
107/**
108 * Initializes the platform object given another platform object
109 * (a kind of copy constructor). This object shares data with
110 * the object passed as an argument.
111 *
112 * @note This object must be destroyed before the original object
113 * it shares data with is destroyed.
114 */
115HRESULT Platform::init(Machine *aParent, Platform *aThat)
116{
117 LogFlowThisFuncEnter();
118 LogFlowThisFunc(("aParent: %p, aThat: %p\n", aParent, aThat));
119
120 ComAssertRet(aParent && aThat, E_INVALIDARG);
121
122 /* Enclose the state transition NotReady->InInit->Ready */
123 AutoInitSpan autoInitSpan(this);
124 AssertReturn(autoInitSpan.isOk(), E_FAIL);
125
126 unconst(mParent) = aParent;
127
128 m = new Data();
129 m->pPeer = aThat;
130
131 AutoWriteLock thatlock(aThat COMMA_LOCKVAL_SRC_POS);
132 m->bd.share(aThat->m->bd);
133
134 /* Allocates architecture-dependent stuff.
135 * Note: We ignore the return value here, as the machine object expects a working platform object.
136 We always want a working platform object, no matter if we support the current platform architecture or not. */
137 i_initArchitecture(aThat->m->bd->architectureType, aThat);
138
139 autoInitSpan.setSucceeded();
140
141 LogFlowThisFuncLeave();
142 return S_OK;
143}
144
145/**
146 * Initializes the guest object given another guest object
147 * (a kind of copy constructor). This object makes a private copy of data
148 * of the original object passed as an argument.
149 */
150HRESULT Platform::initCopy(Machine *aParent, Platform *aThat)
151{
152 LogFlowThisFuncEnter();
153 LogFlowThisFunc(("aParent: %p, aThat: %p\n", aParent, aThat));
154
155 ComAssertRet(aParent && aThat, E_INVALIDARG);
156
157 /* Enclose the state transition NotReady->InInit->Ready */
158 AutoInitSpan autoInitSpan(this);
159 AssertReturn(autoInitSpan.isOk(), E_FAIL);
160
161 unconst(mParent) = aParent;
162
163 m = new Data();
164 // m->pPeer is left null
165
166 AutoWriteLock thatlock(aThat COMMA_LOCKVAL_SRC_POS); /** @todo r=andy Shouldn't a read lock be sufficient here? */
167 m->bd.attachCopy(aThat->m->bd);
168
169 /* Allocates architecture-dependent stuff.
170 * Note: We ignore the return value here, as the machine object expects a working platform object.
171 We always want a working platform object, no matter if we support the current platform architecture or not. */
172 i_initArchitecture(aThat->m->bd->architectureType, aThat, true /* fCopy */);
173
174 autoInitSpan.setSucceeded();
175
176 LogFlowThisFuncLeave();
177 return S_OK;
178}
179
180void Platform::uninit()
181{
182 /* Enclose the state transition Ready->InUninit->NotReady */
183 AutoUninitSpan autoUninitSpan(this);
184 if (autoUninitSpan.uninitDone())
185 return;
186
187 unconst(mParent) = NULL;
188
189 uninitArchitecture();
190
191 m->bd.free();
192
193 unconst(m->pPeer) = NULL;
194
195 delete m;
196 m = NULL;
197}
198
199/**
200 * Unitializes all platform-specific objects.
201 *
202 * Called by uninit() and i_setArchitecture().
203 */
204void Platform::uninitArchitecture()
205{
206 if (mX86)
207 {
208 mX86->uninit();
209 unconst(mX86).setNull();
210 }
211
212#ifdef VBOX_WITH_VIRT_ARMV8
213 if (mARM)
214 {
215 mARM->uninit();
216 unconst(mARM).setNull();
217 }
218#endif
219}
220
221
222// IPlatform properties
223////////////////////////////////////////////////////////////////////////////////
224
225HRESULT Platform::getArchitecture(PlatformArchitecture_T *aArchitecture)
226{
227 /* sanity */
228 AutoCaller autoCaller(this);
229 AssertComRCReturnRC(autoCaller.hrc());
230
231 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
232
233 *aArchitecture = m->bd->architectureType;
234
235 return S_OK;
236}
237
238HRESULT Platform::setArchitecture(PlatformArchitecture_T aArchitecture)
239{
240 /* sanity */
241 AutoCaller autoCaller(this);
242 AssertComRCReturnRC(autoCaller.hrc());
243
244 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
245
246 RT_NOREF(aArchitecture);
247
248 /* Currently we don't allow changing the platform architecture after the object was created.
249 * Mostly makes no sense, as this would render the VMs non-bootable and confuses users. */
250 return E_NOTIMPL;
251}
252
253HRESULT Platform::getProperties(ComPtr<IPlatformProperties> &aProperties)
254{
255 /* sanity */
256 AutoCaller autoCaller(this);
257 AssertComRCReturnRC(autoCaller.hrc());
258
259 ComObjPtr<PlatformProperties> properties;
260 HRESULT hrc = properties.createObject();
261 AssertComRCReturnRC(hrc);
262 hrc = properties->init(mParent->mParent);
263 AssertComRCReturnRC(hrc);
264
265 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
266
267 hrc = properties->i_setArchitecture(m->bd->architectureType);
268 AssertComRCReturnRC(hrc);
269
270 return properties.queryInterfaceTo(aProperties.asOutParam());
271}
272
273HRESULT Platform::getX86(ComPtr<IPlatformX86> &aX86)
274{
275 /* sanity */
276 AutoCaller autoCaller(this);
277 AssertComRCReturnRC(autoCaller.hrc());
278
279 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
280
281 if (m->bd->architectureType == PlatformArchitecture_x86)
282 if (mX86.isNotNull())
283 /** @todo mX86 is constant during life time, no need to lock. */
284 return mX86.queryInterfaceTo(aX86.asOutParam());
285
286 return setErrorBoth(VBOX_E_PLATFORM_ARCH_NOT_SUPPORTED, VERR_PLATFORM_ARCH_NOT_SUPPORTED,
287 "x86-specific platform settings are not available on this platform");
288}
289
290HRESULT Platform::getARM(ComPtr<IPlatformARM> &aARM)
291{
292 /* sanity */
293 AutoCaller autoCaller(this);
294 AssertComRCReturnRC(autoCaller.hrc());
295
296 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
297
298#ifdef VBOX_WITH_VIRT_ARMV8
299 if (m->bd->architectureType == PlatformArchitecture_ARM)
300 if (mARM.isNotNull())
301 /** @todo mARM is constant during life time, no need to lock... */
302 return mARM.queryInterfaceTo(aARM.asOutParam());
303#else
304 RT_NOREF(aARM);
305#endif
306
307 return setErrorBoth(VBOX_E_PLATFORM_ARCH_NOT_SUPPORTED, VERR_PLATFORM_ARCH_NOT_SUPPORTED,
308 "ARM-specific platform settings are not available on this platform");
309}
310
311HRESULT Platform::getChipsetType(ChipsetType_T *aChipsetType)
312{
313 /* sanity */
314 AutoCaller autoCaller(this);
315 AssertComRCReturnRC(autoCaller.hrc());
316
317 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
318
319 *aChipsetType = m->bd->chipsetType;
320
321 return S_OK;
322}
323
324HRESULT Platform::setChipsetType(ChipsetType_T aChipsetType)
325{
326 /* sanity */
327 AutoCaller autoCaller(this);
328 AssertComRCReturnRC(autoCaller.hrc());
329
330 /* the machine needs to be mutable */
331 AutoMutableStateDependency adep(mParent);
332 if (FAILED(adep.hrc())) return adep.hrc();
333
334 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
335
336 if (aChipsetType != m->bd->chipsetType)
337 {
338 m->bd.backup();
339 m->bd->chipsetType = aChipsetType;
340
341 alock.release();
342
343 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
344 mParent->i_setModified(Machine::IsModified_Platform);
345
346 // Resize network adapter array, to be finalized on commit/rollback.
347 // We must not throw away entries yet, otherwise settings are lost
348 // without a way to roll back.
349 size_t const newCount = PlatformProperties::s_getMaxNetworkAdapters(aChipsetType);
350 size_t const oldCount = mParent->mNetworkAdapters.size();
351 if (newCount > oldCount)
352 {
353 mParent->mNetworkAdapters.resize(newCount);
354 for (size_t slot = oldCount; slot < mParent->mNetworkAdapters.size(); slot++)
355 {
356 unconst(mParent->mNetworkAdapters[slot]).createObject();
357 mParent->mNetworkAdapters[slot]->init(mParent, (ULONG)slot);
358 }
359 }
360 }
361
362 return S_OK;
363}
364
365HRESULT Platform::getIommuType(IommuType_T *aIommuType)
366{
367 /* sanity */
368 AutoCaller autoCaller(this);
369 AssertComRCReturnRC(autoCaller.hrc());
370
371 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
372
373 *aIommuType = m->bd->iommuType;
374
375 return S_OK;
376}
377
378HRESULT Platform::setIommuType(IommuType_T aIommuType)
379{
380 /* sanity */
381 AutoCaller autoCaller(this);
382 AssertComRCReturnRC(autoCaller.hrc());
383
384 /* the machine needs to be mutable */
385 AutoMutableStateDependency adep(mParent);
386 if (FAILED(adep.hrc())) return adep.hrc();
387
388 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
389
390 if (aIommuType != m->bd->iommuType)
391 {
392 if (aIommuType == IommuType_Intel)
393 {
394#ifndef VBOX_WITH_IOMMU_INTEL
395 LogRelFunc(("Setting Intel IOMMU when Intel IOMMU support not available!\n"));
396 return E_UNEXPECTED;
397#endif
398 }
399
400 m->bd.backup();
401 m->bd->iommuType = aIommuType;
402
403 alock.release();
404
405 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
406 mParent->i_setModified(Machine::IsModified_Platform);
407 }
408
409 return S_OK;
410}
411
412HRESULT Platform::getRTCUseUTC(BOOL *aRTCUseUTC)
413{
414 /* sanity */
415 AutoCaller autoCaller(this);
416 AssertComRCReturnRC(autoCaller.hrc());
417
418 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
419
420 *aRTCUseUTC = m->bd->fRTCUseUTC;
421
422 return S_OK;
423}
424
425HRESULT Platform::setRTCUseUTC(BOOL aRTCUseUTC)
426{
427 /* sanity */
428 AutoCaller autoCaller(this);
429 AssertComRCReturn(autoCaller.hrc(), autoCaller.hrc());
430
431 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
432
433 if (m->bd->fRTCUseUTC != RT_BOOL(aRTCUseUTC))
434 {
435 /* Only allow it to be set to true when PoweredOff or Aborted.
436 (Clearing it is always permitted.) */
437 if (aRTCUseUTC)
438 {
439 alock.release();
440
441 /* the machine needs to be mutable */
442 AutoMutableStateDependency adep(mParent);
443 if (FAILED(adep.hrc())) return adep.hrc();
444
445 alock.acquire();
446
447 m->bd.backup();
448 m->bd->fRTCUseUTC = RT_BOOL(aRTCUseUTC);
449
450 alock.release();
451
452 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
453 mParent->i_setModified(Machine::IsModified_Platform);
454 }
455 else
456 {
457 m->bd.backup();
458 m->bd->fRTCUseUTC = RT_BOOL(aRTCUseUTC);
459 }
460 }
461
462 return S_OK;
463}
464
465
466// public methods only for internal purposes
467////////////////////////////////////////////////////////////////////////////////
468
469/**
470 * Loads settings from the given platform node.
471 * May be called once right after this object creation.
472 *
473 * @returns HRESULT
474 * @param data Configuration settings.
475 *
476 * @note Locks this object for writing.
477 */
478HRESULT Platform::i_loadSettings(const settings::Platform &data)
479{
480 AutoCaller autoCaller(this);
481 AssertComRCReturnRC(autoCaller.hrc());
482
483 AutoReadLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
484 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
485
486 // simply copy
487 m->bd.assignCopy(&data);
488
489 /* Allocates architecture-dependent stuff. */
490 HRESULT hrc = i_initArchitecture(m->bd->architectureType);
491 if (SUCCEEDED(hrc))
492 {
493 switch (m->bd->architectureType)
494 {
495 case PlatformArchitecture_x86:
496 return mX86->i_loadSettings(data.x86);
497
498#ifdef VBOX_WITH_VIRT_ARMV8
499 case PlatformArchitecture_ARM:
500 return mARM->i_loadSettings(data.arm);
501#endif
502 case PlatformArchitecture_None:
503 RT_FALL_THROUGH();
504 default:
505 break;
506 }
507 }
508
509 return setErrorBoth(VBOX_E_PLATFORM_ARCH_NOT_SUPPORTED, VERR_PLATFORM_ARCH_NOT_SUPPORTED,
510 "Platform '%s' not supported", Global::stringifyPlatformArchitecture(m->bd->architectureType));
511}
512
513/**
514 * Saves settings to the given platform node.
515 *
516 * @returns HRESULT
517 * @param data Configuration settings.
518 *
519 * @note Locks this object for reading.
520 */
521HRESULT Platform::i_saveSettings(settings::Platform &data)
522{
523 AutoCaller autoCaller(this);
524 AssertComRCReturnRC(autoCaller.hrc());
525
526 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
527
528 data = *m->bd.data();
529
530 switch (m->bd->architectureType)
531 {
532 case PlatformArchitecture_x86:
533 return mX86->i_saveSettings(data.x86);
534
535#ifdef VBOX_WITH_VIRT_ARMV8
536 case PlatformArchitecture_ARM:
537 return mARM->i_saveSettings(data.arm);
538#endif
539 case PlatformArchitecture_None:
540 RT_FALL_THROUGH();
541 default:
542 break;
543 }
544
545 return setErrorBoth(VBOX_E_PLATFORM_ARCH_NOT_SUPPORTED, VERR_PLATFORM_ARCH_NOT_SUPPORTED,
546 "Platform '%s' not supported", Global::stringifyPlatformArchitecture(m->bd->architectureType));
547}
548
549void Platform::i_rollback()
550{
551 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
552
553 if (m)
554 {
555 m->bd.rollback();
556
557 switch (m->bd->architectureType)
558 {
559 case PlatformArchitecture_x86:
560 if (mX86.isNotNull())
561 return mX86->i_rollback();
562 break;
563
564#ifdef VBOX_WITH_VIRT_ARMV8
565 case PlatformArchitecture_ARM:
566 if (mARM.isNotNull())
567 return mARM->i_rollback();
568 break;
569#endif
570 case PlatformArchitecture_None:
571 RT_FALL_THROUGH();
572 default:
573 break;
574 }
575 }
576}
577
578void Platform::i_commit()
579{
580 /* sanity */
581 AutoCaller autoCaller(this);
582 AssertComRCReturnVoid(autoCaller.hrc());
583
584 /* sanity too */
585 AutoCaller peerCaller(m->pPeer);
586 AssertComRCReturnVoid(peerCaller.hrc());
587
588 /* lock both for writing since we modify both (mPeer is "master" so locked
589 * first) */
590 AutoMultiWriteLock2 alock(m->pPeer, this COMMA_LOCKVAL_SRC_POS);
591
592 if (m->bd.isBackedUp())
593 {
594 m->bd.commit();
595
596 if (m->pPeer)
597 {
598 /* attach new data to the peer and reshare it */
599 AutoWriteLock peerlock(m->pPeer COMMA_LOCKVAL_SRC_POS);
600 m->pPeer->m->bd.attach(m->bd);
601 }
602 }
603
604 switch (m->bd->architectureType)
605 {
606 case PlatformArchitecture_x86:
607 return mX86->i_commit();
608
609#ifdef VBOX_WITH_VIRT_ARMV8
610 case PlatformArchitecture_ARM:
611 return mARM->i_commit();
612#endif
613 case PlatformArchitecture_None:
614 RT_FALL_THROUGH();
615 default:
616 break;
617 }
618
619 AssertFailedReturnVoid();
620}
621
622void Platform::i_copyFrom(Platform *aThat)
623{
624 AssertReturnVoid(aThat != NULL);
625
626 /* sanity */
627 AutoCaller autoCaller(this);
628 AssertComRCReturnVoid(autoCaller.hrc());
629
630 /* sanity too */
631 AutoCaller thatCaller(aThat);
632 AssertComRCReturnVoid(thatCaller.hrc());
633
634 /* peer is not modified, lock it for reading (aThat is "master" so locked
635 * first) */
636 AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS);
637 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
638
639 /* this will back up current data */
640 m->bd.assignCopy(aThat->m->bd);
641
642 switch (m->bd->architectureType)
643 {
644 case PlatformArchitecture_x86:
645 return mX86->i_copyFrom(aThat->mX86);
646
647#ifdef VBOX_WITH_VIRT_ARMV8
648 case PlatformArchitecture_ARM:
649 return mARM->i_copyFrom(aThat->mARM);
650#endif
651 case PlatformArchitecture_None:
652 RT_FALL_THROUGH();
653 default:
654 break;
655 }
656
657 AssertFailedReturnVoid();
658}
659
660/**
661 * Initializes the platform architecture.
662 *
663 * @returns HRESULT
664 * @retval VBOX_E_PLATFORM_ARCH_NOT_SUPPORTED if platform architecture is not supported.
665 * @param aArchitecture Platform architecture to set.
666 * @param aThat Other platform object to use for shared / copied initialization. Optional.
667 * @param fCopy Whether to copy or share the configuration from / with \a aThat.
668 *
669 * @note Creates the platform-specific sub object (e.g. x86 or ARM).
670 * Usually only called when creating a new machine or loading settings.
671 */
672HRESULT Platform::i_initArchitecture(PlatformArchitecture_T aArchitecture, Platform *aThat /* = NULL */, bool fCopy /* = false */)
673{
674 /* sanity */
675 AutoCaller autoCaller(this);
676 AssertComRCReturn(autoCaller.hrc(), autoCaller.hrc());
677
678 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
679
680 HRESULT hrc = S_OK;
681
682 /* Currently we only keep the current platform-specific object around,
683 * e.g. we destroy any data for the former architecture (if any). */
684 uninitArchitecture();
685
686 switch (aArchitecture)
687 {
688 case PlatformArchitecture_x86:
689 {
690 /* Create associated x86-specific platform object. */
691 Assert(mX86.isNull());
692 hrc = unconst(mX86).createObject();
693 ComAssertComRCRetRC(hrc);
694 if (aThat)
695 {
696 if (fCopy)
697 hrc = mX86->initCopy(this, mParent, aThat->mX86);
698 else
699 hrc = mX86->init(this, mParent, aThat->mX86);
700 }
701 else
702 hrc = mX86->init(this, mParent);
703 break;
704 }
705
706#ifdef VBOX_WITH_VIRT_ARMV8
707 case PlatformArchitecture_ARM:
708 {
709 /* Create associated ARM-specific platform object. */
710 Assert(mARM.isNull());
711 unconst(mARM).createObject();
712 ComAssertComRCRetRC(hrc);
713 if (aThat)
714 {
715 if (fCopy)
716 hrc = mARM->initCopy(this, mParent, aThat->mARM);
717 else
718 hrc = mARM->init(this, mParent, aThat->mARM);
719 }
720 else
721 hrc = mARM->init(this, mParent);
722 break;
723 }
724#endif
725 default:
726 hrc = VBOX_E_PLATFORM_ARCH_NOT_SUPPORTED;
727 break;
728 }
729
730 if (SUCCEEDED(hrc))
731 {
732 m->bd->architectureType = aArchitecture;
733 LogRel(("Platform architecture set to '%s'\n", Global::stringifyPlatformArchitecture(m->bd->architectureType)));
734 }
735
736 return hrc;
737}
738
739HRESULT Platform::i_applyDefaults(GuestOSType *aOsType)
740{
741 /* sanity */
742 AutoCaller autoCaller(this);
743 AssertComRCReturn(autoCaller.hrc(), autoCaller.hrc());
744
745 HRESULT hrc = S_OK;
746
747 ChipsetType_T enmChipsetType = ChipsetType_Null;
748 IommuType_T enmIommuType = IommuType_None;
749 BOOL fRTCUseUTC = FALSE;
750
751 if (aOsType)
752 {
753 hrc = aOsType->COMGETTER(RecommendedChipset)(&enmChipsetType);
754 AssertComRCReturnRC(hrc);
755
756 hrc = aOsType->COMGETTER(RecommendedIommuType)(&enmIommuType);
757 AssertComRCReturnRC(hrc);
758
759 hrc = aOsType->COMGETTER(RecommendedRTCUseUTC)(&fRTCUseUTC);
760 AssertComRCReturnRC(hrc);
761 }
762 else
763 {
764 /* No guest OS type object. Pick some plausible defaults which the
765 * host can handle. There's no way to know or validate anything. */
766 switch (m->bd->architectureType)
767 {
768 case PlatformArchitecture_x86:
769 {
770 /* Note: These are the value we ever had, so default to these. */
771 enmChipsetType = ChipsetType_PIIX3;
772 enmIommuType = IommuType_None;
773 fRTCUseUTC = FALSE;
774 break;
775 }
776
777 case PlatformArchitecture_ARM:
778 {
779 /* Note: These are the value we ever had, so default to these. */
780 enmChipsetType = ChipsetType_ARMv8Virtual;
781 enmIommuType = IommuType_None;
782 fRTCUseUTC = TRUE; /** @todo BUGBUG Is this correct for ARM? */
783 break;
784 }
785
786 default:
787 AssertFailed();
788 break;
789 }
790 }
791
792 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
793
794 m->bd->chipsetType = enmChipsetType;
795 m->bd->iommuType = enmIommuType;
796 m->bd->fRTCUseUTC = fRTCUseUTC;
797
798 alock.release();
799
800 /* Allocates architecture-dependent stuff. */
801 hrc = i_initArchitecture(m->bd->architectureType);
802 AssertComRCReturnRC(hrc);
803
804 /* Do the same for the platform specifics. */
805 switch (m->bd->architectureType)
806 {
807 case PlatformArchitecture_x86:
808 hrc = mX86->i_applyDefaults(aOsType);
809 break;
810
811#ifdef VBOX_WITH_VIRT_ARMV8
812 case PlatformArchitecture_ARM:
813 hrc = mARM->i_applyDefaults(aOsType);
814 break;
815#endif
816 case PlatformArchitecture_None:
817 RT_FALL_THROUGH();
818 default:
819 hrc = VBOX_E_NOT_SUPPORTED;
820 break;
821 }
822 AssertComRCReturnRC(hrc);
823
824 /* Sanity. */
825 Assert(enmChipsetType != ChipsetType_Null);
826
827 return hrc;
828}
829
830/**
831 * Internal helper to return the currently set architecture of this platform.
832 *
833 * @returns Currently set architecture.
834 *
835 * @note Takes the read lock.
836 */
837PlatformArchitecture_T Platform::i_getArchitecture(void)
838{
839 PlatformArchitecture_T enmArchitecture;
840 HRESULT const hrc = getArchitecture(&enmArchitecture);
841 AssertComRCReturn(hrc, PlatformArchitecture_None);
842 return enmArchitecture;
843}
844
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