|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24: /*
25: * Copyright (c) 1997 Apple Computer, Inc.
26: *
27: *
28: * HISTORY
29: *
30: * Simon Douglas 22 Oct 97
31: * - first checked in.
32: */
33:
34:
35:
36: #include <mach/vm_attributes.h>
37: #include <mach/vm_param.h>
38: #import <machdep/ppc/proc_reg.h>
39: #include <machdep/ppc/pmap.h>
40: #include <machdep/ppc/pmap_internals.h>
41:
42: #import <driverkit/generalFuncs.h>
43: #import <driverkit/ppc/IOPCIDevice.h>
44: #import <driverkit/ppc/IODeviceTreeBus.h>
45: #import "IOPEFLibraries.h"
46: #import "IOPEFLoader.h"
47: #import "IONDRVInterface.h"
48:
49: #import <stdio.h>
50: #import <string.h>
51:
52: #define LOG if(1) kprintf
53:
54: #define LOGNAMEREG 0
55:
56: enum {
57: kNVRAMProperty = 0x00000020L, // matches NR
58: };
59:
60: //=========================================================================
61:
62: #define SWAPLONG(value) ( ((value >> 24) & 0xff) | \
63: ((value >> 8) & 0xff00) | \
64: ((value << 8) & 0xff0000) | \
65: ((value << 24) & 0xff000000) )
66:
67:
68: OSStatus _eExpMgrConfigReadLong( void * entryID, UInt32 offset, UInt32 * value )
69: {
70: id ioDevice;
71:
72: REG_ENTRY_TO_ID( entryID, ioDevice)
73:
74: return( [ioDevice configReadLong:offset value:value]);
75: }
76:
77: OSStatus _eExpMgrConfigWriteLong( void * entryID, UInt32 offset, UInt32 value )
78: {
79: id ioDevice;
80:
81: REG_ENTRY_TO_ID( entryID, ioDevice)
82:
83: return( [ioDevice configWriteLong:offset value:value]);
84: }
85:
86:
87: OSStatus _eExpMgrConfigReadWord( void * entryID, UInt32 offset, UInt16 * value )
88: {
89: OSStatus err;
90: UInt32 lvalue;
91:
92: err = _eExpMgrConfigReadLong( entryID, offset & (-4), &lvalue);
93: if( offset & 2)
94: *value = lvalue >> 16;
95: else
96: *value = lvalue;
97: return( err);
98: }
99:
100: OSStatus _eExpMgrConfigWriteWord( void * entryID, UInt32 offset, UInt16 value )
101: {
102: OSStatus err;
103: UInt32 lvalue;
104:
105: err = _eExpMgrConfigReadLong( entryID, offset & (-4), &lvalue);
106:
107: if( offset & 2)
108: lvalue = (lvalue & 0xffff) | (value << 16);
109: else
110: lvalue = (lvalue & 0xffff0000) | value;
111:
112: err = _eExpMgrConfigWriteLong( entryID, offset & (-4), lvalue);
113: return( err);
114: }
115:
116: OSStatus _eExpMgrConfigReadByte( void * entryID, UInt32 offset, UInt8 * value )
117: {
118: OSStatus err;
119: UInt32 lvalue;
120:
121: err = _eExpMgrConfigReadLong( entryID, offset & (-4), &lvalue);
122: *value = lvalue >> ((offset & 3) * 8);
123: return( err);
124: }
125:
126: OSStatus _eExpMgrConfigWriteByte( void * entryID, UInt32 offset, UInt8 value )
127: {
128: OSStatus err;
129: UInt32 lvalue;
130:
131: err = _eExpMgrConfigReadLong( entryID, offset & (-4), &lvalue);
132: lvalue = (lvalue & ~(0xff << ((offset & 3) * 8))) | (value << ((offset & 3) * 8));
133: err = _eExpMgrConfigWriteLong( entryID, offset & (-4), lvalue);
134: return( err);
135: }
136:
137: OSStatus _eExpMgrIOReadLong( void * entryID, UInt32 offset, UInt32 * value )
138: {
139: id ioDevice;
140: UInt32 * io;
141: UInt32 result;
142:
143: REG_ENTRY_TO_ID( entryID, ioDevice)
144:
145: io = (UInt32 *) [ioDevice getIOAperture];
146: if( NULL == io)
147: return( IO_R_UNSUPPORTED);
148:
149: __asm__ ("lwbrx %0,%1,%2" : "=r" (result) : "r" (io), "r" (offset) );
150: eieio();
151: *value = result;
152:
153: return( noErr);
154: }
155:
156: OSStatus _eExpMgrIOWriteLong( void * entryID, UInt32 offset, UInt32 value )
157: {
158: id ioDevice;
159: UInt32 * io;
160:
161: REG_ENTRY_TO_ID( entryID, ioDevice)
162:
163: io = (UInt32 *) [ioDevice getIOAperture];
164: if( NULL == io)
165: return( IO_R_UNSUPPORTED);
166:
167: __asm__ ("stwbrx %0,%1,%2" : : "r" (value), "r" (io), "r" (offset) );
168: eieio();
169:
170: return( noErr);
171: }
172:
173: OSStatus _eExpMgrIOReadWord( void * entryID, UInt32 offset, UInt16 * value )
174: {
175: id ioDevice;
176: UInt16 * io;
177: UInt16 result;
178:
179: REG_ENTRY_TO_ID( entryID, ioDevice)
180:
181: io = (UInt16 *) [ioDevice getIOAperture];
182: if( NULL == io)
183: return( IO_R_UNSUPPORTED);
184:
185: __asm__ ("lhbrx %0,%1,%2" : "=r" (result) : "r" (io), "r" (offset) );
186: eieio();
187: *value = result;
188:
189: return( noErr);
190: }
191:
192: OSStatus _eExpMgrIOWriteWord( void * entryID, UInt32 offset, UInt16 value )
193: {
194: id ioDevice;
195: UInt16 * io;
196:
197: REG_ENTRY_TO_ID( entryID, ioDevice)
198:
199: io = (UInt16 *) [ioDevice getIOAperture];
200: if( NULL == io)
201: return( IO_R_UNSUPPORTED);
202:
203: __asm__ ("sthbrx %0,%1,%2" : : "r" (value), "r" (io), "r" (offset) );
204: eieio();
205:
206: return( noErr);
207: }
208:
209: OSStatus _eExpMgrIOReadByte( void * entryID, UInt32 offset, UInt8 * value )
210: {
211: id ioDevice;
212: UInt8 * io;
213:
214: REG_ENTRY_TO_ID( entryID, ioDevice)
215:
216: io = (UInt8 *) [ioDevice getIOAperture];
217: if( NULL == io)
218: return( IO_R_UNSUPPORTED);
219:
220: *value = io[ offset ];
221: eieio();
222: return( noErr);
223: }
224:
225: OSStatus _eExpMgrIOWriteByte( void * entryID, UInt32 offset, UInt8 value )
226: {
227: id ioDevice;
228: UInt8 * io;
229:
230: REG_ENTRY_TO_ID( entryID, ioDevice)
231:
232: io = (UInt8 *) [ioDevice getIOAperture];
233: if( NULL == io)
234: return( IO_R_UNSUPPORTED);
235:
236: io[ offset ] = value;
237: eieio();
238:
239: return( noErr);
240: }
241:
242:
243: UInt32 _eEndianSwap32Bit( UInt32 data )
244: {
245: return( SWAPLONG( data ));
246: }
247:
248: UInt32 _eEndianSwap16Bit( UInt16 data )
249: {
250: return( ((data >> 8) & 0x00ff) |
251: ((data << 8) & 0xff00) );
252: }
253:
254: //=========================================================================
255:
256: OSStatus _eRegistryEntryIDCopy( void *entryID, void *to )
257: {
258: bcopy( entryID, to, 16 );
259: return( noErr);
260: }
261:
262:
263: OSStatus _eRegistryEntryIDInit( void *entryID )
264: {
265: MAKE_REG_ENTRY( entryID, nil);
266: return( noErr);
267: }
268:
269:
270: /*
271: * Compare EntryID's for equality or if invalid
272: *
273: * If a NULL value is given for either id1 or id2, the other id
274: * is compared with an invalid ID. If both are NULL, the id's
275: * are consided equal (result = true).
276: * note: invalid != uninitialized
277: */
278: Boolean _eRegistryEntryIDCompare( void * entryID1, void * entryID2 )
279: {
280: id ioDevice1 = nil, ioDevice2 = nil;
281:
282: if( entryID1) {
283: REG_ENTRY_TO_ID( entryID1, ioDevice1)
284: }
285: if( entryID2) {
286: REG_ENTRY_TO_ID( entryID2, ioDevice2)
287: }
288: return( ioDevice1 == ioDevice2 );
289: }
290:
291: OSStatus _eRegistryPropertyGetSize( void *entryID, const char *propertyName, UInt32 *propertySize )
292: {
293: OSStatus err;
294: id ioDevice;
295:
296: REG_ENTRY_TO_ID( entryID, ioDevice)
297:
298: err = [[ioDevice propertyTable] getProperty:propertyName flags:kReferenceProperty value:NULL length:propertySize];
299: #if LOGNAMEREG
300: LOG("RegistryPropertyGetSize: %s : %d\n", propertyName, err);
301: #endif
302: return( err);
303:
304: }
305:
306: OSStatus _eRegistryPropertyGet(void *entryID, const char *propertyName, UInt32 *propertyValue, UInt32 *propertySize)
307: {
308: OSStatus err;
309: id ioDevice;
310: void * value = propertyValue;
311:
312: REG_ENTRY_TO_ID( entryID, ioDevice)
313:
314: err = [[ioDevice propertyTable] getProperty:propertyName flags:0 value:&value length:propertySize];
315: #if LOGNAMEREG
316: LOG("RegistryPropertyGet: %s : %d\n", propertyName, err);
317: #endif
318: return( err);
319: }
320:
321: OSStatus _eRegistryPropertyCreate( void *entryID, const char *propertyName, void * propertyValue, UInt32 propertySize )
322: {
323: id ioDevice;
324: OSStatus err;
325:
326: REG_ENTRY_TO_ID( entryID, ioDevice)
327:
328: err = [[ioDevice propertyTable] createProperty:propertyName flags:0 value:propertyValue length:propertySize];
329:
330: #if LOGNAMEREG
331: LOG("RegistryPropertyCreate: %s : %d\n", propertyName, err);
332: #endif
333: return( err);
334: }
335:
336: OSStatus _eRegistryPropertyDelete( void *entryID, const char *propertyName )
337: {
338: id ioDevice;
339: OSStatus err;
340:
341: REG_ENTRY_TO_ID( entryID, ioDevice)
342:
343: err = [[ioDevice propertyTable] deleteProperty:propertyName];
344:
345: #if LOGNAMEREG
346: LOG("RegistryPropertyDelete: %s : %d\n", propertyName, err);
347: #endif
348: return( err);
349: }
350:
351: OSStatus _eRegistryPropertySet( void *entryID, const char *propertyName, void * propertyValue, UInt32 propertySize )
352: {
353: id ioDevice;
354: OSStatus err;
355:
356: REG_ENTRY_TO_ID( entryID, ioDevice)
357:
358: err = [[ioDevice propertyTable] setProperty:propertyName flags:0 value:propertyValue length:propertySize];
359:
360: if( (err == noErr) && ([ioDevice isNVRAMProperty:propertyName]))
361: err = [ioDevice setNVRAMProperty:propertyName];
362:
363: #if LOGNAMEREG
364: LOG("RegistryPropertySet: %s : %d\n", propertyName, err);
365: #endif
366: return( err);
367: }
368:
369: OSStatus _eRegistryPropertyGetMod(void *entryID, const char *propertyName, UInt32 *mod)
370: {
371: id ioDevice;
372:
373: REG_ENTRY_TO_ID( entryID, ioDevice)
374:
375: if( [ioDevice isNVRAMProperty:propertyName])
376: *mod = kNVRAMProperty;
377: else
378: *mod = 0;
379:
380: return( noErr);
381: }
382:
383: OSStatus _eRegistryPropertySetMod(void *entryID, const char *propertyName, UInt32 mod)
384: {
385: OSStatus err = noErr;
386: id ioDevice;
387:
388: REG_ENTRY_TO_ID( entryID, ioDevice)
389:
390: if( mod & kNVRAMProperty)
391: err = [ioDevice setNVRAMProperty:propertyName];
392:
393: return( err);
394: }
395:
396:
397: struct RegIterator
398: {
399: RegEntryID regEntry;
400: UInt32 index;
401: };
402: typedef struct RegIterator RegIterator;
403:
404: OSStatus _eRegistryPropertyIterateCreate (RegEntryID * entryID, RegIterator ** cookie)
405: {
406: id ioDevice;
407: RegIterator * iterator;
408:
409: REG_ENTRY_TO_ID( entryID, ioDevice)
410:
411: iterator = IOMalloc( sizeof( RegIterator));
412: *cookie = iterator;
413: if( iterator == NULL)
414: return( nrNotEnoughMemoryErr);
415:
416: bcopy( entryID, iterator->regEntry, sizeof( RegEntryID));
417: iterator->index = 0;
418:
419: return( noErr);
420: }
421:
422: OSStatus _eRegistryPropertyIterateDispose( RegIterator ** cookie)
423: {
424: IOFree( *cookie, sizeof( RegIterator));
425: *cookie = NULL;
426: return( noErr);
427: }
428:
429:
430: OSStatus _eRegistryPropertyIterate( RegIterator ** cookie, char * name, Boolean * done )
431: {
432: OSStatus err;
433: id ioDevice;
434: RegIterator * iterator = *cookie;
435: RegEntryID * entryID = &iterator->regEntry;
436:
437: REG_ENTRY_TO_ID( entryID, ioDevice)
438:
439: err = [[ioDevice propertyTable] getPropertyWithIndex:(iterator->index++) name:name];
440:
441: // Seems to be differences in handling "done". ATI assumes done = true when getting the last
442: // property. Book says done is true after last property. ATI does check err, so this will work.
443: // Control ignores err and checks done.
444:
445: *done = (err != noErr);
446:
447: return( err);
448: }
449:
450: typedef UInt32 RegEntryIter;
451:
452: OSStatus
453: _eRegistryEntryIterateCreate( RegEntryIter * cookie)
454: {
455: *cookie = 0;
456: return( noErr);
457: }
458:
459: OSStatus
460: _eRegistryEntryIterateDispose( RegEntryIter * cookie)
461: {
462: return( noErr);
463: }
464:
465: OSStatus
466: _eRegistryEntryIterate( RegEntryIter * cookie,
467: UInt32 relationship,
468: RegEntryID * foundEntry,
469: Boolean * done)
470: {
471: id ioDevice;
472:
473: ioDevice = [IOTreeDevice findForIndex:(*cookie)++];
474:
475: MAKE_REG_ENTRY( foundEntry, ioDevice);
476: *done = (ioDevice == nil);
477:
478: if( ioDevice)
479: return( noErr);
480: else
481: return( nrNotFoundErr);
482: }
483:
484: OSStatus
485: _eRegistryCStrEntryToName( const RegEntryID * entryID,
486: RegEntryID * parentEntry,
487: char * nameComponent,
488: Boolean * done)
489: {
490: id ioDevice;
491:
492: REG_ENTRY_TO_ID( entryID, ioDevice)
493:
494: strncpy( nameComponent, [ioDevice nodeName], 31 );
495: nameComponent[ 31 ] = 0;
496: return( noErr);
497: }
498:
499: OSStatus
500: _eRegistryCStrEntryCreate( const RegEntryID * parentEntry,
501: const char * name,
502: RegEntryID * newEntry)
503: {
504: IOPropertyTable * propTable;
505: IOTreeDevice * newDev;
506:
507: // NOT published
508:
509: propTable = [[IOPropertyTable alloc] init];
510:
511: [propTable createProperty:"name" flags:0
512: value:name length:(strlen( name) + 1)];
513:
514: newDev = [[IOTreeDevice alloc] initAt:propTable parent:nil ref:nil];
515:
516: MAKE_REG_ENTRY( newEntry, newDev);
517:
518: return( noErr);
519: }
520:
521: //=========================================================================
522:
523: // in NDRVLibrariesAsm.s
524: extern void _eCompareAndSwap( void );
525: extern void _eSynchronizeIO( void );
526:
527: // platform expert
528: extern vm_offset_t
529: PEResidentAddress( vm_offset_t address, vm_size_t length );
530:
531: enum {
532: kProcessorCacheModeDefault = 0,
533: kProcessorCacheModeInhibited = 1,
534: kProcessorCacheModeWriteThrough = 2,
535: kProcessorCacheModeCopyBack = 3
536: };
537:
538: OSStatus _eSetProcessorCacheMode( UInt32 space, void * addr, UInt32 len, UInt32 mode )
539: {
540: struct phys_entry* pp;
541: vm_offset_t spa;
542: vm_offset_t epa;
543: int wimg;
544:
545: // This doesn't change any existing kernel mapping eg. BAT changes etc.
546: // but this is enough to change user level mappings for DPS etc.
547: // Should use a kernel service when one is available.
548:
549: spa = kvtophys( (vm_offset_t)addr);
550: if( spa == 0) {
551: spa = PEResidentAddress( (vm_offset_t)addr, len);
552: if( spa == 0)
553: return( IO_R_VM_FAILURE);
554: }
555: epa = (len + spa + 0xfff) & 0xfffff000;
556: spa &= 0xfffff000;
557:
558: switch( mode) {
559: case kProcessorCacheModeWriteThrough:
560: wimg = PTE_WIMG_WT_CACHED_COHERENT_GUARDED;
561: break;
562: case kProcessorCacheModeCopyBack:
563: wimg = PTE_WIMG_CB_CACHED_COHERENT_GUARDED;
564: break;
565: default:
566: wimg = PTE_WIMG_UNCACHED_COHERENT_GUARDED;
567: break;
568: }
569:
570: while( spa < epa) {
571: pp = pmap_find_physentry(spa);
572: if (pp != PHYS_NULL)
573: pp->pte1.bits.wimg = wimg;
574: spa += PAGE_SIZE;
575: }
576: _eSynchronizeIO();
577: return( noErr);
578: }
579:
580: char * _ePStrCopy( char *to, const char *from )
581: {
582: UInt32 len;
583: char * copy;
584:
585: copy = to;
586: len = *(from++);
587: *(copy++) = len;
588: bcopy( from, copy, len);
589: return( to);
590: }
591:
592: LogicalAddress _ePoolAllocateResident(ByteCount byteSize, Boolean clear)
593: {
594: LogicalAddress mem;
595:
596: mem = IOMalloc( byteSize );
597: if( clear && mem)
598: memset( mem, 0, byteSize);
599:
600: return( mem);
601: }
602:
603: OSStatus _ePoolDeallocate( void )
604: {
605: LOG("_ePoolDeallocate\n");
606: return( noErr);
607: }
608:
609: UInt32 _eCurrentExecutionLevel(void)
610: {
611: return(0); // kTaskLevel, HWInt = 6
612: }
613:
614: // don't expect any callers of this
615: OSErr _eIOCommandIsComplete( UInt32 commandID, OSErr result )
616: {
617: LOG("_eIOCommandIsComplete\n");
618: return( result);
619: }
620:
621: //=========================================================================
622:
623: #include <mach/clock_types.h>
624: #include <kern/clock.h>
625:
626:
627: tvalspec_t _eUpTime( void )
628: {
629: return( clock_get_counter( System));
630: }
631:
632: tvalspec_t _eAddAbsoluteToAbsolute(tvalspec_t left, tvalspec_t right)
633: {
634: tvalspec_t result = left;
635:
636: ADD_TVALSPEC( &left, &right)
637: return( result);
638: }
639:
640:
641: tvalspec_t _eSubAbsoluteFromAbsolute(tvalspec_t left, tvalspec_t right)
642: {
643: tvalspec_t result = left;
644:
645: // !! ATI bug fix here:
646: // They expect the 64-bit result to be signed. The spec says < 0 => 0
647: // To workaround, make sure this routine takes 10 us to execute.
648: IODelay( 10);
649:
650: SUB_TVALSPEC( &result, &right)
651: if( ((int)result.tv_sec) < 0) {
652: result.tv_sec = 0;
653: result.tv_nsec = 0;
654: }
655: return( result);
656: }
657:
658:
659: tvalspec_t _eDurationToAbsolute( Duration theDuration)
660: {
661: tvalspec_t tval;
662:
663: if( theDuration > 0) {
664: tval.tv_sec = theDuration / 1000;
665: tval.tv_nsec = (theDuration % 1000) * 1000 * 1000;
666:
667: } else {
668: tval.tv_sec = (-theDuration) / 1000000;
669: tval.tv_nsec = (-theDuration % 1000000) * 1000;
670: }
671: return( tval);
672: }
673:
674: tvalspec_t _eAddDurationToAbsolute( Duration duration, tvalspec_t absolute )
675: {
676: return( _eAddAbsoluteToAbsolute(_eDurationToAbsolute( duration), absolute));
677: }
678:
679: tvalspec_t _eNanosecondsToAbsolute ( UnsignedWide theNanoseconds)
680: {
681: tvalspec_t tval;
682:
683: if( theNanoseconds.hi == 0) {
684: tval.tv_sec = theNanoseconds.lo / NSEC_PER_SEC;
685: tval.tv_nsec = theNanoseconds.lo % NSEC_PER_SEC;
686: } else {
687: // overflows?
688: tval.tv_sec = 4 * theNanoseconds.hi;
689: tval.tv_sec += ((294967296 * theNanoseconds.hi) + theNanoseconds.lo) / NSEC_PER_SEC;
690: tval.tv_nsec = ((294967296 * theNanoseconds.hi) + theNanoseconds.lo) % NSEC_PER_SEC;
691: }
692: return( tval);
693: }
694:
695: UnsignedWide _eAbsoluteToNanoseconds( tvalspec_t absolute )
696: {
697: UnsignedWide nano;
698:
699: if( absolute.tv_sec == 0) {
700: nano.hi = 0;
701: nano.lo = absolute.tv_nsec;
702: } else {
703: nano.lo = absolute.tv_nsec + (absolute.tv_sec * NSEC_PER_SEC);
704: nano.hi = (absolute.tv_sec / 4);
705: }
706: return( nano);
707: }
708:
709: Duration _eAbsoluteDeltaToDuration( tvalspec_t left, tvalspec_t right )
710: {
711: Duration dur;
712: tvalspec_t result;
713:
714: if( CMP_TVALSPEC( &left, &right) < 0)
715: return( 0);
716:
717: result = left;
718: SUB_TVALSPEC( &result, &right)
719:
720: if( result.tv_sec >= 2147) {
721: if( result.tv_sec >= 2147483)
722: return( 0x7fffffff);
723: dur = result.tv_sec * 1000 + result.tv_nsec / 1000000; // ms
724: } else {
725: dur = -(result.tv_sec * 1000000 + result.tv_nsec / 1000); // us
726: }
727: return( dur);
728: }
729:
730:
731: OSStatus _eDelayForHardware( tvalspec_t time )
732: {
733: tvalspec_t deadline, now;
734:
735: deadline = time;
736: now = _eUpTime();
737: ADD_TVALSPEC( &deadline, &now);
738:
739: while( CMP_TVALSPEC( &deadline, &now) > 0) {
740: now = _eUpTime();
741: }
742:
743: return( noErr);
744: }
745:
746: OSStatus _eDelayFor( Duration theDuration )
747: {
748: #if 1
749:
750: // In Marconi, DelayFor uses the old toolbox Delay routine
751: // which is based on the 60 Hz timer. Durations are not
752: // rounded up when converting to ticks. Yes, really.
753: // There is some 64-bit math there so we'd better reproduce
754: // the overhead of that calculation.
755:
756: #define DELAY_FOR_TICK_NANO 16666666
757: #define DELAY_FOR_TICK_MILLI 17
758: #define NANO32_MILLI 4295
759:
760: UnsignedWide nano;
761: tvalspec_t abs;
762: unsigned int ms;
763:
764: abs = _eDurationToAbsolute( theDuration);
765: nano = _eAbsoluteToNanoseconds( abs);
766:
767: ms = (nano.lo / DELAY_FOR_TICK_NANO) * DELAY_FOR_TICK_MILLI;
768: ms += nano.hi * NANO32_MILLI;
769: if( ms)
770: IOSleep( ms);
771:
772: #else
773: // Accurate, but incompatible, version
774:
775: #define SLEEP_THRESHOLD 5000
776:
777: if( theDuration < 0) {
778:
779: // us duration
780: theDuration -= theDuration;
781: if( theDuration > SLEEP_THRESHOLD)
782: IOSleep( (theDuration + 999) / 1000);
783: else
784: IODelay( theDuration);
785:
786: } else {
787:
788: // ms duration
789: if( theDuration > (SLEEP_THRESHOLD / 1000))
790: IOSleep( theDuration ); // ms
791: else
792: IODelay( theDuration * 1000); // us
793: }
794: #endif
795:
796: return( noErr);
797: }
798:
799:
800: //=========================================================================
801:
802: SInt32 StdIntHandler( InterruptSetMember setMember, void *refCon, UInt32 theIntCount)
803: {
804: return( kIsrIsComplete);
805: }
806: void StdIntEnabler( InterruptSetMember setMember, void *refCon)
807: {
808: return;
809: }
810: Boolean StdIntDisabler( InterruptSetMember setMember, void *refCon)
811: {
812: return( false);
813: }
814:
815: static TVector _eStdIntHandler = { StdIntHandler, 0 };
816: static TVector _eStdIntEnabler = { StdIntEnabler, 0 };
817: static TVector _eStdIntDisabler = { StdIntDisabler, 0 };
818:
819: OSStatus
820: _eGetInterruptFunctions( id setID,
821: UInt32 member,
822: void * * refCon,
823: TVector ** handler,
824: TVector ** enabler,
825: TVector ** disabler )
826: {
827: OSStatus err = noErr;
828:
829: if( handler)
830: *handler = &_eStdIntHandler;
831: if( enabler)
832: *enabler = &_eStdIntEnabler;
833: if( disabler)
834: *disabler = &_eStdIntDisabler;
835:
836: return( err);
837: }
838:
839: OSStatus
840: _eInstallInterruptFunctions(id setID,
841: UInt32 member,
842: void * refCon,
843: TVector * handler,
844: TVector * enabler,
845: TVector * disabler )
846: {
847: OSStatus err = noErr;
848:
849: return( err);
850: }
851:
852: //=========================================================================
853:
854: extern void PowerSurgeSendIIC( unsigned char iicAddr, unsigned char iicReg, unsigned char iicData);
855:
856: OSStatus _eCallOSTrapUniversalProc( UInt32 theProc, UInt32 procInfo, UInt32 trap, UInt8 * pb )
857: {
858: OSStatus err = -40;
859:
860: if( (procInfo == 0x133822)
861: && (trap == 0xa092) ) {
862:
863: UInt8 addr, reg, data;
864:
865: addr = pb[ 2 ];
866: reg = pb[ 3 ];
867: pb = *( (UInt8 **) ((UInt32) pb + 8));
868: data = pb[ 1 ];
869: PowerSurgeSendIIC( addr, reg, data );
870: err = 0;
871: }
872: return( err);
873: }
874:
875: const UInt32 * _eGetKeys( void )
876: {
877: static const UInt32 zeros[] = { 0, 0, 0, 0 };
878:
879: return( zeros);
880: }
881:
882: UInt32 _eGetIndADB( void * adbInfo, UInt32 index )
883: {
884: bzero( adbInfo, 10);
885: return( 0); // orig address
886: }
887:
888: //=========================================================================
889:
890: OSStatus _eNoErr( void )
891: {
892: return( noErr);
893: }
894:
895: OSStatus _eFail( void )
896: {
897: return( -40);
898: }
899:
900: //=========================================================================
901:
902: // fix this!
903:
904: #define heathrowID ((volatile UInt32 *)0xf3000034)
905: #define heathrowTermEna (1 << 3)
906: #define heathrowTermDir (1 << 0)
907:
908: #define heathrowFeatureControl ((volatile UInt32 *)0xf3000038)
909: #define heathrowMBRES (1 << 24)
910:
911: #define heathrowBrightnessControl ((volatile UInt8 *)0xf3000032)
912: #define defaultBrightness 144
913: #define heathrowContrastControl ((volatile UInt8 *)0xf3000033)
914: #define defaultContrast 183
915:
916: #define gossamerSystemReg1 ((volatile UInt16 *)0xff000004)
917: #define gossamerAllInOne (1 << 4)
918:
919: void _eATISetMBRES( UInt32 state )
920: {
921: UInt32 value;
922:
923: value = *heathrowFeatureControl;
924:
925: if( state == 0)
926: value &= ~heathrowMBRES;
927: else if( state == 1)
928: value |= heathrowMBRES;
929:
930: *heathrowFeatureControl = value;
931: eieio();
932: }
933:
934: void _eATISetMonitorTermination( Boolean enable )
935: {
936:
937: UInt32 value;
938:
939: value = *heathrowID;
940:
941: value |= heathrowTermEna;
942: if( enable)
943: value |= heathrowTermDir;
944: else
945: value &= ~heathrowTermDir;
946:
947: *heathrowID = value;
948: eieio();
949: }
950:
951: Boolean _eATIIsAllInOne( void )
952: {
953: Boolean rtn;
954:
955: rtn = (0 == ((*gossamerSystemReg1) & gossamerAllInOne));
956: if( rtn) {
957: *heathrowBrightnessControl = defaultBrightness;
958: eieio();
959: *heathrowContrastControl = defaultContrast;
960: eieio();
961: }
962: return( rtn);
963: }
964:
965: //=========================================================================
966:
967:
968: static FunctionEntry PCILibFuncs[] =
969: {
970: { "ExpMgrConfigReadLong", _eExpMgrConfigReadLong },
971: { "ExpMgrConfigReadWord", _eExpMgrConfigReadWord },
972: { "ExpMgrConfigReadByte", _eExpMgrConfigReadByte },
973: { "ExpMgrConfigWriteLong", _eExpMgrConfigWriteLong },
974: { "ExpMgrConfigWriteWord", _eExpMgrConfigWriteWord },
975: { "ExpMgrConfigWriteByte", _eExpMgrConfigWriteByte },
976:
977: { "ExpMgrIOReadLong", _eExpMgrIOReadLong },
978: { "ExpMgrIOReadWord", _eExpMgrIOReadWord },
979: { "ExpMgrIOReadByte", _eExpMgrIOReadByte },
980: { "ExpMgrIOWriteLong", _eExpMgrIOWriteLong },
981: { "ExpMgrIOWriteWord", _eExpMgrIOWriteWord },
982: { "ExpMgrIOWriteByte", _eExpMgrIOWriteByte },
983:
984: { "EndianSwap16Bit", _eEndianSwap16Bit },
985: { "EndianSwap32Bit", _eEndianSwap32Bit }
986: };
987:
988: static FunctionEntry VideoServicesLibFuncs[] =
989: {
990: { "VSLPrepareCursorForHardwareCursor", _eFail },
991: { "VSLNewInterruptService", _eNoErr },
992: { "VSLDisposeInterruptService", _eNoErr },
993: { "VSLDoInterruptService", _eNoErr }
994: };
995:
996: static FunctionEntry NameRegistryLibFuncs[] =
997: {
998: { "RegistryEntryIDCopy", _eRegistryEntryIDCopy },
999: { "RegistryEntryIDInit", _eRegistryEntryIDInit },
1000: { "RegistryEntryIDDispose", _eNoErr },
1001: { "RegistryEntryIDCompare", _eRegistryEntryIDCompare },
1002: { "RegistryPropertyGetSize", _eRegistryPropertyGetSize },
1003: { "RegistryPropertyGet", _eRegistryPropertyGet },
1004: { "RegistryPropertyGetMod", _eRegistryPropertyGetMod },
1005: { "RegistryPropertySetMod", _eRegistryPropertySetMod },
1006:
1007: { "RegistryPropertyIterateCreate", _eRegistryPropertyIterateCreate },
1008: { "RegistryPropertyIterateDispose", _eRegistryPropertyIterateDispose },
1009: { "RegistryPropertyIterate", _eRegistryPropertyIterate },
1010:
1011: { "RegistryEntryIterateCreate", _eRegistryEntryIterateCreate },
1012: { "RegistryEntryIterateDispose", _eRegistryEntryIterateDispose },
1013: { "RegistryEntryIterate", _eRegistryEntryIterate },
1014: { "RegistryCStrEntryToName", _eRegistryCStrEntryToName },
1015:
1016: { "RegistryCStrEntryCreate", _eRegistryCStrEntryCreate },
1017: { "RegistryEntryDelete", _eNoErr },
1018:
1019: { "RegistryPropertyCreate", _eRegistryPropertyCreate },
1020: { "RegistryPropertyDelete", _eRegistryPropertyDelete },
1021: { "RegistryPropertySet", _eRegistryPropertySet }
1022: };
1023:
1024:
1025: static FunctionEntry DriverServicesLibFuncs[] =
1026: {
1027: { "SynchronizeIO", _eSynchronizeIO },
1028: { "SetProcessorCacheMode", _eSetProcessorCacheMode },
1029: { "BlockCopy", bcopy },
1030: { "BlockMove", bcopy },
1031: { "CStrCopy", strcpy },
1032: { "CStrCmp", strcmp },
1033: { "CStrLen", strlen },
1034: { "CStrCat", strcat },
1035: { "CStrNCopy", strncpy },
1036: { "CStrNCmp", strncmp },
1037: { "CStrNCat", strncat },
1038: { "PStrCopy", _ePStrCopy },
1039:
1040: { "PoolAllocateResident", _ePoolAllocateResident },
1041: { "MemAllocatePhysicallyContiguous", _ePoolAllocateResident },
1042: { "PoolDeallocate", _ePoolDeallocate },
1043:
1044: { "UpTime", _eUpTime },
1045: { "AbsoluteDeltaToDuration", _eAbsoluteDeltaToDuration },
1046: { "AddAbsoluteToAbsolute", _eAddAbsoluteToAbsolute },
1047: { "SubAbsoluteFromAbsolute", _eSubAbsoluteFromAbsolute },
1048: { "AddDurationToAbsolute", _eAddDurationToAbsolute },
1049: { "NanosecondsToAbsolute", _eNanosecondsToAbsolute },
1050: { "AbsoluteToNanoseconds", _eAbsoluteToNanoseconds },
1051: { "DurationToAbsolute", _eDurationToAbsolute },
1052: { "DelayForHardware", _eDelayForHardware },
1053: { "DelayFor", _eDelayFor },
1054:
1055: { "CurrentExecutionLevel", _eCurrentExecutionLevel },
1056: { "IOCommandIsComplete", _eIOCommandIsComplete },
1057:
1058: { "SysDebugStr", _eNoErr },
1059: { "SysDebug", _eNoErr },
1060:
1061: { "CompareAndSwap", _eCompareAndSwap },
1062:
1063: { "CreateInterruptSet", _eNoErr },
1064: { "DeleteInterruptSet", _eNoErr },
1065: { "GetInterruptFunctions", _eGetInterruptFunctions },
1066: { "InstallInterruptFunctions", _eNoErr }
1067:
1068: };
1069:
1070: static FunctionEntry ATIUtilsFuncs[] =
1071: {
1072: // Gossamer onboard ATI
1073: { "ATISetMBRES", _eATISetMBRES },
1074: { "ATISetMonitorTermination", _eATISetMonitorTermination },
1075: { "ATIIsAllInOne", _eATIIsAllInOne }
1076: };
1077:
1078:
1079: // These are all out of spec
1080:
1081: static FunctionEntry InterfaceLibFuncs[] =
1082: {
1083: // Apple drivers : XPRam and EgretDispatch
1084: { "CallUniversalProc", _eFail },
1085: { "CallOSTrapUniversalProc", _eCallOSTrapUniversalProc },
1086:
1087: // Radius PrecisionColor 16
1088:
1089: { "CountADBs", _eNoErr },
1090: { "GetIndADB", _eGetIndADB },
1091: { "GetKeys", _eGetKeys }
1092: };
1093:
1094:
1095: #define NUMLIBRARIES 6
1096: const ItemCount numLibraries = NUMLIBRARIES;
1097: LibraryEntry Libraries[ NUMLIBRARIES ] =
1098: {
1099: { "PCILib", sizeof(PCILibFuncs) / sizeof(FunctionEntry), PCILibFuncs },
1100: { "VideoServicesLib", sizeof(VideoServicesLibFuncs) / sizeof(FunctionEntry), VideoServicesLibFuncs },
1101: { "NameRegistryLib", sizeof(NameRegistryLibFuncs) / sizeof(FunctionEntry), NameRegistryLibFuncs },
1102: { "DriverServicesLib", sizeof(DriverServicesLibFuncs) / sizeof(FunctionEntry), DriverServicesLibFuncs },
1103:
1104: // G3
1105: { "ATIUtils", sizeof(ATIUtilsFuncs) / sizeof(FunctionEntry), ATIUtilsFuncs },
1106:
1107: // out of spec stuff
1108: { "InterfaceLib", sizeof(InterfaceLibFuncs) / sizeof(FunctionEntry), InterfaceLibFuncs }
1109: };
1110:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.