2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 #include <IOKit/IOLib.h>
24 #include <IOKit/IONVRAM.h>
25 #include <IOKit/IOPlatformExpert.h>
26 #include <IOKit/IOUserClient.h>
27 #include <IOKit/IOKitKeys.h>
29 #define super IOService
31 OSDefineMetaClassAndStructors(IODTNVRAM
, IOService
);
33 bool IODTNVRAM::init(IORegistryEntry
*old
, const IORegistryPlane
*plane
)
37 if (!super::init(old
, plane
)) return false;
39 dict
= OSDictionary::withCapacity(1);
40 if (dict
== 0) return false;
41 setPropertyTable(dict
);
43 _nvramImage
= IONew(UInt8
, kIODTNVRAMImageSize
);
44 if (_nvramImage
== 0) return false;
46 _nvramPartitionOffsets
= OSDictionary::withCapacity(1);
47 if (_nvramPartitionOffsets
== 0) return false;
49 _nvramPartitionLengths
= OSDictionary::withCapacity(1);
50 if (_nvramPartitionLengths
== 0) return false;
52 _registryPropertiesKey
= OSSymbol::withCStringNoCopy("aapl,pci");
53 if (_registryPropertiesKey
== 0) return false;
58 void IODTNVRAM::registerNVRAMController(IONVRAMController
*nvram
)
61 UInt32 partitionOffset
, partitionLength
;
62 UInt32 freePartitionOffset
, freePartitionSize
;
63 UInt32 currentLength
, currentOffset
= 0;
64 OSNumber
*partitionOffsetNumber
, *partitionLengthNumber
;
66 if (_nvramController
!= 0) return;
68 _nvramController
= nvram
;
70 _nvramController
->read(0, _nvramImage
, kIODTNVRAMImageSize
);
72 // Find the offsets for the OF, XPRAM, NameRegistry and PanicInfo partitions.
73 _ofPartitionOffset
= 0xFFFFFFFF;
74 _xpramPartitionOffset
= 0xFFFFFFFF;
75 _nrPartitionOffset
= 0xFFFFFFFF;
76 _piPartitionOffset
= 0xFFFFFFFF;
77 freePartitionOffset
= 0xFFFFFFFF;
78 freePartitionSize
= 0;
79 if (getPlatform()->getBootROMType()) {
80 // Look through the partitions to find the OF, MacOS partitions.
81 while (currentOffset
< kIODTNVRAMImageSize
) {
82 currentLength
= ((UInt16
*)(_nvramImage
+ currentOffset
))[1] * 16;
84 partitionOffset
= currentOffset
+ 16;
85 partitionLength
= currentLength
- 16;
87 if (strncmp((const char *)_nvramImage
+ currentOffset
+ 4,
88 kIODTNVRAMOFPartitionName
, 12) == 0) {
89 _ofPartitionOffset
= partitionOffset
;
90 _ofPartitionSize
= partitionLength
;
91 } else if (strncmp((const char *)_nvramImage
+ currentOffset
+ 4,
92 kIODTNVRAMXPRAMPartitionName
, 12) == 0) {
93 _xpramPartitionOffset
= partitionOffset
;
94 _xpramPartitionSize
= kIODTNVRAMXPRAMSize
;
95 _nrPartitionOffset
= _xpramPartitionOffset
+ _xpramPartitionSize
;
96 _nrPartitionSize
= partitionLength
- _xpramPartitionSize
;
97 } else if (strncmp((const char *)_nvramImage
+ currentOffset
+ 4,
98 kIODTNVRAMPanicInfoPartitonName
, 12) == 0) {
99 _piPartitionOffset
= partitionOffset
;
100 _piPartitionSize
= partitionLength
;
101 } else if (strncmp((const char *)_nvramImage
+ currentOffset
+ 4,
102 kIODTNVRAMFreePartitionName
, 12) == 0) {
103 freePartitionOffset
= currentOffset
;
104 freePartitionSize
= currentLength
;
106 // Construct the partition ID from the signature and name.
107 sprintf(partitionID
, "0x%02x,",
108 *(UInt8
*)(_nvramImage
+ currentOffset
));
109 strncpy(partitionID
+ 5,
110 (const char *)(_nvramImage
+ currentOffset
+ 4), 12);
111 partitionID
[17] = '\0';
113 partitionOffsetNumber
= OSNumber::withNumber(partitionOffset
, 32);
114 partitionLengthNumber
= OSNumber::withNumber(partitionLength
, 32);
116 // Save the partition offset and length
117 _nvramPartitionOffsets
->setObject(partitionID
, partitionOffsetNumber
);
118 _nvramPartitionLengths
->setObject(partitionID
, partitionLengthNumber
);
120 partitionOffsetNumber
->release();
121 partitionLengthNumber
->release();
123 currentOffset
+= currentLength
;
126 // Use the fixed address for old world machines.
127 _ofPartitionOffset
= 0x1800;
128 _ofPartitionSize
= 0x0800;
129 _xpramPartitionOffset
= 0x1300;
130 _xpramPartitionSize
= 0x0100;
131 _nrPartitionOffset
= 0x1400;
132 _nrPartitionSize
= 0x0400;
135 if (_ofPartitionOffset
!= 0xFFFFFFFF)
136 _ofImage
= _nvramImage
+ _ofPartitionOffset
;
137 if (_xpramPartitionOffset
!= 0xFFFFFFFF)
138 _xpramImage
= _nvramImage
+ _xpramPartitionOffset
;
139 if (_nrPartitionOffset
!= 0xFFFFFFFF)
140 _nrImage
= _nvramImage
+ _nrPartitionOffset
;
142 if (_piPartitionOffset
== 0xFFFFFFFF) {
143 if (freePartitionSize
> 0x20) {
144 // Set the signature to 0xa1.
145 _nvramImage
[freePartitionOffset
] = 0xa1;
146 // Set the checksum to 0.
147 _nvramImage
[freePartitionOffset
+ 1] = 0;
148 // Set the name for the Panic Info partition.
149 strncpy((char *)(_nvramImage
+ freePartitionOffset
+ 4),
150 kIODTNVRAMPanicInfoPartitonName
, 12);
152 // Calculate the partition offset and size.
153 _piPartitionOffset
= freePartitionOffset
+ 0x10;
154 _piPartitionSize
= 0x800;
155 if (_piPartitionSize
+ 0x20 > freePartitionSize
)
156 _piPartitionSize
= freePartitionSize
- 0x20;
158 _piImage
= _nvramImage
+ _piPartitionOffset
;
160 // Zero the new partition.
161 bzero(_piImage
, _piPartitionSize
);
163 // Set the partition size.
164 *(UInt16
*)(_nvramImage
+ freePartitionOffset
+ 2) =
165 (_piPartitionSize
/ 0x10) + 1;
167 // Set the partition checksum.
168 _nvramImage
[freePartitionOffset
+ 1] =
169 calculatePartitionChecksum(_nvramImage
+ freePartitionOffset
);
171 // Calculate the free partition offset and size.
172 freePartitionOffset
+= _piPartitionSize
+ 0x10;
173 freePartitionSize
-= _piPartitionSize
+ 0x10;
175 // Set the signature to 0x7f.
176 _nvramImage
[freePartitionOffset
] = 0x7f;
177 // Set the checksum to 0.
178 _nvramImage
[freePartitionOffset
+ 1] = 0;
179 // Set the name for the free partition.
180 strncpy((char *)(_nvramImage
+ freePartitionOffset
+ 4),
181 kIODTNVRAMFreePartitionName
, 12);
182 // Set the partition size.
183 *(UInt16
*)(_nvramImage
+ freePartitionOffset
+ 2) =
184 freePartitionSize
/ 0x10;
185 // Set the partition checksum.
186 _nvramImage
[freePartitionOffset
+ 1] =
187 calculatePartitionChecksum(_nvramImage
+ freePartitionOffset
);
189 // Set the nvram image as dirty.
190 _nvramImageDirty
= true;
193 _piImage
= _nvramImage
+ _piPartitionOffset
;
199 void IODTNVRAM::sync(void)
201 if (!_nvramImageDirty
&& !_ofImageDirty
) return;
203 // Don't try to sync OF Variables if the system has already paniced.
204 if (!_systemPaniced
) syncOFVariables();
206 _nvramController
->write(0, _nvramImage
, kIODTNVRAMImageSize
);
207 _nvramController
->sync();
209 _nvramImageDirty
= false;
212 bool IODTNVRAM::serializeProperties(OSSerialize
*serialize
) const
217 OSDictionary
*dict
, *tmpDict
= 0;
218 OSCollectionIterator
*iter
= 0;
220 if (_ofDict
== 0) return false;
222 // Verify permissions.
223 result
= IOUserClient::clientHasPrivilege(current_task(), kIOClientPrivilegeAdministrator
);
224 if (result
!= kIOReturnSuccess
) {
225 tmpDict
= OSDictionary::withCapacity(1);
226 if (tmpDict
== 0) return false;
228 iter
= OSCollectionIterator::withCollection(_ofDict
);
229 if (iter
== 0) return false;
232 key
= OSDynamicCast(OSSymbol
, iter
->getNextObject());
235 variablePerm
= getOFVariablePerm(key
);
236 if (variablePerm
!= kOFVariablePermRootOnly
) {
237 tmpDict
->setObject(key
, _ofDict
->getObject(key
));
245 result
= dict
->serialize(serialize
);
247 if (tmpDict
!= 0) tmpDict
->release();
248 if (iter
!= 0) iter
->release();
253 OSObject
*IODTNVRAM::getProperty(const OSSymbol
*aKey
) const
258 if (_ofDict
== 0) return 0;
260 // Verify permissions.
261 result
= IOUserClient::clientHasPrivilege(current_task(), "root");
262 if (result
!= kIOReturnSuccess
) {
263 variablePerm
= getOFVariablePerm(aKey
);
264 if (variablePerm
== kOFVariablePermRootOnly
) return 0;
267 return _ofDict
->getObject(aKey
);
270 OSObject
*IODTNVRAM::getProperty(const char *aKey
) const
272 const OSSymbol
*keySymbol
;
273 OSObject
*theObject
= 0;
275 keySymbol
= OSSymbol::withCStringNoCopy(aKey
);
276 if (keySymbol
!= 0) {
277 theObject
= getProperty(keySymbol
);
278 keySymbol
->release();
284 bool IODTNVRAM::setProperty(const OSSymbol
*aKey
, OSObject
*anObject
)
287 UInt32 propType
, propPerm
;
289 OSObject
*propObject
= 0;
291 if (_ofDict
== 0) return false;
293 // Verify permissions.
294 result
= IOUserClient::clientHasPrivilege(current_task(), "root");
295 if (result
!= kIOReturnSuccess
) {
296 propPerm
= getOFVariablePerm(aKey
);
297 if (propPerm
!= kOFVariablePermUserWrite
) return false;
300 // Don't allow creation of new properties on old world machines.
301 if (getPlatform()->getBootROMType() == 0) {
302 if (_ofDict
->getObject(aKey
) == 0) return false;
305 // Don't allow change of 'aapl,panic-info'.
306 if (aKey
->isEqualTo(kIODTNVRAMPanicInfoKey
)) return false;
308 // Make sure the object is of the correct type.
309 propType
= getOFVariableType(aKey
);
311 case kOFVariableTypeBoolean
:
312 propObject
= OSDynamicCast(OSBoolean
, anObject
);
315 case kOFVariableTypeNumber
:
316 propObject
= OSDynamicCast(OSNumber
, anObject
);
319 case kOFVariableTypeString
:
320 propObject
= OSDynamicCast(OSString
, anObject
);
323 case kOFVariableTypeData
:
324 propObject
= OSDynamicCast(OSData
, anObject
);
325 if (propObject
== 0) {
326 tmpString
= OSDynamicCast(OSString
, anObject
);
327 if (tmpString
!= 0) {
328 propObject
= OSData::withBytes(tmpString
->getCStringNoCopy(),
329 tmpString
->getLength());
335 if (propObject
== 0) return false;
337 result
= _ofDict
->setObject(aKey
, propObject
);
340 if (getPlatform()->getBootROMType() == 0) {
341 updateOWBootArgs(aKey
, propObject
);
344 _ofImageDirty
= true;
350 IOReturn
IODTNVRAM::setProperties(OSObject
*properties
)
356 OSCollectionIterator
*iter
;
358 dict
= OSDynamicCast(OSDictionary
, properties
);
359 if (dict
== 0) return kIOReturnBadArgument
;
361 iter
= OSCollectionIterator::withCollection(dict
);
362 if (iter
== 0) return kIOReturnBadArgument
;
365 key
= OSDynamicCast(OSSymbol
, iter
->getNextObject());
368 object
= dict
->getObject(key
);
369 if (object
== 0) continue;
371 result
= setProperty(key
, object
);
376 if (result
) return kIOReturnSuccess
;
377 else return kIOReturnError
;
380 IOReturn
IODTNVRAM::readXPRAM(IOByteCount offset
, UInt8
*buffer
,
383 if (_xpramImage
== 0) return kIOReturnUnsupported
;
385 if ((buffer
== 0) || (length
<= 0) || (offset
< 0) ||
386 (offset
+ length
> kIODTNVRAMXPRAMSize
))
387 return kIOReturnBadArgument
;
389 bcopy(_nvramImage
+ _xpramPartitionOffset
+ offset
, buffer
, length
);
391 return kIOReturnSuccess
;
394 IOReturn
IODTNVRAM::writeXPRAM(IOByteCount offset
, UInt8
*buffer
,
397 if (_xpramImage
== 0) return kIOReturnUnsupported
;
399 if ((buffer
== 0) || (length
<= 0) || (offset
< 0) ||
400 (offset
+ length
> kIODTNVRAMXPRAMSize
))
401 return kIOReturnBadArgument
;
403 bcopy(buffer
, _nvramImage
+ _xpramPartitionOffset
+ offset
, length
);
405 _nvramImageDirty
= true;
407 return kIOReturnSuccess
;
410 IOReturn
IODTNVRAM::readNVRAMProperty(IORegistryEntry
*entry
,
411 const OSSymbol
**name
,
416 if (getPlatform()->getBootROMType())
417 err
= readNVRAMPropertyType1(entry
, name
, value
);
419 err
= readNVRAMPropertyType0(entry
, name
, value
);
424 IOReturn
IODTNVRAM::writeNVRAMProperty(IORegistryEntry
*entry
,
425 const OSSymbol
*name
,
430 if (getPlatform()->getBootROMType())
431 err
= writeNVRAMPropertyType1(entry
, name
, value
);
433 err
= writeNVRAMPropertyType0(entry
, name
, value
);
438 OSDictionary
*IODTNVRAM::getNVRAMPartitions(void)
440 return _nvramPartitionLengths
;
443 IOReturn
IODTNVRAM::readNVRAMPartition(const OSSymbol
*partitionID
,
444 IOByteCount offset
, UInt8
*buffer
,
447 OSNumber
*partitionOffsetNumber
, *partitionLengthNumber
;
448 UInt32 partitionOffset
, partitionLength
;
450 partitionOffsetNumber
=
451 (OSNumber
*)_nvramPartitionOffsets
->getObject(partitionID
);
452 partitionLengthNumber
=
453 (OSNumber
*)_nvramPartitionLengths
->getObject(partitionID
);
455 if ((partitionOffsetNumber
== 0) || (partitionLengthNumber
== 0))
456 return kIOReturnNotFound
;
458 partitionOffset
= partitionOffsetNumber
->unsigned32BitValue();
459 partitionLength
= partitionLengthNumber
->unsigned32BitValue();
461 if ((buffer
== 0) || (length
<= 0) || (offset
< 0) ||
462 (offset
+ length
> partitionLength
))
463 return kIOReturnBadArgument
;
465 bcopy(_nvramImage
+ partitionOffset
+ offset
, buffer
, length
);
467 return kIOReturnSuccess
;
470 IOReturn
IODTNVRAM::writeNVRAMPartition(const OSSymbol
*partitionID
,
471 IOByteCount offset
, UInt8
*buffer
,
474 OSNumber
*partitionOffsetNumber
, *partitionLengthNumber
;
475 UInt32 partitionOffset
, partitionLength
;
477 partitionOffsetNumber
=
478 (OSNumber
*)_nvramPartitionOffsets
->getObject(partitionID
);
479 partitionLengthNumber
=
480 (OSNumber
*)_nvramPartitionLengths
->getObject(partitionID
);
482 if ((partitionOffsetNumber
== 0) || (partitionLengthNumber
== 0))
483 return kIOReturnNotFound
;
485 partitionOffset
= partitionOffsetNumber
->unsigned32BitValue();
486 partitionLength
= partitionLengthNumber
->unsigned32BitValue();
488 if ((buffer
== 0) || (length
<= 0) || (offset
< 0) ||
489 (offset
+ length
> partitionLength
))
490 return kIOReturnBadArgument
;
492 bcopy(buffer
, _nvramImage
+ partitionOffset
+ offset
, length
);
494 _nvramImageDirty
= true;
496 return kIOReturnSuccess
;
499 UInt32
IODTNVRAM::savePanicInfo(UInt8
*buffer
, IOByteCount length
)
501 if ((_piImage
== 0) || (length
<= 0)) return 0;
503 if (length
> (_piPartitionSize
- 4))
504 length
= _piPartitionSize
- 4;
506 // Save the Panic Info.
507 bcopy(buffer
, _piImage
+ 4, length
);
509 // Save the Panic Info length.
510 *(UInt32
*)_piImage
= length
;
512 _nvramImageDirty
= true;
514 _systemPaniced
= true;
521 UInt8
IODTNVRAM::calculatePartitionChecksum(UInt8
*partitionHeader
)
523 UInt8 cnt
, isum
, csum
= 0;
525 for (cnt
= 0; cnt
< 0x10; cnt
++) {
526 isum
= csum
+ partitionHeader
[cnt
];
527 if (isum
< csum
) isum
++;
534 struct OWVariablesHeader
{
549 typedef struct OWVariablesHeader OWVariablesHeader
;
551 IOReturn
IODTNVRAM::initOFVariables(void)
553 UInt32 cnt
, propOffset
, propType
;
554 UInt8
*propName
, *propData
;
555 UInt32 propNameLength
, propDataLength
;
556 const OSSymbol
*propSymbol
;
557 OSObject
*propObject
;
558 OWVariablesHeader
*owHeader
;
560 if (_ofImage
== 0) return kIOReturnNotReady
;
562 _ofDict
= OSDictionary::withCapacity(1);
563 if (_ofDict
== 0) return kIOReturnNoMemory
;
565 if (getPlatform()->getBootROMType()) {
567 while (cnt
< _ofPartitionSize
) {
568 // Break if there is no name.
569 if (_ofImage
[cnt
] == '\0') break;
571 // Find the length of the name.
572 propName
= _ofImage
+ cnt
;
573 for (propNameLength
= 0; (cnt
+ propNameLength
) < _ofPartitionSize
;
575 if (_ofImage
[cnt
+ propNameLength
] == '=') break;
578 // Break if the name goes past the end of the partition.
579 if ((cnt
+ propNameLength
) >= _ofPartitionSize
) break;
580 cnt
+= propNameLength
+ 1;
582 propData
= _ofImage
+ cnt
;
583 for (propDataLength
= 0; (cnt
+ propDataLength
) < _ofPartitionSize
;
585 if (_ofImage
[cnt
+ propDataLength
] == '\0') break;
588 // Break if the data goes past the end of the partition.
589 if ((cnt
+ propDataLength
) >= _ofPartitionSize
) break;
590 cnt
+= propDataLength
+ 1;
592 if (convertPropToObject(propName
, propNameLength
,
593 propData
, propDataLength
,
594 &propSymbol
, &propObject
)) {
595 _ofDict
->setObject(propSymbol
, propObject
);
596 propSymbol
->release();
597 propObject
->release();
601 // Create the boot-args property if it is not in the dictionary.
602 if (_ofDict
->getObject("boot-args") == 0) {
603 propObject
= OSString::withCStringNoCopy("");
604 if (propObject
!= 0) {
605 _ofDict
->setObject("boot-args", propObject
);
606 propObject
->release();
610 // Create the 'aapl,panic-info' property if needed.
612 propDataLength
= *(UInt32
*)_piImage
;
613 if ((propDataLength
!= 0) && (propDataLength
< (_piPartitionSize
- 4))) {
614 propObject
= OSData::withBytes(_piImage
+ 4, propDataLength
);
615 _ofDict
->setObject(kIODTNVRAMPanicInfoKey
, propObject
);
616 propObject
->release();
618 // Clear the length from _piImage and mark dirty.
619 *(UInt32
*)_piImage
= 0;
620 _nvramImageDirty
= true;
624 owHeader
= (OWVariablesHeader
*)_ofImage
;
625 if (!validateOWChecksum(_ofImage
)) {
628 return kIOReturnBadMedia
;
633 if (!getOWVariableInfo(cnt
++, &propSymbol
, &propType
, &propOffset
))
637 case kOFVariableTypeBoolean
:
638 propObject
= OSBoolean::withBoolean(owHeader
->owFlags
& propOffset
);
641 case kOFVariableTypeNumber
:
642 propObject
= OSNumber::withNumber(owHeader
->owNumbers
[propOffset
], 32);
645 case kOFVariableTypeString
:
646 propData
= _ofImage
+ owHeader
->owStrings
[propOffset
].offset
-
648 propDataLength
= owHeader
->owStrings
[propOffset
].length
;
649 propName
= IONew(UInt8
, propDataLength
+ 1);
651 strncpy((char *)propName
, (const char *)propData
, propDataLength
);
652 propName
[propDataLength
] = '\0';
653 propObject
= OSString::withCString((const char *)propName
);
654 IODelete(propName
, UInt8
, propDataLength
+ 1);
659 if (propObject
== 0) break;
661 _ofDict
->setObject(propSymbol
, propObject
);
662 propSymbol
->release();
663 propObject
->release();
666 // Create the boot-args property.
667 propSymbol
= OSSymbol::withCString("boot-command");
668 if (propSymbol
!= 0) {
669 propObject
= _ofDict
->getObject(propSymbol
);
670 if (propObject
!= 0) {
671 updateOWBootArgs(propSymbol
, propObject
);
673 propSymbol
->release();
677 return kIOReturnSuccess
;
680 IOReturn
IODTNVRAM::syncOFVariables(void)
683 UInt32 cnt
, length
, maxLength
;
684 UInt32 curOffset
, tmpOffset
, tmpType
, tmpDataLength
;
685 UInt8
*buffer
, *tmpBuffer
, *tmpData
;
686 const OSSymbol
*tmpSymbol
;
688 OSBoolean
*tmpBoolean
;
691 OSCollectionIterator
*iter
;
692 OWVariablesHeader
*owHeader
, *owHeaderOld
;
694 if ((_ofImage
== 0) || (_ofDict
== 0)) return kIOReturnNotReady
;
696 if (!_ofImageDirty
) return kIOReturnSuccess
;
698 if (getPlatform()->getBootROMType()) {
699 buffer
= tmpBuffer
= IONew(UInt8
, _ofPartitionSize
);
700 if (buffer
== 0) return kIOReturnNoMemory
;
701 bzero(buffer
, _ofPartitionSize
);
704 maxLength
= _ofPartitionSize
;
706 iter
= OSCollectionIterator::withCollection(_ofDict
);
707 if (iter
== 0) ok
= false;
710 tmpSymbol
= OSDynamicCast(OSSymbol
, iter
->getNextObject());
711 if (tmpSymbol
== 0) break;
713 // Don't save 'aapl,panic-info'.
714 if (tmpSymbol
->isEqualTo(kIODTNVRAMPanicInfoKey
)) continue;
716 tmpObject
= _ofDict
->getObject(tmpSymbol
);
719 ok
= convertObjectToProp(tmpBuffer
, &length
, tmpSymbol
, tmpObject
);
728 bcopy(buffer
, _ofImage
, _ofPartitionSize
);
731 IODelete(buffer
, UInt8
, _ofPartitionSize
);
733 if (!ok
) return kIOReturnBadArgument
;
735 buffer
= IONew(UInt8
, _ofPartitionSize
);
736 if (buffer
== 0) return kIOReturnNoMemory
;
737 bzero(buffer
, _ofPartitionSize
);
739 owHeader
= (OWVariablesHeader
*)buffer
;
740 owHeaderOld
= (OWVariablesHeader
*)_ofImage
;
742 owHeader
->owMagic
= owHeaderOld
->owMagic
;
743 owHeader
->owVersion
= owHeaderOld
->owVersion
;
744 owHeader
->owPages
= owHeaderOld
->owPages
;
746 curOffset
= _ofPartitionSize
;
751 if (!getOWVariableInfo(cnt
++, &tmpSymbol
, &tmpType
, &tmpOffset
))
754 tmpObject
= _ofDict
->getObject(tmpSymbol
);
757 case kOFVariableTypeBoolean
:
758 tmpBoolean
= OSDynamicCast(OSBoolean
, tmpObject
);
759 if (tmpBoolean
->getValue()) owHeader
->owFlags
|= tmpOffset
;
762 case kOFVariableTypeNumber
:
763 tmpNumber
= OSDynamicCast(OSNumber
, tmpObject
);
764 owHeader
->owNumbers
[tmpOffset
] = tmpNumber
->unsigned32BitValue();
767 case kOFVariableTypeString
:
768 tmpString
= OSDynamicCast(OSString
, tmpObject
);
769 tmpData
= (UInt8
*) tmpString
->getCStringNoCopy();
770 tmpDataLength
= tmpString
->getLength();
772 if ((curOffset
- tmpDataLength
) < sizeof(OWVariablesHeader
)) {
777 owHeader
->owStrings
[tmpOffset
].length
= tmpDataLength
;
778 curOffset
-= tmpDataLength
;
779 owHeader
->owStrings
[tmpOffset
].offset
= curOffset
+ _ofPartitionOffset
;
780 if (tmpDataLength
!= 0)
781 bcopy(tmpData
, buffer
+ curOffset
, tmpDataLength
);
787 owHeader
->owHere
= _ofPartitionOffset
+ sizeof(OWVariablesHeader
);
788 owHeader
->owTop
= _ofPartitionOffset
+ curOffset
;
789 owHeader
->owNext
= 0;
791 owHeader
->owChecksum
= 0;
792 owHeader
->owChecksum
= ~generateOWChecksum(buffer
);
794 bcopy(buffer
, _ofImage
, _ofPartitionSize
);
797 IODelete(buffer
, UInt8
, _ofPartitionSize
);
799 if (!ok
) return kIOReturnBadArgument
;
802 _ofImageDirty
= false;
803 _nvramImageDirty
= true;
805 return kIOReturnSuccess
;
812 SInt32 variableOffset
;
814 typedef struct OFVariable OFVariable
;
817 kOWVariableOffsetNumber
= 8,
818 kOWVariableOffsetString
= 17
821 OFVariable gOFVariables
[] = {
822 {"little-endian?", kOFVariableTypeBoolean
, kOFVariablePermUserRead
, 0},
823 {"real-mode?", kOFVariableTypeBoolean
, kOFVariablePermUserRead
, 1},
824 {"auto-boot?", kOFVariableTypeBoolean
, kOFVariablePermUserRead
, 2},
825 {"diag-switch?", kOFVariableTypeBoolean
, kOFVariablePermUserRead
, 3},
826 {"fcode-debug?", kOFVariableTypeBoolean
, kOFVariablePermUserRead
, 4},
827 {"oem-banner?", kOFVariableTypeBoolean
, kOFVariablePermUserRead
, 5},
828 {"oem-logo?", kOFVariableTypeBoolean
, kOFVariablePermUserRead
, 6},
829 {"use-nvramrc?", kOFVariableTypeBoolean
, kOFVariablePermUserRead
, 7},
830 {"use-generic?", kOFVariableTypeBoolean
, kOFVariablePermUserRead
, -1},
831 {"default-mac-address?", kOFVariableTypeBoolean
, kOFVariablePermUserRead
,-1},
832 {"real-base", kOFVariableTypeNumber
, kOFVariablePermUserRead
, 8},
833 {"real-size", kOFVariableTypeNumber
, kOFVariablePermUserRead
, 9},
834 {"virt-base", kOFVariableTypeNumber
, kOFVariablePermUserRead
, 10},
835 {"virt-size", kOFVariableTypeNumber
, kOFVariablePermUserRead
, 11},
836 {"load-base", kOFVariableTypeNumber
, kOFVariablePermUserRead
, 12},
837 {"pci-probe-list", kOFVariableTypeNumber
, kOFVariablePermUserRead
, 13},
838 {"pci-probe-mask", kOFVariableTypeNumber
, kOFVariablePermUserRead
, -1},
839 {"screen-#columns", kOFVariableTypeNumber
, kOFVariablePermUserRead
, 14},
840 {"screen-#rows", kOFVariableTypeNumber
, kOFVariablePermUserRead
, 15},
841 {"selftest-#megs", kOFVariableTypeNumber
, kOFVariablePermUserRead
, 16},
842 {"boot-device", kOFVariableTypeString
, kOFVariablePermUserRead
, 17},
843 {"boot-file", kOFVariableTypeString
, kOFVariablePermUserRead
, 18},
844 {"boot-screen", kOFVariableTypeString
, kOFVariablePermUserRead
, -1},
845 {"console-screen", kOFVariableTypeString
, kOFVariablePermUserRead
, -1},
846 {"diag-device", kOFVariableTypeString
, kOFVariablePermUserRead
, 19},
847 {"diag-file", kOFVariableTypeString
, kOFVariablePermUserRead
, 20},
848 {"input-device", kOFVariableTypeString
, kOFVariablePermUserRead
, 21},
849 {"output-device", kOFVariableTypeString
, kOFVariablePermUserRead
, 22},
850 {"input-device-1", kOFVariableTypeString
, kOFVariablePermUserRead
, -1},
851 {"output-device-1", kOFVariableTypeString
, kOFVariablePermUserRead
, -1},
852 {"mouse-device", kOFVariableTypeString
, kOFVariablePermUserRead
, -1},
853 {"oem-banner", kOFVariableTypeString
, kOFVariablePermUserRead
, 23},
854 {"oem-logo", kOFVariableTypeString
, kOFVariablePermUserRead
, 24},
855 {"nvramrc", kOFVariableTypeString
, kOFVariablePermUserRead
, 25},
856 {"boot-command", kOFVariableTypeString
, kOFVariablePermUserRead
, 26},
857 {"default-client-ip", kOFVariableTypeString
, kOFVariablePermUserRead
, -1},
858 {"default-server-ip", kOFVariableTypeString
, kOFVariablePermUserRead
, -1},
859 {"default-gateway-ip", kOFVariableTypeString
, kOFVariablePermUserRead
, -1},
860 {"default-subnet-mask", kOFVariableTypeString
, kOFVariablePermUserRead
, -1},
861 {"default-router-ip", kOFVariableTypeString
, kOFVariablePermUserRead
, -1},
862 {"boot-script", kOFVariableTypeString
, kOFVariablePermUserRead
, -1},
863 {"boot-args", kOFVariableTypeString
, kOFVariablePermUserRead
, -1},
864 {"aapl,pci", kOFVariableTypeData
, kOFVariablePermRootOnly
, -1},
865 {"security-mode", kOFVariableTypeString
, kOFVariablePermUserRead
, -1},
866 {"security-password", kOFVariableTypeData
, kOFVariablePermRootOnly
, -1},
867 {0, kOFVariableTypeData
, kOFVariablePermUserRead
, -1}
870 UInt32
IODTNVRAM::getOFVariableType(const OSSymbol
*propSymbol
) const
874 ofVar
= gOFVariables
;
876 if ((ofVar
->variableName
== 0) ||
877 propSymbol
->isEqualTo(ofVar
->variableName
)) break;
881 return ofVar
->variableType
;
884 UInt32
IODTNVRAM::getOFVariablePerm(const OSSymbol
*propSymbol
) const
888 ofVar
= gOFVariables
;
890 if ((ofVar
->variableName
== 0) ||
891 propSymbol
->isEqualTo(ofVar
->variableName
)) break;
895 return ofVar
->variablePerm
;
898 bool IODTNVRAM::getOWVariableInfo(UInt32 variableNumber
, const OSSymbol
**propSymbol
,
899 UInt32
*propType
, UInt32
*propOffset
)
903 ofVar
= gOFVariables
;
905 if (ofVar
->variableName
== 0) return false;
907 if (ofVar
->variableOffset
== (SInt32
) variableNumber
) break;
912 *propSymbol
= OSSymbol::withCStringNoCopy(ofVar
->variableName
);
913 *propType
= ofVar
->variableType
;
916 case kOFVariableTypeBoolean
:
917 *propOffset
= 1 << (31 - variableNumber
);
920 case kOFVariableTypeNumber
:
921 *propOffset
= variableNumber
- kOWVariableOffsetNumber
;
924 case kOFVariableTypeString
:
925 *propOffset
= variableNumber
- kOWVariableOffsetString
;
932 bool IODTNVRAM::convertPropToObject(UInt8
*propName
, UInt32 propNameLength
,
933 UInt8
*propData
, UInt32 propDataLength
,
934 const OSSymbol
**propSymbol
,
935 OSObject
**propObject
)
938 const OSSymbol
*tmpSymbol
;
943 // Create the symbol.
944 propName
[propNameLength
] = '\0';
945 tmpSymbol
= OSSymbol::withCString((const char *)propName
);
946 propName
[propNameLength
] = '=';
947 if (tmpSymbol
== 0) {
951 propType
= getOFVariableType(tmpSymbol
);
953 // Create the object.
956 case kOFVariableTypeBoolean
:
957 if (!strncmp("true", (const char *)propData
, propDataLength
)) {
958 tmpObject
= kOSBooleanTrue
;
959 } else if (!strncmp("false", (const char *)propData
, propDataLength
)) {
960 tmpObject
= kOSBooleanFalse
;
964 case kOFVariableTypeNumber
:
965 tmpNumber
= OSNumber::withNumber(strtol((const char *)propData
, 0, 0), 32);
966 if (tmpNumber
!= 0) tmpObject
= tmpNumber
;
969 case kOFVariableTypeString
:
970 tmpString
= OSString::withCString((const char *)propData
);
971 if (tmpString
!= 0) tmpObject
= tmpString
;
974 case kOFVariableTypeData
:
975 tmpObject
= unescapeBytesToData(propData
, propDataLength
);
979 if (tmpObject
== 0) {
980 tmpSymbol
->release();
984 *propSymbol
= tmpSymbol
;
985 *propObject
= tmpObject
;
990 bool IODTNVRAM::convertObjectToProp(UInt8
*buffer
, UInt32
*length
,
991 const OSSymbol
*propSymbol
, OSObject
*propObject
)
994 UInt32 propNameLength
, propDataLength
;
995 UInt32 propType
, tmpValue
;
996 OSBoolean
*tmpBoolean
= 0;
997 OSNumber
*tmpNumber
= 0;
998 OSString
*tmpString
= 0;
1001 propName
= (UInt8
*)propSymbol
->getCStringNoCopy();
1002 propNameLength
= propSymbol
->getLength();
1003 propType
= getOFVariableType(propSymbol
);
1005 // Get the size of the data.
1006 propDataLength
= 0xFFFFFFFF;
1008 case kOFVariableTypeBoolean
:
1009 tmpBoolean
= OSDynamicCast(OSBoolean
, propObject
);
1010 if (tmpBoolean
!= 0) propDataLength
= 5;
1013 case kOFVariableTypeNumber
:
1014 tmpNumber
= OSDynamicCast(OSNumber
, propObject
);
1015 if (tmpNumber
!= 0) propDataLength
= 10;
1018 case kOFVariableTypeString
:
1019 tmpString
= OSDynamicCast(OSString
, propObject
);
1020 if (tmpString
!= 0) propDataLength
= tmpString
->getLength();
1023 case kOFVariableTypeData
:
1024 tmpData
= OSDynamicCast(OSData
, propObject
);
1026 tmpData
= escapeDataToData(tmpData
);
1027 propDataLength
= tmpData
->getLength();
1032 // Make sure the propertySize is known and will fit.
1033 if (propDataLength
== 0xFFFFFFFF) return false;
1034 if ((propNameLength
+ propDataLength
+ 2) > *length
) return false;
1036 // Copy the property name equal sign.
1037 sprintf((char *)buffer
, "%s=", propName
);
1038 buffer
+= propNameLength
+ 1;
1041 case kOFVariableTypeBoolean
:
1042 if (tmpBoolean
->getValue()) {
1043 strcpy((char *)buffer
, "true");
1045 strcpy((char *)buffer
, "false");
1049 case kOFVariableTypeNumber
:
1050 tmpValue
= tmpNumber
->unsigned32BitValue();
1051 if (tmpValue
== 0xFFFFFFFF) {
1052 strcpy((char *)buffer
, "-1");
1053 } else if (tmpValue
< 1000) {
1054 sprintf((char *)buffer
, "%ld", tmpValue
);
1056 sprintf((char *)buffer
, "0x%lx", tmpValue
);
1060 case kOFVariableTypeString
:
1061 strcpy((char *)buffer
, tmpString
->getCStringNoCopy());
1064 case kOFVariableTypeData
:
1065 bcopy(tmpData
->getBytesNoCopy(), buffer
, propDataLength
);
1070 propDataLength
= strlen((const char *)buffer
);
1072 *length
= propNameLength
+ propDataLength
+ 2;
1078 UInt16
IODTNVRAM::generateOWChecksum(UInt8
*buffer
)
1080 UInt32 cnt
, checksum
= 0;
1081 UInt16
*tmpBuffer
= (UInt16
*)buffer
;
1083 for (cnt
= 0; cnt
< _ofPartitionSize
/ 2; cnt
++)
1084 checksum
+= tmpBuffer
[cnt
];
1086 return checksum
% 0x0000FFFF;
1089 bool IODTNVRAM::validateOWChecksum(UInt8
*buffer
)
1091 UInt32 cnt
, checksum
, sum
= 0;
1092 UInt16
*tmpBuffer
= (UInt16
*)buffer
;
1094 for (cnt
= 0; cnt
< _ofPartitionSize
/ 2; cnt
++)
1095 sum
+= tmpBuffer
[cnt
];
1097 checksum
= (sum
>> 16) + (sum
& 0x0000FFFF);
1098 if (checksum
== 0x10000) checksum
--;
1099 checksum
= (checksum
^ 0x0000FFFF) & 0x0000FFFF;
1101 return checksum
== 0;
1104 void IODTNVRAM::updateOWBootArgs(const OSSymbol
*key
, OSObject
*value
)
1106 bool wasBootArgs
, bootr
= false;
1108 OSString
*tmpString
, *bootCommand
, *bootArgs
= 0;
1109 UInt8
*bootCommandData
, *bootArgsData
, *tmpData
;
1110 UInt32 bootCommandDataLength
, bootArgsDataLength
, tmpDataLength
;
1112 tmpString
= OSDynamicCast(OSString
, value
);
1113 if (tmpString
== 0) return;
1115 if (key
->isEqualTo("boot-command")) {
1116 wasBootArgs
= false;
1117 bootCommand
= tmpString
;
1118 } else if (key
->isEqualTo("boot-args")) {
1120 bootArgs
= tmpString
;
1121 bootCommand
= OSDynamicCast(OSString
, _ofDict
->getObject("boot-command"));
1122 if (bootCommand
== 0) return;
1125 bootCommandData
= (UInt8
*)bootCommand
->getCStringNoCopy();
1126 bootCommandDataLength
= bootCommand
->getLength();
1128 if (bootCommandData
== 0) return;
1130 for (cnt
= 0; cnt
< bootCommandDataLength
; cnt
++) {
1131 if ((bootCommandData
[cnt
] == 'b') &&
1132 !strncmp("bootr", (const char *)bootCommandData
+ cnt
, 5)) {
1134 while (bootCommandData
[cnt
] == ' ') cnt
++;
1140 _ofDict
->removeObject("boot-args");
1145 bootArgsData
= (UInt8
*)bootArgs
->getCStringNoCopy();
1146 bootArgsDataLength
= bootArgs
->getLength();
1147 if (bootArgsData
== 0) return;
1149 tmpDataLength
= cnt
+ bootArgsDataLength
;
1150 tmpData
= IONew(UInt8
, tmpDataLength
+ 1);
1151 if (tmpData
== 0) return;
1153 strncpy((char *)tmpData
, (const char *)bootCommandData
, cnt
);
1154 tmpData
[cnt
] = '\0';
1155 strcat((char *)tmpData
, (const char *)bootArgsData
);
1157 bootCommand
= OSString::withCString((const char *)tmpData
);
1158 if (bootCommand
!= 0) {
1159 _ofDict
->setObject("boot-command", bootCommand
);
1160 bootCommand
->release();
1163 IODelete(tmpData
, UInt8
, tmpDataLength
+ 1);
1165 bootArgs
= OSString::withCString((const char *)(bootCommandData
+ cnt
));
1166 if (bootArgs
!= 0) {
1167 _ofDict
->setObject("boot-args", bootArgs
);
1168 bootArgs
->release();
1174 // Private methods for Name Registry access.
1177 kMaxNVNameLength
= 4,
1178 kMaxNVDataLength
= 8
1181 #pragma options align=mac68k
1182 struct NVRAMProperty
1184 IONVRAMDescriptor header
;
1186 UInt8 name
[ kMaxNVNameLength
];
1188 UInt8 data
[ kMaxNVDataLength
];
1190 #pragma options align=reset
1192 bool IODTNVRAM::searchNVRAMProperty(IONVRAMDescriptor
*hdr
, UInt32
*where
)
1197 nvEnd
= *((UInt16
*)_nrImage
);
1198 if(getPlatform()->getBootROMType()) {
1199 // on NewWorld, offset to partition start
1202 // on old world, absolute
1203 nvEnd
-= _nrPartitionOffset
;
1205 if((nvEnd
< 0) || (nvEnd
>= kIODTNVRAMNameRegistrySize
))
1209 while ((offset
+ sizeof(NVRAMProperty
)) <= (UInt32
)nvEnd
) {
1210 if (bcmp(_nrImage
+ offset
, hdr
, sizeof(*hdr
)) == 0) {
1214 offset
+= sizeof(NVRAMProperty
);
1217 if ((nvEnd
+ sizeof(NVRAMProperty
)) <= kIODTNVRAMNameRegistrySize
)
1225 IOReturn
IODTNVRAM::readNVRAMPropertyType0(IORegistryEntry
*entry
,
1226 const OSSymbol
**name
,
1229 IONVRAMDescriptor hdr
;
1230 NVRAMProperty
*prop
;
1234 char nameBuf
[kMaxNVNameLength
+ 1];
1236 if (_nrImage
== 0) return kIOReturnUnsupported
;
1237 if ((entry
== 0) || (name
== 0) || (value
== 0)) return kIOReturnBadArgument
;
1239 err
= IODTMakeNVDescriptor(entry
, &hdr
);
1240 if (err
!= kIOReturnSuccess
) return err
;
1242 if (searchNVRAMProperty(&hdr
, &offset
)) {
1243 prop
= (NVRAMProperty
*)(_nrImage
+ offset
);
1245 length
= prop
->nameLength
;
1246 if (length
> kMaxNVNameLength
) length
= kMaxNVNameLength
;
1247 strncpy(nameBuf
, (const char *)prop
->name
, length
);
1248 nameBuf
[length
] = 0;
1249 *name
= OSSymbol::withCString(nameBuf
);
1251 length
= prop
->dataLength
;
1252 if (length
> kMaxNVDataLength
) length
= kMaxNVDataLength
;
1253 *value
= OSData::withBytes(prop
->data
, length
);
1255 if ((*name
!= 0) && (*value
!= 0)) return kIOReturnSuccess
;
1256 else return kIOReturnNoMemory
;
1259 return kIOReturnNoResources
;
1262 IOReturn
IODTNVRAM::writeNVRAMPropertyType0(IORegistryEntry
*entry
,
1263 const OSSymbol
*name
,
1266 IONVRAMDescriptor hdr
;
1267 NVRAMProperty
*prop
;
1268 IOByteCount nameLength
;
1269 IOByteCount dataLength
;
1275 if (_nrImage
== 0) return kIOReturnUnsupported
;
1276 if ((entry
== 0) || (name
== 0) || (value
== 0)) return kIOReturnBadArgument
;
1278 nameLength
= name
->getLength();
1279 dataLength
= value
->getLength();
1280 if (nameLength
> kMaxNVNameLength
) return kIOReturnNoSpace
;
1281 if (dataLength
> kMaxNVDataLength
) return kIOReturnNoSpace
;
1283 err
= IODTMakeNVDescriptor(entry
, &hdr
);
1284 if (err
!= kIOReturnSuccess
) return err
;
1286 exists
= searchNVRAMProperty(&hdr
, &offset
);
1287 if (offset
== 0) return kIOReturnNoMemory
;
1289 prop
= (NVRAMProperty
*)(_nrImage
+ offset
);
1290 if (!exists
) bcopy(&hdr
, &prop
->header
, sizeof(hdr
));
1292 prop
->nameLength
= nameLength
;
1293 bcopy(name
->getCStringNoCopy(), prop
->name
, nameLength
);
1294 prop
->dataLength
= dataLength
;
1295 bcopy(value
->getBytesNoCopy(), prop
->data
, dataLength
);
1298 nvLength
= offset
+ sizeof(NVRAMProperty
);
1299 if (getPlatform()->getBootROMType())
1302 nvLength
+= _nrPartitionOffset
;
1303 *((UInt16
*)_nrImage
) = nvLength
;
1306 _nvramImageDirty
= true;
1311 OSData
*IODTNVRAM::unescapeBytesToData(UInt8
*bytes
, UInt32 length
)
1314 UInt32 totalLength
= 0;
1319 // Calculate the actual length of the data.
1322 for (cnt
= 0; cnt
< length
;) {
1323 byte
= bytes
[cnt
++];
1325 byte
= bytes
[cnt
++];
1333 totalLength
+= cnt2
;
1337 // Create an empty OSData of the correct size.
1338 data
= OSData::withCapacity(totalLength
);
1340 for (cnt
= 0; cnt
< length
;) {
1341 byte
= bytes
[cnt
++];
1343 byte
= bytes
[cnt
++];
1345 byte
= (byte
& 0x80) ? 0xFF : 0x00;
1348 data
->appendByte(byte
, cnt2
);
1356 OSData
* IODTNVRAM::escapeDataToData(OSData
* value
)
1365 where
= (UInt8
*) value
->getBytesNoCopy();
1366 end
= where
+ value
->getLength();
1368 result
= OSData::withCapacity(end
- where
);
1372 while (where
< end
) {
1375 if ((byte
== 0x00) || (byte
== 0xFF)) {
1377 ((where
- start
) < 0x80) && (where
< end
) && (byte
== *where
);
1379 ok
&= result
->appendByte(0xff, 1);
1380 byte
= (byte
& 0x80) | (where
- start
);
1382 ok
&= result
->appendByte(byte
, 1);
1384 ok
&= result
->appendByte(0, 1);
1394 IOReturn
IODTNVRAM::readNVRAMPropertyType1(IORegistryEntry
*entry
,
1395 const OSSymbol
**name
,
1398 IOReturn err
= kIOReturnNoResources
;
1407 if (_ofDict
== 0) return err
;
1408 data
= OSDynamicCast(OSData
, _ofDict
->getObject(_registryPropertiesKey
));
1409 if (data
== 0) return err
;
1411 start
= (UInt8
*) data
->getBytesNoCopy();
1412 end
= start
+ data
->getLength();
1415 while (where
< end
) {
1422 else if (nvName
== 0)
1425 IORegistryEntry::fromPath((const char *) nvPath
, gIODTPlane
)) {
1426 *name
= OSSymbol::withCString((const char *) nvName
);
1427 *value
= unescapeBytesToData(start
, where
- start
- 1);
1428 if ((*name
!= 0) && (*value
!= 0))
1429 err
= kIOReturnSuccess
;
1431 err
= kIOReturnNoMemory
;
1434 nvPath
= nvName
= 0;
1442 IOReturn
IODTNVRAM::writeNVRAMPropertyType1(IORegistryEntry
*entry
,
1443 const OSSymbol
*propName
,
1459 if (_ofDict
== 0) return kIOReturnNoResources
;
1461 // copy over existing properties for other entries
1463 oldData
= OSDynamicCast(OSData
, _ofDict
->getObject(_registryPropertiesKey
));
1465 start
= (UInt8
*) oldData
->getBytesNoCopy();
1466 end
= start
+ oldData
->getLength();
1470 while (where
< end
) {
1476 else if (nvName
== 0)
1479 IORegistryEntry::fromPath((const char *) nvPath
, gIODTPlane
)) {
1480 // delete old property (nvPath -> where)
1481 data
= OSData::withBytes(propStart
, nvPath
- propStart
);
1483 ok
&= data
->appendBytes(where
, end
- where
);
1486 nvPath
= nvName
= 0;
1492 // make the new property
1496 data
= OSData::withData(oldData
);
1498 data
= OSData::withCapacity(16);
1500 return kIOReturnNoMemory
;
1503 // get entries in path
1504 OSArray
*array
= OSArray::withCapacity(5);
1507 return kIOReturnNoMemory
;
1510 array
->setObject(entry
);
1511 while ((entry
= entry
->getParentEntry(gIODTPlane
)));
1514 for (int i
= array
->getCount() - 3;
1515 (entry
= (IORegistryEntry
*) array
->getObject(i
));
1518 name
= entry
->getName(gIODTPlane
);
1519 comp
= entry
->getLocation(gIODTPlane
);
1520 if( comp
&& (0 == strcmp("pci", name
))
1521 && (0 == strcmp("80000000", comp
))) {
1523 comp
= "/pci@80000000";
1526 ok
&= data
->appendBytes("/@", 2);
1530 ok
&= data
->appendByte('/', 1);
1534 ok
&= data
->appendBytes(comp
, strlen(comp
));
1536 ok
&= data
->appendByte(0, 1);
1540 ok
&= data
->appendBytes(propName
->getCStringNoCopy(), propName
->getLength() + 1);
1542 // append escaped data
1543 oldData
= escapeDataToData(value
);
1544 ok
&= (oldData
!= 0);
1546 ok
&= data
->appendBytes(oldData
);
1549 ok
= _ofDict
->setObject(_registryPropertiesKey
, data
);
1551 _ofImageDirty
= true;
1555 return ok
? kIOReturnSuccess
: kIOReturnNoMemory
;