/* * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* cc Tests.c -o /tmp/tests -framework IOKit -Wno-four-char-constants -g */ #include #include #include #include #include #include #include /* */ #include #include #include //#include #include #include EvGlobals * evg; StdFBShmem_t * fbshmem; mach_port_t masterPort; unsigned int clock_freq; /* */ inline UInt64 CFReadTSR() { union { UInt64 time64; UInt32 word[2]; } now; /* Read from PowerPC 64-bit time base register. The increment */ /* rate of the time base is implementation-dependent, but is */ /* 1/4th the bus clock cycle on 603/604/750 processors. */ UInt32 t3; #ifdef __ppc__ do { __asm__ volatile("mftbu %0" : "=r" (now.word[0])); __asm__ volatile("mftb %0" : "=r" (now.word[1])); __asm__ volatile("mftbu %0" : "=r" (t3)); } while (now.word[0] != t3); #endif return now.time64; } void getClockFrequency( void ) { kern_return_t kr; unsigned int size; io_registry_entry_t root; assert( ( root = IORegistryEntryFromPath( masterPort, "IODeviceTree:/" ) )); size = sizeof( clock_freq ); assert( KERN_SUCCESS == ( kr = IORegistryEntryGetProperty( root, "clock-frequency", (char *)&clock_freq, &size ) )); assert( size == sizeof( clock_freq )); printf("clock-frequency = %d\n", clock_freq); IOObjectRelease( root ); } void printElapsed( UInt64 start, UInt64 end ) { #define numer 1000 #define divisor 1000 printf("elapsed %d us\n", (int)((end - start) / (clock_freq / divisor / 4 ) * numer )); } void AccelTests( int reset, int count ) { io_iterator_t iter; io_service_t fb; io_name_t name; kern_return_t kr; void * blitter; int quality, i; int color, x, y; thread_port_t tself; volatile UInt64 start, end; int waited, busy; boolean_t didit; UInt32 * vars; IOGraphicsEngineContext * shmem; if( reset) { } if( !count) count = 10000; assert( KERN_SUCCESS == ( kr = IOServiceGetMatchingServices( masterPort, IOServiceMatching( IOFRAMEBUFFER_CONFORMSTO ), &iter) )); assert( fb = IOIteratorNext( iter ) ); assert( KERN_SUCCESS == ( kr = IORegistryEntryGetName( fb, name ) )); assert( KERN_SUCCESS == ( kr = IOPSAllocateBlitEngine( fb, &blitter, &quality ) )); vars = (UInt32 *) blitter; shmem = (IOGraphicsEngineContext *) vars[ 3 ]; srandom( shmem->reserved[0] ); tself = random(); x = tself % 600; tself = random(); y = tself % 500; shmem->reserved[0] = tself; waited = busy = 0; start = CFReadTSR(); for( i = 0; i < count; i++ ) { // IOPSBlitFill( blitter, x, y, 200, 200, color ); IOPSBlitInvert( blitter, x, y, 100, 1 ); } IOPSBlitIdle( blitter ); end = CFReadTSR(); // thread_switch( 0, SWITCH_OPTION_WAIT, 2 * 1000 ); printf("%s: Count: %d, ", name, count ); printElapsed( start, end ); IOObjectRelease( iter ); IOObjectRelease( fb ); } void SetCursor( StdFBShmem_t * fbshmem); void SetCursor( StdFBShmem_t * fbshmem) { UInt32 cursor[] = { 0x00004000,0x60007000,0x78007C00,0x7E007F00, 0x7F807C00,0x6C004600,0x06000300,0x03000000, 0xC000E000,0xF000F800,0xFC00FE00,0xFF00FF80, 0xFFC0FFE0,0xFE00EF00,0xCF008780,0x07800380, 0x00080001, }; UInt32 * dataPtr; UInt32 data, mask; volatile UInt8 * dataOut; int i; dataPtr = cursor; dataOut = fbshmem->cursor.bw8.image[0]; for( i = 0; i < 8; i++) { data = *dataPtr++; for( mask = 0x80000000; mask; mask >>= 1) *dataOut++ = (data & mask) ? 0xff : 0x00; } dataOut = fbshmem->cursor.bw8.mask[0]; for( i = 0; i < 8; i++) { data = *dataPtr++; for( mask = 0x80000000; mask; mask >>= 1) *dataOut++ = (data & mask) ? 0xff : 0x00; } data = *dataPtr++; fbshmem->hotSpot[0].x = data >> 16; fbshmem->hotSpot[0].y = data & 0xffff; fbshmem->cursorShow = 1; } void SetupFBandHID( void ) { register kern_return_t kr; mach_port_t ev, fb, enumer, iter; io_name_t name; vm_address_t shmem, vram; vm_size_t shmemSize; int i,j; IODisplayModeID displayMode; IOIndex displayDepth; IOFramebufferInformation fbInfo; IOPixelEncoding format; assert( KERN_SUCCESS == ( kr = IOServiceGetMatchingServices( masterPort, IOServiceMatching( IOFRAMEBUFFER_CONFORMSTO ), &iter) )); assert( enumer = IOIteratorNext( iter ) ); assert( KERN_SUCCESS == ( kr = IORegistryEntryGetName( enumer, name ) )); printf("Opening %s\n", name); assert( KERN_SUCCESS == ( kr = IOServiceOpen( enumer, mach_task_self(), kIOFBServerConnectType, &fb) )); IOObjectRelease( enumer ); enumer = 0; assert( KERN_SUCCESS == ( kr = IOConnectGetService( fb, &enumer ) )); assert( KERN_SUCCESS == ( kr = IORegistryEntryGetName( enumer, name ) )); printf("Opened %s\n", name); IOObjectRelease( iter ); IOObjectRelease( enumer ); assert( KERN_SUCCESS == ( kr = IOFBCreateSharedCursor( fb, kIOFBCurrentShmemVersion, 32, 32) )); //exit(0); assert( KERN_SUCCESS == ( kr = IOFBGetFramebufferInformationForAperture( fb, 0, &fbInfo) )); assert( KERN_SUCCESS == ( kr = IOFBGetCurrentDisplayModeAndDepth( fb, &displayMode, &displayDepth) )); assert( KERN_SUCCESS == ( kr = IOFBGetPixelFormat( fb, displayMode, displayDepth, kIOFBSystemAperture, &format) )); assert( KERN_SUCCESS == ( kr = IOMapMemory( fb, kIOFBCursorMemory, mach_task_self(), &shmem, &shmemSize, TRUE) )); fbshmem = (StdFBShmem_t *)shmem; // assert( sizeof( StdFBShmem_t) == fbshmem->structSize ); SetCursor( fbshmem); assert( KERN_SUCCESS == ( kr = IOMapMemory( fb, kIOFBSystemAperture, mach_task_self(), &vram, &shmemSize, TRUE) )); if( 0 ) { printf("%ld x %ld", fbInfo.activeWidth, fbInfo.activeHeight); printf(", \"%s\"", format); printf(", mode %ld-%ld", displayMode, displayDepth); printf(", fbshmem mapped @ %x", fbshmem); printf(", vram mapped @ %x", vram); printf(", hidshmem mapped @ %x\n", kr, evg ); } if( 1 ) { unsigned char * bits = (unsigned char *) vram; bits += (fbInfo.activeWidth / 2) + fbInfo.bytesPerRow * (fbInfo.activeHeight / 2); for( i=0; i < 128; i++) { for( j=0; j < 128; j++) bits[j] = ((i << 1) & 0xf0) | (j >> 3); bits += fbInfo.bytesPerRow; } } if( 1 ) { unsigned char data[ 768 ]; for( i=0; i<256; i++) { data[ i ] = 255 - i; data[ i+ 256 ] = 255 - i; data[ i+ 512 ] = 255 - i; } #if 0 assert( KERN_SUCCESS == ( kr = IOFBSetGamma( fb, 3, 256, 8, data ) )); #endif } if(0) { vm_address_t vs = vram; vm_size_t vl; vm_region_basic_info_data_t vminfo; mach_msg_type_number_t len = VM_REGION_BASIC_INFO_COUNT; mach_port_t obj; kr = vm_region( mach_task_self(), &vs, &vl, VM_REGION_BASIC_INFO, (vm_region_info_t) &vminfo, &len, &obj ); printf("vm_region = %lx, start: %08x, len: %08x\n", kr, vs, vl ); } assert( KERN_SUCCESS == ( kr = IOServiceGetMatchingServices( masterPort, IOServiceMatching( kIOHIDSystemClass ), &iter) )); assert( enumer = IOIteratorNext( iter ) ); assert( KERN_SUCCESS == ( kr = IORegistryEntryGetName( enumer, name ) )); printf("Opening %s\n", name); assert( KERN_SUCCESS == ( kr = IOServiceOpen( enumer, mach_task_self(), kIOHIDServerConnectType, &ev) )); IOObjectRelease( iter ); assert( KERN_SUCCESS == ( kr = IOHIDCreateSharedMemory( ev, kIOHIDCurrentShmemVersion) )); assert( KERN_SUCCESS == ( kr = IOHIDSetEventsEnable( ev, TRUE) )); assert( KERN_SUCCESS == ( kr = IORegisterClient( ev, fb) )); assert( KERN_SUCCESS == ( kr = IOHIDSetCursorEnable( ev, TRUE) )); assert( KERN_SUCCESS == ( kr = IOMapMemory( ev, kIOHIDGlobalMemory, mach_task_self(), &shmem, &shmemSize, TRUE) )); evg = (EvGlobals *) (shmem + ((EvOffsets *)shmem)->evGlobalsOffset); assert( sizeof( EvGlobals) == evg->structSize ); // printf("=%d, IOSetNotificationPort\n", kr); // kr = IOSetNotificationPort( ev, kIOHIDEventNotification, // bootstrap_event_port); assert( KERN_SUCCESS == ( kr = IORegistryDisposeEnumerator( enumer) )); if( 1 ) { printf("%ld x %ld", fbInfo.activeWidth, fbInfo.activeHeight); printf(", \"%s\"", format); printf(", mode %ld-%ld", displayMode, displayDepth); printf(", fbshmem mapped @ %x", fbshmem); printf(", vram mapped @ %x", vram); printf(", hidshmem mapped @ %x\n", evg ); } } void dumpIter( io_iterator_t iter ) { kern_return_t kr; io_object_t obj; io_name_t name; io_string_t path; while( (obj = IOIteratorNext( iter))) { assert( KERN_SUCCESS == ( kr = IORegistryEntryGetName( obj, name ) )); printf("name:%s(%d)\n", name, obj); kr = IORegistryEntryGetPath( obj, "IOService", path ); if( KERN_SUCCESS == kr) // if the object is detached, getPath is expected to fail printf("path:%s\n", path); // IOObjectRelease( obj ); } } void regTest( void ) { UInt64 start, end; kern_return_t kr; io_registry_entry_t entry, root; io_iterator_t iter; io_name_t name; assert( ( root = IORegistryEntryFromPath( masterPort, kIODeviceTreePlane ":/" ) )); assert( KERN_SUCCESS == ( kr = IORegistryEntryGetChildIterator( root, kIODeviceTreePlane, &iter ) )); printf("TOT: "); entry = root; do { assert( KERN_SUCCESS == ( kr = IORegistryEntryGetName( entry, name ) )); printf("%s, ", name); IOObjectRelease( entry ); } while( (entry = IOIteratorNext( iter))); printf("\n"); IOObjectRelease( iter ); assert( KERN_SUCCESS == ( kr = IORegistryCreateIterator( masterPort, kIOServicePlane, TRUE, &iter ) )); printf("All service: "); start = CFReadTSR(); dumpIter( iter ); end = CFReadTSR(); printElapsed( start, end ); IOObjectRelease( iter ); } int main(int argc, char **argv) { kern_return_t kr; boolean_t reset = 0; int count = 0; /* * Get master device port */ assert( KERN_SUCCESS == ( kr = IOMasterPort( bootstrap_port, &masterPort) )); // getClockFrequency(); // regTest(); if( argc > 1) { reset = (0 == strcmp("reset", argv[1])); if( !reset) count = strtol( argv[1], 0, 10 ); } // AccelTests( reset, count ); SetupFBandHID(); // printf("Done, sleeping...\n"); thread_switch( 0, SWITCH_OPTION_WAIT, 10 * 1000 ); printf("Exit\n"); }