VirtualBox

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

Last change on this file since 101505 was 101460, checked in by vboxsync, 14 months ago

Main: Moved Platform::s_platformArchitectureToStr() to Global::stringifyPlatformArchitecture(), so that the client part of VBoxSVC also can make use of this. bugref:10384

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