|
|
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) 1998 Apple Computer, Inc. All rights reserved.
24: *
25: * HISTORY
26: *
27: * 14 Aug 98 sdouglas created.
28: * 08 Dec 98 sdouglas cpp.
29: */
30:
31: #define IOFRAMEBUFFER_PRIVATE
32: #include <IOKit/graphics/IOFramebufferShared.h>
33: #include <IOKit/IOLib.h>
34: #include <libkern/c++/OSContainers.h>
35: #include <IOKit/IOBufferMemoryDescriptor.h>
36:
37: #include <IOKit/IOPlatformExpert.h>
38:
39: #include <IOKit/assert.h>
40:
41: #include "IOFramebufferUserClient.h"
42:
43: #include <IOKit/graphics/IOGraphicsEngine.h>
44:
45:
46: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
47:
48: #undef super
49: #define super IOUserClient
50:
51: OSDefineMetaClassAndStructors(IOFramebufferUserClient, IOUserClient)
52:
53: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
54:
55: IOFramebufferUserClient * IOFramebufferUserClient::withTask( task_t owningTask )
56: {
57: IOFramebufferUserClient * inst;
58:
59: inst = new IOFramebufferUserClient;
60:
61: if( inst && !inst->init()) {
62: inst->release();
63: inst = 0;
64: }
65:
66: return( inst );
67: }
68:
69: bool IOFramebufferUserClient::start( IOService * _owner )
70: {
71: static const IOExternalMethod methodTemplate[] = {
72: /* 0 */ { NULL, NULL, kIOUCScalarIScalarO, 3, 0 },
73: /* 1 */ { NULL, NULL, kIOUCScalarIStructO, 3, sizeof( IOPixelInformation) },
74: /* 2 */ { NULL, NULL, kIOUCScalarIScalarO, 0, 2 },
75: /* 3 */ { NULL, NULL, kIOUCScalarIScalarO, 2, 0 },
76: /* 4 */ { NULL, NULL, kIOUCScalarIScalarO, 2, 0 },
77: /* 5 */ { NULL, NULL, kIOUCScalarIStructO,
78: 1, sizeof( IODisplayModeInformation) },
79: /* 6 */ { NULL, NULL, kIOUCScalarIScalarO, 0, 1 },
80: /* 7 */ { NULL, NULL, kIOUCStructIStructO, 0, 0xffffffff },
81: /* 8 */ { NULL, NULL, kIOUCScalarIScalarO, 1, 1 },
82: /* 9 */ { NULL, NULL, kIOUCStructIStructO, sizeof( Bounds), 0 },
83: /* 10 */ { NULL, NULL, kIOUCScalarIScalarO, 3, 0 },
84: /* 11 */ { NULL, NULL, kIOUCScalarIStructI, 3, 0xffffffff },
85: /* 12 */ { NULL, NULL, kIOUCScalarIScalarO, 1, 0 },
86: /* 13 */ { NULL, NULL, kIOUCScalarIScalarO, 2, 0 },
87: /* 14 */ { NULL, NULL, kIOUCScalarIScalarO, 0, 0 },
88: /* 15 */ { NULL, NULL, kIOUCScalarIStructI, 1, 0xffffffff },
89: /* 16 */ { NULL, NULL, kIOUCScalarIStructI, 2, 0xffffffff },
90:
91: };
92:
93: if( !super::start( _owner ))
94: return( false);
95:
96: owner = (IOFramebuffer *) _owner;
97:
98: assert( sizeof( methodTemplate) == sizeof( externals));
99: bcopy( methodTemplate, externals, sizeof( externals ));
100:
101: externals[0].object = owner;
102: externals[0].func = (IOMethod) &IOFramebuffer::createSharedCursor;
103:
104: externals[1].object = owner;
105: externals[1].func = (IOMethod) &IOFramebuffer::getPixelInformation;
106:
107: externals[2].object = owner;
108: externals[2].func = (IOMethod) &IOFramebuffer::getCurrentDisplayMode;
109:
110: externals[3].object = owner;
111: externals[3].func = (IOMethod) &IOFramebuffer::setStartupDisplayMode;
112:
113: externals[4].object = owner;
114: externals[4].func = (IOMethod) &IOFramebuffer::extSetDisplayMode;
115:
116: externals[5].object = owner;
117: externals[5].func =
118: (IOMethod) &IOFramebuffer::extGetInformationForDisplayMode;
119:
120: externals[6].object = owner;
121: externals[6].func = (IOMethod) &IOFramebuffer::extGetDisplayModeCount;
122:
123: externals[7].object = owner;
124: externals[7].func = (IOMethod) &IOFramebuffer::extGetDisplayModes;
125:
126: externals[8].object = owner;
127: externals[8].func = (IOMethod) &IOFramebuffer::extGetVRAMMapOffset;
128:
129: externals[9].object = owner;
130: externals[9].func = (IOMethod) &IOFramebuffer::extSetBounds;
131:
132: externals[10].object = owner;
133: externals[10].func = (IOMethod) &IOFramebuffer::extSetNewCursor;
134:
135: externals[11].object = owner;
136: externals[11].func = (IOMethod) &IOFramebuffer::setGammaTable;
137:
138: externals[12].object = owner;
139: externals[12].func = (IOMethod) &IOFramebuffer::extSetCursorVisible;
140:
141: externals[13].object = owner;
142: externals[13].func = (IOMethod) &IOFramebuffer::extSetCursorPosition;
143:
144: externals[14].object = this;
145: externals[14].func = (IOMethod) &IOFramebufferUserClient::acknowledgeNotification;
146:
147: externals[15].object = owner;
148: externals[15].func = (IOMethod) &IOFramebuffer::extSetColorConvertTable;
149:
150: externals[16].object = owner;
151: externals[16].func = (IOMethod) &IOFramebuffer::extSetCLUTWithEntries;
152:
153: owner->serverConnect = this;
154:
155: current_power_state = owner->registerInterestedDriver(this);
156: owner->disallowPowerDown();
157: return( true );
158: }
159:
160:
161: IOReturn
162: IOFramebufferUserClient::acknowledgeNotification( void )
163: {
164: return( owner->acknowledgePowerChange(this));
165: }
166:
167: // If the frame buffer is being powered down, tell the window server.
168: IOReturn
169: IOFramebufferUserClient::powerStateWillChangeTo (IOPMPowerFlags newState, unsigned long, IOService* )
170: {
171: kern_return_t r;
172: mach_msg_header_t *msgh;
173:
174: if ( (current_power_state & IOPMDeviceUsable) && ! (newState & IOPMDeviceUsable) ) {
175: msgh = (mach_msg_header_t *)notificationMsg;
176: if( msgh && WSnotificationPort ) {
177: msgh->msgh_id = 0;
178: r = mach_msg_send_from_kernel( msgh, msgh->msgh_size);
179: }
180: current_power_state = newState;
181: return 10000000; // WS will ack within ten seconds
182: }
183: return IOPMAckImplied;
184: }
185:
186:
187: // If the frame buffer has been powered up, tell the window server.
188: IOReturn
189: IOFramebufferUserClient::powerStateDidChangeTo (IOPMPowerFlags newState, unsigned long, IOService* )
190: {
191: kern_return_t r;
192: mach_msg_header_t *msgh;
193:
194: if ( !(current_power_state & IOPMDeviceUsable) && (newState & IOPMDeviceUsable) ) {
195: msgh = (mach_msg_header_t *)notificationMsg;
196: if( msgh && WSnotificationPort ) {
197: msgh->msgh_id = 1;
198: r = mach_msg_send_from_kernel( msgh, msgh->msgh_size);
199: }
200: current_power_state = newState;
201: return 10000000; // WS will ack within ten seconds
202: }
203: return IOPMAckImplied;
204: }
205:
206:
207: IOReturn IOFramebufferUserClient::registerNotificationPort(
208: mach_port_t port,
209: UInt32 type,
210: UInt32 refCon )
211: {
212: static mach_msg_header_t init_msg = {
213: // mach_msg_bits_t msgh_bits;
214: MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,0),
215: // mach_msg_size_t msgh_size;
216: sizeof (mach_msg_header_t),
217: // mach_port_t msgh_remote_port;
218: MACH_PORT_NULL,
219: // mach_port_t msgh_local_port;
220: MACH_PORT_NULL,
221: // mach_msg_size_t msgh_reserved;
222: 0,
223: // mach_msg_id_t msgh_id;
224: 0
225: };
226:
227: if ( notificationMsg == NULL )
228: notificationMsg = IOMalloc( sizeof (mach_msg_header_t) );
229: // Initialize the power state change notification message.
230: *((mach_msg_header_t *)notificationMsg) = init_msg;
231:
232: ((mach_msg_header_t *)notificationMsg)->msgh_remote_port = port;
233:
234: WSnotificationPort = port;
235: owner->allowPowerDown();
236: return( kIOReturnSuccess);
237: }
238:
239: IOReturn IOFramebufferUserClient::getNotificationSemaphore(
240: UInt32 interruptType, semaphore_t * semaphore )
241: {
242: return( owner->getNotificationSemaphore(interruptType, semaphore) );
243: }
244:
245: // The window server is going away.
246: // We disallow power down to prevent idle sleep while the console is running.
247: IOReturn IOFramebufferUserClient::clientClose( void )
248: {
249: owner->close();
250: if( owner->isConsoleDevice())
251: getPlatform()->setConsoleInfo( 0, kPEAcquireScreen);
252:
253: owner->deRegisterInterestedDriver(this);
254: owner->disallowPowerDown();
255: if( notificationMsg)
256: IOFree( notificationMsg, sizeof (mach_msg_header_t));
257: owner->serverConnect = 0;
258: WSnotificationPort = NULL;
259: detach( owner);
260:
261: return( kIOReturnSuccess);
262: }
263:
264: IOService * IOFramebufferUserClient::getService( void )
265: {
266: return( owner );
267: }
268:
269: IOReturn IOFramebufferUserClient::clientMemoryForType( UInt32 type,
270: IOOptionBits * flags, IOMemoryDescriptor ** memory )
271: {
272: IOMemoryDescriptor * mem;
273: IOReturn err;
274:
275: switch( type) {
276:
277: case kIOFBCursorMemory:
278: mem = owner->sharedCursor;
279: mem->retain();
280: break;
281:
282: case kIOFBVRAMMemory:
283: mem = owner->getVRAMRange();
284: break;
285:
286: default:
287: mem = (IOMemoryDescriptor *) owner->userAccessRanges->getObject( type );
288: mem->retain();
289: break;
290: }
291:
292: *memory = mem;
293: if( mem)
294: err = kIOReturnSuccess;
295: else
296: err = kIOReturnBadArgument;
297:
298: return( err );
299: }
300:
301: IOExternalMethod * IOFramebufferUserClient::getExternalMethodForIndex( UInt32 index )
302: {
303: if( index < (sizeof( externals) / sizeof( externals[0])))
304: return( externals + index);
305: else
306: return( NULL);
307: }
308:
309:
310: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
311:
312: OSDefineMetaClassAndStructors(IOGraphicsEngineClient, IOUserClient)
313:
314: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
315:
316: IOGraphicsEngineClient * IOGraphicsEngineClient::withTask( task_t owningTask )
317: {
318: IOGraphicsEngineClient * inst;
319:
320: inst = new IOGraphicsEngineClient;
321:
322: if( inst && !inst->init()) {
323: inst->release();
324: inst = 0;
325: }
326: if( inst)
327: inst->owningTask = owningTask;
328:
329: return( inst );
330: }
331:
332: bool IOGraphicsEngineClient::start( IOService * _owner )
333: {
334:
335: static const IOExternalMethod methodTemplate[] = {
336: /* 0 */ { NULL, NULL, kIOUCScalarIScalarO, 3, 1 },
337: /* 1 */ { NULL, NULL, kIOUCScalarIScalarO, 2, 2 },
338: /* 2 */ { NULL, NULL, kIOUCScalarIScalarO, 3, 2 },
339: /* 3 */ { NULL, NULL, kIOUCScalarIScalarO, 1, 0 },
340: };
341:
342: IOGraphicsEngineContext * mem;
343: IOByteCount size;
344:
345: if( !super::start( _owner ))
346: return( false);
347:
348: owner = (IOFramebuffer *) _owner;
349: agpDev = OSDynamicCast( IOAGPDevice, owner->getProvider());
350: descriptors = OSArray::withCapacity( 1 );
351:
352: bcopy( methodTemplate, externals, sizeof( methodTemplate ));
353:
354: externals[0].object = this;
355: externals[0].func = (IOMethod) &IOGraphicsEngineClient::addUserRange;
356: externals[1].object = this;
357: externals[1].func = (IOMethod) &IOGraphicsEngineClient::createAGPSpace;
358: externals[2].object = this;
359: externals[2].func = (IOMethod) &IOGraphicsEngineClient::commitAGPMemory;
360: externals[3].object = this;
361: externals[3].func = (IOMethod) &IOGraphicsEngineClient::releaseAGPMemory;
362:
363: if( 0 == owner->engineContext) {
364:
365: size = round_page( sizeof( IOGraphicsEngineContext));
366: owner->engineContext = IOBufferMemoryDescriptor::withCapacity(
367: size, kIODirectionNone, false );
368: if( !owner->engineContext)
369: return( kIOReturnNoMemory );
370: owner->engineContext->setLength( size );
371:
372: mem = (IOGraphicsEngineContext *)
373: owner->engineContext->getBytesNoCopy();
374: memset((char *)mem, 0, size);
375: mem->version = kIOGraphicsEngineContextVersion;
376: mem->structSize = size;
377: }
378:
379: return( true );
380: }
381:
382: void IOGraphicsEngineClient::free()
383: {
384: if( descriptors)
385: descriptors->free();
386:
387: if( agpDev && haveAGP)
388: agpDev->destroyAGPSpace();
389:
390: super::free();
391: }
392:
393: IOReturn IOGraphicsEngineClient::clientClose( void )
394: {
395: detach( owner );
396:
397: return( kIOReturnSuccess);
398: }
399:
400: IOService * IOGraphicsEngineClient::getService( void )
401: {
402: return( owner );
403: }
404:
405: IOReturn IOGraphicsEngineClient::clientMemoryForType( UInt32 type,
406: IOOptionBits * options, IOMemoryDescriptor ** memory )
407: {
408: IOMemoryDescriptor * mem;
409:
410: switch( type) {
411: case kIOGraphicsEngineContext:
412: mem = owner->engineContext;
413: break;
414: default:
415: mem = (IOMemoryDescriptor *) owner->engineAccessRanges->getObject( type );
416: break;
417: }
418:
419: if( mem) {
420: mem->retain();
421: *memory = mem;
422: return( kIOReturnSuccess);
423: } else
424: return( kIOReturnBadArgument);
425: }
426:
427: IOExternalMethod * IOGraphicsEngineClient::getExternalMethodForIndex( UInt32 index )
428: {
429: if( index < (sizeof( externals) / sizeof( externals[0])))
430: return( externals + index);
431: else
432: return( NULL);
433: }
434:
435: IOReturn IOGraphicsEngineClient::addUserRange( vm_address_t start,
436: vm_size_t length, UInt32 apertureIndex, IOPhysicalAddress * phys )
437: {
438: IODeviceMemory * mem;
439: IOReturn err = kIOReturnSuccess;
440: OSArray * ranges;
441: int i;
442: IODeviceMemory * aperture
443: = owner->getProvider()->getDeviceMemoryWithIndex( apertureIndex );
444:
445: if( 0 == aperture)
446: return( kIOReturnBadArgument );
447:
448: ranges = owner->engineAccessRanges;
449: i = 0;
450: while( (mem = (IODeviceMemory *) ranges->getObject( i++ ))) {
451: if( (mem->getPhysicalAddress() ==
452: (start + aperture->getPhysicalAddress()))
453: && (length <= mem->getLength()) )
454: break;
455: }
456:
457: if( 0 == mem) {
458: mem = IODeviceMemory::withSubRange(
459: aperture, start, length );
460: if( mem) {
461: owner->engineAccessRanges->setObject( mem );
462: err = kIOReturnSuccess;
463: } else
464: err = kIOReturnNoResources;
465: }
466:
467: if( kIOReturnSuccess == err)
468: *phys = mem->getPhysicalAddress();
469:
470: return( err );
471: }
472:
473: IOReturn IOGraphicsEngineClient::createAGPSpace( IOOptionBits options,
474: IOPhysicalLength length,
475: IOPhysicalAddress * address,
476: IOPhysicalLength * lengthOut )
477: {
478: IOReturn err;
479:
480: if( !agpDev)
481: return( kIOReturnUnsupported );
482:
483: *lengthOut = length;
484: err = agpDev->createAGPSpace( options, address, lengthOut );
485: haveAGP = (kIOReturnSuccess == err);
486:
487: return( err );
488: }
489:
490: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
491:
492: class _IOGraphicsClientMemory : public OSObject {
493: OSDeclareDefaultStructors(_IOGraphicsClientMemory)
494: public:
495: IOMemoryDescriptor * memory;
496: IOAGPDevice * agpDev;
497: IOByteCount agpOffset;
498:
499: virtual bool init();
500: virtual void free();
501: };
502:
503: OSDefineMetaClassAndStructors(_IOGraphicsClientMemory, OSObject)
504:
505: bool _IOGraphicsClientMemory::init()
506: {
507: return( OSObject::init());
508: }
509:
510: void _IOGraphicsClientMemory::free()
511: {
512: if( memory) {
513: agpDev->getAGPRangeAllocator()->deallocate( agpOffset,
514: memory->getLength() );
515: memory->complete();
516: memory->release();
517: }
518:
519: OSObject::free();
520: }
521:
522: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
523:
524: IOReturn IOGraphicsEngineClient::commitAGPMemory( vm_address_t start,
525: vm_size_t length, IOOptionBits options,
526: void ** ref, IOByteCount * offset )
527: {
528: _IOGraphicsClientMemory * graphicsMem;
529: IORangeAllocator * rangeAllocator;
530: IOByteCount agpOffset;
531: IOReturn err = kIOReturnNoMemory;
532: bool ok;
533:
534: if( !agpDev)
535: return( kIOReturnUnsupported );
536: if( (!start) || (!length))
537: return( kIOReturnBadArgument );
538: rangeAllocator = agpDev->getAGPRangeAllocator();
539: if( !rangeAllocator)
540: return( kIOReturnUnsupported );
541:
542: do {
543: graphicsMem = new _IOGraphicsClientMemory;
544: if( (!graphicsMem) || (!graphicsMem->init()))
545: continue;
546:
547: ok = rangeAllocator->allocate( length, (IORangeScalar *) &agpOffset );
548: if( !ok) {
549: err = kIOReturnNoSpace;
550: continue;
551: }
552:
553: graphicsMem->agpDev = agpDev;
554: graphicsMem->agpOffset = agpOffset;
555:
556: graphicsMem->memory = IOMemoryDescriptor::withAddress( start, length,
557: kIODirectionOut, owningTask );
558: if( !graphicsMem->memory)
559: continue;
560:
561: err = graphicsMem->memory->prepare();
562: if( err != kIOReturnSuccess)
563: continue;
564:
565: err = agpDev->commitAGPMemory( graphicsMem->memory, agpOffset );
566: if( err != kIOReturnSuccess)
567: continue;
568:
569: *ref = (void *) descriptors->getCount();
570: *offset = agpOffset;
571: descriptors->setObject( graphicsMem );
572:
573: } while( false );
574:
575: if( graphicsMem)
576: graphicsMem->release();
577:
578: if( (kIOReturnSuccess != err) && (!graphicsMem))
579: rangeAllocator->deallocate( agpOffset, length );
580:
581: return( err );
582: }
583:
584: IOReturn IOGraphicsEngineClient::releaseAGPMemory( void * ref )
585: {
586: _IOGraphicsClientMemory * graphicsMem;
587: UInt32 index = (UInt32) ref;
588:
589: if( 0 == (graphicsMem = (_IOGraphicsClientMemory *)
590: descriptors->getObject( index )))
591: return( kIOReturnBadArgument );
592:
593: descriptors->removeObject( index );
594:
595: return( kIOReturnSuccess );
596: }
597:
598: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
599:
600: OSDefineMetaClassAndStructors(IOFramebufferSharedUserClient, IOUserClient)
601:
602: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
603:
604: IOFramebufferSharedUserClient * IOFramebufferSharedUserClient::withTask(
605: task_t owningTask )
606: {
607: IOFramebufferSharedUserClient * inst;
608:
609: inst = new IOFramebufferSharedUserClient;
610:
611: if( inst && !inst->init()) {
612: inst->release();
613: inst = 0;
614: }
615:
616: return( inst );
617: }
618:
619: bool IOFramebufferSharedUserClient::start( IOService * _owner )
620: {
621:
622: static const IOExternalMethod methodTemplate[] = {
623: };
624:
625: if( !super::start( _owner ))
626: return( false);
627:
628: owner = (IOFramebuffer *) _owner;
629:
630: bcopy( methodTemplate, externals, sizeof( methodTemplate ));
631:
632: return( true );
633: }
634:
635: void IOFramebufferSharedUserClient::free( void )
636: {
637: retain(); retain();
638: owner->sharedConnect = 0;
639: detach( owner);
640: super::free();
641: }
642:
643: void IOFramebufferSharedUserClient::release() const
644: {
645: super::release(2);
646: }
647:
648: IOReturn IOFramebufferSharedUserClient::clientClose( void )
649: {
650: return( kIOReturnSuccess);
651: }
652:
653: IOService * IOFramebufferSharedUserClient::getService( void )
654: {
655: return( owner );
656: }
657:
658: IOReturn IOFramebufferSharedUserClient::clientMemoryForType( UInt32 type,
659: IOOptionBits * options, IOMemoryDescriptor ** memory )
660: {
661: IOMemoryDescriptor * mem = 0;
662: IOReturn err;
663:
664: switch( type) {
665:
666: case kIOFBCursorMemory:
667: mem = owner->sharedCursor;
668: mem->retain();
669: *options = kIOMapReadOnly;
670: break;
671:
672: case kIOFBVRAMMemory:
673: mem = owner->getVRAMRange();
674: break;
675: }
676:
677: *memory = mem;
678: if( mem)
679: err = kIOReturnSuccess;
680: else
681: err = kIOReturnBadArgument;
682:
683: return( err );
684: }
685:
686: IOReturn IOFramebufferSharedUserClient::getNotificationSemaphore(
687: UInt32 interruptType, semaphore_t * semaphore )
688: {
689: return( owner->getNotificationSemaphore(interruptType, semaphore) );
690: }
691:
692: IOExternalMethod * IOFramebufferSharedUserClient::getExternalMethodForIndex( UInt32 index )
693: {
694: if( index < (sizeof( externals) / sizeof( externals[0])))
695: return( externals + index);
696: else
697: return( NULL);
698: }
699:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.