VirtualBox

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

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

Main/PlatformImpl.cpp: Unreachable NOREF in switch in Platform::getARM. jiraref:VBP-1171

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