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 * Copyright (c) 1997 Apple Computer, Inc.
28 * sdouglas 22 Oct 97 - first checked in.
29 * sdouglas 21 Jul 98 - start IOKit
30 * sdouglas 14 Dec 98 - start cpp.
34 #include <IOKit/IOLib.h>
35 #include <libkern/c++/OSContainers.h>
36 #include <IOKit/IODeviceTreeSupport.h>
37 #include <IOKit/IOPlatformExpert.h>
38 #include <IOKit/pci/IOPCIDevice.h>
39 #include <IOKit/ndrvsupport/IONDRVSupport.h>
40 #include <IOKit/ndrvsupport/IONDRVFramebuffer.h>
42 #include <libkern/OSByteOrder.h>
43 #include <libkern/OSAtomic.h>
44 #include <IOKit/assert.h>
46 #include <pexpert/pexpert.h>
48 #include "IOPEFLibraries.h"
49 #include "IOPEFLoader.h"
57 extern void *kern_os_malloc(size_t size
);
58 extern void kern_os_free(void * addr
);
60 #define LOG if(1) kprintf
64 /* NameRegistry error codes */
67 nrNotEnoughMemoryErr
= -2537,
68 nrInvalidNodeErr
= -2538,
69 nrNotFoundErr
= -2539,
70 nrNotCreatedErr
= -2540,
72 nrNotSlotDeviceErr
= -2542,
73 nrDataTruncatedErr
= -2543,
75 nrPowerSwitchAbortErr
= -2545,
76 nrTypeMismatchErr
= -2546,
77 nrNotModifiedErr
= -2547,
79 nrResultCodeBase
= -2549,
80 nrPathNotFound
= -2550, /* a path component lookup failed */
81 nrPathBufferTooSmall
= -2551, /* buffer for path is too small */
82 nrInvalidEntryIterationOp
= -2552, /* invalid entry iteration operation */
83 nrPropertyAlreadyExists
= -2553, /* property already exists */
84 nrIterationDone
= -2554, /* iteration operation is done */
85 nrExitedIteratorScope
= -2555, /* outer scope of iterator was exited */
86 nrTransactionAborted
= -2556 /* transaction was aborted */
90 kNVRAMProperty
= 0x00000020L
, // matches NR
91 kRegMaximumPropertyNameLength
= 31
94 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
96 UInt32
_eEndianSwap32Bit( UInt32 data
)
98 return( OSReadSwapInt32(&data
, 0));
101 UInt16
_eEndianSwap16Bit( UInt16 data
)
103 return( OSReadSwapInt16(&data
, 0));
106 OSStatus
_eExpMgrConfigReadLong( RegEntryID entryID
, UInt8 offset
, UInt32
* value
)
108 IORegistryEntry
* regEntry
;
109 IOPCIDevice
* ioDevice
;
112 REG_ENTRY_TO_OBJ( entryID
, regEntry
)
114 ioDevice
= OSDynamicCast( IOPCIDevice
, regEntry
);
116 ioDevice
= OSDynamicCast( IOPCIDevice
, regEntry
->getParentEntry( gIODTPlane
) );
118 return( nrNotSlotDeviceErr
);
120 adj
= ioDevice
->configRead32( offset
);
122 IOMemoryMap
* map
= 0;
123 if( (offset
>= kIOPCIConfigBaseAddress2
)
124 && (offset
<= kIOPCIConfigBaseAddress5
)) {
125 if( (map
= ioDevice
->mapDeviceMemoryWithRegister( offset
, kIOMapReference
))) {
126 adj
= (adj
& 3) | (map
->getVirtualAddress());
136 OSStatus
_eExpMgrConfigWriteLong( RegEntryID entryID
, UInt8 offset
, UInt32 value
)
139 REG_ENTRY_TO_SERVICE( entryID
, IOPCIDevice
, ioDevice
)
141 ioDevice
->configWrite32( offset
, value
);
147 OSStatus
_eExpMgrConfigReadWord( RegEntryID entryID
, UInt8 offset
, UInt16
* value
)
149 IORegistryEntry
* regEntry
;
150 IOPCIDevice
* ioDevice
;
152 REG_ENTRY_TO_OBJ( entryID
, regEntry
)
154 ioDevice
= OSDynamicCast( IOPCIDevice
, regEntry
);
156 ioDevice
= OSDynamicCast( IOPCIDevice
, regEntry
->getParentEntry( gIODTPlane
) );
158 return( nrNotSlotDeviceErr
);
160 *value
= ioDevice
->configRead16( offset
);
165 OSStatus
_eExpMgrConfigWriteWord( RegEntryID entryID
, UInt8 offset
, UInt16 value
)
168 REG_ENTRY_TO_SERVICE( entryID
, IOPCIDevice
, ioDevice
)
170 ioDevice
->configWrite16( offset
, value
);
175 OSStatus
_eExpMgrConfigReadByte( RegEntryID entryID
, UInt8 offset
, UInt8
* value
)
177 IORegistryEntry
* regEntry
;
178 IOPCIDevice
* ioDevice
;
180 REG_ENTRY_TO_OBJ( entryID
, regEntry
)
182 ioDevice
= OSDynamicCast( IOPCIDevice
, regEntry
);
184 ioDevice
= OSDynamicCast( IOPCIDevice
, regEntry
->getParentEntry( gIODTPlane
) );
186 return( nrNotSlotDeviceErr
);
188 *value
= ioDevice
->configRead8( offset
);
193 OSStatus
_eExpMgrConfigWriteByte( RegEntryID entryID
, UInt8 offset
, UInt8 value
)
196 REG_ENTRY_TO_SERVICE( entryID
, IOPCIDevice
, ioDevice
)
198 ioDevice
->configWrite8( offset
, value
);
203 OSStatus
_eExpMgrIOReadLong( RegEntryID entryID
, UInt16 offset
, UInt32
* value
)
206 REG_ENTRY_TO_SERVICE( entryID
, IOPCIDevice
, ioDevice
)
208 *value
= ioDevice
->ioRead32( offset
);
213 OSStatus
_eExpMgrIOWriteLong( RegEntryID entryID
, UInt16 offset
, UInt32 value
)
216 REG_ENTRY_TO_SERVICE( entryID
, IOPCIDevice
, ioDevice
)
218 ioDevice
->ioWrite32( offset
, value
);
223 OSStatus
_eExpMgrIOReadWord( RegEntryID entryID
, UInt16 offset
, UInt16
* value
)
225 REG_ENTRY_TO_SERVICE( entryID
, IOPCIDevice
, ioDevice
)
227 *value
= ioDevice
->ioRead16( offset
);
232 OSStatus
_eExpMgrIOWriteWord( RegEntryID entryID
, UInt16 offset
, UInt16 value
)
235 REG_ENTRY_TO_SERVICE( entryID
, IOPCIDevice
, ioDevice
)
237 ioDevice
->ioWrite16( offset
, value
);
242 OSStatus
_eExpMgrIOReadByte( RegEntryID entryID
, UInt16 offset
, UInt8
* value
)
244 REG_ENTRY_TO_SERVICE( entryID
, IOPCIDevice
, ioDevice
)
246 *value
= ioDevice
->ioRead8( offset
);
251 OSStatus
_eExpMgrIOWriteByte( RegEntryID entryID
, UInt16 offset
, UInt8 value
)
254 REG_ENTRY_TO_SERVICE( entryID
, IOPCIDevice
, ioDevice
)
256 ioDevice
->ioWrite8( offset
, value
);
261 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
263 OSStatus
_eRegistryEntryIDCopy( RegEntryID entryID
, RegEntryID to
)
265 bcopy( entryID
, to
, sizeof( RegEntryID
) );
270 OSStatus
_eRegistryEntryIDInit( RegEntryID entryID
)
272 MAKE_REG_ENTRY( entryID
, 0);
277 * Compare EntryID's for equality or if invalid
279 * If a NULL value is given for either id1 or id2, the other id
280 * is compared with an invalid ID. If both are NULL, the id's
281 * are consided equal (result = true).
282 * note: invalid != uninitialized
284 Boolean
_eRegistryEntryIDCompare( RegEntryID entryID1
, RegEntryID entryID2
)
286 IORegistryEntry
* regEntry1
;
287 IORegistryEntry
* regEntry2
;
290 REG_ENTRY_TO_OBJ_RET( entryID1
, regEntry1
, false)
295 REG_ENTRY_TO_OBJ_RET( entryID2
, regEntry2
, false)
299 return( regEntry1
== regEntry2
);
302 OSStatus
_eRegistryPropertyGetSize( void *entryID
, char *propertyName
,
303 UInt32
* propertySize
)
305 OSStatus err
= noErr
;
308 REG_ENTRY_TO_PT( entryID
, regEntry
)
310 prop
= (OSData
*) regEntry
->getProperty( propertyName
);
312 *propertySize
= prop
->getLength();
317 LOG("RegistryPropertyGetSize: %s : %d\n", propertyName
, err
);
323 OSStatus
_eRegistryPropertyGet(void *entryID
, char *propertyName
, UInt32
*propertyValue
, UInt32
*propertySize
)
325 OSStatus err
= noErr
;
329 REG_ENTRY_TO_PT( entryID
, regEntry
)
331 prop
= OSDynamicCast( OSData
, regEntry
->getProperty( propertyName
));
335 *propertySize
= prop
->getLength();
336 len
= (len
> prop
->getLength()) ? prop
->getLength() : len
;
337 bcopy( prop
->getBytesNoCopy(), propertyValue
, len
);
339 LOG("value: %08x ", *propertyValue
);
345 LOG("RegistryPropertyGet: %s : %d\n", propertyName
, err
);
350 OSStatus
_eRegistryPropertyCreate( void *entryID
, char *propertyName
,
351 void * propertyValue
, UInt32 propertySize
)
353 OSStatus err
= noErr
;
356 REG_ENTRY_TO_PT( entryID
, regEntry
)
358 prop
= OSData::withBytes( propertyValue
, propertySize
);
362 regEntry
->setProperty( propertyName
, prop
);
366 err
= nrNotCreatedErr
;
369 LOG("RegistryPropertyCreate: %s : %d\n", propertyName
, err
);
374 OSStatus
_eRegistryPropertyDelete( void *entryID
, char *propertyName
)
376 OSStatus err
= noErr
;
379 REG_ENTRY_TO_PT( entryID
, regEntry
)
381 old
= regEntry
->getProperty(propertyName
);
383 regEntry
->removeProperty(propertyName
);
388 LOG("RegistryPropertyDelete: %s : %d\n", propertyName
, err
);
393 void IONDRVSetNVRAMPropertyName( IORegistryEntry
* regEntry
,
394 const OSSymbol
* sym
)
396 regEntry
->setProperty( "IONVRAMProperty", (OSObject
*) sym
);
399 static IOReturn
IONDRVSetNVRAMPropertyValue( IORegistryEntry
* regEntry
,
400 const OSSymbol
* name
, OSData
* value
)
403 IODTPlatformExpert
* platform
=
404 (IODTPlatformExpert
*) IOService::getPlatform();
406 err
= platform
->writeNVRAMProperty( regEntry
, name
, value
);
411 OSStatus
_eRegistryPropertySet( void *entryID
, char *propertyName
, void * propertyValue
, UInt32 propertySize
)
413 OSStatus err
= noErr
;
415 const OSSymbol
* sym
;
417 REG_ENTRY_TO_PT( entryID
, regEntry
)
419 sym
= OSSymbol::withCString( propertyName
);
421 return( kIOReturnNoMemory
);
423 prop
= OSDynamicCast( OSData
, regEntry
->getProperty( sym
));
427 else if( (prop
= OSData::withBytes( propertyValue
, propertySize
))) {
428 regEntry
->setProperty( sym
, prop
);
430 if( (sym
== (const OSSymbol
*)
431 regEntry
->getProperty("IONVRAMProperty")))
432 err
= IONDRVSetNVRAMPropertyValue( regEntry
, sym
, prop
);
436 err
= nrNotCreatedErr
;
441 LOG("RegistryPropertySet: %s : %d\n", propertyName
, err
);
446 OSStatus
_eRegistryPropertyGetMod(void * entryID
, char * propertyName
,
449 const OSSymbol
* sym
;
451 REG_ENTRY_TO_PT( entryID
, regEntry
)
453 if( (sym
= OSDynamicCast( OSSymbol
,
454 regEntry
->getProperty("IONVRAMProperty")))
455 && (0 == strcmp( propertyName
, sym
->getCStringNoCopy())))
457 *mod
= kNVRAMProperty
;
464 OSStatus
_eRegistryPropertySetMod(void *entryID
, char *propertyName
,
467 OSStatus err
= noErr
;
469 const OSSymbol
* sym
;
471 REG_ENTRY_TO_PT( entryID
, regEntry
)
473 if( (mod
& kNVRAMProperty
)
474 && (sym
= OSSymbol::withCString( propertyName
))) {
476 if( (data
= OSDynamicCast( OSData
, regEntry
->getProperty( sym
))) ) {
477 err
= IONDRVSetNVRAMPropertyValue( regEntry
, sym
, data
);
478 if( kIOReturnSuccess
== err
)
479 IONDRVSetNVRAMPropertyName( regEntry
, sym
);
487 OSStatus
_eVSLSetDisplayConfiguration(RegEntryID
* entryID
,
492 IOReturn err
= nrNotCreatedErr
;
493 IORegistryEntry
* options
;
494 const OSSymbol
* sym
= 0;
496 enum { kMaxDisplayConfigDataSize
= 64 };
498 if( (configDataSize
> kMaxDisplayConfigDataSize
)
499 || (strlen(propertyName
) > kRegMaximumPropertyNameLength
))
500 return( nrNotCreatedErr
);
503 options
= IORegistryEntry::fromPath( "/options", gIODTPlane
);
506 data
= OSData::withBytes( configData
, configDataSize
);
509 sym
= OSSymbol::withCString( propertyName
);
512 if( !options
->setProperty( sym
, data
))
514 err
= kIOReturnSuccess
;
528 OSStatus
_eRegistryPropertyIterateCreate( RegEntryID
* entryID
,
529 OSCollectionIterator
** cookie
)
532 REG_ENTRY_TO_PT( entryID
, regEntry
)
534 // NB. unsynchronized. But should only happen on an owned nub!
535 // Should non OSData be filtered out?
536 *cookie
= OSCollectionIterator::withCollection(
537 regEntry
->getPropertyTable());
542 return( nrNotEnoughMemoryErr
);
545 OSStatus
_eRegistryPropertyIterateDispose( OSCollectionIterator
** cookie
)
548 (*cookie
)->release();
552 return( nrIterationDone
);
556 OSStatus
_eRegistryPropertyIterate( OSCollectionIterator
** cookie
,
557 char * name
, Boolean
* done
)
559 const OSSymbol
* key
;
561 key
= (const OSSymbol
*) (*cookie
)->getNextObject();
563 strncpy( name
, key
->getCStringNoCopy(), kRegMaximumPropertyNameLength
);
565 // Seems to be differences in handling "done".
566 // ATI assumes done = true when getting the last property.
567 // The Book says done is true after last property.
568 // ATI does check err, so this will work.
569 // Control ignores err and checks done.
576 return( nrIterationDone
);
580 _eRegistryEntryIterateCreate( IORegistryIterator
** cookie
)
582 *cookie
= IORegistryIterator::iterateOver( gIODTPlane
);
586 return( nrNotEnoughMemoryErr
);
590 _eRegistryEntryIterateDispose( IORegistryIterator
** cookie
)
593 (*cookie
)->release();
597 return( nrIterationDone
);
601 _eRegistryEntryIterate( IORegistryIterator
** cookie
,
602 UInt32
/* relationship */,
603 RegEntryID foundEntry
,
606 IORegistryEntry
* regEntry
;
608 // TODO: check requested type of iteration
609 regEntry
= (*cookie
)->getNextObjectRecursive();
611 MAKE_REG_ENTRY( foundEntry
, regEntry
);
612 *done
= (0 == regEntry
);
616 LOG("RegistryEntryIterate: %s\n", regEntry
->getName( gIODTPlane
));
622 return( nrNotFoundErr
);
626 _eRegistryCStrEntryToName( const RegEntryID
* entryID
,
627 RegEntryID parentEntry
,
628 char * nameComponent
,
631 IORegistryEntry
* regEntry
;
633 REG_ENTRY_TO_OBJ( entryID
, regEntry
)
635 strncpy( nameComponent
, regEntry
->getName( gIODTPlane
), kRegMaximumPropertyNameLength
);
636 nameComponent
[ kRegMaximumPropertyNameLength
] = 0;
638 regEntry
= regEntry
->getParentEntry( gIODTPlane
);
640 MAKE_REG_ENTRY( parentEntry
, regEntry
);
649 _eRegistryCStrEntryLookup( const RegEntryID
* parentEntry
,
654 IORegistryEntry
* regEntry
= 0;
658 #define kDTRoot "Devices:device-tree:"
661 REG_ENTRY_TO_OBJ( parentEntry
, regEntry
)
665 buf
= IONew( char, 512 );
667 return( nrNotEnoughMemoryErr
);
672 else if( 0 == strncmp( path
, kDTRoot
, strlen( kDTRoot
))) {
673 path
+= strlen( kDTRoot
) - 1;
685 regEntry
= regEntry
->childFromPath( buf
, gIODTPlane
);
687 regEntry
= IORegistryEntry::fromPath( buf
, gIODTPlane
);
690 MAKE_REG_ENTRY( newEntry
, regEntry
);
696 IODelete( buf
, char, 512 );
703 _eRegistryCStrEntryCreate( const RegEntryID
* parentEntry
,
707 IORegistryEntry
* newDev
;
708 IORegistryEntry
* parent
;
710 REG_ENTRY_TO_OBJ( parentEntry
, parent
)
714 newDev
= new IORegistryEntry
;
715 if( newDev
&& (false == newDev
->init()))
719 newDev
->attachToParent( parent
, gIODTPlane
);
722 newDev
->setName( name
);
725 MAKE_REG_ENTRY( newEntry
, newDev
);
730 return( nrNotCreatedErr
);
733 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
737 // in NDRVLibrariesAsm.s
738 extern void _eSynchronizeIO( void );
742 PEResidentAddress( vm_offset_t address
, vm_size_t length
);
747 kProcessorCacheModeDefault
= 0,
748 kProcessorCacheModeInhibited
= 1,
749 kProcessorCacheModeWriteThrough
= 2,
750 kProcessorCacheModeCopyBack
= 3
753 OSStatus
_eSetProcessorCacheMode( UInt32
/* space */, void * /* addr */,
754 UInt32
/* len */, UInt32
/* mode */ )
757 struct phys_entry
* pp
;
762 // This doesn't change any existing kernel mapping eg. BAT changes etc.
763 // but this is enough to change user level mappings for DPS etc.
764 // Should use a kernel service when one is available.
766 spa
= kvtophys( (vm_offset_t
)addr
);
768 spa
= PEResidentAddress( (vm_offset_t
)addr
, len
);
770 return( kIOReturnVMError
);
772 epa
= (len
+ spa
+ 0xfff) & 0xfffff000;
776 case kProcessorCacheModeWriteThrough
:
777 wimg
= PTE_WIMG_WT_CACHED_COHERENT_GUARDED
;
779 case kProcessorCacheModeCopyBack
:
780 wimg
= PTE_WIMG_CB_CACHED_COHERENT_GUARDED
;
783 wimg
= PTE_WIMG_UNCACHED_COHERENT_GUARDED
;
788 pp
= pmap_find_physentry(spa
);
790 pp
->pte1
.bits
.wimg
= wimg
;
798 char * _ePStrCopy( char *to
, const char *from
)
806 bcopy( from
, copy
, len
);
810 LogicalAddress
_ePoolAllocateResident(ByteCount byteSize
, Boolean clear
)
814 mem
= (LogicalAddress
) kern_os_malloc( (size_t) byteSize
);
816 memset( mem
, 0, byteSize
);
821 OSStatus
_ePoolDeallocate( LogicalAddress address
)
823 kern_os_free( (void *) address
);
827 UInt32
_eCurrentExecutionLevel(void)
829 return(0); // == kTaskLevel, HWInt == 6
832 // don't expect any callers of this
833 OSErr
_eIOCommandIsComplete( UInt32
/* commandID */, OSErr result
)
835 LOG("_eIOCommandIsComplete\n");
836 return( result
); // !!??!!
839 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
841 #include <kern/clock.h>
844 AbsoluteTime
_eUpTime( void )
848 clock_get_uptime( &result
);
853 AbsoluteTime
_eAddAbsoluteToAbsolute(AbsoluteTime left
, AbsoluteTime right
)
855 AbsoluteTime result
= left
;
857 ADD_ABSOLUTETIME( &left
, &right
);
863 AbsoluteTime
_eSubAbsoluteFromAbsolute(AbsoluteTime left
, AbsoluteTime right
)
865 AbsoluteTime result
= left
;
867 // !! ATI bug fix here:
868 // They expect the 64-bit result to be signed. The spec says < 0 => 0
869 // To workaround, make sure this routine takes 10 us to execute.
872 if( CMP_ABSOLUTETIME( &result
, &right
) < 0) {
873 AbsoluteTime_to_scalar( &result
) = 0;
876 SUB_ABSOLUTETIME( &result
, &right
);
883 AbsoluteTime
_eDurationToAbsolute( Duration theDuration
)
887 if( theDuration
> 0) {
888 clock_interval_to_absolutetime_interval( theDuration
, kMillisecondScale
,
892 clock_interval_to_absolutetime_interval( (-theDuration
), kMicrosecondScale
,
899 AbsoluteTime
_eAddDurationToAbsolute( Duration duration
, AbsoluteTime absolute
)
901 return( _eAddAbsoluteToAbsolute(_eDurationToAbsolute( duration
), absolute
));
904 #define UnsignedWideToUInt64(x) (*(UInt64 *)(x))
905 #define UInt64ToUnsignedWide(x) (*(UnsignedWide *)(x))
907 AbsoluteTime
_eNanosecondsToAbsolute ( UnsignedWide theNanoseconds
)
910 UInt64 nano
= UnsignedWideToUInt64(&theNanoseconds
);
912 nanoseconds_to_absolutetime( nano
, &result
);
917 UnsignedWide
_eAbsoluteToNanoseconds( AbsoluteTime absolute
)
922 absolutetime_to_nanoseconds( absolute
, &nano
);
923 result
= UInt64ToUnsignedWide( &nano
);
928 Duration
_eAbsoluteDeltaToDuration( AbsoluteTime left
, AbsoluteTime right
)
934 if( CMP_ABSOLUTETIME( &left
, &right
) < 0)
938 SUB_ABSOLUTETIME( &result
, &right
);
939 absolutetime_to_nanoseconds( result
, &nano
);
941 if( nano
>= ((1ULL << 31) * 1000ULL)) {
943 if( nano
>= ((1ULL << 31) * 1000ULL * 1000ULL))
946 dur
= nano
/ 1000000ULL;
949 dur
= -(nano
/ 1000ULL);
956 OSStatus
_eDelayForHardware( AbsoluteTime time
)
958 AbsoluteTime deadline
;
960 clock_absolutetime_interval_to_deadline( time
, &deadline
);
961 clock_delay_until( deadline
);
966 OSStatus
_eDelayFor( Duration theDuration
)
970 // In Marconi, DelayFor uses the old toolbox Delay routine
971 // which is based on the 60 Hz timer. Durations are not
972 // rounded up when converting to ticks. Yes, really.
973 // Some ATI drivers call DelayFor(1) 50000 times starting up.
974 // There is some 64-bit math there so we'd better reproduce
975 // the overhead of that calculation.
977 #define DELAY_FOR_TICK_NANO 16666666
978 #define DELAY_FOR_TICK_MILLI 17
979 #define NANO32_MILLI 4295
985 abs
= _eDurationToAbsolute( theDuration
);
986 nano
= _eAbsoluteToNanoseconds( abs
);
988 ms
= (nano
.lo
/ DELAY_FOR_TICK_NANO
) * DELAY_FOR_TICK_MILLI
;
989 ms
+= nano
.hi
* NANO32_MILLI
;
994 // Accurate, but incompatible, version
996 #define SLEEP_THRESHOLD 5000
998 if( theDuration
< 0) {
1001 theDuration
-= theDuration
;
1002 if( theDuration
> SLEEP_THRESHOLD
)
1003 IOSleep( (theDuration
+ 999) / 1000);
1005 IODelay( theDuration
);
1010 if( theDuration
> (SLEEP_THRESHOLD
/ 1000))
1011 IOSleep( theDuration
); // ms
1013 IODelay( theDuration
* 1000); // us
1020 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1022 OSStatus
_eCallOSTrapUniversalProc( UInt32
/* theProc */,
1023 UInt32 procInfo
, UInt32 trap
, UInt8
* pb
)
1026 struct PMgrOpParamBlock
{
1033 #define readExtSwitches 0xDC
1035 if( (procInfo
== 0x133822)
1036 && (trap
== 0xa085) ) {
1038 PMgrOpParamBlock
* pmOp
= (PMgrOpParamBlock
*) pb
;
1040 if( (readExtSwitches
== pmOp
->pmCommand
) && pmOp
->pmRBuffer
) {
1041 OSNumber
* num
= OSDynamicCast(OSNumber
,
1042 IOService::getPlatform()->getProperty("AppleExtSwitchBootState"));
1043 *pmOp
->pmRBuffer
= (num
->unsigned32BitValue() & 1);
1047 } else if( (procInfo
== 0x133822)
1048 && (trap
== 0xa092) ) {
1050 UInt8 addr
, reg
, data
;
1054 pb
= *( (UInt8
**) ((UInt32
) pb
+ 8));
1056 (*PE_write_IIC
)( addr
, reg
, data
);
1062 const UInt32
* _eGetKeys( void )
1064 static const UInt32 zeros
[] = { 0, 0, 0, 0 };
1069 UInt32
_eGetIndADB( void * adbInfo
, UInt32
/* index */)
1071 bzero( adbInfo
, 10);
1072 return( 0); // orig address
1075 char * _eLMGetPowerMgrVars( void )
1077 static char * powerMgrVars
= NULL
;
1079 if( powerMgrVars
== NULL
) {
1080 powerMgrVars
= (char *) IOMalloc( 0x3c0);
1082 bzero( powerMgrVars
, 0x3c0);
1084 return( powerMgrVars
);
1087 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1089 OSStatus
_eNoErr( void )
1094 OSStatus
_eFail( void )
1099 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1103 #define heathrowID ((volatile UInt32 *)0xf3000034)
1104 #define heathrowTermEna (1 << 3)
1105 #define heathrowTermDir (1 << 0)
1107 #define heathrowFeatureControl ((volatile UInt32 *)0xf3000038)
1108 #define heathrowMBRES (1 << 24)
1110 #define heathrowBrightnessControl ((volatile UInt8 *)0xf3000032)
1111 #define defaultBrightness 144
1112 #define heathrowContrastControl ((volatile UInt8 *)0xf3000033)
1113 #define defaultContrast 183
1115 #define gossamerSystemReg1 ((volatile UInt16 *)0xff000004)
1116 #define gossamerAllInOne (1 << 4)
1118 void _eATISetMBRES( UInt32 state
)
1122 value
= *heathrowFeatureControl
;
1125 value
&= ~heathrowMBRES
;
1126 else if( state
== 1)
1127 value
|= heathrowMBRES
;
1129 *heathrowFeatureControl
= value
;
1133 void _eATISetMonitorTermination( Boolean enable
)
1138 value
= *heathrowID
;
1140 value
|= heathrowTermEna
;
1142 value
|= heathrowTermDir
;
1144 value
&= ~heathrowTermDir
;
1146 *heathrowID
= value
;
1150 Boolean
_eATIIsAllInOne( void )
1153 static bool didBrightness
;
1155 rtn
= (0 == ((*gossamerSystemReg1
) & gossamerAllInOne
));
1156 if( rtn
&& !didBrightness
) {
1157 *heathrowBrightnessControl
= defaultBrightness
;
1159 *heathrowContrastControl
= defaultContrast
;
1161 didBrightness
= true;
1166 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1168 static void IONDRVInterruptAction( OSObject
* target
, void * refCon
,
1169 IOService
* provider
, int index
)
1171 IONDRVInterruptSet
* set
;
1172 IONDRVInterruptSource
* source
;
1175 set
= (IONDRVInterruptSet
*) target
;
1180 assert( (UInt32
) index
<= set
->count
);
1181 if( (UInt32
) index
> set
->count
)
1184 source
= set
->sources
+ index
;
1185 result
= CallTVector( set
, (void *) index
, source
->refCon
, 0, 0, 0,
1190 case kIONDRVIsrIsNotComplete
:
1192 case kIONDRVIsrIsComplete
:
1195 case kIONDRVMemberNumberParent
:
1205 } while( result
!= kIONDRVIsrIsComplete
);
1208 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1210 static SInt32
IONDRVStdInterruptHandler( IONDRVInterruptSetMember setMember
,
1211 void *refCon
, UInt32 theIntCount
)
1215 return( kIONDRVIsrIsComplete
);
1218 static bool IONDRVStdInterruptDisabler( IONDRVInterruptSetMember setMember
,
1221 IONDRVInterruptSet
* set
;
1222 IONDRVInterruptSource
* source
;
1225 set
= (IONDRVInterruptSet
*) setMember
.setID
;
1226 assert( OSDynamicCast( IONDRVInterruptSet
, set
));
1227 assert( setMember
.member
<= set
->count
);
1228 source
= set
->sources
+ setMember
.member
;
1230 was
= source
->enabled
;
1231 source
->enabled
= false;
1233 assert( set
->provider
);
1234 set
->provider
->disableInterrupt( setMember
.member
- 1 );
1239 static void IONDRVStdInterruptEnabler( IONDRVInterruptSetMember setMember
,
1242 IONDRVInterruptSet
* set
;
1243 IONDRVInterruptSource
* source
;
1245 set
= (IONDRVInterruptSet
*) setMember
.setID
;
1246 assert( OSDynamicCast( IONDRVInterruptSet
, set
));
1247 assert( setMember
.member
<= set
->count
);
1248 source
= set
->sources
+ setMember
.member
;
1250 source
->enabled
= true;
1252 assert( set
->provider
);
1254 if( !source
->registered
) {
1255 source
->registered
= true;
1256 set
->provider
->registerInterrupt( setMember
.member
- 1, set
,
1257 &IONDRVInterruptAction
, (void *) 0x53 );
1260 set
->provider
->enableInterrupt( setMember
.member
- 1 );
1263 static IOTVector tvIONDRVStdInterruptHandler
= { IONDRVStdInterruptHandler
, 0 };
1264 static IOTVector tvIONDRVStdInterruptEnabler
= { IONDRVStdInterruptEnabler
, 0 };
1265 static IOTVector tvIONDRVStdInterruptDisabler
= { IONDRVStdInterruptDisabler
, 0 };
1268 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1271 _eGetInterruptFunctions( void * setID
,
1274 IOTVector
** handler
,
1275 IOTVector
** enabler
,
1276 IOTVector
** disabler
)
1278 IONDRVInterruptSet
* set
;
1279 IONDRVInterruptSource
* source
;
1280 OSStatus err
= noErr
;
1282 set
= (IONDRVInterruptSet
*) setID
;
1283 assert( OSDynamicCast( IONDRVInterruptSet
, set
));
1284 assert( member
<= set
->count
);
1285 source
= set
->sources
+ member
;
1288 *refCon
= source
->refCon
;
1290 *handler
= source
->handler
;
1292 *enabler
= source
->enabler
;
1294 *disabler
= source
->disabler
;
1300 IONDRVInstallInterruptFunctions(void * setID
,
1303 IOTVector
* handler
,
1304 IOTVector
* enabler
,
1305 IOTVector
* disabler
)
1307 IONDRVInterruptSet
* set
;
1308 IONDRVInterruptSource
* source
;
1309 OSStatus err
= noErr
;
1311 set
= (IONDRVInterruptSet
*) setID
;
1312 assert( OSDynamicCast( IONDRVInterruptSet
, set
));
1313 if( member
> set
->count
)
1315 source
= set
->sources
+ member
;
1317 source
->refCon
= refCon
;
1319 source
->handler
= handler
;
1321 source
->enabler
= enabler
;
1323 source
->disabler
= disabler
;
1329 _eInstallInterruptFunctions(void * setID
,
1332 IOTVector
* handler
,
1333 IOTVector
* enabler
,
1334 IOTVector
* disabler
)
1336 return( IONDRVInstallInterruptFunctions( setID
, member
, refCon
,
1337 handler
, enabler
, disabler
));
1341 _eCreateInterruptSet( void * parentSet
,
1342 UInt32 parentMember
,
1345 IOOptionBits options
)
1347 IONDRVInterruptSet
* set
;
1348 IONDRVInterruptSet
* newSet
;
1349 IONDRVInterruptSource
* source
;
1350 OSStatus err
= noErr
;
1352 set
= (IONDRVInterruptSet
*) parentSet
;
1353 assert( OSDynamicCast( IONDRVInterruptSet
, set
));
1354 assert( parentMember
<= set
->count
);
1355 source
= set
->sources
+ parentMember
;
1357 newSet
= IONDRVInterruptSet::with( 0, options
, setSize
);
1360 if( newSet
) for( UInt32 i
= 1; i
<= setSize
; i
++ ) {
1362 source
= newSet
->sources
+ i
;
1363 source
->handler
= &tvIONDRVStdInterruptHandler
;
1364 source
->enabler
= &tvIONDRVStdInterruptEnabler
;
1365 source
->disabler
= &tvIONDRVStdInterruptDisabler
;
1368 set
->child
= newSet
;
1375 _eDeleteInterruptSet( void * setID
)
1377 IONDRVInterruptSet
* set
;
1378 OSStatus err
= noErr
;
1380 set
= (IONDRVInterruptSet
*) setID
;
1381 assert( OSDynamicCast( IONDRVInterruptSet
, set
));
1388 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1390 #define MAKEFUNC(s,e) { s, e, 0 }
1392 static FunctionEntry PCILibFuncs
[] =
1394 MAKEFUNC( "ExpMgrConfigReadLong", _eExpMgrConfigReadLong
),
1395 MAKEFUNC( "ExpMgrConfigReadWord", _eExpMgrConfigReadWord
),
1396 MAKEFUNC( "ExpMgrConfigReadByte", _eExpMgrConfigReadByte
),
1397 MAKEFUNC( "ExpMgrConfigWriteLong", _eExpMgrConfigWriteLong
),
1398 MAKEFUNC( "ExpMgrConfigWriteWord", _eExpMgrConfigWriteWord
),
1399 MAKEFUNC( "ExpMgrConfigWriteByte", _eExpMgrConfigWriteByte
),
1401 MAKEFUNC( "ExpMgrIOReadLong", _eExpMgrIOReadLong
),
1402 MAKEFUNC( "ExpMgrIOReadWord", _eExpMgrIOReadWord
),
1403 MAKEFUNC( "ExpMgrIOReadByte", _eExpMgrIOReadByte
),
1404 MAKEFUNC( "ExpMgrIOWriteLong", _eExpMgrIOWriteLong
),
1405 MAKEFUNC( "ExpMgrIOWriteWord", _eExpMgrIOWriteWord
),
1406 MAKEFUNC( "ExpMgrIOWriteByte", _eExpMgrIOWriteByte
),
1408 MAKEFUNC( "EndianSwap16Bit", _eEndianSwap16Bit
),
1409 MAKEFUNC( "EndianSwap32Bit", _eEndianSwap32Bit
)
1412 static FunctionEntry VideoServicesLibFuncs
[] =
1414 MAKEFUNC( "VSLPrepareCursorForHardwareCursor",
1415 IONDRVFramebuffer::VSLPrepareCursorForHardwareCursor
),
1416 MAKEFUNC( "VSLNewInterruptService", IONDRVFramebuffer::VSLNewInterruptService
),
1417 MAKEFUNC( "VSLDisposeInterruptService", IONDRVFramebuffer::VSLDisposeInterruptService
),
1418 MAKEFUNC( "VSLDoInterruptService", IONDRVFramebuffer::VSLDoInterruptService
),
1419 MAKEFUNC( "VSLSetDisplayConfiguration", _eVSLSetDisplayConfiguration
)
1422 static FunctionEntry NameRegistryLibFuncs
[] =
1424 MAKEFUNC( "RegistryEntryIDCopy", _eRegistryEntryIDCopy
),
1425 MAKEFUNC( "RegistryEntryIDInit", _eRegistryEntryIDInit
),
1426 MAKEFUNC( "RegistryEntryIDDispose", _eNoErr
),
1427 MAKEFUNC( "RegistryEntryIDCompare", _eRegistryEntryIDCompare
),
1428 MAKEFUNC( "RegistryPropertyGetSize", _eRegistryPropertyGetSize
),
1429 MAKEFUNC( "RegistryPropertyGet", _eRegistryPropertyGet
),
1430 MAKEFUNC( "RegistryPropertyGetMod", _eRegistryPropertyGetMod
),
1431 MAKEFUNC( "RegistryPropertySetMod", _eRegistryPropertySetMod
),
1433 MAKEFUNC( "RegistryPropertyIterateCreate", _eRegistryPropertyIterateCreate
),
1434 MAKEFUNC( "RegistryPropertyIterateDispose", _eRegistryPropertyIterateDispose
),
1435 MAKEFUNC( "RegistryPropertyIterate", _eRegistryPropertyIterate
),
1437 MAKEFUNC( "RegistryEntryIterateCreate", _eRegistryEntryIterateCreate
),
1438 MAKEFUNC( "RegistryEntryIterateDispose", _eRegistryEntryIterateDispose
),
1439 MAKEFUNC( "RegistryEntryIterate", _eRegistryEntryIterate
),
1440 MAKEFUNC( "RegistryCStrEntryToName", _eRegistryCStrEntryToName
),
1441 MAKEFUNC( "RegistryCStrEntryLookup", _eRegistryCStrEntryLookup
),
1443 MAKEFUNC( "RegistryCStrEntryCreate", _eRegistryCStrEntryCreate
),
1444 MAKEFUNC( "RegistryEntryDelete", _eNoErr
),
1446 MAKEFUNC( "RegistryPropertyCreate", _eRegistryPropertyCreate
),
1447 MAKEFUNC( "RegistryPropertyDelete", _eRegistryPropertyDelete
),
1448 MAKEFUNC( "RegistryPropertySet", _eRegistryPropertySet
)
1452 static FunctionEntry DriverServicesLibFuncs
[] =
1454 MAKEFUNC( "SynchronizeIO", _eSynchronizeIO
),
1455 MAKEFUNC( "SetProcessorCacheMode", _eSetProcessorCacheMode
),
1456 MAKEFUNC( "BlockCopy", bcopy
),
1457 MAKEFUNC( "BlockMove", bcopy
),
1458 MAKEFUNC( "BlockMoveData", bcopy
),
1459 MAKEFUNC( "CStrCopy", strcpy
),
1460 MAKEFUNC( "CStrCmp", strcmp
),
1461 MAKEFUNC( "CStrLen", strlen
),
1462 MAKEFUNC( "CStrCat", strcat
),
1463 MAKEFUNC( "CStrNCopy", strncpy
),
1464 MAKEFUNC( "CStrNCmp", strncmp
),
1465 MAKEFUNC( "CStrNCat", strncat
),
1466 MAKEFUNC( "PStrCopy", _ePStrCopy
),
1468 MAKEFUNC( "PoolAllocateResident", _ePoolAllocateResident
),
1469 MAKEFUNC( "MemAllocatePhysicallyContiguous", _ePoolAllocateResident
),
1470 MAKEFUNC( "PoolDeallocate", _ePoolDeallocate
),
1472 MAKEFUNC( "UpTime", _eUpTime
),
1473 MAKEFUNC( "AbsoluteDeltaToDuration", _eAbsoluteDeltaToDuration
),
1474 MAKEFUNC( "AddAbsoluteToAbsolute", _eAddAbsoluteToAbsolute
),
1475 MAKEFUNC( "SubAbsoluteFromAbsolute", _eSubAbsoluteFromAbsolute
),
1476 MAKEFUNC( "AddDurationToAbsolute", _eAddDurationToAbsolute
),
1477 MAKEFUNC( "NanosecondsToAbsolute", _eNanosecondsToAbsolute
),
1478 MAKEFUNC( "AbsoluteToNanoseconds", _eAbsoluteToNanoseconds
),
1479 MAKEFUNC( "DurationToAbsolute", _eDurationToAbsolute
),
1480 MAKEFUNC( "DelayForHardware", _eDelayForHardware
),
1481 MAKEFUNC( "DelayFor", _eDelayFor
),
1483 MAKEFUNC( "CurrentExecutionLevel", _eCurrentExecutionLevel
),
1484 MAKEFUNC( "IOCommandIsComplete", _eIOCommandIsComplete
),
1486 MAKEFUNC( "SysDebugStr", _eNoErr
),
1487 MAKEFUNC( "SysDebug", _eNoErr
),
1489 MAKEFUNC( "CompareAndSwap", OSCompareAndSwap
),
1491 MAKEFUNC( "CreateInterruptSet", _eCreateInterruptSet
),
1492 MAKEFUNC( "DeleteInterruptSet", _eDeleteInterruptSet
),
1493 MAKEFUNC( "GetInterruptFunctions", _eGetInterruptFunctions
),
1494 MAKEFUNC( "InstallInterruptFunctions", _eInstallInterruptFunctions
)
1498 static FunctionEntry ATIUtilsFuncs
[] =
1500 // Gossamer onboard ATI
1501 MAKEFUNC( "ATISetMBRES", _eATISetMBRES
),
1502 MAKEFUNC( "ATISetMonitorTermination", _eATISetMonitorTermination
),
1503 MAKEFUNC( "ATIIsAllInOne", _eATIIsAllInOne
)
1506 // These are all out of spec
1508 static FunctionEntry InterfaceLibFuncs
[] =
1510 // Apple control : XPRam and EgretDispatch
1511 MAKEFUNC( "CallUniversalProc", _eFail
),
1512 MAKEFUNC( "CallOSTrapUniversalProc", _eCallOSTrapUniversalProc
),
1515 // MAKEFUNC( "NewRoutineDescriptor", _eCallOSTrapUniversalProc),
1516 // MAKEFUNC( "DisposeRoutineDescriptor", _eNoErr),
1517 // MAKEFUNC( "InsTime", _eInsTime),
1518 // MAKEFUNC( "PrimeTime", _ePrimeTime),
1520 // Radius PrecisionColor 16
1521 MAKEFUNC( "CountADBs", _eNoErr
),
1522 MAKEFUNC( "GetIndADB", _eGetIndADB
),
1523 MAKEFUNC( "GetKeys", _eGetKeys
)
1526 static FunctionEntry PrivateInterfaceLibFuncs
[] =
1529 MAKEFUNC( "LMGetPowerMgrVars", _eLMGetPowerMgrVars
)
1532 #define NUMLIBRARIES 7
1533 const ItemCount IONumNDRVLibraries
= NUMLIBRARIES
;
1534 LibraryEntry IONDRVLibraries
[ NUMLIBRARIES
] =
1536 { "PCILib", sizeof(PCILibFuncs
) / sizeof(FunctionEntry
), PCILibFuncs
},
1537 { "VideoServicesLib", sizeof(VideoServicesLibFuncs
) / sizeof(FunctionEntry
), VideoServicesLibFuncs
},
1538 { "NameRegistryLib", sizeof(NameRegistryLibFuncs
) / sizeof(FunctionEntry
), NameRegistryLibFuncs
},
1539 { "DriverServicesLib", sizeof(DriverServicesLibFuncs
) / sizeof(FunctionEntry
), DriverServicesLibFuncs
},
1542 { "ATIUtils", sizeof(ATIUtilsFuncs
) / sizeof(FunctionEntry
), ATIUtilsFuncs
},
1544 // out of spec stuff
1545 { "InterfaceLib", sizeof(InterfaceLibFuncs
) / sizeof(FunctionEntry
), InterfaceLibFuncs
},
1546 { "PrivateInterfaceLib", sizeof(PrivateInterfaceLibFuncs
) / sizeof(FunctionEntry
), PrivateInterfaceLibFuncs
}
1551 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1553 #define super OSObject
1555 OSDefineMetaClassAndStructors(IONDRVInterruptSet
, OSObject
)
1557 IONDRVInterruptSet
* IONDRVInterruptSet::with(IOService
* provider
,
1558 IOOptionBits options
, SInt32 count
)
1560 IONDRVInterruptSet
* set
;
1562 set
= new IONDRVInterruptSet
;
1563 if( set
&& !set
->init()) {
1570 set
->provider
= provider
;
1571 set
->options
= options
;
1575 set
->sources
= IONew( IONDRVInterruptSource
, count
);
1576 assert( set
->sources
);
1577 bzero( set
->sources
, count
* sizeof( IONDRVInterruptSource
));
1583 void IONDRVInterruptSet::free()
1586 IODelete( sources
, IONDRVInterruptSource
, count
+ 1 );
1591 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1595 static void IONDRVLibrariesTest( IOService
* provider
)
1599 AbsoluteTime abs1
, abs2
;
1602 abs1
= _eNanosecondsToAbsolute(UInt64ToUnsignedWide(&nano
));
1603 IOLog("_eNanosecondsToAbsolute %08lx:%08lx\n", abs1
.hi
, abs1
.lo
);
1604 nano2
= _eAbsoluteToNanoseconds(abs1
);
1605 IOLog("_eAbsoluteToNanoseconds %08lx:%08lx\n", nano2
.hi
, nano2
.lo
);
1606 AbsoluteTime_to_scalar(&abs2
) = 0;
1607 IOLog("_eAbsoluteDeltaToDuration %ld\n", _eAbsoluteDeltaToDuration(abs1
,abs2
));
1609 nano
= 0x13161b000ULL
;
1610 abs1
= _eNanosecondsToAbsolute(UInt64ToUnsignedWide(&nano
));
1611 IOLog("_eNanosecondsToAbsolute %08lx:%08lx\n", abs1
.hi
, abs1
.lo
);
1612 nano2
= _eAbsoluteToNanoseconds(abs1
);
1613 IOLog("_eAbsoluteToNanoseconds %08lx:%08lx\n", nano2
.hi
, nano2
.lo
);
1614 AbsoluteTime_to_scalar(&abs2
) = 0;
1615 IOLog("_eAbsoluteDeltaToDuration %ld\n", _eAbsoluteDeltaToDuration(abs1
,abs2
));
1617 nano
= 0x6acfc00000000ULL
;
1618 abs1
= _eNanosecondsToAbsolute(UInt64ToUnsignedWide(&nano
));
1619 IOLog("_eNanosecondsToAbsolute %08lx:%08lx\n", abs1
.hi
, abs1
.lo
);
1620 nano2
= _eAbsoluteToNanoseconds(abs1
);
1621 IOLog("_eAbsoluteToNanoseconds %08lx:%08lx\n", nano2
.hi
, nano2
.lo
);
1622 AbsoluteTime_to_scalar(&abs2
) = 0;
1623 IOLog("_eAbsoluteDeltaToDuration %ld\n", _eAbsoluteDeltaToDuration(abs1
,abs2
));
1628 IOLog("10us duration %ld\n", _eAbsoluteDeltaToDuration(abs2
,abs1
));
1631 for( int i
=0; i
< 50000; i
++)
1634 IOLog("50000 DelayFor(1) %ld\n", _eAbsoluteDeltaToDuration(abs2
,abs1
));
1639 IOLog("DelayFor(50) %ld\n", _eAbsoluteDeltaToDuration(abs2
,abs1
));
1641 abs1
= _eDurationToAbsolute( -10);
1642 IOLog("_eDurationToAbsolute(-10) %08lx:%08lx\n", abs1
.hi
, abs1
.lo
);
1643 abs1
= _eDurationToAbsolute( 10);
1644 IOLog("_eDurationToAbsolute(10) %08lx:%08lx\n", abs1
.hi
, abs1
.lo
);
1649 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1651 IOReturn
IONDRVLibrariesInitialize( IOService
* provider
)
1653 IODTPlatformExpert
* platform
;
1654 const OSSymbol
* sym
;
1657 unsigned int len
, i
;
1660 IONDRVLibrariesTest( provider
);
1663 // copy nvram property
1665 if( (platform
= OSDynamicCast( IODTPlatformExpert
,
1666 IOService::getPlatform()))) {
1668 // IOService::waitForService( IOService::resourceMatching( "IONVRAM" ));
1670 if( kIOReturnSuccess
== platform
->readNVRAMProperty( provider
,
1673 IONDRVSetNVRAMPropertyName( provider
, sym
);
1674 provider
->setProperty( sym
, data
);
1680 // create interrupt properties, if none present
1682 if( (intSpec
= (OSArray
*)provider
->getProperty( gIOInterruptSpecifiersKey
))
1683 && (0 == provider
->getProperty( gIODTAAPLInterruptsKey
))) {
1684 // make AAPL,interrupts property if not present (NW)
1685 for( i
= 0, len
= 0; i
< intSpec
->getCount(); i
++ ) {
1686 data
= (OSData
*) intSpec
->getObject(i
);
1688 len
+= data
->getLength();
1691 data
= OSData::withCapacity( len
);
1693 for( i
= 0; i
< intSpec
->getCount(); i
++ )
1694 data
->appendBytes( (OSData
*) intSpec
->getObject(i
));
1695 provider
->setProperty( gIODTAAPLInterruptsKey
, data
);
1700 // make NDRV interrupts
1702 data
= OSData::withCapacity( kIONDRVISTPropertyMemberCount
1703 * sizeof( IONDRVInterruptSetMember
));
1705 IONDRVInterruptSetMember setMember
;
1706 IONDRVInterruptSet
* set
;
1707 IONDRVInterruptSource
* source
;
1709 set
= IONDRVInterruptSet::with( provider
, 0,
1710 kIONDRVISTPropertyMemberCount
);
1712 if( set
) for( i
= 1; i
<= kIONDRVISTPropertyMemberCount
; i
++ ) {
1714 source
= set
->sources
+ i
;
1715 source
->handler
= &tvIONDRVStdInterruptHandler
;
1716 source
->enabler
= &tvIONDRVStdInterruptEnabler
;
1717 source
->disabler
= &tvIONDRVStdInterruptDisabler
;
1719 setMember
.setID
= (void *) set
;
1720 setMember
.member
= i
;
1721 data
->appendBytes( &setMember
, sizeof( setMember
));
1727 provider
->setProperty( kIONDRVISTPropertyName
, data
);
1734 IOItemCount numMaps
= provider
->getDeviceMemoryCount();
1735 IOVirtualAddress virtAddress
;
1737 for( i
= 0; i
< numMaps
; i
++) {
1738 IODeviceMemory
* mem
;
1742 consoleDevice
= (0 != provider
->getProperty("AAPL,boot-display"));
1744 mem
= provider
->getDeviceMemoryWithIndex( i
);
1748 // set up a 1-1 mapping for the BAT map of the console device
1750 if( consoleDevice
&& (0 == mem
->map( kIOMapReference
)))
1751 mem
->setMapping( kernel_task
, mem
->getPhysicalAddress() );
1755 // IOLog("%s: map[%ld] failed\n", provider->getName(), i);
1759 virtAddress
= map
->getVirtualAddress();
1761 data
= OSData::withCapacity( numMaps
* sizeof( IOVirtualAddress
));
1764 data
->appendBytes( &virtAddress
, sizeof( IOVirtualAddress
));
1765 kprintf("ndrv base = %lx\n", virtAddress
);
1768 // NDRV aperture vectors
1770 provider
->setProperty( "AAPL,address", data
);
1774 return( kIOReturnSuccess
);