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:"
659 #define kMacIORoot "Devices:device-tree:pci:mac-io:"
662 REG_ENTRY_TO_OBJ( parentEntry
, regEntry
)
666 buf
= IONew( char, 512 );
668 return( nrNotEnoughMemoryErr
);
673 else if( 0 == strncmp( path
, kMacIORoot
, strlen( kMacIORoot
))) {
674 path
+= strlen( kMacIORoot
) - 7;
677 else if( 0 == strncmp( path
, kDTRoot
, strlen( kDTRoot
))) {
678 path
+= strlen( kDTRoot
) - 1;
690 regEntry
= regEntry
->childFromPath( buf
, gIODTPlane
);
692 regEntry
= IORegistryEntry::fromPath( buf
, gIODTPlane
);
695 MAKE_REG_ENTRY( newEntry
, regEntry
);
701 IODelete( buf
, char, 512 );
708 _eRegistryCStrEntryCreate( const RegEntryID
* parentEntry
,
712 IORegistryEntry
* newDev
;
713 IORegistryEntry
* parent
;
715 REG_ENTRY_TO_OBJ( parentEntry
, parent
)
719 newDev
= new IORegistryEntry
;
720 if( newDev
&& (false == newDev
->init()))
724 newDev
->attachToParent( parent
, gIODTPlane
);
727 newDev
->setName( name
);
730 MAKE_REG_ENTRY( newEntry
, newDev
);
735 return( nrNotCreatedErr
);
738 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
742 // in NDRVLibrariesAsm.s
743 extern void _eSynchronizeIO( void );
747 PEResidentAddress( vm_offset_t address
, vm_size_t length
);
752 kProcessorCacheModeDefault
= 0,
753 kProcessorCacheModeInhibited
= 1,
754 kProcessorCacheModeWriteThrough
= 2,
755 kProcessorCacheModeCopyBack
= 3
758 OSStatus
_eSetProcessorCacheMode( UInt32
/* space */, void * /* addr */,
759 UInt32
/* len */, UInt32
/* mode */ )
762 struct phys_entry
* pp
;
767 // This doesn't change any existing kernel mapping eg. BAT changes etc.
768 // but this is enough to change user level mappings for DPS etc.
769 // Should use a kernel service when one is available.
771 spa
= kvtophys( (vm_offset_t
)addr
);
773 spa
= PEResidentAddress( (vm_offset_t
)addr
, len
);
775 return( kIOReturnVMError
);
777 epa
= (len
+ spa
+ 0xfff) & 0xfffff000;
781 case kProcessorCacheModeWriteThrough
:
782 wimg
= PTE_WIMG_WT_CACHED_COHERENT_GUARDED
;
784 case kProcessorCacheModeCopyBack
:
785 wimg
= PTE_WIMG_CB_CACHED_COHERENT_GUARDED
;
788 wimg
= PTE_WIMG_UNCACHED_COHERENT_GUARDED
;
793 pp
= pmap_find_physentry(spa
);
795 pp
->pte1
.bits
.wimg
= wimg
;
803 char * _ePStrCopy( char *to
, const char *from
)
811 bcopy( from
, copy
, len
);
815 LogicalAddress
_ePoolAllocateResident(ByteCount byteSize
, Boolean clear
)
819 mem
= (LogicalAddress
) kern_os_malloc( (size_t) byteSize
);
821 memset( mem
, 0, byteSize
);
826 OSStatus
_ePoolDeallocate( LogicalAddress address
)
828 kern_os_free( (void *) address
);
832 UInt32
_eCurrentExecutionLevel(void)
834 return(0); // == kTaskLevel, HWInt == 6
837 // don't expect any callers of this
838 OSErr
_eIOCommandIsComplete( UInt32
/* commandID */, OSErr result
)
840 LOG("_eIOCommandIsComplete\n");
841 return( result
); // !!??!!
844 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
846 #include <kern/clock.h>
849 AbsoluteTime
_eUpTime( void )
853 clock_get_uptime( &result
);
858 AbsoluteTime
_eAddAbsoluteToAbsolute(AbsoluteTime left
, AbsoluteTime right
)
860 AbsoluteTime result
= left
;
862 ADD_ABSOLUTETIME( &left
, &right
);
868 AbsoluteTime
_eSubAbsoluteFromAbsolute(AbsoluteTime left
, AbsoluteTime right
)
870 AbsoluteTime result
= left
;
872 // !! ATI bug fix here:
873 // They expect the 64-bit result to be signed. The spec says < 0 => 0
874 // To workaround, make sure this routine takes 10 us to execute.
877 if( CMP_ABSOLUTETIME( &result
, &right
) < 0) {
878 AbsoluteTime_to_scalar( &result
) = 0;
881 SUB_ABSOLUTETIME( &result
, &right
);
888 AbsoluteTime
_eDurationToAbsolute( Duration theDuration
)
892 if( theDuration
> 0) {
893 clock_interval_to_absolutetime_interval( theDuration
, kMillisecondScale
,
897 clock_interval_to_absolutetime_interval( (-theDuration
), kMicrosecondScale
,
904 AbsoluteTime
_eAddDurationToAbsolute( Duration duration
, AbsoluteTime absolute
)
906 return( _eAddAbsoluteToAbsolute(_eDurationToAbsolute( duration
), absolute
));
909 #define UnsignedWideToUInt64(x) (*(UInt64 *)(x))
910 #define UInt64ToUnsignedWide(x) (*(UnsignedWide *)(x))
912 AbsoluteTime
_eNanosecondsToAbsolute ( UnsignedWide theNanoseconds
)
915 UInt64 nano
= UnsignedWideToUInt64(&theNanoseconds
);
917 nanoseconds_to_absolutetime( nano
, &result
);
922 UnsignedWide
_eAbsoluteToNanoseconds( AbsoluteTime absolute
)
927 absolutetime_to_nanoseconds( absolute
, &nano
);
928 result
= UInt64ToUnsignedWide( &nano
);
933 Duration
_eAbsoluteDeltaToDuration( AbsoluteTime left
, AbsoluteTime right
)
939 if( CMP_ABSOLUTETIME( &left
, &right
) < 0)
943 SUB_ABSOLUTETIME( &result
, &right
);
944 absolutetime_to_nanoseconds( result
, &nano
);
946 if( nano
>= ((1ULL << 31) * 1000ULL)) {
948 if( nano
>= ((1ULL << 31) * 1000ULL * 1000ULL))
951 dur
= nano
/ 1000000ULL;
954 dur
= -(nano
/ 1000ULL);
961 OSStatus
_eDelayForHardware( AbsoluteTime time
)
963 AbsoluteTime deadline
;
965 clock_absolutetime_interval_to_deadline( time
, &deadline
);
966 clock_delay_until( deadline
);
971 OSStatus
_eDelayFor( Duration theDuration
)
975 // In Marconi, DelayFor uses the old toolbox Delay routine
976 // which is based on the 60 Hz timer. Durations are not
977 // rounded up when converting to ticks. Yes, really.
978 // Some ATI drivers call DelayFor(1) 50000 times starting up.
979 // There is some 64-bit math there so we'd better reproduce
980 // the overhead of that calculation.
982 #define DELAY_FOR_TICK_NANO 16666666
983 #define DELAY_FOR_TICK_MILLI 17
984 #define NANO32_MILLI 4295
990 abs
= _eDurationToAbsolute( theDuration
);
991 nano
= _eAbsoluteToNanoseconds( abs
);
993 ms
= (nano
.lo
/ DELAY_FOR_TICK_NANO
) * DELAY_FOR_TICK_MILLI
;
994 ms
+= nano
.hi
* NANO32_MILLI
;
999 // Accurate, but incompatible, version
1001 #define SLEEP_THRESHOLD 5000
1003 if( theDuration
< 0) {
1006 theDuration
-= theDuration
;
1007 if( theDuration
> SLEEP_THRESHOLD
)
1008 IOSleep( (theDuration
+ 999) / 1000);
1010 IODelay( theDuration
);
1015 if( theDuration
> (SLEEP_THRESHOLD
/ 1000))
1016 IOSleep( theDuration
); // ms
1018 IODelay( theDuration
* 1000); // us
1025 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1027 OSStatus
_eCallOSTrapUniversalProc( UInt32
/* theProc */,
1028 UInt32 procInfo
, UInt32 trap
, UInt8
* pb
)
1031 struct PMgrOpParamBlock
{
1038 #define readExtSwitches 0xDC
1040 if( (procInfo
== 0x133822)
1041 && (trap
== 0xa085) ) {
1043 PMgrOpParamBlock
* pmOp
= (PMgrOpParamBlock
*) pb
;
1045 if( (readExtSwitches
== pmOp
->pmCommand
) && pmOp
->pmRBuffer
) {
1046 OSNumber
* num
= OSDynamicCast(OSNumber
,
1047 IOService::getPlatform()->getProperty("AppleExtSwitchBootState"));
1048 *pmOp
->pmRBuffer
= (num
->unsigned32BitValue() & 1);
1052 } else if( (procInfo
== 0x133822)
1053 && (trap
== 0xa092) ) {
1055 UInt8 addr
, reg
, data
;
1059 pb
= *( (UInt8
**) ((UInt32
) pb
+ 8));
1061 (*PE_write_IIC
)( addr
, reg
, data
);
1067 const UInt32
* _eGetKeys( void )
1069 static const UInt32 zeros
[] = { 0, 0, 0, 0 };
1074 UInt32
_eGetIndADB( void * adbInfo
, UInt32
/* index */)
1076 bzero( adbInfo
, 10);
1077 return( 0); // orig address
1080 char * _eLMGetPowerMgrVars( void )
1082 static char * powerMgrVars
= NULL
;
1084 if( powerMgrVars
== NULL
) {
1085 powerMgrVars
= (char *) IOMalloc( 0x3c0);
1087 bzero( powerMgrVars
, 0x3c0);
1089 return( powerMgrVars
);
1092 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1094 OSStatus
_eNoErr( void )
1099 OSStatus
_eFail( void )
1104 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1108 #define heathrowID ((volatile UInt32 *)0xf3000034)
1109 #define heathrowTermEna (1 << 3)
1110 #define heathrowTermDir (1 << 0)
1112 #define heathrowFeatureControl ((volatile UInt32 *)0xf3000038)
1113 #define heathrowMBRES (1 << 24)
1115 #define heathrowBrightnessControl ((volatile UInt8 *)0xf3000032)
1116 #define defaultBrightness 144
1117 #define heathrowContrastControl ((volatile UInt8 *)0xf3000033)
1118 #define defaultContrast 183
1120 #define gossamerSystemReg1 ((volatile UInt16 *)0xff000004)
1121 #define gossamerAllInOne (1 << 4)
1123 void _eATISetMBRES( UInt32 state
)
1127 value
= *heathrowFeatureControl
;
1130 value
&= ~heathrowMBRES
;
1131 else if( state
== 1)
1132 value
|= heathrowMBRES
;
1134 *heathrowFeatureControl
= value
;
1138 void _eATISetMonitorTermination( Boolean enable
)
1143 value
= *heathrowID
;
1145 value
|= heathrowTermEna
;
1147 value
|= heathrowTermDir
;
1149 value
&= ~heathrowTermDir
;
1151 *heathrowID
= value
;
1155 Boolean
_eATIIsAllInOne( void )
1158 static bool didBrightness
;
1160 rtn
= (0 == ((*gossamerSystemReg1
) & gossamerAllInOne
));
1161 if( rtn
&& !didBrightness
) {
1162 *heathrowBrightnessControl
= defaultBrightness
;
1164 *heathrowContrastControl
= defaultContrast
;
1166 didBrightness
= true;
1171 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1173 static void IONDRVInterruptAction( OSObject
* target
, void * refCon
,
1174 IOService
* provider
, int index
)
1176 IONDRVInterruptSet
* set
;
1177 IONDRVInterruptSource
* source
;
1180 set
= (IONDRVInterruptSet
*) target
;
1185 assert( (UInt32
) index
<= set
->count
);
1186 if( (UInt32
) index
> set
->count
)
1189 source
= set
->sources
+ index
;
1190 result
= CallTVector( set
, (void *) index
, source
->refCon
, 0, 0, 0,
1195 case kIONDRVIsrIsNotComplete
:
1197 case kIONDRVIsrIsComplete
:
1200 case kIONDRVMemberNumberParent
:
1210 } while( result
!= kIONDRVIsrIsComplete
);
1213 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1215 static SInt32
IONDRVStdInterruptHandler( IONDRVInterruptSetMember setMember
,
1216 void *refCon
, UInt32 theIntCount
)
1220 return( kIONDRVIsrIsComplete
);
1223 static bool IONDRVStdInterruptDisabler( IONDRVInterruptSetMember setMember
,
1226 IONDRVInterruptSet
* set
;
1227 IONDRVInterruptSource
* source
;
1230 set
= (IONDRVInterruptSet
*) setMember
.setID
;
1231 assert( OSDynamicCast( IONDRVInterruptSet
, set
));
1232 assert( setMember
.member
<= set
->count
);
1233 source
= set
->sources
+ setMember
.member
;
1235 was
= source
->enabled
;
1236 source
->enabled
= false;
1238 assert( set
->provider
);
1239 set
->provider
->disableInterrupt( setMember
.member
- 1 );
1244 static void IONDRVStdInterruptEnabler( IONDRVInterruptSetMember setMember
,
1247 IONDRVInterruptSet
* set
;
1248 IONDRVInterruptSource
* source
;
1250 set
= (IONDRVInterruptSet
*) setMember
.setID
;
1251 assert( OSDynamicCast( IONDRVInterruptSet
, set
));
1252 assert( setMember
.member
<= set
->count
);
1253 source
= set
->sources
+ setMember
.member
;
1255 source
->enabled
= true;
1257 assert( set
->provider
);
1259 if( !source
->registered
) {
1260 source
->registered
= true;
1261 set
->provider
->registerInterrupt( setMember
.member
- 1, set
,
1262 &IONDRVInterruptAction
, (void *) 0x53 );
1265 set
->provider
->enableInterrupt( setMember
.member
- 1 );
1268 static IOTVector tvIONDRVStdInterruptHandler
= { IONDRVStdInterruptHandler
, 0 };
1269 static IOTVector tvIONDRVStdInterruptEnabler
= { IONDRVStdInterruptEnabler
, 0 };
1270 static IOTVector tvIONDRVStdInterruptDisabler
= { IONDRVStdInterruptDisabler
, 0 };
1273 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1276 _eGetInterruptFunctions( void * setID
,
1279 IOTVector
** handler
,
1280 IOTVector
** enabler
,
1281 IOTVector
** disabler
)
1283 IONDRVInterruptSet
* set
;
1284 IONDRVInterruptSource
* source
;
1285 OSStatus err
= noErr
;
1287 set
= (IONDRVInterruptSet
*) setID
;
1288 assert( OSDynamicCast( IONDRVInterruptSet
, set
));
1289 assert( member
<= set
->count
);
1290 source
= set
->sources
+ member
;
1293 *refCon
= source
->refCon
;
1295 *handler
= source
->handler
;
1297 *enabler
= source
->enabler
;
1299 *disabler
= source
->disabler
;
1305 IONDRVInstallInterruptFunctions(void * setID
,
1308 IOTVector
* handler
,
1309 IOTVector
* enabler
,
1310 IOTVector
* disabler
)
1312 IONDRVInterruptSet
* set
;
1313 IONDRVInterruptSource
* source
;
1314 OSStatus err
= noErr
;
1316 set
= (IONDRVInterruptSet
*) setID
;
1317 assert( OSDynamicCast( IONDRVInterruptSet
, set
));
1318 if( member
> set
->count
)
1320 source
= set
->sources
+ member
;
1322 source
->refCon
= refCon
;
1324 source
->handler
= handler
;
1326 source
->enabler
= enabler
;
1328 source
->disabler
= disabler
;
1334 _eInstallInterruptFunctions(void * setID
,
1337 IOTVector
* handler
,
1338 IOTVector
* enabler
,
1339 IOTVector
* disabler
)
1341 return( IONDRVInstallInterruptFunctions( setID
, member
, refCon
,
1342 handler
, enabler
, disabler
));
1346 _eCreateInterruptSet( void * parentSet
,
1347 UInt32 parentMember
,
1350 IOOptionBits options
)
1352 IONDRVInterruptSet
* set
;
1353 IONDRVInterruptSet
* newSet
;
1354 IONDRVInterruptSource
* source
;
1355 OSStatus err
= noErr
;
1357 set
= (IONDRVInterruptSet
*) parentSet
;
1358 assert( OSDynamicCast( IONDRVInterruptSet
, set
));
1359 assert( parentMember
<= set
->count
);
1360 source
= set
->sources
+ parentMember
;
1362 newSet
= IONDRVInterruptSet::with( 0, options
, setSize
);
1365 if( newSet
) for( UInt32 i
= 1; i
<= setSize
; i
++ ) {
1367 source
= newSet
->sources
+ i
;
1368 source
->handler
= &tvIONDRVStdInterruptHandler
;
1369 source
->enabler
= &tvIONDRVStdInterruptEnabler
;
1370 source
->disabler
= &tvIONDRVStdInterruptDisabler
;
1373 set
->child
= newSet
;
1380 _eDeleteInterruptSet( void * setID
)
1382 IONDRVInterruptSet
* set
;
1383 OSStatus err
= noErr
;
1385 set
= (IONDRVInterruptSet
*) setID
;
1386 assert( OSDynamicCast( IONDRVInterruptSet
, set
));
1393 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1395 #define MAKEFUNC(s,e) { s, e, 0 }
1397 static FunctionEntry PCILibFuncs
[] =
1399 MAKEFUNC( "ExpMgrConfigReadLong", _eExpMgrConfigReadLong
),
1400 MAKEFUNC( "ExpMgrConfigReadWord", _eExpMgrConfigReadWord
),
1401 MAKEFUNC( "ExpMgrConfigReadByte", _eExpMgrConfigReadByte
),
1402 MAKEFUNC( "ExpMgrConfigWriteLong", _eExpMgrConfigWriteLong
),
1403 MAKEFUNC( "ExpMgrConfigWriteWord", _eExpMgrConfigWriteWord
),
1404 MAKEFUNC( "ExpMgrConfigWriteByte", _eExpMgrConfigWriteByte
),
1406 MAKEFUNC( "ExpMgrIOReadLong", _eExpMgrIOReadLong
),
1407 MAKEFUNC( "ExpMgrIOReadWord", _eExpMgrIOReadWord
),
1408 MAKEFUNC( "ExpMgrIOReadByte", _eExpMgrIOReadByte
),
1409 MAKEFUNC( "ExpMgrIOWriteLong", _eExpMgrIOWriteLong
),
1410 MAKEFUNC( "ExpMgrIOWriteWord", _eExpMgrIOWriteWord
),
1411 MAKEFUNC( "ExpMgrIOWriteByte", _eExpMgrIOWriteByte
),
1413 MAKEFUNC( "EndianSwap16Bit", _eEndianSwap16Bit
),
1414 MAKEFUNC( "EndianSwap32Bit", _eEndianSwap32Bit
)
1417 static FunctionEntry VideoServicesLibFuncs
[] =
1419 MAKEFUNC( "VSLPrepareCursorForHardwareCursor",
1420 IONDRVFramebuffer::VSLPrepareCursorForHardwareCursor
),
1421 MAKEFUNC( "VSLNewInterruptService", IONDRVFramebuffer::VSLNewInterruptService
),
1422 MAKEFUNC( "VSLDisposeInterruptService", IONDRVFramebuffer::VSLDisposeInterruptService
),
1423 MAKEFUNC( "VSLDoInterruptService", IONDRVFramebuffer::VSLDoInterruptService
),
1424 MAKEFUNC( "VSLSetDisplayConfiguration", _eVSLSetDisplayConfiguration
)
1427 static FunctionEntry NameRegistryLibFuncs
[] =
1429 MAKEFUNC( "RegistryEntryIDCopy", _eRegistryEntryIDCopy
),
1430 MAKEFUNC( "RegistryEntryIDInit", _eRegistryEntryIDInit
),
1431 MAKEFUNC( "RegistryEntryIDDispose", _eNoErr
),
1432 MAKEFUNC( "RegistryEntryIDCompare", _eRegistryEntryIDCompare
),
1433 MAKEFUNC( "RegistryPropertyGetSize", _eRegistryPropertyGetSize
),
1434 MAKEFUNC( "RegistryPropertyGet", _eRegistryPropertyGet
),
1435 MAKEFUNC( "RegistryPropertyGetMod", _eRegistryPropertyGetMod
),
1436 MAKEFUNC( "RegistryPropertySetMod", _eRegistryPropertySetMod
),
1438 MAKEFUNC( "RegistryPropertyIterateCreate", _eRegistryPropertyIterateCreate
),
1439 MAKEFUNC( "RegistryPropertyIterateDispose", _eRegistryPropertyIterateDispose
),
1440 MAKEFUNC( "RegistryPropertyIterate", _eRegistryPropertyIterate
),
1442 MAKEFUNC( "RegistryEntryIterateCreate", _eRegistryEntryIterateCreate
),
1443 MAKEFUNC( "RegistryEntryIterateDispose", _eRegistryEntryIterateDispose
),
1444 MAKEFUNC( "RegistryEntryIterate", _eRegistryEntryIterate
),
1445 MAKEFUNC( "RegistryCStrEntryToName", _eRegistryCStrEntryToName
),
1446 MAKEFUNC( "RegistryCStrEntryLookup", _eRegistryCStrEntryLookup
),
1448 MAKEFUNC( "RegistryCStrEntryCreate", _eRegistryCStrEntryCreate
),
1449 MAKEFUNC( "RegistryEntryDelete", _eNoErr
),
1451 MAKEFUNC( "RegistryPropertyCreate", _eRegistryPropertyCreate
),
1452 MAKEFUNC( "RegistryPropertyDelete", _eRegistryPropertyDelete
),
1453 MAKEFUNC( "RegistryPropertySet", _eRegistryPropertySet
)
1457 static FunctionEntry DriverServicesLibFuncs
[] =
1459 MAKEFUNC( "SynchronizeIO", _eSynchronizeIO
),
1460 MAKEFUNC( "SetProcessorCacheMode", _eSetProcessorCacheMode
),
1461 MAKEFUNC( "BlockCopy", bcopy
),
1462 MAKEFUNC( "BlockMove", bcopy
),
1463 MAKEFUNC( "BlockMoveData", bcopy
),
1464 MAKEFUNC( "CStrCopy", strcpy
),
1465 MAKEFUNC( "CStrCmp", strcmp
),
1466 MAKEFUNC( "CStrLen", strlen
),
1467 MAKEFUNC( "CStrCat", strcat
),
1468 MAKEFUNC( "CStrNCopy", strncpy
),
1469 MAKEFUNC( "CStrNCmp", strncmp
),
1470 MAKEFUNC( "CStrNCat", strncat
),
1471 MAKEFUNC( "PStrCopy", _ePStrCopy
),
1473 MAKEFUNC( "PoolAllocateResident", _ePoolAllocateResident
),
1474 MAKEFUNC( "MemAllocatePhysicallyContiguous", _ePoolAllocateResident
),
1475 MAKEFUNC( "PoolDeallocate", _ePoolDeallocate
),
1477 MAKEFUNC( "UpTime", _eUpTime
),
1478 MAKEFUNC( "AbsoluteDeltaToDuration", _eAbsoluteDeltaToDuration
),
1479 MAKEFUNC( "AddAbsoluteToAbsolute", _eAddAbsoluteToAbsolute
),
1480 MAKEFUNC( "SubAbsoluteFromAbsolute", _eSubAbsoluteFromAbsolute
),
1481 MAKEFUNC( "AddDurationToAbsolute", _eAddDurationToAbsolute
),
1482 MAKEFUNC( "NanosecondsToAbsolute", _eNanosecondsToAbsolute
),
1483 MAKEFUNC( "AbsoluteToNanoseconds", _eAbsoluteToNanoseconds
),
1484 MAKEFUNC( "DurationToAbsolute", _eDurationToAbsolute
),
1485 MAKEFUNC( "DelayForHardware", _eDelayForHardware
),
1486 MAKEFUNC( "DelayFor", _eDelayFor
),
1488 MAKEFUNC( "CurrentExecutionLevel", _eCurrentExecutionLevel
),
1489 MAKEFUNC( "IOCommandIsComplete", _eIOCommandIsComplete
),
1491 MAKEFUNC( "SysDebugStr", _eNoErr
),
1492 MAKEFUNC( "SysDebug", _eNoErr
),
1494 MAKEFUNC( "CompareAndSwap", OSCompareAndSwap
),
1496 MAKEFUNC( "CreateInterruptSet", _eCreateInterruptSet
),
1497 MAKEFUNC( "DeleteInterruptSet", _eDeleteInterruptSet
),
1498 MAKEFUNC( "GetInterruptFunctions", _eGetInterruptFunctions
),
1499 MAKEFUNC( "InstallInterruptFunctions", _eInstallInterruptFunctions
)
1503 static FunctionEntry ATIUtilsFuncs
[] =
1505 // Gossamer onboard ATI
1506 MAKEFUNC( "ATISetMBRES", _eATISetMBRES
),
1507 MAKEFUNC( "ATISetMonitorTermination", _eATISetMonitorTermination
),
1508 MAKEFUNC( "ATIIsAllInOne", _eATIIsAllInOne
)
1511 // These are all out of spec
1513 static FunctionEntry InterfaceLibFuncs
[] =
1515 // Apple control : XPRam and EgretDispatch
1516 MAKEFUNC( "CallUniversalProc", _eFail
),
1517 MAKEFUNC( "CallOSTrapUniversalProc", _eCallOSTrapUniversalProc
),
1520 // MAKEFUNC( "NewRoutineDescriptor", _eCallOSTrapUniversalProc),
1521 // MAKEFUNC( "DisposeRoutineDescriptor", _eNoErr),
1522 // MAKEFUNC( "InsTime", _eInsTime),
1523 // MAKEFUNC( "PrimeTime", _ePrimeTime),
1525 // Radius PrecisionColor 16
1526 MAKEFUNC( "CountADBs", _eNoErr
),
1527 MAKEFUNC( "GetIndADB", _eGetIndADB
),
1528 MAKEFUNC( "GetKeys", _eGetKeys
)
1531 static FunctionEntry PrivateInterfaceLibFuncs
[] =
1534 MAKEFUNC( "LMGetPowerMgrVars", _eLMGetPowerMgrVars
)
1537 #define NUMLIBRARIES 7
1538 const ItemCount IONumNDRVLibraries
= NUMLIBRARIES
;
1539 LibraryEntry IONDRVLibraries
[ NUMLIBRARIES
] =
1541 { "PCILib", sizeof(PCILibFuncs
) / sizeof(FunctionEntry
), PCILibFuncs
},
1542 { "VideoServicesLib", sizeof(VideoServicesLibFuncs
) / sizeof(FunctionEntry
), VideoServicesLibFuncs
},
1543 { "NameRegistryLib", sizeof(NameRegistryLibFuncs
) / sizeof(FunctionEntry
), NameRegistryLibFuncs
},
1544 { "DriverServicesLib", sizeof(DriverServicesLibFuncs
) / sizeof(FunctionEntry
), DriverServicesLibFuncs
},
1547 { "ATIUtils", sizeof(ATIUtilsFuncs
) / sizeof(FunctionEntry
), ATIUtilsFuncs
},
1549 // out of spec stuff
1550 { "InterfaceLib", sizeof(InterfaceLibFuncs
) / sizeof(FunctionEntry
), InterfaceLibFuncs
},
1551 { "PrivateInterfaceLib", sizeof(PrivateInterfaceLibFuncs
) / sizeof(FunctionEntry
), PrivateInterfaceLibFuncs
}
1556 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1558 #define super OSObject
1560 OSDefineMetaClassAndStructors(IONDRVInterruptSet
, OSObject
)
1562 IONDRVInterruptSet
* IONDRVInterruptSet::with(IOService
* provider
,
1563 IOOptionBits options
, SInt32 count
)
1565 IONDRVInterruptSet
* set
;
1567 set
= new IONDRVInterruptSet
;
1568 if( set
&& !set
->init()) {
1575 set
->provider
= provider
;
1576 set
->options
= options
;
1580 set
->sources
= IONew( IONDRVInterruptSource
, count
);
1581 assert( set
->sources
);
1582 bzero( set
->sources
, count
* sizeof( IONDRVInterruptSource
));
1588 void IONDRVInterruptSet::free()
1591 IODelete( sources
, IONDRVInterruptSource
, count
+ 1 );
1596 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1600 static void IONDRVLibrariesTest( IOService
* provider
)
1604 AbsoluteTime abs1
, abs2
;
1607 abs1
= _eNanosecondsToAbsolute(UInt64ToUnsignedWide(&nano
));
1608 IOLog("_eNanosecondsToAbsolute %08lx:%08lx\n", abs1
.hi
, abs1
.lo
);
1609 nano2
= _eAbsoluteToNanoseconds(abs1
);
1610 IOLog("_eAbsoluteToNanoseconds %08lx:%08lx\n", nano2
.hi
, nano2
.lo
);
1611 AbsoluteTime_to_scalar(&abs2
) = 0;
1612 IOLog("_eAbsoluteDeltaToDuration %ld\n", _eAbsoluteDeltaToDuration(abs1
,abs2
));
1614 nano
= 0x13161b000ULL
;
1615 abs1
= _eNanosecondsToAbsolute(UInt64ToUnsignedWide(&nano
));
1616 IOLog("_eNanosecondsToAbsolute %08lx:%08lx\n", abs1
.hi
, abs1
.lo
);
1617 nano2
= _eAbsoluteToNanoseconds(abs1
);
1618 IOLog("_eAbsoluteToNanoseconds %08lx:%08lx\n", nano2
.hi
, nano2
.lo
);
1619 AbsoluteTime_to_scalar(&abs2
) = 0;
1620 IOLog("_eAbsoluteDeltaToDuration %ld\n", _eAbsoluteDeltaToDuration(abs1
,abs2
));
1622 nano
= 0x6acfc00000000ULL
;
1623 abs1
= _eNanosecondsToAbsolute(UInt64ToUnsignedWide(&nano
));
1624 IOLog("_eNanosecondsToAbsolute %08lx:%08lx\n", abs1
.hi
, abs1
.lo
);
1625 nano2
= _eAbsoluteToNanoseconds(abs1
);
1626 IOLog("_eAbsoluteToNanoseconds %08lx:%08lx\n", nano2
.hi
, nano2
.lo
);
1627 AbsoluteTime_to_scalar(&abs2
) = 0;
1628 IOLog("_eAbsoluteDeltaToDuration %ld\n", _eAbsoluteDeltaToDuration(abs1
,abs2
));
1633 IOLog("10us duration %ld\n", _eAbsoluteDeltaToDuration(abs2
,abs1
));
1636 for( int i
=0; i
< 50000; i
++)
1639 IOLog("50000 DelayFor(1) %ld\n", _eAbsoluteDeltaToDuration(abs2
,abs1
));
1644 IOLog("DelayFor(50) %ld\n", _eAbsoluteDeltaToDuration(abs2
,abs1
));
1646 abs1
= _eDurationToAbsolute( -10);
1647 IOLog("_eDurationToAbsolute(-10) %08lx:%08lx\n", abs1
.hi
, abs1
.lo
);
1648 abs1
= _eDurationToAbsolute( 10);
1649 IOLog("_eDurationToAbsolute(10) %08lx:%08lx\n", abs1
.hi
, abs1
.lo
);
1654 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1656 IOReturn
IONDRVLibrariesInitialize( IOService
* provider
)
1658 IODTPlatformExpert
* platform
;
1659 const OSSymbol
* sym
;
1662 unsigned int len
, i
;
1665 IONDRVLibrariesTest( provider
);
1668 // copy nvram property
1670 if( (platform
= OSDynamicCast( IODTPlatformExpert
,
1671 IOService::getPlatform()))) {
1673 // IOService::waitForService( IOService::resourceMatching( "IONVRAM" ));
1675 if( kIOReturnSuccess
== platform
->readNVRAMProperty( provider
,
1678 IONDRVSetNVRAMPropertyName( provider
, sym
);
1679 provider
->setProperty( sym
, data
);
1685 // create interrupt properties, if none present
1687 if( (intSpec
= (OSArray
*)provider
->getProperty( gIOInterruptSpecifiersKey
))
1688 && (0 == provider
->getProperty( gIODTAAPLInterruptsKey
))) {
1689 // make AAPL,interrupts property if not present (NW)
1690 for( i
= 0, len
= 0; i
< intSpec
->getCount(); i
++ ) {
1691 data
= (OSData
*) intSpec
->getObject(i
);
1693 len
+= data
->getLength();
1696 data
= OSData::withCapacity( len
);
1698 for( i
= 0; i
< intSpec
->getCount(); i
++ )
1699 data
->appendBytes( (OSData
*) intSpec
->getObject(i
));
1700 provider
->setProperty( gIODTAAPLInterruptsKey
, data
);
1705 // make NDRV interrupts
1707 data
= OSData::withCapacity( kIONDRVISTPropertyMemberCount
1708 * sizeof( IONDRVInterruptSetMember
));
1710 IONDRVInterruptSetMember setMember
;
1711 IONDRVInterruptSet
* set
;
1712 IONDRVInterruptSource
* source
;
1714 set
= IONDRVInterruptSet::with( provider
, 0,
1715 kIONDRVISTPropertyMemberCount
);
1717 if( set
) for( i
= 1; i
<= kIONDRVISTPropertyMemberCount
; i
++ ) {
1719 source
= set
->sources
+ i
;
1720 source
->handler
= &tvIONDRVStdInterruptHandler
;
1721 source
->enabler
= &tvIONDRVStdInterruptEnabler
;
1722 source
->disabler
= &tvIONDRVStdInterruptDisabler
;
1724 setMember
.setID
= (void *) set
;
1725 setMember
.member
= i
;
1726 data
->appendBytes( &setMember
, sizeof( setMember
));
1732 provider
->setProperty( kIONDRVISTPropertyName
, data
);
1739 IOItemCount numMaps
= provider
->getDeviceMemoryCount();
1740 IOVirtualAddress virtAddress
;
1742 for( i
= 0; i
< numMaps
; i
++) {
1743 IODeviceMemory
* mem
;
1747 consoleDevice
= (0 != provider
->getProperty("AAPL,boot-display"));
1749 mem
= provider
->getDeviceMemoryWithIndex( i
);
1753 // set up a 1-1 mapping for the BAT map of the console device
1755 if( consoleDevice
&& (0 == mem
->map( kIOMapReference
)))
1756 mem
->setMapping( kernel_task
, mem
->getPhysicalAddress() );
1760 // IOLog("%s: map[%ld] failed\n", provider->getName(), i);
1764 virtAddress
= map
->getVirtualAddress();
1766 data
= OSData::withCapacity( numMaps
* sizeof( IOVirtualAddress
));
1769 data
->appendBytes( &virtAddress
, sizeof( IOVirtualAddress
));
1770 kprintf("ndrv base = %lx\n", virtAddress
);
1773 // NDRV aperture vectors
1775 provider
->setProperty( "AAPL,address", data
);
1779 return( kIOReturnSuccess
);