VirtualBox

source: vbox/trunk/src/VBox/Main/BIOSSettingsImpl.cpp@ 14953

Last change on this file since 14953 was 14772, checked in by vboxsync, 16 years ago

Added vim modelines to aid following coding guidelines, like no tabs,
similar to what is already in the xidl file.

  • Property svn:eol-style set to native
File size: 19.8 KB
Line 
1/** @file
2 *
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#include "BIOSSettingsImpl.h"
23#include "MachineImpl.h"
24#include "Logging.h"
25#include "GuestOSTypeImpl.h"
26#include <iprt/cpputils.h>
27
28// constructor / destructor
29/////////////////////////////////////////////////////////////////////////////
30
31HRESULT BIOSSettings::FinalConstruct()
32{
33 return S_OK;
34}
35
36void BIOSSettings::FinalRelease()
37{
38 uninit ();
39}
40
41// public initializer/uninitializer for internal purposes only
42/////////////////////////////////////////////////////////////////////////////
43
44/**
45 * Initializes the audio adapter object.
46 *
47 * @returns COM result indicator
48 */
49HRESULT BIOSSettings::init (Machine *aParent)
50{
51 LogFlowThisFuncEnter();
52 LogFlowThisFunc (("aParent: %p\n", aParent));
53
54 ComAssertRet (aParent, E_INVALIDARG);
55
56 /* Enclose the state transition NotReady->InInit->Ready */
57 AutoInitSpan autoInitSpan (this);
58 AssertReturn (autoInitSpan.isOk(), E_FAIL);
59
60 /* share the parent weakly */
61 unconst (mParent) = aParent;
62
63 mData.allocate();
64
65 autoInitSpan.setSucceeded();
66
67 LogFlowThisFuncLeave();
68 return S_OK;
69}
70
71/**
72 * Initializes the audio adapter object given another audio adapter object
73 * (a kind of copy constructor). This object shares data with
74 * the object passed as an argument.
75 *
76 * @note This object must be destroyed before the original object
77 * it shares data with is destroyed.
78 */
79HRESULT BIOSSettings::init (Machine *aParent, BIOSSettings *that)
80{
81 LogFlowThisFuncEnter();
82 LogFlowThisFunc (("aParent: %p, that: %p\n", aParent, that));
83
84 ComAssertRet (aParent && that, E_INVALIDARG);
85
86 /* Enclose the state transition NotReady->InInit->Ready */
87 AutoInitSpan autoInitSpan (this);
88 AssertReturn (autoInitSpan.isOk(), E_FAIL);
89
90 mParent = aParent;
91 mPeer = that;
92
93 AutoWriteLock thatlock (that);
94 mData.share (that->mData);
95
96 autoInitSpan.setSucceeded();
97
98 LogFlowThisFuncLeave();
99 return S_OK;
100}
101
102/**
103 * Initializes the guest object given another guest object
104 * (a kind of copy constructor). This object makes a private copy of data
105 * of the original object passed as an argument.
106 */
107HRESULT BIOSSettings::initCopy (Machine *aParent, BIOSSettings *that)
108{
109 LogFlowThisFuncEnter();
110 LogFlowThisFunc (("aParent: %p, that: %p\n", aParent, that));
111
112 ComAssertRet (aParent && that, E_INVALIDARG);
113
114 /* Enclose the state transition NotReady->InInit->Ready */
115 AutoInitSpan autoInitSpan (this);
116 AssertReturn (autoInitSpan.isOk(), E_FAIL);
117
118 mParent = aParent;
119 // mPeer is left null
120
121 AutoWriteLock thatlock (that);
122 mData.attachCopy (that->mData);
123
124 autoInitSpan.setSucceeded();
125
126 LogFlowThisFuncLeave();
127 return S_OK;
128}
129
130/**
131 * Uninitializes the instance and sets the ready flag to FALSE.
132 * Called either from FinalRelease() or by the parent when it gets destroyed.
133 */
134void BIOSSettings::uninit()
135{
136 LogFlowThisFuncEnter();
137
138 /* Enclose the state transition Ready->InUninit->NotReady */
139 AutoUninitSpan autoUninitSpan (this);
140 if (autoUninitSpan.uninitDone())
141 return;
142
143 mData.free();
144
145 mPeer.setNull();
146 mParent.setNull();
147
148 LogFlowThisFuncLeave();
149}
150
151// IBIOSSettings properties
152/////////////////////////////////////////////////////////////////////////////
153
154STDMETHODIMP BIOSSettings::COMGETTER(LogoFadeIn)(BOOL *enabled)
155{
156 if (!enabled)
157 return E_POINTER;
158
159 AutoCaller autoCaller (this);
160 CheckComRCReturnRC (autoCaller.rc());
161
162 AutoReadLock alock (this);
163
164 *enabled = mData->mLogoFadeIn;
165
166 return S_OK;
167}
168
169STDMETHODIMP BIOSSettings::COMSETTER(LogoFadeIn)(BOOL enable)
170{
171 AutoCaller autoCaller (this);
172 CheckComRCReturnRC (autoCaller.rc());
173
174 /* the machine needs to be mutable */
175 Machine::AutoMutableStateDependency adep (mParent);
176 CheckComRCReturnRC (adep.rc());
177
178 AutoWriteLock alock (this);
179
180 mData.backup();
181 mData->mLogoFadeIn = enable;
182
183 return S_OK;
184}
185
186STDMETHODIMP BIOSSettings::COMGETTER(LogoFadeOut)(BOOL *enabled)
187{
188 if (!enabled)
189 return E_POINTER;
190
191 AutoCaller autoCaller (this);
192 CheckComRCReturnRC (autoCaller.rc());
193
194 AutoReadLock alock (this);
195
196 *enabled = mData->mLogoFadeOut;
197
198 return S_OK;
199}
200
201STDMETHODIMP BIOSSettings::COMSETTER(LogoFadeOut)(BOOL enable)
202{
203 AutoCaller autoCaller (this);
204 CheckComRCReturnRC (autoCaller.rc());
205
206 /* the machine needs to be mutable */
207 Machine::AutoMutableStateDependency adep (mParent);
208 CheckComRCReturnRC (adep.rc());
209
210 AutoWriteLock alock (this);
211
212 mData.backup();
213 mData->mLogoFadeOut = enable;
214
215 return S_OK;
216}
217
218STDMETHODIMP BIOSSettings::COMGETTER(LogoDisplayTime)(ULONG *displayTime)
219{
220 if (!displayTime)
221 return E_POINTER;
222
223 AutoCaller autoCaller (this);
224 CheckComRCReturnRC (autoCaller.rc());
225
226 AutoReadLock alock (this);
227
228 *displayTime = mData->mLogoDisplayTime;
229
230 return S_OK;
231}
232
233STDMETHODIMP BIOSSettings::COMSETTER(LogoDisplayTime)(ULONG displayTime)
234{
235 AutoCaller autoCaller (this);
236 CheckComRCReturnRC (autoCaller.rc());
237
238 /* the machine needs to be mutable */
239 Machine::AutoMutableStateDependency adep (mParent);
240 CheckComRCReturnRC (adep.rc());
241
242 AutoWriteLock alock (this);
243
244 mData.backup();
245 mData->mLogoDisplayTime = displayTime;
246
247 return S_OK;
248}
249
250STDMETHODIMP BIOSSettings::COMGETTER(LogoImagePath)(BSTR *imagePath)
251{
252 if (!imagePath)
253 return E_POINTER;
254
255 AutoCaller autoCaller (this);
256 CheckComRCReturnRC (autoCaller.rc());
257
258 AutoReadLock alock (this);
259
260 mData->mLogoImagePath.cloneTo(imagePath);
261 return S_OK;
262}
263
264STDMETHODIMP BIOSSettings::COMSETTER(LogoImagePath)(INPTR BSTR imagePath)
265{
266 /* empty strings are not allowed as path names */
267 if (imagePath && !(*imagePath))
268 return E_INVALIDARG;
269
270 AutoCaller autoCaller (this);
271 CheckComRCReturnRC (autoCaller.rc());
272
273 /* the machine needs to be mutable */
274 Machine::AutoMutableStateDependency adep (mParent);
275 CheckComRCReturnRC (adep.rc());
276
277 AutoWriteLock alock (this);
278
279 mData.backup();
280 mData->mLogoImagePath = imagePath;
281
282 return S_OK;
283}
284
285STDMETHODIMP BIOSSettings::COMGETTER(BootMenuMode)(BIOSBootMenuMode_T *bootMenuMode)
286{
287 if (!bootMenuMode)
288 return E_POINTER;
289
290 AutoCaller autoCaller (this);
291 CheckComRCReturnRC (autoCaller.rc());
292
293 AutoReadLock alock (this);
294
295 *bootMenuMode = mData->mBootMenuMode;
296 return S_OK;
297}
298
299STDMETHODIMP BIOSSettings::COMSETTER(BootMenuMode)(BIOSBootMenuMode_T bootMenuMode)
300{
301 AutoCaller autoCaller (this);
302 CheckComRCReturnRC (autoCaller.rc());
303
304 /* the machine needs to be mutable */
305 Machine::AutoMutableStateDependency adep (mParent);
306 CheckComRCReturnRC (adep.rc());
307
308 AutoWriteLock alock (this);
309
310 mData.backup();
311 mData->mBootMenuMode = bootMenuMode;
312
313 return S_OK;
314}
315
316STDMETHODIMP BIOSSettings::COMGETTER(ACPIEnabled)(BOOL *enabled)
317{
318 if (!enabled)
319 return E_POINTER;
320
321 AutoCaller autoCaller (this);
322 CheckComRCReturnRC (autoCaller.rc());
323
324 AutoReadLock alock (this);
325
326 *enabled = mData->mACPIEnabled;
327
328 return S_OK;
329}
330
331STDMETHODIMP BIOSSettings::COMSETTER(ACPIEnabled)(BOOL enable)
332{
333 AutoCaller autoCaller (this);
334 CheckComRCReturnRC (autoCaller.rc());
335
336 /* the machine needs to be mutable */
337 Machine::AutoMutableStateDependency adep (mParent);
338 CheckComRCReturnRC (adep.rc());
339
340 AutoWriteLock alock (this);
341
342 mData.backup();
343 mData->mACPIEnabled = enable;
344
345 return S_OK;
346}
347
348STDMETHODIMP BIOSSettings::COMGETTER(IOAPICEnabled)(BOOL *enabled)
349{
350 if (!enabled)
351 return E_POINTER;
352
353 AutoCaller autoCaller (this);
354 CheckComRCReturnRC (autoCaller.rc());
355
356 AutoReadLock alock (this);
357
358 *enabled = mData->mIOAPICEnabled;
359
360 return S_OK;
361}
362
363STDMETHODIMP BIOSSettings::COMSETTER(IOAPICEnabled)(BOOL enable)
364{
365 AutoCaller autoCaller (this);
366 CheckComRCReturnRC (autoCaller.rc());
367
368 /* the machine needs to be mutable */
369 Machine::AutoMutableStateDependency adep (mParent);
370 CheckComRCReturnRC (adep.rc());
371
372 AutoWriteLock alock (this);
373
374 mData.backup();
375 mData->mIOAPICEnabled = enable;
376
377 return S_OK;
378}
379
380STDMETHODIMP BIOSSettings::COMGETTER(PXEDebugEnabled)(BOOL *enabled)
381{
382 if (!enabled)
383 return E_POINTER;
384
385 AutoCaller autoCaller (this);
386 CheckComRCReturnRC (autoCaller.rc());
387
388 AutoReadLock alock (this);
389
390 *enabled = mData->mPXEDebugEnabled;
391
392 return S_OK;
393}
394
395STDMETHODIMP BIOSSettings::COMSETTER(PXEDebugEnabled)(BOOL enable)
396{
397 AutoCaller autoCaller (this);
398 CheckComRCReturnRC (autoCaller.rc());
399
400 /* the machine needs to be mutable */
401 Machine::AutoMutableStateDependency adep (mParent);
402 CheckComRCReturnRC (adep.rc());
403
404 AutoWriteLock alock (this);
405
406 mData.backup();
407 mData->mPXEDebugEnabled = enable;
408
409 return S_OK;
410}
411
412STDMETHODIMP BIOSSettings::COMGETTER(IDEControllerType)(IDEControllerType_T *aControllerType)
413{
414 if (!aControllerType)
415 return E_POINTER;
416
417 AutoCaller autoCaller (this);
418 CheckComRCReturnRC (autoCaller.rc());
419
420 AutoReadLock alock (this);
421
422 *aControllerType = mData->mIDEControllerType;
423
424 return S_OK;
425}
426
427STDMETHODIMP BIOSSettings::COMSETTER(IDEControllerType)(IDEControllerType_T aControllerType)
428{
429 AutoCaller autoCaller (this);
430 CheckComRCReturnRC (autoCaller.rc());
431
432 /* the machine needs to be mutable */
433 Machine::AutoMutableStateDependency adep (mParent);
434 CheckComRCReturnRC (adep.rc());
435
436 AutoWriteLock alock (this);
437
438 /* make sure the value is allowed */
439 switch (aControllerType)
440 {
441 case IDEControllerType_PIIX3:
442 case IDEControllerType_PIIX4:
443 break;
444 default:
445 return setError (E_INVALIDARG,
446 tr("Invalid IDE controller type '%d'"),
447 aControllerType);
448 }
449
450 mData.backup();
451
452 mData->mIDEControllerType = aControllerType;
453
454 return S_OK;
455}
456
457STDMETHODIMP BIOSSettings::COMGETTER(TimeOffset)(LONG64 *offset)
458{
459 if (!offset)
460 return E_POINTER;
461
462 AutoCaller autoCaller (this);
463 CheckComRCReturnRC (autoCaller.rc());
464
465 AutoReadLock alock (this);
466
467 *offset = mData->mTimeOffset;
468
469 return S_OK;
470}
471
472STDMETHODIMP BIOSSettings::COMSETTER(TimeOffset)(LONG64 offset)
473{
474 AutoCaller autoCaller (this);
475 CheckComRCReturnRC (autoCaller.rc());
476
477 /* the machine needs to be mutable */
478 Machine::AutoMutableStateDependency adep (mParent);
479 CheckComRCReturnRC (adep.rc());
480
481 AutoWriteLock alock (this);
482
483 mData.backup();
484 mData->mTimeOffset = offset;
485
486 return S_OK;
487}
488
489
490// IBIOSSettings methods
491/////////////////////////////////////////////////////////////////////////////
492
493// public methods only for internal purposes
494/////////////////////////////////////////////////////////////////////////////
495
496/**
497 * Loads settings from the given machine node.
498 * May be called once right after this object creation.
499 *
500 * @param aMachineNode <Machine> node.
501 *
502 * @note Locks this object for writing.
503 */
504HRESULT BIOSSettings::loadSettings (const settings::Key &aMachineNode)
505{
506 using namespace settings;
507
508 AssertReturn (!aMachineNode.isNull(), E_FAIL);
509
510 AutoCaller autoCaller (this);
511 AssertComRCReturnRC (autoCaller.rc());
512
513 AutoWriteLock alock (this);
514
515 /* Note: we assume that the default values for attributes of optional
516 * nodes are assigned in the Data::Data() constructor and don't do it
517 * here. It implies that this method may only be called after constructing
518 * a new BIOSSettings object while all its data fields are in the default
519 * values. Exceptions are fields whose creation time defaults don't match
520 * values that should be applied when these fields are not explicitly set
521 * in the settings file (for backwards compatibility reasons). This takes
522 * place when a setting of a newly created object must default to A while
523 * the same setting of an object loaded from the old settings file must
524 * default to B. */
525
526 /* BIOS node (required) */
527 Key biosNode = aMachineNode.key ("BIOS");
528
529 /* ACPI (required) */
530 {
531 Key acpiNode = biosNode.key ("ACPI");
532
533 mData->mACPIEnabled = acpiNode.value <bool> ("enabled");
534 }
535
536 /* IOAPIC (optional) */
537 {
538 Key ioapicNode = biosNode.findKey ("IOAPIC");
539 if (!ioapicNode.isNull())
540 mData->mIOAPICEnabled = ioapicNode.value <bool> ("enabled");
541 }
542
543 /* Logo (optional) */
544 {
545 Key logoNode = biosNode.findKey ("Logo");
546 if (!logoNode.isNull())
547 {
548 mData->mLogoFadeIn = logoNode.value <bool> ("fadeIn");
549 mData->mLogoFadeOut = logoNode.value <bool> ("fadeOut");
550 mData->mLogoDisplayTime = logoNode.value <ULONG> ("displayTime");
551 mData->mLogoImagePath = logoNode.stringValue ("imagePath");
552 }
553 }
554
555 /* boot menu (optional) */
556 {
557 Key bootMenuNode = biosNode.findKey ("BootMenu");
558 if (!bootMenuNode.isNull())
559 {
560 mData->mBootMenuMode = BIOSBootMenuMode_MessageAndMenu;
561 const char *modeStr = bootMenuNode.stringValue ("mode");
562
563 if (strcmp (modeStr, "Disabled") == 0)
564 mData->mBootMenuMode = BIOSBootMenuMode_Disabled;
565 else if (strcmp (modeStr, "MenuOnly") == 0)
566 mData->mBootMenuMode = BIOSBootMenuMode_MenuOnly;
567 else if (strcmp (modeStr, "MessageAndMenu") == 0)
568 mData->mBootMenuMode = BIOSBootMenuMode_MessageAndMenu;
569 else
570 ComAssertMsgFailedRet (("Invalid boot menu mode '%s'\n", modeStr),
571 E_FAIL);
572 }
573 }
574
575 /* PXE debug logging (optional) */
576 {
577 Key pxedebugNode = biosNode.findKey ("PXEDebug");
578 if (!pxedebugNode.isNull())
579 mData->mPXEDebugEnabled = pxedebugNode.value <bool> ("enabled");
580 }
581
582 /* time offset (optional) */
583 {
584 Key timeOffsetNode = biosNode.findKey ("TimeOffset");
585 if (!timeOffsetNode.isNull())
586 mData->mTimeOffset = timeOffsetNode.value <LONG64> ("value");
587 }
588
589 /* IDE controller type (optional, for old machines that lack this node,
590 * defaults to PIIX3) */
591 {
592 mData->mIDEControllerType = IDEControllerType_PIIX3;
593
594 Key ideControllerNode = biosNode.findKey ("IDEController");
595 if (!ideControllerNode.isNull())
596 {
597 const char *typeStr = ideControllerNode.stringValue ("type");
598 if (strcmp (typeStr, "PIIX3") == 0)
599 mData->mIDEControllerType = IDEControllerType_PIIX3;
600 else if (strcmp (typeStr, "PIIX4") == 0)
601 mData->mIDEControllerType = IDEControllerType_PIIX4;
602 else
603 ComAssertMsgFailedRet (("Invalid boot menu mode '%s'\n", typeStr),
604 E_FAIL);
605 }
606 }
607
608 return S_OK;
609}
610
611/**
612 * Saves settings to the given machine node.
613 *
614 * @param aMachineNode <Machine> node.
615 *
616 * @note Locks this object for reading.
617 */
618HRESULT BIOSSettings::saveSettings (settings::Key &aMachineNode)
619{
620 using namespace settings;
621
622 AssertReturn (!aMachineNode.isNull(), E_FAIL);
623
624 AutoCaller autoCaller (this);
625 AssertComRCReturnRC (autoCaller.rc());
626
627 AutoReadLock alock (this);
628
629 Key biosNode = aMachineNode.createKey ("BIOS");
630
631 /* ACPI */
632 {
633 Key acpiNode = biosNode.createKey ("ACPI");
634 acpiNode.setValue <bool> ("enabled", !!mData->mACPIEnabled);
635 }
636
637 /* IOAPIC */
638 {
639 Key ioapicNode = biosNode.createKey ("IOAPIC");
640 ioapicNode.setValue <bool> ("enabled", !!mData->mIOAPICEnabled);
641 }
642
643 /* BIOS logo (optional) **/
644 {
645 Key logoNode = biosNode.createKey ("Logo");
646 logoNode.setValue <bool> ("fadeIn", !!mData->mLogoFadeIn);
647 logoNode.setValue <bool> ("fadeOut", !!mData->mLogoFadeOut);
648 logoNode.setValue <ULONG> ("displayTime", mData->mLogoDisplayTime);
649 logoNode.setValueOr <Bstr> ("imagePath", mData->mLogoImagePath, Bstr::Null);
650 }
651
652 /* boot menu (optional) */
653 {
654 Key bootMenuNode = biosNode.createKey ("BootMenu");
655 const char *modeStr = NULL;
656 switch (mData->mBootMenuMode)
657 {
658 case BIOSBootMenuMode_Disabled:
659 modeStr = "Disabled";
660 break;
661 case BIOSBootMenuMode_MenuOnly:
662 modeStr = "MenuOnly";
663 break;
664 case BIOSBootMenuMode_MessageAndMenu:
665 modeStr = "MessageAndMenu";
666 break;
667 default:
668 ComAssertMsgFailedRet (("Invalid boot menu type: %d\n",
669 mData->mBootMenuMode),
670 E_FAIL);
671 }
672 bootMenuNode.setStringValue ("mode", modeStr);
673 }
674
675 /* time offset (optional) */
676 {
677 Key timeOffsetNode = biosNode.createKey ("TimeOffset");
678 timeOffsetNode.setValue <LONG64> ("value", mData->mTimeOffset);
679 }
680
681 /* PXE debug flag (optional) */
682 {
683 Key pxedebugNode = biosNode.createKey ("PXEDebug");
684 pxedebugNode.setValue <bool> ("enabled", !!mData->mPXEDebugEnabled);
685 }
686
687 /* IDE controller type */
688 {
689 Key ideControllerNode = biosNode.createKey ("IDEController");
690 const char *ideControllerTypeStr = NULL;
691 switch (mData->mIDEControllerType)
692 {
693 case IDEControllerType_PIIX3:
694 ideControllerTypeStr = "PIIX3";
695 break;
696 case IDEControllerType_PIIX4:
697 ideControllerTypeStr = "PIIX4";
698 break;
699 default:
700 ComAssertMsgFailedRet (("Invalid IDE Controller type: %d\n",
701 mData->mIDEControllerType),
702 E_FAIL);
703 }
704 ideControllerNode.setStringValue ("type", ideControllerTypeStr);
705 }
706
707 return S_OK;
708}
709
710void BIOSSettings::commit()
711{
712 /* sanity */
713 AutoCaller autoCaller (this);
714 AssertComRCReturnVoid (autoCaller.rc());
715
716 /* sanity too */
717 AutoCaller peerCaller (mPeer);
718 AssertComRCReturnVoid (peerCaller.rc());
719
720 /* lock both for writing since we modify both (mPeer is "master" so locked
721 * first) */
722 AutoMultiWriteLock2 alock (mPeer, this);
723
724 if (mData.isBackedUp())
725 {
726 mData.commit();
727 if (mPeer)
728 {
729 /* attach new data to the peer and reshare it */
730 AutoWriteLock peerlock (mPeer);
731 mPeer->mData.attach (mData);
732 }
733 }
734}
735
736void BIOSSettings::copyFrom (BIOSSettings *aThat)
737{
738 AssertReturnVoid (aThat != NULL);
739
740 /* sanity */
741 AutoCaller autoCaller (this);
742 AssertComRCReturnVoid (autoCaller.rc());
743
744 /* sanity too */
745 AutoCaller thatCaller (aThat);
746 AssertComRCReturnVoid (thatCaller.rc());
747
748 /* peer is not modified, lock it for reading (aThat is "master" so locked
749 * first) */
750 AutoMultiLock2 alock (aThat->rlock(), this->wlock());
751
752 /* this will back up current data */
753 mData.assignCopy (aThat->mData);
754}
755
756void BIOSSettings::applyDefaults (GuestOSType *aOsType)
757{
758 AssertReturnVoid (aOsType != NULL);
759
760 /* sanity */
761 AutoCaller autoCaller (this);
762 AssertComRCReturnVoid (autoCaller.rc());
763
764 AutoWriteLock alock (this);
765
766 /* Initialize default BIOS settings here */
767 mData->mIOAPICEnabled = aOsType->recommendedIOAPIC();
768}
769/* vi: set tabstop=4 shiftwidth=4 expandtab: */
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