1/* 2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24cc Tests.c -o tests -lIOKit -Wno-four-char-constants -fno-rtti -fno-exceptions -fcheck-new -fvtable-thunks 25*/ 26 27#include <ctype.h> 28#include <stdlib.h> 29#include <assert.h> 30#include <limits.h> 31 32 33#include <mach/mach_interface.h> 34#include <mach/vm_region.h> 35#include <mach/thread_switch.h> 36 37 38/* 39 */ 40 41#define OLDCONNECT 0 42#define TRAP 1 43 44#include <mach/clock_types.h> 45#include <IOKit/IOKitLib.h> 46#include <IOKit/hidsystem/IOHIDShared.h> 47//#include <dev/evio.h> 48#include <IOKit/graphics/IOFramebufferShared.h> 49 50#include <IOKit/graphics/IOGraphicsEngine.h> 51 52EvGlobals * evg; 53StdFBShmem_t * fbshmem; 54mach_port_t masterPort; 55unsigned int clock_freq; 56 57/* 58 */ 59 60inline UInt64 CFReadTSR() { 61 union { 62 UInt64 time64; 63 UInt32 word[2]; 64 } now; 65 66 /* Read from PowerPC 64-bit time base register. The increment */ 67 /* rate of the time base is implementation-dependent, but is */ 68 /* 1/4th the bus clock cycle on 603/604/750 processors. */ 69 UInt32 t3; 70 do { 71 __asm__ volatile("mftbu %0" : "=r" (now.word[0])); 72 __asm__ volatile("mftb %0" : "=r" (now.word[1])); 73 __asm__ volatile("mftbu %0" : "=r" (t3)); 74 } while (now.word[0] != t3); 75 76 return now.time64; 77} 78 79void getClockFrequency( void ) 80{ 81 kern_return_t kr; 82 unsigned int size; 83 io_registry_entry_t root; 84 85 assert( ( 86 root = IORegistryEntryFromPath( masterPort, "IODeviceTree:/" ) 87 )); 88 89 size = sizeof( clock_freq ); 90 assert( KERN_SUCCESS == ( 91 kr = IORegistryEntryGetProperty( root, "clock-frequency", (char *)&clock_freq, &size ) 92 )); 93 assert( size == sizeof( clock_freq )); 94 95 printf("clock-frequency = %d\n", clock_freq); 96 97 IOObjectRelease( root ); 98} 99 100void printElapsed( UInt64 start, UInt64 end ) 101{ 102#define numer 1000 103#define divisor 1000 104 printf("elapsed %d us\n", (int)((end - start) / (clock_freq / divisor / 4 ) * numer )); 105} 106 107void AccelTests( int reset, int count ) 108{ 109 io_iterator_t iter; 110 io_service_t fb; 111 io_name_t name; 112 kern_return_t kr; 113 void * blitterRef; 114 int quality, i; 115 int color, x, y; 116 thread_port_t tself; 117 volatile UInt64 start, end; 118 int waited, busy; 119 boolean_t didit; 120 121UInt32 * vars; 122IOGraphicsEngineContext * shmem; 123 124 if( reset) { 125 } 126 if( !count) 127 count = 10000; 128 129 assert( KERN_SUCCESS == ( 130 kr = IOServiceGetMatchingServices( masterPort, 131 IOServiceMatching( IOFRAMEBUFFER_CONFORMSTO ), &iter) 132 )); 133 134 assert( 135 fb = IOIteratorNext( iter ) 136 ); 137 138 assert( KERN_SUCCESS == ( 139 kr = IORegistryEntryGetName( fb, name ) 140 )); 141 142 assert( KERN_SUCCESS == ( 143 kr = IOPSAllocateBlitEngine( fb, &blitterRef, &quality ) 144 )); 145 146#if 0 147vars = (UInt32 *) blitter; 148shmem = (IOGraphicsEngineContext *) vars[ 3 ]; 149srandom( shmem->reserved[0] ); 150 151 tself = random(); 152 x = tself % 600; 153 tself = random(); 154 y = tself % 500; 155 shmem->reserved[0] = tself; 156 157 waited = busy = 0; 158 159 start = CFReadTSR(); 160 for( i = 0; i < count; i++ ) { 161// IOPSBlitFill( blitter, x, y, 200, 200, color ); 162 IOPSBlitInvert( blitter, x, y, 100, 1 ); 163 } 164 IOPSBlitIdle( blitter ); 165 166 end = CFReadTSR(); 167 168// thread_switch( 0, SWITCH_OPTION_WAIT, 2 * 1000 ); 169 170 printf("%s: Count: %d, ", name, count ); 171 printElapsed( start, end ); 172#endif 173 174 if( 1 ) { 175 176 void * burstRef; 177 int count; 178 int i,j = 0, lines; 179 UInt64 start,end; 180 int w = 1280; 181 int h = 100; 182 int bytesPerPixel = 2; 183 int slice = 1; 184 int NUMBLITS = 300; 185 void * fill1; 186 void * fill2; 187 188 count = ((slice * h * bytesPerPixel) + 31) / 32; 189 fill1 = (void *)0x3c0001e0; 190 fill2 = (void *)0x3c0001e0; 191 192 start = CFReadTSR(); 193 194 for( i=0; i < NUMBLITS; i++) { 195 for( j=0; j < w; j += slice) { 196 assert( KERN_SUCCESS == ( 197 kr = IOFBSetupFIFOBurst( blitterRef, j, 200, slice, h, 0, 198 &burstRef ) 199 )); 200 lines = count; 201 while( lines--) 202 IOFBBurstWrite32( fill1, fill2, fill1, fill2, 203 fill1, fill2, fill1, fill2 ); 204 } 205 } 206 207 end = CFReadTSR(); 208 209 { 210 double bytes = w * h * 2 * NUMBLITS; 211 double secs = (end - start); 212 213 secs /= 24932500; 214 215 printf("%d x %d * %d = %qd ticks\n", w, h, NUMBLITS, end - start); 216 printf("%f bytes %f secs, %f Mbytes per sec\n", bytes, secs, 217 bytes / secs / 1024 / 1024); 218 } 219 } 220 221 IOObjectRelease( iter ); 222 IOObjectRelease( fb ); 223} 224 225 226void SetCursor( StdFBShmem_t * fbshmem); 227void SetCursor( StdFBShmem_t * fbshmem) 228{ 229 UInt32 cursor[] = { 230 0x00004000,0x60007000,0x78007C00,0x7E007F00, 231 0x7F807C00,0x6C004600,0x06000300,0x03000000, 232 0xC000E000,0xF000F800,0xFC00FE00,0xFF00FF80, 233 0xFFC0FFE0,0xFE00EF00,0xCF008780,0x07800380, 234 0x00080001, 235 }; 236 UInt32 * dataPtr; 237 UInt32 data, mask; 238 volatile UInt8 * dataOut; 239 int i; 240 241 dataPtr = cursor; 242 dataOut = fbshmem->cursor.bw8.image[0]; 243 for( i = 0; i < 8; i++) { 244 data = *dataPtr++; 245 for( mask = 0x80000000; mask; mask >>= 1) 246 *dataOut++ = (data & mask) ? 0xff : 0x00; 247 } 248 dataOut = fbshmem->cursor.bw8.mask[0]; 249 for( i = 0; i < 8; i++) { 250 data = *dataPtr++; 251 for( mask = 0x80000000; mask; mask >>= 1) 252 *dataOut++ = (data & mask) ? 0xff : 0x00; 253 } 254 data = *dataPtr++; 255 fbshmem->hotSpot[0].x = data >> 16; 256 fbshmem->hotSpot[0].y = data & 0xffff; 257 258 fbshmem->cursorShow = 1; 259} 260 261 262 263void SetupFBandHID( void ) 264{ 265 register kern_return_t kr; 266 mach_port_t ev, fb, enumer, iter; 267 io_name_t name; 268 vm_address_t shmem, vram; 269 vm_size_t shmemSize; 270 int i,j; 271 IODisplayModeID displayMode; 272 IOIndex displayDepth; 273 IOFramebufferInformation fbInfo; 274 IOPixelEncoding format; 275 276#if OLDCONNECT 277 278 assert( KERN_SUCCESS == ( 279 kr = IORegistryCreateEnumerator( masterPort, 280 &enumer) 281 )); 282 283 assert( KERN_SUCCESS == ( 284 kr = IORegistryEnumeratorNextConforming( enumer, 285 (char *) IOFRAMEBUFFER_CONFORMSTO, TRUE) 286 )); 287 288 assert( KERN_SUCCESS == ( 289 kr = IOOpenConnection( enumer, 290 mach_task_self(), 291 kIOFBServerConnectType, 292 &fb) 293 )); 294 295#else 296 assert( KERN_SUCCESS == ( 297 kr = IOServiceGetMatchingServices( masterPort, 298 IOServiceMatching( IOFRAMEBUFFER_CONFORMSTO ), &iter) 299 )); 300 301 assert( 302 enumer = IOIteratorNext( iter ) 303 ); 304 305 assert( KERN_SUCCESS == ( 306 kr = IORegistryEntryGetName( enumer, name ) 307 )); 308 309 printf("Opening %s\n", name); 310 311 assert( KERN_SUCCESS == ( 312 kr = IOServiceOpen( enumer, 313 mach_task_self(), 314 kIOFBServerConnectType, 315 &fb) 316 317 )); 318 319 IOObjectRelease( enumer ); 320 enumer = 0; 321 assert( KERN_SUCCESS == ( 322 kr = IOConnectGetService( fb, &enumer ) 323 )); 324 325 assert( KERN_SUCCESS == ( 326 kr = IORegistryEntryGetName( enumer, name ) 327 )); 328 329 printf("Opened %s\n", name); 330 331 IOObjectRelease( iter ); 332 IOObjectRelease( enumer ); 333#endif 334 335 assert( KERN_SUCCESS == ( 336 kr = IOFBCreateSharedCursor( fb, 337 kIOFBCurrentShmemVersion, 32, 32) 338 )); 339//exit(0); 340 341 assert( KERN_SUCCESS == ( 342 kr = IOFBGetFramebufferInformationForAperture( fb, 0, &fbInfo) 343 )); 344 345 assert( KERN_SUCCESS == ( 346 kr = IOFBGetCurrentDisplayModeAndDepth( fb, 347 &displayMode, &displayDepth) 348 )); 349 350 assert( KERN_SUCCESS == ( 351 kr = IOFBGetPixelFormat( fb, displayMode, displayDepth, 352 kIOFBSystemAperture, &format) 353 )); 354 355 assert( KERN_SUCCESS == ( 356 kr = IOMapMemory( fb, kIOFBCursorMemory, mach_task_self(), 357 &shmem, &shmemSize, TRUE) 358 )); 359 360 fbshmem = (StdFBShmem_t *)shmem; 361 362// assert( sizeof( StdFBShmem_t) == fbshmem->structSize ); 363 SetCursor( fbshmem); 364 365 assert( KERN_SUCCESS == ( 366 kr = IOConnectMapMemory( fb, kIOFBSystemAperture, mach_task_self(), 367 &vram, &shmemSize, kIOMapDefaultCache | kIOMapAnywhere) 368 )); 369 370 assert( KERN_SUCCESS == ( 371 kr = IOConnectMapMemory( fb, kIOFBSystemAperture, mach_task_self(), 372 &vram, &shmemSize, kIOMapCopybackCache | kIOMapAnywhere) 373 )); 374 375 if( 0 ) { 376 printf("%ld x %ld", fbInfo.activeWidth, fbInfo.activeHeight); 377 printf(", \"%s\"", format); 378 printf(", mode %ld-%ld", displayMode, displayDepth); 379 printf(", fbshmem mapped @ %x", fbshmem); 380 printf(", vram mapped @ %x", vram); 381 printf(", hidshmem mapped @ %x\n", kr, evg ); 382 } 383 384 if( 1 ) { 385 unsigned char * bits = (unsigned char *) vram; 386 387 bits += (fbInfo.activeWidth / 2) 388 + fbInfo.bytesPerRow * (fbInfo.activeHeight / 2); 389 for( i=0; i < 128; i++) { 390 for( j=0; j < 128; j++) 391 bits[j] = ((i << 1) & 0xf0) | (j >> 3); 392 bits += fbInfo.bytesPerRow; 393 } 394 } 395 396 if( 0 ) { 397 unsigned char data[ 768 ]; 398 for( i=0; i<256; i++) { 399 data[ i ] = 255 - i; 400 data[ i+ 256 ] = 255 - i; 401 data[ i+ 512 ] = 255 - i; 402 } 403 assert( KERN_SUCCESS == ( 404 kr = IOFBSetGamma( fb, 3, 256, 8, data ) 405 )); 406 } 407 408if(0) { 409 vm_address_t vs = vram; 410 vm_size_t vl; 411 vm_region_basic_info_data_t vminfo; 412 mach_msg_type_number_t len = VM_REGION_BASIC_INFO_COUNT; 413 mach_port_t obj; 414 415 kr = vm_region( mach_task_self(), 416 &vs, &vl, 417 VM_REGION_BASIC_INFO, 418 (vm_region_info_t) &vminfo, 419 &len, 420 &obj ); 421 422 printf("vm_region = %lx, start: %08x, len: %08x\n", kr, vs, vl ); 423 } 424 425#if OLDCONNECT 426 assert( KERN_SUCCESS == ( 427 kr = IORegistryEnumeratorReset( enumer) 428 )); 429 430 assert( KERN_SUCCESS == ( 431 kr = IORegistryEnumeratorNextConforming( enumer, 432 (char *) kIOHIDSystemClass, TRUE) 433 )); 434 435 assert( KERN_SUCCESS == ( 436 kr = IOOpenConnection( enumer, 437 mach_task_self(), 438 kIOFBServerConnectType, 439 &ev) 440 )); 441#else 442 assert( KERN_SUCCESS == ( 443 kr = IOServiceGetMatchingServices( masterPort, 444 IOServiceMatching( kIOHIDSystemClass ), &iter) 445 )); 446 447 assert( 448 enumer = IOIteratorNext( iter ) 449 ); 450 451 assert( KERN_SUCCESS == ( 452 kr = IORegistryEntryGetName( enumer, name ) 453 )); 454 455 printf("Opening %s\n", name); 456 457 assert( KERN_SUCCESS == ( 458 kr = IOServiceOpen( enumer, 459 mach_task_self(), 460 kIOHIDServerConnectType, 461 &ev) 462 )); 463 464 IOObjectRelease( iter ); 465#endif 466 467 assert( KERN_SUCCESS == ( 468 kr = IOHIDCreateSharedMemory( ev, kIOHIDCurrentShmemVersion) 469 )); 470 471 assert( KERN_SUCCESS == ( 472 kr = IOHIDSetEventsEnable( ev, TRUE) 473 )); 474 475 assert( KERN_SUCCESS == ( 476 kr = IORegisterClient( ev, fb) 477 )); 478 479 assert( KERN_SUCCESS == ( 480 kr = IOHIDSetCursorEnable( ev, TRUE) 481 )); 482 483 assert( KERN_SUCCESS == ( 484 kr = IOMapMemory( ev, kIOHIDGlobalMemory, mach_task_self(), 485 &shmem, &shmemSize, TRUE) 486 )); 487 488 evg = (EvGlobals *) 489 (shmem + ((EvOffsets *)shmem)->evGlobalsOffset); 490 491 assert( sizeof( EvGlobals) == evg->structSize ); 492 493// printf("=%d, IOSetNotificationPort\n", kr); 494// kr = IOSetNotificationPort( ev, kIOHIDEventNotification, 495// bootstrap_event_port); 496 497 assert( KERN_SUCCESS == ( 498 kr = IORegistryDisposeEnumerator( enumer) 499 )); 500 501 if( 1 ) { 502 printf("%ld x %ld", fbInfo.activeWidth, fbInfo.activeHeight); 503 printf(", \"%s\"", format); 504 printf(", mode %ld-%ld", displayMode, displayDepth); 505 printf(", fbshmem mapped @ %x", fbshmem); 506 printf(", vram mapped @ %x", vram); 507 printf(", hidshmem mapped @ %x\n", kr, evg ); 508 } 509} 510 511void dumpIter( io_iterator_t iter ) 512{ 513 kern_return_t kr; 514 io_object_t obj; 515 io_name_t name; 516 io_string_t path; 517 518 while( (obj = IOIteratorNext( iter))) { 519 assert( KERN_SUCCESS == ( 520 kr = IORegistryEntryGetName( obj, name ) 521 )); 522 printf("name:%s(%d)\n", name, obj); 523 kr = IORegistryEntryGetPath( obj, "IOService", path ); 524 if( KERN_SUCCESS == kr) 525 // if the object is detached, getPath is expected to fail 526 printf("path:%s\n", path); 527// IOObjectRelease( obj ); 528 } 529} 530 531void regTest( void ) 532{ 533 UInt64 start, end; 534 kern_return_t kr; 535 io_registry_entry_t entry, root; 536 io_iterator_t iter; 537 io_name_t name; 538 539 assert( ( 540 root = IORegistryEntryFromPath( masterPort, kIODeviceTreePlane ":/" ) 541 )); 542 543 assert( KERN_SUCCESS == ( 544 kr = IORegistryEntryGetChildIterator( root, kIODeviceTreePlane, &iter ) 545 )); 546 547 printf("TOT: "); 548 entry = root; 549 do { 550 assert( KERN_SUCCESS == ( 551 kr = IORegistryEntryGetName( entry, name ) 552 )); 553 printf("%s, ", name); 554 IOObjectRelease( entry ); 555 } while( (entry = IOIteratorNext( iter))); 556 printf("\n"); 557 558 IOObjectRelease( iter ); 559 560 assert( KERN_SUCCESS == ( 561 kr = IORegistryCreateIterator( masterPort, kIOServicePlane, TRUE, &iter ) 562 )); 563 564 printf("All service: "); 565 start = CFReadTSR(); 566 dumpIter( iter ); 567 end = CFReadTSR(); 568 569 printElapsed( start, end ); 570 571 IOObjectRelease( iter ); 572} 573 574int 575main(int argc, char **argv) 576{ 577 kern_return_t kr; 578 boolean_t reset = 0; 579 int count = 0; 580 581 /* 582 * Get master device port 583 */ 584 assert( KERN_SUCCESS == ( 585 kr = IOMasterPort( bootstrap_port, 586 &masterPort) 587 )); 588 589// getClockFrequency(); 590// regTest(); 591 592 if( argc > 1) { 593 reset = (0 == strcmp("reset", argv[1])); 594 if( !reset) 595 count = strtol( argv[1], 0, 10 ); 596 } 597 598 AccelTests( reset, count ); 599 600// SetupFBandHID(); 601 602// printf("Done, sleeping...\n"); thread_switch( 0, SWITCH_OPTION_WAIT, 10 * 1000 ); 603 printf("Exit\n"); 604 605} 606 607