|
|
1.1 root 1: /*
2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
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.
11: *
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
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * Copyright (c) 1997 Apple Computer, Inc.
24: *
25: *
26: * HISTORY
27: *
28: * sdouglas 22 Oct 97 - first checked in.
29: * sdouglas 21 Jul 98 - start IOKit
30: * sdouglas 14 Dec 98 - start cpp.
31: */
32:
33:
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/IONDRVFramebuffer.h>
40:
41: #include <libkern/OSByteOrder.h>
42: #include <libkern/OSAtomic.h>
43: #include <IOKit/assert.h>
44:
45: #include <pexpert/pexpert.h>
46:
47: #include "IOPEFLibraries.h"
48: #include "IOPEFLoader.h"
49: #include "IONDRV.h"
50:
51: #include <string.h>
52:
53: extern "C"
54: {
55:
56: extern void *kern_os_malloc(size_t size);
57: extern void kern_os_free(void * addr);
58:
59: #define LOG if(1) kprintf
60:
61: #define LOGNAMEREG 0
62:
63: /* NameRegistry error codes */
64: enum {
65: nrLockedErr = -2536,
66: nrNotEnoughMemoryErr = -2537,
67: nrInvalidNodeErr = -2538,
68: nrNotFoundErr = -2539,
69: nrNotCreatedErr = -2540,
70: nrNameErr = -2541,
71: nrNotSlotDeviceErr = -2542,
72: nrDataTruncatedErr = -2543,
73: nrPowerErr = -2544,
74: nrPowerSwitchAbortErr = -2545,
75: nrTypeMismatchErr = -2546,
76: nrNotModifiedErr = -2547,
77: nrOverrunErr = -2548,
78: nrResultCodeBase = -2549,
79: nrPathNotFound = -2550, /* a path component lookup failed */
80: nrPathBufferTooSmall = -2551, /* buffer for path is too small */
81: nrInvalidEntryIterationOp = -2552, /* invalid entry iteration operation */
82: nrPropertyAlreadyExists = -2553, /* property already exists */
83: nrIterationDone = -2554, /* iteration operation is done */
84: nrExitedIteratorScope = -2555, /* outer scope of iterator was exited */
85: nrTransactionAborted = -2556 /* transaction was aborted */
86: };
87:
88: enum {
89: kNVRAMProperty = 0x00000020L, // matches NR
90: kRegMaximumPropertyNameLength = 31
91: };
92:
93: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
94:
95: UInt32 _eEndianSwap32Bit( UInt32 data )
96: {
97: return( OSReadSwapInt32(&data, 0));
98: }
99:
100: UInt16 _eEndianSwap16Bit( UInt16 data )
101: {
102: return( OSReadSwapInt16(&data, 0));
103: }
104:
105: OSStatus _eExpMgrConfigReadLong( RegEntryID entryID, UInt8 offset, UInt32 * value )
106: {
107:
108: REG_ENTRY_TO_SERVICE( entryID, IOPCIDevice, ioDevice)
109:
110: *value = ioDevice->configRead32( offset );
111:
112: return( noErr );
113: }
114:
115: OSStatus _eExpMgrConfigWriteLong( RegEntryID entryID, UInt8 offset, UInt32 value )
116: {
117:
118: REG_ENTRY_TO_SERVICE( entryID, IOPCIDevice, ioDevice)
119:
120: ioDevice->configWrite32( offset, value);
121:
122: return( noErr );
123: }
124:
125:
126: OSStatus _eExpMgrConfigReadWord( RegEntryID entryID, UInt8 offset, UInt16 * value )
127: {
128: OSStatus err;
129: UInt32 lvalue;
130:
131: err = _eExpMgrConfigReadLong( entryID, offset & (-4), &lvalue);
132: if( offset & 2)
133: *value = lvalue >> 16;
134: else
135: *value = lvalue;
136: return( err);
137: }
138:
139: OSStatus _eExpMgrConfigWriteWord( RegEntryID entryID, UInt8 offset, UInt16 value )
140: {
141: OSStatus err;
142: UInt32 lvalue;
143:
144: err = _eExpMgrConfigReadLong( entryID, offset & (-4), &lvalue);
145:
146: if( offset & 2)
147: lvalue = (lvalue & 0xffff) | (value << 16);
148: else
149: lvalue = (lvalue & 0xffff0000) | value;
150:
151: err = _eExpMgrConfigWriteLong( entryID, offset & (-4), lvalue);
152: return( err);
153: }
154:
155: OSStatus _eExpMgrConfigReadByte( RegEntryID entryID, UInt8 offset, UInt8 * value )
156: {
157: OSStatus err;
158: UInt32 lvalue;
159:
160: err = _eExpMgrConfigReadLong( entryID, offset & (-4), &lvalue);
161: *value = lvalue >> ((offset & 3) * 8);
162: return( err);
163: }
164:
165: OSStatus _eExpMgrConfigWriteByte( RegEntryID entryID, UInt8 offset, UInt8 value )
166: {
167: OSStatus err;
168: UInt32 lvalue;
169:
170: err = _eExpMgrConfigReadLong( entryID, offset & (-4), &lvalue);
171: lvalue = (lvalue & ~(0xff << ((offset & 3) * 8))) | (value << ((offset & 3) * 8));
172: err = _eExpMgrConfigWriteLong( entryID, offset & (-4), lvalue);
173: return( err);
174: }
175:
176: OSStatus _eExpMgrIOReadLong( RegEntryID entryID, UInt16 offset, UInt32 * value )
177: {
178:
179: REG_ENTRY_TO_SERVICE( entryID, IOPCIDevice, ioDevice)
180:
181: *value = ioDevice->ioRead32( offset );
182:
183: return( noErr);
184: }
185:
186: OSStatus _eExpMgrIOWriteLong( RegEntryID entryID, UInt16 offset, UInt32 value )
187: {
188:
189: REG_ENTRY_TO_SERVICE( entryID, IOPCIDevice, ioDevice)
190:
191: ioDevice->ioWrite32( offset, value );
192:
193: return( noErr);
194: }
195:
196: OSStatus _eExpMgrIOReadWord( RegEntryID entryID, UInt16 offset, UInt16 * value )
197: {
198: REG_ENTRY_TO_SERVICE( entryID, IOPCIDevice, ioDevice)
199:
200: *value = ioDevice->ioRead16( offset );
201:
202: return( noErr);
203: }
204:
205: OSStatus _eExpMgrIOWriteWord( RegEntryID entryID, UInt16 offset, UInt16 value )
206: {
207:
208: REG_ENTRY_TO_SERVICE( entryID, IOPCIDevice, ioDevice)
209:
210: ioDevice->ioWrite16( offset, value );
211:
212: return( noErr);
213: }
214:
215: OSStatus _eExpMgrIOReadByte( RegEntryID entryID, UInt16 offset, UInt8 * value )
216: {
217: REG_ENTRY_TO_SERVICE( entryID, IOPCIDevice, ioDevice)
218:
219: *value = ioDevice->ioRead8( offset );
220:
221: return( noErr);
222: }
223:
224: OSStatus _eExpMgrIOWriteByte( RegEntryID entryID, UInt16 offset, UInt8 value )
225: {
226:
227: REG_ENTRY_TO_SERVICE( entryID, IOPCIDevice, ioDevice)
228:
229: ioDevice->ioWrite8( offset, value );
230:
231: return( noErr);
232: }
233:
234: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
235:
236: OSStatus _eRegistryEntryIDCopy( RegEntryID entryID, RegEntryID to )
237: {
238: bcopy( entryID, to, sizeof( RegEntryID) );
239: return( noErr);
240: }
241:
242:
243: OSStatus _eRegistryEntryIDInit( RegEntryID entryID )
244: {
245: MAKE_REG_ENTRY( entryID, 0);
246: return( noErr);
247: }
248:
249: /*
250: * Compare EntryID's for equality or if invalid
251: *
252: * If a NULL value is given for either id1 or id2, the other id
253: * is compared with an invalid ID. If both are NULL, the id's
254: * are consided equal (result = true).
255: * note: invalid != uninitialized
256: */
257: Boolean _eRegistryEntryIDCompare( RegEntryID entryID1, RegEntryID entryID2 )
258: {
259: IORegistryEntry * regEntry1;
260: IORegistryEntry * regEntry2;
261:
262: if( entryID1) {
263: REG_ENTRY_TO_OBJ_RET( entryID1, regEntry1, false)
264: } else
265: regEntry1 = 0;
266:
267: if( entryID2) {
268: REG_ENTRY_TO_OBJ_RET( entryID2, regEntry2, false)
269: } else
270: regEntry2 = 0;
271:
272: return( regEntry1 == regEntry2 );
273: }
274:
275: OSStatus _eRegistryPropertyGetSize( void *entryID, char *propertyName,
276: UInt32 * propertySize )
277: {
278: OSStatus err = noErr;
279: OSData * prop;
280:
281: REG_ENTRY_TO_PT( entryID, regEntry)
282:
283: prop = (OSData *) regEntry->getProperty( propertyName);
284: if( prop)
285: *propertySize = prop->getLength();
286: else
287: err = nrNotFoundErr;
288:
289: #if LOGNAMEREG
290: LOG("RegistryPropertyGetSize: %s : %d\n", propertyName, err);
291: #endif
292: return( err);
293:
294: }
295:
296: OSStatus _eRegistryPropertyGet(void *entryID, char *propertyName, UInt32 *propertyValue, UInt32 *propertySize)
297: {
298: OSStatus err = noErr;
299: OSData * prop;
300: UInt32 len;
301:
302: REG_ENTRY_TO_PT( entryID, regEntry)
303:
304: prop = OSDynamicCast( OSData, regEntry->getProperty( propertyName));
305: if( prop) {
306:
307: len = *propertySize;
308: *propertySize = prop->getLength();
309: len = (len > prop->getLength()) ? prop->getLength() : len;
310: bcopy( prop->getBytesNoCopy(), propertyValue, len);
311: #if LOGNAMEREG
312: LOG("value: %08x ", *propertyValue);
313: #endif
314: } else
315: err = nrNotFoundErr;
316:
317: #if LOGNAMEREG
318: LOG("RegistryPropertyGet: %s : %d\n", propertyName, err);
319: #endif
320: return( err);
321: }
322:
323: OSStatus _eRegistryPropertyCreate( void *entryID, char *propertyName,
324: void * propertyValue, UInt32 propertySize )
325: {
326: OSStatus err = noErr;
327: OSData * prop;
328:
329: REG_ENTRY_TO_PT( entryID, regEntry)
330:
331: prop = OSData::withBytes( propertyValue, propertySize );
332:
333: if( prop) {
334:
335: regEntry->setProperty( propertyName, prop);
336: prop->release();
337:
338: } else
339: err = nrNotCreatedErr;
340:
341: #if LOGNAMEREG
342: LOG("RegistryPropertyCreate: %s : %d\n", propertyName, err);
343: #endif
344: return( err);
345: }
346:
347: OSStatus _eRegistryPropertyDelete( void *entryID, char *propertyName )
348: {
349: OSStatus err = noErr;
350: OSObject * old;
351:
352: REG_ENTRY_TO_PT( entryID, regEntry)
353:
354: old = regEntry->getProperty(propertyName);
355: if ( old )
356: regEntry->removeProperty(propertyName);
357: else
358: err = nrNotFoundErr;
359:
360: #if LOGNAMEREG
361: LOG("RegistryPropertyDelete: %s : %d\n", propertyName, err);
362: #endif
363: return( err);
364: }
365:
366: void IONDRVSetNVRAMPropertyName( IORegistryEntry * regEntry,
367: const OSSymbol * sym )
368: {
369: regEntry->setProperty( "IONVRAMProperty", (OSObject *) sym );
370: }
371:
372: static IOReturn IONDRVSetNVRAMPropertyValue( IORegistryEntry * regEntry,
373: const OSSymbol * name, OSData * value )
374: {
375: IOReturn err;
376: IODTPlatformExpert * platform =
377: (IODTPlatformExpert *) IOService::getPlatform();
378:
379: err = platform->writeNVRAMProperty( regEntry, name, value );
380:
381: return( err );
382: }
383:
384: OSStatus _eRegistryPropertySet( void *entryID, char *propertyName, void * propertyValue, UInt32 propertySize )
385: {
386: OSStatus err = noErr;
387: OSData * prop;
388: const OSSymbol * sym;
389:
390: REG_ENTRY_TO_PT( entryID, regEntry)
391:
392: sym = OSSymbol::withCString( propertyName );
393: if( !sym)
394: return( kIOReturnNoMemory );
395:
396: prop = OSDynamicCast( OSData, regEntry->getProperty( sym ));
397: if( 0 == prop)
398: err = nrNotFoundErr;
399:
400: else if( (prop = OSData::withBytes( propertyValue, propertySize))) {
401: regEntry->setProperty( sym, prop);
402:
403: if( (sym == (const OSSymbol *)
404: regEntry->getProperty("IONVRAMProperty")))
405: err = IONDRVSetNVRAMPropertyValue( regEntry, sym, prop );
406: prop->release();
407:
408: } else
409: err = nrNotCreatedErr;
410:
411: sym->release();
412:
413: #if LOGNAMEREG
414: LOG("RegistryPropertySet: %s : %d\n", propertyName, err);
415: #endif
416: return( err);
417: }
418:
419: OSStatus _eRegistryPropertyGetMod(void * entryID, char * propertyName,
420: UInt32 * mod)
421: {
422: const OSSymbol * sym;
423:
424: REG_ENTRY_TO_PT( entryID, regEntry)
425:
426: if( (sym = OSDynamicCast( OSSymbol,
427: regEntry->getProperty("IONVRAMProperty")))
428: && (0 == strcmp( propertyName, sym->getCStringNoCopy())))
429:
430: *mod = kNVRAMProperty;
431: else
432: *mod = 0;
433:
434: return( noErr);
435: }
436:
437: OSStatus _eRegistryPropertySetMod(void *entryID, char *propertyName,
438: UInt32 mod )
439: {
440: OSStatus err = noErr;
441: OSData * data;
442: const OSSymbol * sym;
443:
444: REG_ENTRY_TO_PT( entryID, regEntry)
445:
446: if( (mod & kNVRAMProperty)
447: && (sym = OSSymbol::withCString( propertyName ))) {
448:
449: if( (data = OSDynamicCast( OSData, regEntry->getProperty( sym))) ) {
450: err = IONDRVSetNVRAMPropertyValue( regEntry, sym, data );
451: if( kIOReturnSuccess == err)
452: IONDRVSetNVRAMPropertyName( regEntry, sym );
453: }
454: sym->release();
455: }
456:
457: return( err);
458: }
459:
460:
461: OSStatus _eRegistryPropertyIterateCreate( RegEntryID * entryID,
462: OSCollectionIterator ** cookie)
463: {
464:
465: REG_ENTRY_TO_PT( entryID, regEntry)
466:
467: // NB. unsynchronized. But should only happen on an owned nub!
468: // Should non OSData be filtered out?
469: *cookie = OSCollectionIterator::withCollection(
470: regEntry->getPropertyTable());
471:
472: if( *cookie)
473: return( noErr);
474: else
475: return( nrNotEnoughMemoryErr);
476: }
477:
478: OSStatus _eRegistryPropertyIterateDispose( OSCollectionIterator ** cookie)
479: {
480: if( *cookie) {
481: (*cookie)->release();
482: *cookie = NULL;
483: return( noErr);
484: } else
485: return( nrIterationDone);
486: }
487:
488:
489: OSStatus _eRegistryPropertyIterate( OSCollectionIterator ** cookie,
490: char * name, Boolean * done )
491: {
492: const OSSymbol * key;
493:
494: key = (const OSSymbol *) (*cookie)->getNextObject();
495: if( key)
496: strncpy( name, key->getCStringNoCopy(), kRegMaximumPropertyNameLength);
497:
498: // Seems to be differences in handling "done".
499: // ATI assumes done = true when getting the last property.
500: // The Book says done is true after last property.
501: // ATI does check err, so this will work.
502: // Control ignores err and checks done.
503:
504: *done = (key == 0);
505:
506: if( 0 != key)
507: return( noErr);
508: else
509: return( nrIterationDone );
510: }
511:
512: OSStatus
513: _eRegistryEntryIterateCreate( IORegistryIterator ** cookie)
514: {
515: *cookie = IORegistryIterator::iterateOver( gIODTPlane );
516: if( *cookie)
517: return( noErr);
518: else
519: return( nrNotEnoughMemoryErr);
520: }
521:
522: OSStatus
523: _eRegistryEntryIterateDispose( IORegistryIterator ** cookie)
524: {
525: if( *cookie) {
526: (*cookie)->release();
527: *cookie = NULL;
528: return( noErr);
529: } else
530: return( nrIterationDone);
531: }
532:
533: OSStatus
534: _eRegistryEntryIterate( IORegistryIterator ** cookie,
535: UInt32 /* relationship */,
536: RegEntryID foundEntry,
537: Boolean * done)
538: {
539: IORegistryEntry * regEntry;
540:
541: // TODO: check requested type of iteration
542: regEntry = (*cookie)->getNextObjectRecursive();
543:
544: MAKE_REG_ENTRY( foundEntry, regEntry);
545: *done = (0 == regEntry);
546:
547: #if LOGNAMEREG
548: if( regEntry)
549: LOG("RegistryEntryIterate: %s\n", regEntry->getName( gIODTPlane ));
550: #endif
551:
552: if( regEntry)
553: return( noErr);
554: else
555: return( nrNotFoundErr);
556: }
557:
558: OSStatus
559: _eRegistryCStrEntryToName( const RegEntryID * entryID,
560: RegEntryID parentEntry,
561: char * nameComponent,
562: Boolean * done )
563: {
564: IORegistryEntry * regEntry;
565:
566: REG_ENTRY_TO_OBJ( entryID, regEntry)
567:
568: strncpy( nameComponent, regEntry->getName( gIODTPlane ), kRegMaximumPropertyNameLength );
569: nameComponent[ kRegMaximumPropertyNameLength ] = 0;
570:
571: regEntry = regEntry->getParentEntry( gIODTPlane );
572: if( regEntry) {
573: MAKE_REG_ENTRY( parentEntry, regEntry);
574: *done = false;
575: } else
576: *done = true;
577:
578: return( noErr);
579: }
580:
581: OSStatus
582: _eRegistryCStrEntryLookup( const RegEntryID * parentEntry,
583: const char * path,
584: RegEntryID newEntry)
585: {
586: IOReturn err;
587: IORegistryEntry * regEntry;
588: char * buf;
589: char * cvtPath;
590: char c;
591: #define kDTRoot "Devices:device-tree:"
592:
593: return( nrNotEnoughMemoryErr );
594:
595: REG_ENTRY_TO_OBJ( parentEntry, regEntry)
596:
597: IOLog("%s: %s, %s\n", __FUNCTION__, regEntry->getName(), path);
598:
599: buf = IONew( char, 512 );
600: if( !buf)
601: return( nrNotEnoughMemoryErr );
602:
603: cvtPath = buf;
604: if( ':' == path[0])
605: path++;
606: else if( 0 == strncmp( path, kDTRoot, strlen( kDTRoot ))) {
607: path += strlen( kDTRoot ) - 1;
608: regEntry = 0;
609: }
610:
611: do {
612: c = *(path++);
613: if( ':' == c)
614: c = '/';
615: *(cvtPath++) = c;
616: } while( c != 0 );
617:
618: if( regEntry)
619: regEntry = regEntry->childFromPath( buf, gIODTPlane );
620: else
621: regEntry = IORegistryEntry::fromPath( buf, gIODTPlane );
622:
623: if( regEntry) {
624: MAKE_REG_ENTRY( newEntry, regEntry);
625: regEntry->release();
626: err = noErr;
627: } else
628: err = nrNotFoundErr;
629:
630: IODelete( buf, char, 512 );
631:
632: return( err );
633: }
634:
635:
636: OSStatus
637: _eRegistryCStrEntryCreate( const RegEntryID * parentEntry,
638: char * name,
639: RegEntryID newEntry)
640: {
641: IORegistryEntry * newDev;
642: IORegistryEntry * parent;
643:
644: REG_ENTRY_TO_OBJ( parentEntry, parent)
645:
646: // NOT published
647:
648: newDev = new IORegistryEntry;
649: if( newDev && (false == newDev->init()))
650: newDev = 0;
651:
652: if( newDev) {
653: newDev->attachToParent( parent, gIODTPlane );
654: if( ':' == name[0])
655: name++;
656: newDev->setName( name );
657: }
658:
659: MAKE_REG_ENTRY( newEntry, newDev);
660:
661: if( newDev)
662: return( noErr);
663: else
664: return( nrNotCreatedErr);
665: }
666:
667: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
668:
669: extern "C" {
670:
671: // in NDRVLibrariesAsm.s
672: extern void _eSynchronizeIO( void );
673:
674: // platform expert
675: extern vm_offset_t
676: PEResidentAddress( vm_offset_t address, vm_size_t length );
677:
678: };
679:
680: enum {
681: kProcessorCacheModeDefault = 0,
682: kProcessorCacheModeInhibited = 1,
683: kProcessorCacheModeWriteThrough = 2,
684: kProcessorCacheModeCopyBack = 3
685: };
686:
687: OSStatus _eSetProcessorCacheMode( UInt32 /* space */, void * /* addr */,
688: UInt32 /* len */, UInt32 /* mode */ )
689: {
690: #if 0
691: struct phys_entry* pp;
692: vm_offset_t spa;
693: vm_offset_t epa;
694: int wimg;
695:
696: // This doesn't change any existing kernel mapping eg. BAT changes etc.
697: // but this is enough to change user level mappings for DPS etc.
698: // Should use a kernel service when one is available.
699:
700: spa = kvtophys( (vm_offset_t)addr);
701: if( spa == 0) {
702: spa = PEResidentAddress( (vm_offset_t)addr, len);
703: if( spa == 0)
704: return( kIOReturnVMError);
705: }
706: epa = (len + spa + 0xfff) & 0xfffff000;
707: spa &= 0xfffff000;
708:
709: switch( mode) {
710: case kProcessorCacheModeWriteThrough:
711: wimg = PTE_WIMG_WT_CACHED_COHERENT_GUARDED;
712: break;
713: case kProcessorCacheModeCopyBack:
714: wimg = PTE_WIMG_CB_CACHED_COHERENT_GUARDED;
715: break;
716: default:
717: wimg = PTE_WIMG_UNCACHED_COHERENT_GUARDED;
718: break;
719: }
720:
721: while( spa < epa) {
722: pp = pmap_find_physentry(spa);
723: if (pp != PHYS_NULL)
724: pp->pte1.bits.wimg = wimg;
725: spa += PAGE_SIZE;
726: }
727: #endif
728: _eSynchronizeIO();
729: return( noErr);
730: }
731:
732: char * _ePStrCopy( char *to, const char *from )
733: {
734: UInt32 len;
735: char * copy;
736:
737: copy = to;
738: len = *(from++);
739: *(copy++) = len;
740: bcopy( from, copy, len);
741: return( to);
742: }
743:
744: LogicalAddress _ePoolAllocateResident(ByteCount byteSize, Boolean clear)
745: {
746: LogicalAddress mem;
747:
748: mem = (LogicalAddress) kern_os_malloc( (size_t) byteSize );
749: if( clear && mem)
750: memset( mem, 0, byteSize);
751:
752: return( mem);
753: }
754:
755: OSStatus _ePoolDeallocate( LogicalAddress address )
756: {
757: kern_os_free( (void *) address );
758: return( noErr);
759: }
760:
761: UInt32 _eCurrentExecutionLevel(void)
762: {
763: return(0); // == kTaskLevel, HWInt == 6
764: }
765:
766: // don't expect any callers of this
767: OSErr _eIOCommandIsComplete( UInt32 /* commandID */, OSErr result)
768: {
769: LOG("_eIOCommandIsComplete\n");
770: return( result); // !!??!!
771: }
772:
773: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
774:
775: #include <kern/clock.h>
776:
777:
778: AbsoluteTime _eUpTime( void )
779: {
780: AbsoluteTime result;
781:
782: clock_get_uptime( &result);
783:
784: return( result);
785: }
786:
787: AbsoluteTime _eAddAbsoluteToAbsolute(AbsoluteTime left, AbsoluteTime right)
788: {
789: AbsoluteTime result = left;
790:
791: ADD_ABSOLUTETIME( &left, &right);
792:
793: return( result);
794: }
795:
796:
797: AbsoluteTime _eSubAbsoluteFromAbsolute(AbsoluteTime left, AbsoluteTime right)
798: {
799: AbsoluteTime result = left;
800:
801: // !! ATI bug fix here:
802: // They expect the 64-bit result to be signed. The spec says < 0 => 0
803: // To workaround, make sure this routine takes 10 us to execute.
804: IODelay( 10);
805:
806: if( CMP_ABSOLUTETIME( &result, &right) < 0) {
807: AbsoluteTime_to_scalar( &result ) = 0;
808: } else {
809: result = left;
810: SUB_ABSOLUTETIME( &result, &right);
811: }
812:
813: return( result);
814: }
815:
816:
817: AbsoluteTime _eDurationToAbsolute( Duration theDuration)
818: {
819: AbsoluteTime result;
820:
821: if( theDuration > 0) {
822: clock_interval_to_absolutetime_interval( theDuration, kMillisecondScale,
823: &result );
824:
825: } else {
826: clock_interval_to_absolutetime_interval( (-theDuration), kMicrosecondScale,
827: &result );
828: }
829:
830: return( result);
831: }
832:
833: AbsoluteTime _eAddDurationToAbsolute( Duration duration, AbsoluteTime absolute )
834: {
835: return( _eAddAbsoluteToAbsolute(_eDurationToAbsolute( duration), absolute));
836: }
837:
838: #define UnsignedWideToUInt64(x) (*(UInt64 *)(x))
839: #define UInt64ToUnsignedWide(x) (*(UnsignedWide *)(x))
840:
841: AbsoluteTime _eNanosecondsToAbsolute ( UnsignedWide theNanoseconds)
842: {
843: AbsoluteTime result;
844: UInt64 nano = UnsignedWideToUInt64(&theNanoseconds);
845:
846: nanoseconds_to_absolutetime( nano, &result);
847:
848: return( result);
849: }
850:
851: UnsignedWide _eAbsoluteToNanoseconds( AbsoluteTime absolute )
852: {
853: UnsignedWide result;
854: UInt64 nano;
855:
856: absolutetime_to_nanoseconds( absolute, &nano);
857: result = UInt64ToUnsignedWide( &nano );
858:
859: return( result);
860: }
861:
862: Duration _eAbsoluteDeltaToDuration( AbsoluteTime left, AbsoluteTime right )
863: {
864: Duration dur;
865: AbsoluteTime result;
866: UInt64 nano;
867:
868: if( CMP_ABSOLUTETIME( &left, &right) < 0)
869: return( 0);
870:
871: result = left;
872: SUB_ABSOLUTETIME( &result, &right);
873: absolutetime_to_nanoseconds( result, &nano);
874:
875: if( nano >= ((1ULL << 31) * 1000ULL)) {
876: // +ve milliseconds
877: if( nano >= ((1ULL << 31) * 1000ULL * 1000ULL))
878: dur = 0x7fffffff;
879: else
880: dur = nano / 1000000ULL;
881: } else {
882: // -ve microseconds
883: dur = -(nano / 1000ULL);
884: }
885:
886: return( dur);
887: }
888:
889:
890: OSStatus _eDelayForHardware( AbsoluteTime time )
891: {
892: AbsoluteTime deadline;
893:
894: clock_absolutetime_interval_to_deadline( time, &deadline );
895: clock_delay_until( deadline );
896:
897: return( noErr);
898: }
899:
900: OSStatus _eDelayFor( Duration theDuration )
901: {
902: #if 1
903:
904: // In Marconi, DelayFor uses the old toolbox Delay routine
905: // which is based on the 60 Hz timer. Durations are not
906: // rounded up when converting to ticks. Yes, really.
907: // Some ATI drivers call DelayFor(1) 50000 times starting up.
908: // There is some 64-bit math there so we'd better reproduce
909: // the overhead of that calculation.
910:
911: #define DELAY_FOR_TICK_NANO 16666666
912: #define DELAY_FOR_TICK_MILLI 17
913: #define NANO32_MILLI 4295
914:
915: UnsignedWide nano;
916: AbsoluteTime abs;
917: unsigned int ms;
918:
919: abs = _eDurationToAbsolute( theDuration);
920: nano = _eAbsoluteToNanoseconds( abs);
921:
922: ms = (nano.lo / DELAY_FOR_TICK_NANO) * DELAY_FOR_TICK_MILLI;
923: ms += nano.hi * NANO32_MILLI;
924: if( ms)
925: IOSleep( ms);
926:
927: #else
928: // Accurate, but incompatible, version
929:
930: #define SLEEP_THRESHOLD 5000
931:
932: if( theDuration < 0) {
933:
934: // us duration
935: theDuration -= theDuration;
936: if( theDuration > SLEEP_THRESHOLD)
937: IOSleep( (theDuration + 999) / 1000);
938: else
939: IODelay( theDuration);
940:
941: } else {
942:
943: // ms duration
944: if( theDuration > (SLEEP_THRESHOLD / 1000))
945: IOSleep( theDuration ); // ms
946: else
947: IODelay( theDuration * 1000); // us
948: }
949: #endif
950:
951: return( noErr);
952: }
953:
954: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
955:
956: OSStatus _eCallOSTrapUniversalProc( UInt32 /* theProc */,
957: UInt32 procInfo, UInt32 trap, UInt8 * pb )
958: {
959: OSStatus err = -40;
960:
961: if( (procInfo == 0x133822)
962: && (trap == 0xa092) ) {
963:
964: UInt8 addr, reg, data;
965:
966: addr = pb[ 2 ];
967: reg = pb[ 3 ];
968: pb = *( (UInt8 **) ((UInt32) pb + 8));
969: data = pb[ 1 ];
970: (*PE_write_IIC)( addr, reg, data );
971: err = 0;
972: }
973: return( err);
974: }
975:
976: const UInt32 * _eGetKeys( void )
977: {
978: static const UInt32 zeros[] = { 0, 0, 0, 0 };
979:
980: return( zeros);
981: }
982:
983: UInt32 _eGetIndADB( void * adbInfo, UInt32 /* index */)
984: {
985: bzero( adbInfo, 10);
986: return( 0); // orig address
987: }
988:
989: char * _eLMGetPowerMgrVars( void )
990: {
991: static char * powerMgrVars = NULL;
992:
993: if( powerMgrVars == NULL) {
994: powerMgrVars = (char *) IOMalloc( 0x3c0);
995: if( powerMgrVars)
996: bzero( powerMgrVars, 0x3c0);
997: }
998: return( powerMgrVars);
999: }
1000:
1001: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1002:
1003: OSStatus _eNoErr( void )
1004: {
1005: return( noErr);
1006: }
1007:
1008: OSStatus _eFail( void )
1009: {
1010: return( -40);
1011: }
1012:
1013: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1014:
1015: // fix this!
1016:
1017: #define heathrowID ((volatile UInt32 *)0xf3000034)
1018: #define heathrowTermEna (1 << 3)
1019: #define heathrowTermDir (1 << 0)
1020:
1021: #define heathrowFeatureControl ((volatile UInt32 *)0xf3000038)
1022: #define heathrowMBRES (1 << 24)
1023:
1024: #define heathrowBrightnessControl ((volatile UInt8 *)0xf3000032)
1025: #define defaultBrightness 144
1026: #define heathrowContrastControl ((volatile UInt8 *)0xf3000033)
1027: #define defaultContrast 183
1028:
1029: #define gossamerSystemReg1 ((volatile UInt16 *)0xff000004)
1030: #define gossamerAllInOne (1 << 4)
1031:
1032: void _eATISetMBRES( UInt32 state )
1033: {
1034: UInt32 value;
1035:
1036: value = *heathrowFeatureControl;
1037:
1038: if( state == 0)
1039: value &= ~heathrowMBRES;
1040: else if( state == 1)
1041: value |= heathrowMBRES;
1042:
1043: *heathrowFeatureControl = value;
1044: eieio();
1045: }
1046:
1047: void _eATISetMonitorTermination( Boolean enable )
1048: {
1049:
1050: UInt32 value;
1051:
1052: value = *heathrowID;
1053:
1054: value |= heathrowTermEna;
1055: if( enable)
1056: value |= heathrowTermDir;
1057: else
1058: value &= ~heathrowTermDir;
1059:
1060: *heathrowID = value;
1061: eieio();
1062: }
1063:
1064: Boolean _eATIIsAllInOne( void )
1065: {
1066: Boolean rtn;
1067:
1068: rtn = (0 == ((*gossamerSystemReg1) & gossamerAllInOne));
1069: if( rtn) {
1070: *heathrowBrightnessControl = defaultBrightness;
1071: eieio();
1072: *heathrowContrastControl = defaultContrast;
1073: eieio();
1074: }
1075: return( rtn);
1076: }
1077:
1078: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1079:
1080: static SInt32 IONDRVStdInterruptHandler( InterruptSetMember setMember,
1081: void *refCon, UInt32 theIntCount )
1082: {
1083: // assert( false );
1084:
1085: return( kIsrIsComplete );
1086: }
1087:
1088: static bool IONDRVStdInterruptDisabler( InterruptSetMember setMember,
1089: void *refCon )
1090: {
1091: IONDRVInterruptSet * set;
1092: IONDRVInterruptSource * source;
1093: bool was;
1094:
1095: set = (IONDRVInterruptSet *) setMember.setID;
1096: assert( OSDynamicCast( IONDRVInterruptSet, set ));
1097: assert( setMember.member <= set->count );
1098: source = set->sources + setMember.member;
1099:
1100: was = source->enabled;
1101: source->enabled = false;
1102:
1103: assert( set->provider );
1104: set->provider->disableInterrupt( setMember.member - 1 );
1105:
1106: return( was );
1107: }
1108:
1109: static void IONDRVStdInterruptEnabler( InterruptSetMember setMember,
1110: void *refCon )
1111: {
1112: IONDRVInterruptSet * set;
1113: IONDRVInterruptSource * source;
1114:
1115: set = (IONDRVInterruptSet *) setMember.setID;
1116: assert( OSDynamicCast( IONDRVInterruptSet, set ));
1117: assert( setMember.member <= set->count );
1118: source = set->sources + setMember.member;
1119:
1120: source->enabled = true;
1121:
1122: assert( set->provider );
1123: set->provider->enableInterrupt( setMember.member - 1 );
1124: }
1125:
1126: static TVector tvIONDRVStdInterruptHandler = { IONDRVStdInterruptHandler, 0 };
1127: static TVector tvIONDRVStdInterruptEnabler = { IONDRVStdInterruptEnabler, 0 };
1128: static TVector tvIONDRVStdInterruptDisabler = { IONDRVStdInterruptDisabler, 0 };
1129:
1130:
1131: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1132:
1133: static void IONDRVInterruptAction( OSObject * target, void * refCon,
1134: IOService * provider, int index )
1135: {
1136: IONDRVInterruptSet * set;
1137: IONDRVInterruptSource * source;
1138: SInt32 result;
1139:
1140: set = (IONDRVInterruptSet *) target;
1141: index++;
1142:
1143: do {
1144:
1145: assert( (UInt32) index <= set->count);
1146: if( (UInt32) index > set->count)
1147: break;
1148:
1149: source = set->sources + index;
1150: result = CallTVector( set, (void *) index, source->refCon, 0, 0, 0,
1151: source->handler );
1152:
1153: switch( result ) {
1154:
1155: case kIsrIsNotComplete:
1156: index++;
1157: case kIsrIsComplete:
1158: break;
1159:
1160: case kMemberNumberParent:
1161: assert( false );
1162: break;
1163:
1164: default:
1165: index = result;
1166: set = set->child;
1167: break;
1168: }
1169:
1170: } while( result != kIsrIsComplete );
1171: }
1172:
1173: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1174:
1175: OSStatus
1176: _eGetInterruptFunctions( void * setID,
1177: UInt32 member,
1178: void ** refCon,
1179: TVector ** handler,
1180: TVector ** enabler,
1181: TVector ** disabler )
1182: {
1183: IONDRVInterruptSet * set;
1184: IONDRVInterruptSource * source;
1185: OSStatus err = noErr;
1186:
1187: set = (IONDRVInterruptSet *) setID;
1188: assert( OSDynamicCast( IONDRVInterruptSet, set ));
1189: assert( member <= set->count );
1190: source = set->sources + member;
1191:
1192: if( refCon)
1193: *refCon = source->refCon;
1194: if( handler)
1195: *handler = source->handler;
1196: if( enabler)
1197: *enabler = source->enabler;
1198: if( disabler)
1199: *disabler = source->disabler;
1200:
1201: return( err);
1202: }
1203:
1204: OSStatus
1205: _eInstallInterruptFunctions(void * setID,
1206: UInt32 member,
1207: void * refCon,
1208: TVector * handler,
1209: TVector * enabler,
1210: TVector * disabler )
1211: {
1212: IONDRVInterruptSet * set;
1213: IONDRVInterruptSource * source;
1214: OSStatus err = noErr;
1215:
1216: set = (IONDRVInterruptSet *) setID;
1217: assert( OSDynamicCast( IONDRVInterruptSet, set ));
1218: assert( member <= set->count );
1219: source = set->sources + member;
1220:
1221: source->refCon = refCon;
1222: if( handler)
1223: source->handler = handler;
1224: if( enabler)
1225: source->enabler = enabler;
1226: if( disabler)
1227: source->disabler = disabler;
1228:
1229: return( err);
1230: }
1231:
1232: OSStatus
1233: _eCreateInterruptSet( void * parentSet,
1234: UInt32 parentMember,
1235: UInt32 setSize,
1236: void ** setID,
1237: IOOptionBits options )
1238: {
1239: IONDRVInterruptSet * set;
1240: IONDRVInterruptSet * newSet;
1241: IONDRVInterruptSource * source;
1242: OSStatus err = noErr;
1243:
1244: set = (IONDRVInterruptSet *) parentSet;
1245: assert( OSDynamicCast( IONDRVInterruptSet, set ));
1246: assert( parentMember <= set->count );
1247: source = set->sources + parentMember;
1248:
1249: newSet = IONDRVInterruptSet::with( 0, options, setSize );
1250: assert( newSet );
1251:
1252: if( newSet) for( UInt32 i = 1; i <= setSize; i++ ) {
1253:
1254: source = newSet->sources + i;
1255: source->handler = &tvIONDRVStdInterruptHandler;
1256: source->enabler = &tvIONDRVStdInterruptEnabler;
1257: source->disabler = &tvIONDRVStdInterruptDisabler;
1258: }
1259:
1260: set->child = newSet;
1261: *setID = newSet;
1262:
1263: return( err );
1264: }
1265:
1266: OSStatus
1267: _eDeleteInterruptSet( void * setID )
1268: {
1269: IONDRVInterruptSet * set;
1270: OSStatus err = noErr;
1271:
1272: set = (IONDRVInterruptSet *) setID;
1273: assert( OSDynamicCast( IONDRVInterruptSet, set ));
1274:
1275: set->release();
1276:
1277: return( err );
1278: }
1279:
1280: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1281:
1282: #define MAKEFUNC(s,e) { s, e, 0 }
1283:
1284: static FunctionEntry PCILibFuncs[] =
1285: {
1286: MAKEFUNC( "ExpMgrConfigReadLong", _eExpMgrConfigReadLong),
1287: MAKEFUNC( "ExpMgrConfigReadWord", _eExpMgrConfigReadWord),
1288: MAKEFUNC( "ExpMgrConfigReadByte", _eExpMgrConfigReadByte),
1289: MAKEFUNC( "ExpMgrConfigWriteLong", _eExpMgrConfigWriteLong),
1290: MAKEFUNC( "ExpMgrConfigWriteWord", _eExpMgrConfigWriteWord),
1291: MAKEFUNC( "ExpMgrConfigWriteByte", _eExpMgrConfigWriteByte),
1292:
1293: MAKEFUNC( "ExpMgrIOReadLong", _eExpMgrIOReadLong),
1294: MAKEFUNC( "ExpMgrIOReadWord", _eExpMgrIOReadWord),
1295: MAKEFUNC( "ExpMgrIOReadByte", _eExpMgrIOReadByte),
1296: MAKEFUNC( "ExpMgrIOWriteLong", _eExpMgrIOWriteLong),
1297: MAKEFUNC( "ExpMgrIOWriteWord", _eExpMgrIOWriteWord),
1298: MAKEFUNC( "ExpMgrIOWriteByte", _eExpMgrIOWriteByte),
1299:
1300: MAKEFUNC( "EndianSwap16Bit", _eEndianSwap16Bit),
1301: MAKEFUNC( "EndianSwap32Bit", _eEndianSwap32Bit)
1302: };
1303:
1304: static FunctionEntry VideoServicesLibFuncs[] =
1305: {
1306: MAKEFUNC( "VSLPrepareCursorForHardwareCursor",
1307: IONDRVFramebuffer::VSLPrepareCursorForHardwareCursor),
1308: MAKEFUNC( "VSLNewInterruptService", IONDRVFramebuffer::VSLNewInterruptService),
1309: MAKEFUNC( "VSLDisposeInterruptService", IONDRVFramebuffer::VSLDisposeInterruptService),
1310: MAKEFUNC( "VSLDoInterruptService", IONDRVFramebuffer::VSLDoInterruptService)
1311: };
1312:
1313: static FunctionEntry NameRegistryLibFuncs[] =
1314: {
1315: MAKEFUNC( "RegistryEntryIDCopy", _eRegistryEntryIDCopy),
1316: MAKEFUNC( "RegistryEntryIDInit", _eRegistryEntryIDInit),
1317: MAKEFUNC( "RegistryEntryIDDispose", _eNoErr),
1318: MAKEFUNC( "RegistryEntryIDCompare", _eRegistryEntryIDCompare),
1319: MAKEFUNC( "RegistryPropertyGetSize", _eRegistryPropertyGetSize),
1320: MAKEFUNC( "RegistryPropertyGet", _eRegistryPropertyGet),
1321: MAKEFUNC( "RegistryPropertyGetMod", _eRegistryPropertyGetMod),
1322: MAKEFUNC( "RegistryPropertySetMod", _eRegistryPropertySetMod),
1323:
1324: MAKEFUNC( "RegistryPropertyIterateCreate", _eRegistryPropertyIterateCreate),
1325: MAKEFUNC( "RegistryPropertyIterateDispose", _eRegistryPropertyIterateDispose),
1326: MAKEFUNC( "RegistryPropertyIterate", _eRegistryPropertyIterate),
1327:
1328: MAKEFUNC( "RegistryEntryIterateCreate", _eRegistryEntryIterateCreate),
1329: MAKEFUNC( "RegistryEntryIterateDispose", _eRegistryEntryIterateDispose),
1330: MAKEFUNC( "RegistryEntryIterate", _eRegistryEntryIterate),
1331: MAKEFUNC( "RegistryCStrEntryToName", _eRegistryCStrEntryToName),
1332: MAKEFUNC( "RegistryCStrEntryLookup", _eRegistryCStrEntryLookup),
1333:
1334: MAKEFUNC( "RegistryCStrEntryCreate", _eRegistryCStrEntryCreate),
1335: MAKEFUNC( "RegistryEntryDelete", _eNoErr),
1336:
1337: MAKEFUNC( "RegistryPropertyCreate", _eRegistryPropertyCreate),
1338: MAKEFUNC( "RegistryPropertyDelete", _eRegistryPropertyDelete),
1339: MAKEFUNC( "RegistryPropertySet", _eRegistryPropertySet)
1340: };
1341:
1342:
1343: static FunctionEntry DriverServicesLibFuncs[] =
1344: {
1345: MAKEFUNC( "SynchronizeIO", _eSynchronizeIO),
1346: MAKEFUNC( "SetProcessorCacheMode", _eSetProcessorCacheMode),
1347: MAKEFUNC( "BlockCopy", bcopy),
1348: MAKEFUNC( "BlockMove", bcopy),
1349: MAKEFUNC( "CStrCopy", strcpy),
1350: MAKEFUNC( "CStrCmp", strcmp),
1351: MAKEFUNC( "CStrLen", strlen),
1352: MAKEFUNC( "CStrCat", strcat),
1353: MAKEFUNC( "CStrNCopy", strncpy),
1354: MAKEFUNC( "CStrNCmp", strncmp),
1355: MAKEFUNC( "CStrNCat", strncat),
1356: MAKEFUNC( "PStrCopy", _ePStrCopy),
1357:
1358: MAKEFUNC( "PoolAllocateResident", _ePoolAllocateResident),
1359: MAKEFUNC( "MemAllocatePhysicallyContiguous", _ePoolAllocateResident),
1360: MAKEFUNC( "PoolDeallocate", _ePoolDeallocate),
1361:
1362: MAKEFUNC( "UpTime", _eUpTime),
1363: MAKEFUNC( "AbsoluteDeltaToDuration", _eAbsoluteDeltaToDuration),
1364: MAKEFUNC( "AddAbsoluteToAbsolute", _eAddAbsoluteToAbsolute),
1365: MAKEFUNC( "SubAbsoluteFromAbsolute", _eSubAbsoluteFromAbsolute),
1366: MAKEFUNC( "AddDurationToAbsolute", _eAddDurationToAbsolute),
1367: MAKEFUNC( "NanosecondsToAbsolute", _eNanosecondsToAbsolute),
1368: MAKEFUNC( "AbsoluteToNanoseconds", _eAbsoluteToNanoseconds),
1369: MAKEFUNC( "DurationToAbsolute", _eDurationToAbsolute),
1370: MAKEFUNC( "DelayForHardware", _eDelayForHardware),
1371: MAKEFUNC( "DelayFor", _eDelayFor),
1372:
1373: MAKEFUNC( "CurrentExecutionLevel", _eCurrentExecutionLevel),
1374: MAKEFUNC( "IOCommandIsComplete", _eIOCommandIsComplete),
1375:
1376: MAKEFUNC( "SysDebugStr", _eNoErr),
1377: MAKEFUNC( "SysDebug", _eNoErr),
1378:
1379: MAKEFUNC( "CompareAndSwap", OSCompareAndSwap),
1380:
1381: MAKEFUNC( "CreateInterruptSet", _eCreateInterruptSet),
1382: MAKEFUNC( "DeleteInterruptSet", _eDeleteInterruptSet),
1383: MAKEFUNC( "GetInterruptFunctions", _eGetInterruptFunctions),
1384: MAKEFUNC( "InstallInterruptFunctions", _eInstallInterruptFunctions)
1385:
1386: };
1387:
1388: static FunctionEntry ATIUtilsFuncs[] =
1389: {
1390: // Gossamer onboard ATI
1391: MAKEFUNC( "ATISetMBRES", _eATISetMBRES),
1392: MAKEFUNC( "ATISetMonitorTermination", _eATISetMonitorTermination),
1393: MAKEFUNC( "ATIIsAllInOne", _eATIIsAllInOne)
1394: };
1395:
1396: // These are all out of spec
1397:
1398: static FunctionEntry InterfaceLibFuncs[] =
1399: {
1400: // Apple control : XPRam and EgretDispatch
1401: MAKEFUNC( "CallUniversalProc", _eFail),
1402: MAKEFUNC( "CallOSTrapUniversalProc", _eCallOSTrapUniversalProc),
1403:
1404: // Apple chips65550
1405: // MAKEFUNC( "NewRoutineDescriptor", _eCallOSTrapUniversalProc),
1406: // MAKEFUNC( "DisposeRoutineDescriptor", _eNoErr),
1407: // MAKEFUNC( "InsTime", _eInsTime),
1408: // MAKEFUNC( "PrimeTime", _ePrimeTime),
1409:
1410: // Radius PrecisionColor 16
1411: MAKEFUNC( "CountADBs", _eNoErr),
1412: MAKEFUNC( "GetIndADB", _eGetIndADB),
1413: MAKEFUNC( "GetKeys", _eGetKeys)
1414: };
1415:
1416: static FunctionEntry PrivateInterfaceLibFuncs[] =
1417: {
1418: // Apple chips65550
1419: MAKEFUNC( "LMGetPowerMgrVars", _eLMGetPowerMgrVars )
1420: };
1421:
1422: #define NUMLIBRARIES 7
1423: const ItemCount IONumNDRVLibraries = NUMLIBRARIES;
1424: LibraryEntry IONDRVLibraries[ NUMLIBRARIES ] =
1425: {
1426: { "PCILib", sizeof(PCILibFuncs) / sizeof(FunctionEntry), PCILibFuncs },
1427: { "VideoServicesLib", sizeof(VideoServicesLibFuncs) / sizeof(FunctionEntry), VideoServicesLibFuncs },
1428: { "NameRegistryLib", sizeof(NameRegistryLibFuncs) / sizeof(FunctionEntry), NameRegistryLibFuncs },
1429: { "DriverServicesLib", sizeof(DriverServicesLibFuncs) / sizeof(FunctionEntry), DriverServicesLibFuncs },
1430:
1431: // G3
1432: { "ATIUtils", sizeof(ATIUtilsFuncs) / sizeof(FunctionEntry), ATIUtilsFuncs },
1433:
1434: // out of spec stuff
1435: { "InterfaceLib", sizeof(InterfaceLibFuncs) / sizeof(FunctionEntry), InterfaceLibFuncs },
1436: { "PrivateInterfaceLib", sizeof(PrivateInterfaceLibFuncs) / sizeof(FunctionEntry), PrivateInterfaceLibFuncs }
1437: };
1438:
1439: } /* extern "C" */
1440:
1441: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1442:
1443: #define super OSObject
1444:
1445: OSDefineMetaClassAndStructors(IONDRVInterruptSet, OSObject)
1446:
1447: IONDRVInterruptSet * IONDRVInterruptSet::with(IOService * provider,
1448: IOOptionBits options, SInt32 count )
1449: {
1450: IONDRVInterruptSet * set;
1451:
1452: set = new IONDRVInterruptSet;
1453: if( set && !set->init()) {
1454: set->release();
1455: set = 0;
1456: }
1457:
1458: if( set) {
1459:
1460: set->provider = provider;
1461: set->options = options;
1462: set->count = count;
1463:
1464: count++;
1465: set->sources = IONew( IONDRVInterruptSource, count );
1466: assert( set->sources );
1467: bzero( set->sources, count * sizeof( IONDRVInterruptSource));
1468: }
1469:
1470: return( set );
1471: }
1472:
1473: void IONDRVInterruptSet::free()
1474: {
1475: if( sources)
1476: IODelete( sources, IONDRVInterruptSource, count + 1 );
1477:
1478: super::free();
1479: }
1480:
1481: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1482:
1483: #if NDRVLIBTEST
1484:
1485: static void IONDRVLibrariesTest( IOService * provider )
1486: {
1487: UInt64 nano;
1488: UnsignedWide nano2;
1489: AbsoluteTime abs1, abs2;
1490:
1491: nano = 1000ULL;
1492: abs1 = _eNanosecondsToAbsolute(UInt64ToUnsignedWide(&nano));
1493: IOLog("_eNanosecondsToAbsolute %08lx:%08lx\n", abs1.hi, abs1.lo);
1494: nano2 = _eAbsoluteToNanoseconds(abs1);
1495: IOLog("_eAbsoluteToNanoseconds %08lx:%08lx\n", nano2.hi, nano2.lo);
1496: AbsoluteTime_to_scalar(&abs2) = 0;
1497: IOLog("_eAbsoluteDeltaToDuration %ld\n", _eAbsoluteDeltaToDuration(abs1,abs2));
1498:
1499: nano = 0x13161b000ULL;
1500: abs1 = _eNanosecondsToAbsolute(UInt64ToUnsignedWide(&nano));
1501: IOLog("_eNanosecondsToAbsolute %08lx:%08lx\n", abs1.hi, abs1.lo);
1502: nano2 = _eAbsoluteToNanoseconds(abs1);
1503: IOLog("_eAbsoluteToNanoseconds %08lx:%08lx\n", nano2.hi, nano2.lo);
1504: AbsoluteTime_to_scalar(&abs2) = 0;
1505: IOLog("_eAbsoluteDeltaToDuration %ld\n", _eAbsoluteDeltaToDuration(abs1,abs2));
1506:
1507: nano = 0x6acfc00000000ULL;
1508: abs1 = _eNanosecondsToAbsolute(UInt64ToUnsignedWide(&nano));
1509: IOLog("_eNanosecondsToAbsolute %08lx:%08lx\n", abs1.hi, abs1.lo);
1510: nano2 = _eAbsoluteToNanoseconds(abs1);
1511: IOLog("_eAbsoluteToNanoseconds %08lx:%08lx\n", nano2.hi, nano2.lo);
1512: AbsoluteTime_to_scalar(&abs2) = 0;
1513: IOLog("_eAbsoluteDeltaToDuration %ld\n", _eAbsoluteDeltaToDuration(abs1,abs2));
1514:
1515: abs1 = _eUpTime();
1516: IODelay(10);
1517: abs2 = _eUpTime();
1518: IOLog("10us duration %ld\n", _eAbsoluteDeltaToDuration(abs2,abs1));
1519:
1520: abs1 = _eUpTime();
1521: for( int i =0; i < 50000; i++)
1522: _eDelayFor(1);
1523: abs2 = _eUpTime();
1524: IOLog("50000 DelayFor(1) %ld\n", _eAbsoluteDeltaToDuration(abs2,abs1));
1525:
1526: abs1 = _eUpTime();
1527: _eDelayFor(50);
1528: abs2 = _eUpTime();
1529: IOLog("DelayFor(50) %ld\n", _eAbsoluteDeltaToDuration(abs2,abs1));
1530:
1531: abs1 = _eDurationToAbsolute( -10);
1532: IOLog("_eDurationToAbsolute(-10) %08lx:%08lx\n", abs1.hi, abs1.lo);
1533: abs1 = _eDurationToAbsolute( 10);
1534: IOLog("_eDurationToAbsolute(10) %08lx:%08lx\n", abs1.hi, abs1.lo);
1535:
1536: }
1537: #endif
1538:
1539: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1540:
1541: IOReturn IONDRVLibrariesInitialize( IOService * provider )
1542: {
1543: IODTPlatformExpert * platform;
1544: const OSSymbol * sym;
1545: OSData * data;
1546: OSArray * intSpec;
1547: unsigned int len, i;
1548:
1549: #if NDRVLIBTEST
1550: IONDRVLibrariesTest( provider );
1551: #endif
1552:
1553: // copy nvram property
1554:
1555: if( (platform = OSDynamicCast( IODTPlatformExpert,
1556: IOService::getPlatform()))) {
1557:
1558: // IOService::waitForService( IOService::resourceMatching( "IONVRAM" ));
1559:
1560: if( kIOReturnSuccess == platform->readNVRAMProperty( provider,
1561: &sym, &data )) {
1562:
1563: IONDRVSetNVRAMPropertyName( provider, sym );
1564: provider->setProperty( sym, data);
1565: data->release();
1566: sym->release();
1567: }
1568: }
1569:
1570: // create interrupt properties, if none present
1571:
1572: if( (intSpec = (OSArray *)provider->getProperty( gIOInterruptSpecifiersKey))
1573: && (0 == provider->getProperty( gIODTAAPLInterruptsKey ))) {
1574: // make AAPL,interrupts property if not present (NW)
1575: for( i = 0, len = 0; i < intSpec->getCount(); i++ ) {
1576: data = (OSData *) intSpec->getObject(i);
1577: assert( data );
1578: len += data->getLength();
1579: }
1580: if( len)
1581: data = OSData::withCapacity( len );
1582: if( data) {
1583: for( i = 0; i < intSpec->getCount(); i++ )
1584: data->appendBytes( (OSData *) intSpec->getObject(i));
1585: provider->setProperty( gIODTAAPLInterruptsKey, data );
1586: data->release();
1587: }
1588: }
1589:
1590: // make NDRV interrupts
1591:
1592: data = OSData::withCapacity( kISTPropertyMemberCount
1593: * sizeof( InterruptSetMember));
1594:
1595: InterruptSetMember setMember;
1596: IONDRVInterruptSet * set;
1597: IONDRVInterruptSource * source;
1598:
1599: set = IONDRVInterruptSet::with( provider, 0,
1600: kISTPropertyMemberCount );
1601:
1602: if( set) for( i = 1; i <= kISTPropertyMemberCount; i++ ) {
1603:
1604: source = set->sources + i;
1605: source->handler = &tvIONDRVStdInterruptHandler;
1606: source->enabler = &tvIONDRVStdInterruptEnabler;
1607: source->disabler = &tvIONDRVStdInterruptDisabler;
1608:
1609: setMember.setID = (void *) set;
1610: setMember.member = i;
1611: data->appendBytes( &setMember, sizeof( setMember));
1612:
1613: provider->registerInterrupt( i - 1, set,
1614: &IONDRVInterruptAction, (void *) 0x53 );
1615: } else
1616: data = 0;
1617:
1618: if( data) {
1619: provider->setProperty( kISTPropertyName, data );
1620: data->release();
1621: data = 0;
1622: }
1623:
1624: // map memory
1625:
1626: IOItemCount numMaps = provider->getDeviceMemoryCount();
1627: IOVirtualAddress virtAddress;
1628:
1629: for( i = 0; i < numMaps; i++) {
1630: IODeviceMemory * mem;
1631: IOMemoryMap * map;
1632: bool consoleDevice;
1633:
1634: consoleDevice = (0 != provider->getProperty("AAPL,boot-display"));
1635:
1636: mem = provider->getDeviceMemoryWithIndex( i );
1637: if( 0 == mem)
1638: continue;
1639:
1640: // set up a 1-1 mapping for the BAT map of the console device
1641: // remove this soon
1642: if( consoleDevice && (0 == mem->map( kIOMapReference)))
1643: mem->setMapping( kernel_task, mem->getPhysicalAddress() );
1644:
1645: map = mem->map();
1646: if( 0 == map) {
1647: // IOLog("%s: map[%ld] failed\n", provider->getName(), i);
1648: continue;
1649: }
1650:
1651: virtAddress = map->getVirtualAddress();
1652: if( !data)
1653: data = OSData::withCapacity( numMaps * sizeof( IOVirtualAddress));
1654: if( !data)
1655: continue;
1656: data->appendBytes( &virtAddress, sizeof( IOVirtualAddress));
1657: kprintf("ndrv base = %lx\n", virtAddress);
1658: }
1659:
1660: // NDRV aperture vectors
1661: if( data) {
1662: provider->setProperty( "AAPL,address", data );
1663: data->release();
1664: }
1665:
1666: return( kIOReturnSuccess );
1667: }
1668:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.