VirtualBox

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

Last change on this file since 103131 was 102455, checked in by vboxsync, 10 months ago

Main: Removed some more BUGBUG entries and documented empty / non-implemented code areas where needed. bugref:10384

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.5 KB
Line 
1/* $Id: PlatformImpl.cpp 102455 2023-12-04 15:53:11Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation - Platform settings.
4 */
5
6/*
7 * Copyright (C) 2023 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 switch (m->bd->architectureType)
281 {
282 case PlatformArchitecture_x86:
283 {
284 if (mX86.isNotNull())
285 {
286 /* mX86 is constant during life time, no need to lock. */
287 return mX86.queryInterfaceTo(aX86.asOutParam());
288 }
289 break;
290 }
291
292 default:
293 /* For anything else return an error. */
294 break;
295 }
296
297 return setErrorBoth(VBOX_E_PLATFORM_ARCH_NOT_SUPPORTED, VERR_PLATFORM_ARCH_NOT_SUPPORTED,
298 "x86-specific platform settings are not available on this platform");
299}
300
301HRESULT Platform::getARM(ComPtr<IPlatformARM> &aARM)
302{
303 /* sanity */
304 AutoCaller autoCaller(this);
305 AssertComRCReturnRC(autoCaller.hrc());
306
307 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
308
309 switch (m->bd->architectureType)
310 {
311#ifdef VBOX_WITH_VIRT_ARMV8
312 case PlatformArchitecture_ARM:
313 {
314 if (mARM.isNotNull())
315 {
316 /* mARM is constant during life time, no need to lock. */
317 return mARM.queryInterfaceTo(aARM.asOutParam());
318 }
319 break;
320 }
321#else
322 RT_NOREF(aARM);
323#endif
324 default:
325 /* For anything else return an error. */
326 break;
327 }
328
329 return setErrorBoth(VBOX_E_PLATFORM_ARCH_NOT_SUPPORTED, VERR_PLATFORM_ARCH_NOT_SUPPORTED,
330 "ARM-specific platform settings are not available on this platform");
331}
332
333HRESULT Platform::getChipsetType(ChipsetType_T *aChipsetType)
334{
335 /* sanity */
336 AutoCaller autoCaller(this);
337 AssertComRCReturnRC(autoCaller.hrc());
338
339 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
340
341 *aChipsetType = m->bd->chipsetType;
342
343 return S_OK;
344}
345
346HRESULT Platform::setChipsetType(ChipsetType_T aChipsetType)
347{
348 /* sanity */
349 AutoCaller autoCaller(this);
350 AssertComRCReturnRC(autoCaller.hrc());
351
352 /* the machine needs to be mutable */
353 AutoMutableStateDependency adep(mParent);
354 if (FAILED(adep.hrc())) return adep.hrc();
355
356 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
357
358 if (aChipsetType != m->bd->chipsetType)
359 {
360 m->bd.backup();
361 m->bd->chipsetType = aChipsetType;
362
363 alock.release();
364
365 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
366 mParent->i_setModified(Machine::IsModified_Platform);
367
368 // Resize network adapter array, to be finalized on commit/rollback.
369 // We must not throw away entries yet, otherwise settings are lost
370 // without a way to roll back.
371 size_t const newCount = PlatformProperties::s_getMaxNetworkAdapters(aChipsetType);
372 size_t const oldCount = mParent->mNetworkAdapters.size();
373 if (newCount > oldCount)
374 {
375 mParent->mNetworkAdapters.resize(newCount);
376 for (size_t slot = oldCount; slot < mParent->mNetworkAdapters.size(); slot++)
377 {
378 unconst(mParent->mNetworkAdapters[slot]).createObject();
379 mParent->mNetworkAdapters[slot]->init(mParent, (ULONG)slot);
380 }
381 }
382 }
383
384 return S_OK;
385}
386
387HRESULT Platform::getIommuType(IommuType_T *aIommuType)
388{
389 /* sanity */
390 AutoCaller autoCaller(this);
391 AssertComRCReturnRC(autoCaller.hrc());
392
393 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
394
395 *aIommuType = m->bd->iommuType;
396
397 return S_OK;
398}
399
400HRESULT Platform::setIommuType(IommuType_T aIommuType)
401{
402 /* sanity */
403 AutoCaller autoCaller(this);
404 AssertComRCReturnRC(autoCaller.hrc());
405
406 /* the machine needs to be mutable */
407 AutoMutableStateDependency adep(mParent);
408 if (FAILED(adep.hrc())) return adep.hrc();
409
410 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
411
412 if (aIommuType != m->bd->iommuType)
413 {
414 if (aIommuType == IommuType_Intel)
415 {
416#ifndef VBOX_WITH_IOMMU_INTEL
417 LogRelFunc(("Setting Intel IOMMU when Intel IOMMU support not available!\n"));
418 return E_UNEXPECTED;
419#endif
420 }
421
422 m->bd.backup();
423 m->bd->iommuType = aIommuType;
424
425 alock.release();
426
427 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
428 mParent->i_setModified(Machine::IsModified_Platform);
429 }
430
431 return S_OK;
432}
433
434HRESULT Platform::getRTCUseUTC(BOOL *aRTCUseUTC)
435{
436 /* sanity */
437 AutoCaller autoCaller(this);
438 AssertComRCReturnRC(autoCaller.hrc());
439
440 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
441
442 *aRTCUseUTC = m->bd->fRTCUseUTC;
443
444 return S_OK;
445}
446
447HRESULT Platform::setRTCUseUTC(BOOL aRTCUseUTC)
448{
449 /* sanity */
450 AutoCaller autoCaller(this);
451 AssertComRCReturn(autoCaller.hrc(), autoCaller.hrc());
452
453 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
454
455 if (m->bd->fRTCUseUTC != RT_BOOL(aRTCUseUTC))
456 {
457 /* Only allow it to be set to true when PoweredOff or Aborted.
458 (Clearing it is always permitted.) */
459 if (aRTCUseUTC)
460 {
461 alock.release();
462
463 /* the machine needs to be mutable */
464 AutoMutableStateDependency adep(mParent);
465 if (FAILED(adep.hrc())) return adep.hrc();
466
467 alock.acquire();
468
469 m->bd.backup();
470 m->bd->fRTCUseUTC = RT_BOOL(aRTCUseUTC);
471
472 alock.release();
473
474 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
475 mParent->i_setModified(Machine::IsModified_Platform);
476 }
477 else
478 {
479 m->bd.backup();
480 m->bd->fRTCUseUTC = RT_BOOL(aRTCUseUTC);
481 }
482 }
483
484 return S_OK;
485}
486
487
488// public methods only for internal purposes
489////////////////////////////////////////////////////////////////////////////////
490
491/**
492 * Loads settings from the given platform node.
493 * May be called once right after this object creation.
494 *
495 * @returns HRESULT
496 * @param data Configuration settings.
497 *
498 * @note Locks this object for writing.
499 */
500HRESULT Platform::i_loadSettings(const settings::Platform &data)
501{
502 AutoCaller autoCaller(this);
503 AssertComRCReturnRC(autoCaller.hrc());
504
505 AutoReadLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
506 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
507
508 // simply copy
509 m->bd.assignCopy(&data);
510
511 /* Allocates architecture-dependent stuff. */
512 HRESULT hrc = i_initArchitecture(m->bd->architectureType);
513 if (SUCCEEDED(hrc))
514 {
515 switch (m->bd->architectureType)
516 {
517 case PlatformArchitecture_x86:
518 return mX86->i_loadSettings(data.x86);
519
520#ifdef VBOX_WITH_VIRT_ARMV8
521 case PlatformArchitecture_ARM:
522 return mARM->i_loadSettings(data.arm);
523#endif
524 case PlatformArchitecture_None:
525 RT_FALL_THROUGH();
526 default:
527 break;
528 }
529 }
530
531 return setErrorBoth(VBOX_E_PLATFORM_ARCH_NOT_SUPPORTED, VERR_PLATFORM_ARCH_NOT_SUPPORTED,
532 "Platform '%s' not supported", Global::stringifyPlatformArchitecture(m->bd->architectureType));
533}
534
535/**
536 * Saves settings to the given platform node.
537 *
538 * @returns HRESULT
539 * @param data Configuration settings.
540 *
541 * @note Locks this object for reading.
542 */
543HRESULT Platform::i_saveSettings(settings::Platform &data)
544{
545 AutoCaller autoCaller(this);
546 AssertComRCReturnRC(autoCaller.hrc());
547
548 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
549
550 data = *m->bd.data();
551
552 switch (m->bd->architectureType)
553 {
554 case PlatformArchitecture_x86:
555 return mX86->i_saveSettings(data.x86);
556
557#ifdef VBOX_WITH_VIRT_ARMV8
558 case PlatformArchitecture_ARM:
559 return mARM->i_saveSettings(data.arm);
560#endif
561 case PlatformArchitecture_None:
562 RT_FALL_THROUGH();
563 default:
564 break;
565 }
566
567 return setErrorBoth(VBOX_E_PLATFORM_ARCH_NOT_SUPPORTED, VERR_PLATFORM_ARCH_NOT_SUPPORTED,
568 "Platform '%s' not supported", Global::stringifyPlatformArchitecture(m->bd->architectureType));
569}
570
571void Platform::i_rollback()
572{
573 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
574
575 if (m)
576 {
577 m->bd.rollback();
578
579 switch (m->bd->architectureType)
580 {
581 case PlatformArchitecture_x86:
582 if (mX86.isNotNull())
583 return mX86->i_rollback();
584 break;
585
586#ifdef VBOX_WITH_VIRT_ARMV8
587 case PlatformArchitecture_ARM:
588 if (mARM.isNotNull())
589 return mARM->i_rollback();
590 break;
591#endif
592 case PlatformArchitecture_None:
593 RT_FALL_THROUGH();
594 default:
595 break;
596 }
597 }
598}
599
600void Platform::i_commit()
601{
602 /* sanity */
603 AutoCaller autoCaller(this);
604 AssertComRCReturnVoid(autoCaller.hrc());
605
606 /* sanity too */
607 AutoCaller peerCaller(m->pPeer);
608 AssertComRCReturnVoid(peerCaller.hrc());
609
610 /* lock both for writing since we modify both (mPeer is "master" so locked
611 * first) */
612 AutoMultiWriteLock2 alock(m->pPeer, this COMMA_LOCKVAL_SRC_POS);
613
614 if (m->bd.isBackedUp())
615 {
616 m->bd.commit();
617
618 if (m->pPeer)
619 {
620 /* attach new data to the peer and reshare it */
621 AutoWriteLock peerlock(m->pPeer COMMA_LOCKVAL_SRC_POS);
622 m->pPeer->m->bd.attach(m->bd);
623 }
624 }
625
626 switch (m->bd->architectureType)
627 {
628 case PlatformArchitecture_x86:
629 return mX86->i_commit();
630
631#ifdef VBOX_WITH_VIRT_ARMV8
632 case PlatformArchitecture_ARM:
633 return mARM->i_commit();
634#endif
635 case PlatformArchitecture_None:
636 RT_FALL_THROUGH();
637 default:
638 break;
639 }
640
641 AssertFailedReturnVoid();
642}
643
644void Platform::i_copyFrom(Platform *aThat)
645{
646 AssertReturnVoid(aThat != NULL);
647
648 /* sanity */
649 AutoCaller autoCaller(this);
650 AssertComRCReturnVoid(autoCaller.hrc());
651
652 /* sanity too */
653 AutoCaller thatCaller(aThat);
654 AssertComRCReturnVoid(thatCaller.hrc());
655
656 /* peer is not modified, lock it for reading (aThat is "master" so locked
657 * first) */
658 AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS);
659 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
660
661 /* this will back up current data */
662 m->bd.assignCopy(aThat->m->bd);
663
664 switch (m->bd->architectureType)
665 {
666 case PlatformArchitecture_x86:
667 return mX86->i_copyFrom(aThat->mX86);
668
669#ifdef VBOX_WITH_VIRT_ARMV8
670 case PlatformArchitecture_ARM:
671 return mARM->i_copyFrom(aThat->mARM);
672#endif
673 case PlatformArchitecture_None:
674 RT_FALL_THROUGH();
675 default:
676 break;
677 }
678
679 AssertFailedReturnVoid();
680}
681
682/**
683 * Initializes the platform architecture.
684 *
685 * @returns HRESULT
686 * @retval VBOX_E_PLATFORM_ARCH_NOT_SUPPORTED if platform architecture is not supported.
687 * @param aArchitecture Platform architecture to set.
688 * @param aThat Other platform object to use for shared / copied initialization. Optional.
689 * @param fCopy Whether to copy or share the configuration from / with \a aThat.
690 *
691 * @note Creates the platform-specific sub object (e.g. x86 or ARM).
692 * Usually only called when creating a new machine or loading settings.
693 */
694HRESULT Platform::i_initArchitecture(PlatformArchitecture_T aArchitecture, Platform *aThat /* = NULL */, bool fCopy /* = false */)
695{
696 /* sanity */
697 AutoCaller autoCaller(this);
698 AssertComRCReturn(autoCaller.hrc(), autoCaller.hrc());
699
700 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
701
702 HRESULT hrc = S_OK;
703
704 /* Currently we only keep the current platform-specific object around,
705 * e.g. we destroy any data for the former architecture (if any). */
706 uninitArchitecture();
707
708 switch (aArchitecture)
709 {
710 case PlatformArchitecture_x86:
711 {
712 /* Create associated x86-specific platform object. */
713 Assert(mX86.isNull());
714 hrc = unconst(mX86).createObject();
715 ComAssertComRCRetRC(hrc);
716 if (aThat)
717 {
718 if (fCopy)
719 hrc = mX86->initCopy(this, mParent, aThat->mX86);
720 else
721 hrc = mX86->init(this, mParent, aThat->mX86);
722 }
723 else
724 hrc = mX86->init(this, mParent);
725 break;
726 }
727
728#ifdef VBOX_WITH_VIRT_ARMV8
729 case PlatformArchitecture_ARM:
730 {
731 /* Create associated ARM-specific platform object. */
732 Assert(mARM.isNull());
733 unconst(mARM).createObject();
734 ComAssertComRCRetRC(hrc);
735 if (aThat)
736 {
737 if (fCopy)
738 hrc = mARM->initCopy(this, mParent, aThat->mARM);
739 else
740 hrc = mARM->init(this, mParent, aThat->mARM);
741 }
742 else
743 hrc = mARM->init(this, mParent);
744 break;
745 }
746#endif
747 default:
748 hrc = VBOX_E_PLATFORM_ARCH_NOT_SUPPORTED;
749 break;
750 }
751
752 if (SUCCEEDED(hrc))
753 {
754 m->bd->architectureType = aArchitecture;
755 LogRel(("Platform architecture set to '%s'\n", Global::stringifyPlatformArchitecture(m->bd->architectureType)));
756 }
757
758 return hrc;
759}
760
761HRESULT Platform::i_applyDefaults(GuestOSType *aOsType)
762{
763 /* sanity */
764 AutoCaller autoCaller(this);
765 AssertComRCReturn(autoCaller.hrc(), autoCaller.hrc());
766
767 HRESULT hrc = S_OK;
768
769 ChipsetType_T enmChipsetType = ChipsetType_Null;
770 IommuType_T enmIommuType = IommuType_None;
771 BOOL fRTCUseUTC = FALSE;
772
773 if (aOsType)
774 {
775 hrc = aOsType->COMGETTER(RecommendedChipset)(&enmChipsetType);
776 AssertComRCReturnRC(hrc);
777
778 hrc = aOsType->COMGETTER(RecommendedIommuType)(&enmIommuType);
779 AssertComRCReturnRC(hrc);
780
781 hrc = aOsType->COMGETTER(RecommendedRTCUseUTC)(&fRTCUseUTC);
782 AssertComRCReturnRC(hrc);
783 }
784 else
785 {
786 /* No guest OS type object. Pick some plausible defaults which the
787 * host can handle. There's no way to know or validate anything. */
788 switch (m->bd->architectureType)
789 {
790 case PlatformArchitecture_x86:
791 {
792 /* Note: These are the value we ever had, so default to these. */
793 enmChipsetType = ChipsetType_PIIX3;
794 enmIommuType = IommuType_None;
795 fRTCUseUTC = FALSE;
796 break;
797 }
798
799 case PlatformArchitecture_ARM:
800 {
801 /* Note: These are the value we ever had, so default to these. */
802 enmChipsetType = ChipsetType_ARMv8Virtual;
803 enmIommuType = IommuType_None;
804 fRTCUseUTC = TRUE; /** @todo BUGBUG Is this correct for ARM? */
805 break;
806 }
807
808 default:
809 AssertFailed();
810 break;
811 }
812 }
813
814 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
815
816 m->bd->chipsetType = enmChipsetType;
817 m->bd->iommuType = enmIommuType;
818 m->bd->fRTCUseUTC = fRTCUseUTC;
819
820 alock.release();
821
822 /* Allocates architecture-dependent stuff. */
823 hrc = i_initArchitecture(m->bd->architectureType);
824 AssertComRCReturnRC(hrc);
825
826 /* Do the same for the platform specifics. */
827 switch (m->bd->architectureType)
828 {
829 case PlatformArchitecture_x86:
830 hrc = mX86->i_applyDefaults(aOsType);
831 break;
832
833#ifdef VBOX_WITH_VIRT_ARMV8
834 case PlatformArchitecture_ARM:
835 hrc = mARM->i_applyDefaults(aOsType);
836 break;
837#endif
838 case PlatformArchitecture_None:
839 RT_FALL_THROUGH();
840 default:
841 hrc = VBOX_E_NOT_SUPPORTED;
842 break;
843 }
844 AssertComRCReturnRC(hrc);
845
846 /* Sanity. */
847 Assert(enmChipsetType != ChipsetType_Null);
848
849 return hrc;
850}
851
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