VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/FirmwareSettingsImpl.cpp@ 101359

Last change on this file since 101359 was 101038, checked in by vboxsync, 19 months ago

Initial commit (based draft v2 / on patch v5) for implementing platform architecture support for x86 and ARM: Re-applied FirmwareSettings[.h|.cpp] changes. bugref:10384

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.8 KB
Line 
1/* $Id: FirmwareSettingsImpl.cpp 101038 2023-09-07 09:21:54Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation - Machine firmware settings.
4 */
5
6/*
7 * Copyright (C) 2006-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_FIRMWARESETTINGS
29#include "FirmwareSettingsImpl.h"
30#include "MachineImpl.h"
31#include "GuestOSTypeImpl.h"
32
33#include <iprt/cpp/utils.h>
34#include <VBox/settings.h>
35
36#include "AutoStateDep.h"
37#include "AutoCaller.h"
38#include "LoggingNew.h"
39
40
41////////////////////////////////////////////////////////////////////////////////
42//
43// FirmwareSettings private data definition
44//
45////////////////////////////////////////////////////////////////////////////////
46
47struct FirmwareSettings::Data
48{
49 Data()
50 : pMachine(NULL)
51 { }
52
53 Machine * const pMachine;
54 ComObjPtr<FirmwareSettings> pPeer;
55
56 // use the XML settings structure in the members for simplicity
57 Backupable<settings::FirmwareSettings> bd;
58};
59
60// constructor / destructor
61/////////////////////////////////////////////////////////////////////////////
62
63DEFINE_EMPTY_CTOR_DTOR(FirmwareSettings)
64
65HRESULT FirmwareSettings::FinalConstruct()
66{
67 return BaseFinalConstruct();
68}
69
70void FirmwareSettings::FinalRelease()
71{
72 uninit();
73 BaseFinalRelease();
74}
75
76// public initializer/uninitializer for internal purposes only
77/////////////////////////////////////////////////////////////////////////////
78
79/**
80 * Initializes the BIOS settings object.
81 *
82 * @returns COM result indicator
83 */
84HRESULT FirmwareSettings::init(Machine *aParent)
85{
86 LogFlowThisFuncEnter();
87 LogFlowThisFunc(("aParent: %p\n", aParent));
88
89 ComAssertRet(aParent, E_INVALIDARG);
90
91 /* Enclose the state transition NotReady->InInit->Ready */
92 AutoInitSpan autoInitSpan(this);
93 AssertReturn(autoInitSpan.isOk(), E_FAIL);
94
95 m = new Data();
96
97 /* share the parent weakly */
98 unconst(m->pMachine) = aParent;
99
100 m->bd.allocate();
101
102 autoInitSpan.setSucceeded();
103
104 LogFlowThisFuncLeave();
105 return S_OK;
106}
107
108/**
109 * Initializes the firmware settings object given another firmware settings object
110 * (a kind of copy constructor). This object shares data with
111 * the object passed as an argument.
112 *
113 * @note This object must be destroyed before the original object
114 * it shares data with is destroyed.
115 */
116HRESULT FirmwareSettings::init(Machine *aParent, FirmwareSettings *that)
117{
118 LogFlowThisFuncEnter();
119 LogFlowThisFunc(("aParent: %p, that: %p\n", aParent, that));
120
121 ComAssertRet(aParent && that, E_INVALIDARG);
122
123 /* Enclose the state transition NotReady->InInit->Ready */
124 AutoInitSpan autoInitSpan(this);
125 AssertReturn(autoInitSpan.isOk(), E_FAIL);
126
127 m = new Data();
128
129 unconst(m->pMachine) = aParent;
130 m->pPeer = that;
131
132 AutoWriteLock thatlock(that COMMA_LOCKVAL_SRC_POS);
133 m->bd.share(that->m->bd);
134
135 autoInitSpan.setSucceeded();
136
137 LogFlowThisFuncLeave();
138 return S_OK;
139}
140
141/**
142 * Initializes the guest object given another guest object
143 * (a kind of copy constructor). This object makes a private copy of data
144 * of the original object passed as an argument.
145 */
146HRESULT FirmwareSettings::initCopy(Machine *aParent, FirmwareSettings *that)
147{
148 LogFlowThisFuncEnter();
149 LogFlowThisFunc(("aParent: %p, that: %p\n", aParent, that));
150
151 ComAssertRet(aParent && that, E_INVALIDARG);
152
153 /* Enclose the state transition NotReady->InInit->Ready */
154 AutoInitSpan autoInitSpan(this);
155 AssertReturn(autoInitSpan.isOk(), E_FAIL);
156
157 m = new Data();
158
159 unconst(m->pMachine) = aParent;
160 // mPeer is left null
161
162 AutoWriteLock thatlock(that COMMA_LOCKVAL_SRC_POS); /** @todo r=andy Shouldn't a read lock be sufficient here? */
163 m->bd.attachCopy(that->m->bd);
164
165 autoInitSpan.setSucceeded();
166
167 LogFlowThisFuncLeave();
168 return S_OK;
169}
170
171/**
172 * Uninitializes the instance and sets the ready flag to FALSE.
173 * Called either from FinalRelease() or by the parent when it gets destroyed.
174 */
175void FirmwareSettings::uninit()
176{
177 LogFlowThisFuncEnter();
178
179 /* Enclose the state transition Ready->InUninit->NotReady */
180 AutoUninitSpan autoUninitSpan(this);
181 if (autoUninitSpan.uninitDone())
182 return;
183
184 m->bd.free();
185
186 unconst(m->pPeer) = NULL;
187 unconst(m->pMachine) = NULL;
188
189 delete m;
190 m = NULL;
191
192 LogFlowThisFuncLeave();
193}
194
195// IFirmwareSettings properties
196/////////////////////////////////////////////////////////////////////////////
197
198
199HRESULT FirmwareSettings::getLogoFadeIn(BOOL *enabled)
200{
201 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
202
203 *enabled = m->bd->fLogoFadeIn;
204
205 return S_OK;
206}
207
208HRESULT FirmwareSettings::setLogoFadeIn(BOOL enable)
209{
210 /* the machine needs to be mutable */
211 AutoMutableStateDependency adep(m->pMachine);
212 if (FAILED(adep.hrc())) return adep.hrc();
213
214 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
215
216 m->bd.backup();
217 m->bd->fLogoFadeIn = RT_BOOL(enable);
218
219 alock.release();
220 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
221 m->pMachine->i_setModified(Machine::IsModified_Firmware);
222
223 return S_OK;
224}
225
226
227HRESULT FirmwareSettings::getLogoFadeOut(BOOL *enabled)
228{
229 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
230
231 *enabled = m->bd->fLogoFadeOut;
232
233 return S_OK;
234}
235
236HRESULT FirmwareSettings::setLogoFadeOut(BOOL enable)
237{
238 /* the machine needs to be mutable */
239 AutoMutableStateDependency adep(m->pMachine);
240 if (FAILED(adep.hrc())) return adep.hrc();
241
242 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
243
244 m->bd.backup();
245 m->bd->fLogoFadeOut = RT_BOOL(enable);
246
247 alock.release();
248 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
249 m->pMachine->i_setModified(Machine::IsModified_Firmware);
250
251 return S_OK;
252}
253
254
255HRESULT FirmwareSettings::getLogoDisplayTime(ULONG *displayTime)
256{
257 if (!displayTime)
258 return E_POINTER;
259
260 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
261
262 *displayTime = m->bd->ulLogoDisplayTime;
263
264 return S_OK;
265}
266
267HRESULT FirmwareSettings::setLogoDisplayTime(ULONG displayTime)
268{
269 /* the machine needs to be mutable */
270 AutoMutableStateDependency adep(m->pMachine);
271 if (FAILED(adep.hrc())) return adep.hrc();
272
273 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
274
275 m->bd.backup();
276 m->bd->ulLogoDisplayTime = displayTime;
277
278 alock.release();
279 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
280 m->pMachine->i_setModified(Machine::IsModified_Firmware);
281
282 return S_OK;
283}
284
285
286HRESULT FirmwareSettings::getLogoImagePath(com::Utf8Str &imagePath)
287{
288 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
289
290 imagePath = m->bd->strLogoImagePath;
291 return S_OK;
292}
293
294HRESULT FirmwareSettings::setLogoImagePath(const com::Utf8Str &imagePath)
295{
296 /* the machine needs to be mutable */
297 AutoMutableStateDependency adep(m->pMachine);
298 if (FAILED(adep.hrc())) return adep.hrc();
299
300 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
301
302 m->bd.backup();
303 m->bd->strLogoImagePath = imagePath;
304
305 alock.release();
306 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
307 m->pMachine->i_setModified(Machine::IsModified_Firmware);
308
309 return S_OK;
310}
311
312HRESULT FirmwareSettings::getBootMenuMode(FirmwareBootMenuMode_T *bootMenuMode)
313{
314 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
315
316 *bootMenuMode = m->bd->enmBootMenuMode;
317 return S_OK;
318}
319
320HRESULT FirmwareSettings::setBootMenuMode(FirmwareBootMenuMode_T bootMenuMode)
321{
322 /* the machine needs to be mutable */
323 AutoMutableStateDependency adep(m->pMachine);
324 if (FAILED(adep.hrc())) return adep.hrc();
325
326 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
327
328 m->bd.backup();
329 m->bd->enmBootMenuMode = bootMenuMode;
330
331 alock.release();
332 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
333 m->pMachine->i_setModified(Machine::IsModified_Firmware);
334
335 return S_OK;
336}
337
338
339HRESULT FirmwareSettings::getACPIEnabled(BOOL *enabled)
340{
341 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
342
343 *enabled = m->bd->fACPIEnabled;
344
345 return S_OK;
346}
347
348HRESULT FirmwareSettings::setACPIEnabled(BOOL enable)
349{
350 /* the machine needs to be mutable */
351 AutoMutableStateDependency adep(m->pMachine);
352 if (FAILED(adep.hrc())) return adep.hrc();
353
354 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
355
356 m->bd.backup();
357 m->bd->fACPIEnabled = RT_BOOL(enable);
358
359 alock.release();
360 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
361 m->pMachine->i_setModified(Machine::IsModified_Firmware);
362
363 return S_OK;
364}
365
366
367HRESULT FirmwareSettings::getIOAPICEnabled(BOOL *aIOAPICEnabled)
368{
369 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
370
371 *aIOAPICEnabled = m->bd->fIOAPICEnabled;
372
373 return S_OK;
374}
375
376HRESULT FirmwareSettings::getFirmwareType(FirmwareType_T *aType)
377{
378 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
379
380 *aType = m->bd->firmwareType;
381
382 return S_OK;
383}
384
385HRESULT FirmwareSettings::setFirmwareType(FirmwareType_T aType)
386{
387 /* the machine needs to be mutable */
388 AutoMutableStateDependency adep(m->pMachine);
389 if (FAILED(adep.hrc())) return adep.hrc();
390
391 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
392
393 m->bd.backup();
394 m->bd->firmwareType = aType;
395
396 alock.release();
397
398 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // pMachine is const, needs no locking
399 m->pMachine->i_setModified(Machine::IsModified_Firmware);
400 Utf8Str strNVRAM = m->pMachine->i_getDefaultNVRAMFilename();
401 mlock.release();
402
403 m->pMachine->i_getNVRAMStore()->i_updateNonVolatileStorageFile(strNVRAM);
404
405 return S_OK;
406}
407
408HRESULT FirmwareSettings::setIOAPICEnabled(BOOL aIOAPICEnabled)
409{
410 /* the machine needs to be mutable */
411 AutoMutableStateDependency adep(m->pMachine);
412 if (FAILED(adep.hrc())) return adep.hrc();
413
414 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
415
416 m->bd.backup();
417 m->bd->fIOAPICEnabled = RT_BOOL(aIOAPICEnabled);
418
419 alock.release();
420 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
421 m->pMachine->i_setModified(Machine::IsModified_Firmware);
422
423 return S_OK;
424}
425
426
427HRESULT FirmwareSettings::getAPICMode(APICMode_T *aAPICMode)
428{
429 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
430
431 *aAPICMode = m->bd->apicMode;
432
433 return S_OK;
434}
435
436HRESULT FirmwareSettings::setAPICMode(APICMode_T aAPICMode)
437{
438 /* the machine needs to be mutable */
439 AutoMutableStateDependency adep(m->pMachine);
440 if (FAILED(adep.hrc())) return adep.hrc();
441
442 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
443
444 m->bd.backup();
445 m->bd->apicMode = aAPICMode;
446
447 alock.release();
448 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
449 m->pMachine->i_setModified(Machine::IsModified_Firmware);
450
451 return S_OK;
452}
453
454
455HRESULT FirmwareSettings::getPXEDebugEnabled(BOOL *enabled)
456{
457 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
458
459 *enabled = m->bd->fPXEDebugEnabled;
460
461 return S_OK;
462}
463
464HRESULT FirmwareSettings::setPXEDebugEnabled(BOOL enable)
465{
466 /* the machine needs to be mutable */
467 AutoMutableStateDependency adep(m->pMachine);
468 if (FAILED(adep.hrc())) return adep.hrc();
469
470 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
471
472 m->bd.backup();
473 m->bd->fPXEDebugEnabled = RT_BOOL(enable);
474
475 alock.release();
476 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
477 m->pMachine->i_setModified(Machine::IsModified_Firmware);
478
479 return S_OK;
480}
481
482
483HRESULT FirmwareSettings::getTimeOffset(LONG64 *offset)
484{
485 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
486
487 *offset = m->bd->llTimeOffset;
488
489 return S_OK;
490}
491
492HRESULT FirmwareSettings::setTimeOffset(LONG64 offset)
493{
494 /* the machine needs to be mutable */
495 AutoMutableStateDependency adep(m->pMachine);
496 if (FAILED(adep.hrc())) return adep.hrc();
497
498 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
499
500 m->bd.backup();
501 m->bd->llTimeOffset = offset;
502
503 alock.release();
504 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
505 m->pMachine->i_setModified(Machine::IsModified_Firmware);
506
507 return S_OK;
508}
509
510
511HRESULT FirmwareSettings::getSMBIOSUuidLittleEndian(BOOL *enabled)
512{
513 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
514
515 *enabled = m->bd->fSmbiosUuidLittleEndian;
516
517 return S_OK;
518}
519
520HRESULT FirmwareSettings::setSMBIOSUuidLittleEndian(BOOL enable)
521{
522 /* the machine needs to be mutable */
523 AutoMutableStateDependency adep(m->pMachine);
524 if (FAILED(adep.hrc())) return adep.hrc();
525
526 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
527
528 m->bd.backup();
529 m->bd->fSmbiosUuidLittleEndian = RT_BOOL(enable);
530
531 alock.release();
532 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
533 m->pMachine->i_setModified(Machine::IsModified_Firmware);
534
535 return S_OK;
536}
537
538
539// IFirmwareSettings methods
540/////////////////////////////////////////////////////////////////////////////
541
542// public methods only for internal purposes
543/////////////////////////////////////////////////////////////////////////////
544
545/**
546 * Loads settings from the given machine node.
547 * May be called once right after this object creation.
548 *
549 * @param data Configuration settings.
550 *
551 * @note Locks this object for writing.
552 */
553HRESULT FirmwareSettings::i_loadSettings(const settings::FirmwareSettings &data)
554{
555 AutoCaller autoCaller(this);
556 AssertComRCReturnRC(autoCaller.hrc());
557
558 AutoReadLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
559 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
560
561 // simply copy
562 m->bd.assignCopy(&data);
563 return S_OK;
564}
565
566/**
567 * Saves settings to the given machine node.
568 *
569 * @param data Configuration settings.
570 *
571 * @note Locks this object for reading.
572 */
573HRESULT FirmwareSettings::i_saveSettings(settings::FirmwareSettings &data)
574{
575 AutoCaller autoCaller(this);
576 AssertComRCReturnRC(autoCaller.hrc());
577
578 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
579
580 data = *m->bd.data();
581
582 return S_OK;
583}
584
585FirmwareType_T FirmwareSettings::i_getFirmwareType() const
586{
587 return m->bd->firmwareType;
588}
589
590void FirmwareSettings::i_rollback()
591{
592 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
593 m->bd.rollback();
594}
595
596void FirmwareSettings::i_commit()
597{
598 /* sanity */
599 AutoCaller autoCaller(this);
600 AssertComRCReturnVoid(autoCaller.hrc());
601
602 /* sanity too */
603 AutoCaller peerCaller(m->pPeer);
604 AssertComRCReturnVoid(peerCaller.hrc());
605
606 /* lock both for writing since we modify both (mPeer is "master" so locked
607 * first) */
608 AutoMultiWriteLock2 alock(m->pPeer, this COMMA_LOCKVAL_SRC_POS);
609
610 if (m->bd.isBackedUp())
611 {
612 m->bd.commit();
613 if (m->pPeer)
614 {
615 /* attach new data to the peer and reshare it */
616 AutoWriteLock peerlock(m->pPeer COMMA_LOCKVAL_SRC_POS);
617 m->pPeer->m->bd.attach(m->bd);
618 }
619 }
620}
621
622void FirmwareSettings::i_copyFrom(FirmwareSettings *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
643void FirmwareSettings::i_applyDefaults(GuestOSType *aOsType)
644{
645 /* sanity */
646 AutoCaller autoCaller(this);
647 AssertComRCReturnVoid(autoCaller.hrc());
648
649 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
650
651 /* Initialize default firmware settings here */
652 if (aOsType)
653 {
654 HRESULT hrc = aOsType->COMGETTER(RecommendedFirmware)(&m->bd->firmwareType);
655 AssertComRC(hrc);
656
657 m->bd->fIOAPICEnabled = aOsType->i_recommendedIOAPIC();
658 }
659 else
660 {
661 m->bd->firmwareType = FirmwareType_BIOS; /** @todo BUGBUG Handle ARM? */
662 m->bd->fIOAPICEnabled = true;
663 }
664
665 /// @todo r=andy BUGBUG Is this really enough here? What about the other stuff?
666}
667
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette