File:  [Apple Darwin 0.x] / driverkit / libDriver / ppc / IONDRVInterface.m
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:37:51 2018 UTC (8 years, 3 months ago) by root
Branches: MAIN, Apple
CVS tags: HEAD, Darwin03, Darwin02
Darwin 0.2 Driver Kit

/*
 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
 * Reserved.  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 1.1 (the "License").  You may not use this file
 * except in compliance with the License.  Please obtain a copy of the
 * License at http://www.apple.com/publicsource 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 OR NON- INFRINGEMENT.  Please see the
 * License for the specific language governing rights and limitations
 * under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
/*
 * Copyright (c) 1997 Apple Computer, Inc.
 *
 *
 * HISTORY
 *
 * Simon Douglas  22 Oct 97
 * - first checked in.
 */



#import  <driverkit/ppc/IOTreeDevice.h>
#import "IOPEFLoader.h"
#import "IONDRVInterface.h"

#define LOG	if(1) kprintf

struct NDRVInstanceVars {
    PCodeInstance 	pcInst;
};
typedef struct NDRVInstanceVars NDRVInstanceVars;


OSStatus    NDRVLoad( LogicalAddress container, ByteCount containerSize, NDRVInstance * instance )
{
    NDRVInstanceVars *	ndrvInst;
    OSStatus            err;

    ndrvInst = (NDRVInstanceVars *) IOMalloc( sizeof( NDRVInstanceVars));

    err = PCodeOpen( container, containerSize, &ndrvInst->pcInst );

    if( err == noErr)
	err = PCodeInstantiate( ndrvInst->pcInst );

    *instance = ndrvInst;

    return( err);
}

OSStatus    NDRVGetSymbol( NDRVInstance instance, const char * symbolName, LogicalAddress * address )
{
    NDRVInstanceVars  * ndrvInst = (NDRVInstanceVars *) instance;
    OSStatus            err;

    err = PCodeFindExport( ndrvInst->pcInst, symbolName, address, NULL );
    return( err);
}

OSStatus    NDRVGetShimClass( id ioDevice, NDRVInstance instance, UInt32 serviceIndex, char * className )
{
    NDRVInstanceVars  * 	ndrvInst = (NDRVInstanceVars *) instance;
    OSStatus            	err;
    static const char *		driverDescProperty = "TheDriverDescription";
    static const char *		frameBufferShim = "IONDRVFramebuffer";
    DriverDescription * 	desc;
    UInt32			serviceType;

    className[ 0 ] = 0;
    do {
	err = PCodeFindExport( ndrvInst->pcInst, driverDescProperty, (LogicalAddress *)&desc, NULL );
        if( err) continue;

	if( desc->driverDescSignature != kTheDescriptionSignature) {
	    err = -1;
	    continue;
	}
	if( serviceIndex >= desc->driverServices.nServices) {
	    err = -1;
	    continue;
	}

	serviceType = desc->driverServices.service[ serviceIndex ].serviceType;
	switch( desc->driverServices.service[ serviceIndex ].serviceCategory) {

	    case kServiceCategoryNdrvDriver:
		if( serviceType == kNdrvTypeIsVideo) {
                    strcpy( className, frameBufferShim);
		    break;
		}
	    default:
		err = -1;
	}
    } while( false);

    return( err);
}

OSStatus    NDRVUnload( NDRVInstance * instance )
{
    return( noErr);
}


OSStatus    NDRVDoDriverIO( LogicalAddress entry,
		UInt32 commandID, void * contents, UInt32 commandCode, UInt32 commandKind )
{
    OSStatus            	err;

#if 1

    fpu_save_thread();
    err = CallTVector( /*AddressSpaceID*/ 0, (void *)commandID, contents,
		(void *)commandCode, (void *)commandKind, /*p6*/ 0, entry );
    fpu_disable_thread();

#else

static	LogicalAddress	stack = NULL;		// FIXME

    if( stack == NULL)
	stack = (LogicalAddress) ( IOMalloc( 32768) + 32768 );

    fpu_save();
    err = CallTVectorWithStack( /*AddressSpaceID*/ 0, (void *)commandID, contents,
		(void *)commandCode, (void *)commandKind, /*p6*/ 0, entry, stack);
    fpu_disable();

#endif

#if 0
    if( err) {
	UInt32 i;
	static const char * commands[] = 
		{ "kOpenCommand", "kCloseCommand", "kReadCommand", "kWriteCommand",
		"kControlCommand", "kStatusCommand", "kKillIOCommand", "kInitializeCommand",
		"kFinalizeCommand", "kReplaceCommand", "kSupersededCommand" };

	LOG("Driver failed (%d) on %s : ", err, commands[ commandCode ] );

	switch( commandCode) {
	    case kControlCommand:
	    case kStatusCommand:
		LOG("%d : ", ((UInt16 *)contents)[ 0x1a / 2 ]);
		contents = ((void **)contents)[ 0x1c / 4 ];
		for( i = 0; i<5; i++ )
		    LOG("%08x, ", ((UInt32 *)contents)[i] );
		break;
	}
	LOG("\n");
    }
#endif

    return( err);
}

// autoconf_ppc comes here for matching
BOOL
NDRVForDevice( IOTreeDevice * ioDevice )
{
    OSStatus		err;
    NDRVInstance	instance;
    LogicalAddress	pef;
    IOByteCount		propSize;
    static const char * pefPropertyName = "driver,AAPL,MacOS,PowerPC";
    IOPropertyTable   *	propTable = [ioDevice propertyTable];
    char		classNames[ 80 ];


    if( NO == [ioDevice isKindOf:[IOTreeDevice class]] )
        return( NO);

#if 0
    // to test code aligning
    err = [propTable getProperty:pefPropertyName flags:kReferenceProperty
                value:nil length:&propSize];
    if( err == noErr) {
	pef = IOMalloc( propSize);
	err = [propTable getProperty:pefPropertyName flags:0
		    value:&pef length:&propSize];
    }
#else
    err = [propTable getProperty:pefPropertyName flags:kReferenceProperty
                value:&pef length:&propSize];
#endif

    // God awful hack:
    // Some onboard devices don't have the ndrv in the tree. The new booter
    // can load & match PEF's but only from disk, not network boots.

    if( err && (strcmp( [ioDevice nodeName], "ATY,mach64_3DU") == 0) ) {

        unsigned int * patch;

        patch = (unsigned int *) 0xffe88140;
        propSize = 0x10a80;

	// Check ati PEF exists there
        if( patch[ 0x1f0 / 4 ] == 'ATIU') {

            pef = (LogicalAddress) IOMalloc( propSize );
            bcopy( (void *) patch, pef, propSize );
            err = noErr;
        }
    }

    if( err && (strcmp( [ioDevice nodeName], "ATY,mach64_3DUPro") == 0) ) {

        unsigned int * patch;

        patch = (unsigned int *) 0xffe99510;
        propSize = 0x12008;

	// Check ati PEF exists there
        if( patch[ 0x1fc / 4 ] == 'ATIU') {

            pef = (LogicalAddress) IOMalloc( propSize );
            bcopy( (void *) patch, pef, propSize );
            err = noErr;
        }
    }

    if( err && (strcmp( [ioDevice nodeName], "control") == 0) ) {

#define ins(i,d,a,simm) ((i<<26)+(d<<21)+(a<<16)+simm)
        unsigned int * patch;

        patch = (unsigned int *) 0xffe6bd50;
        propSize = 0xac10;

	// Check control PEF exists there
        if( patch[ 0x41ac / 4 ] == ins( 32, 3, 0, 0x544)) {	// lwz r3,0x544(0)

            pef = (LogicalAddress) IOMalloc( propSize );
            bcopy( (void *) patch, pef, propSize );
            patch = (unsigned int *) pef;
	    // patch out low mem accesses
            patch[ 0x8680 / 4 ] = ins( 14, 12, 0, 0);		// addi r12,0,0x0
            patch[ 0x41ac / 4 ] = ins( 14, 3, 0, 0x544);	// addi r3,0,0x544;
            patch[ 0x8fa0 / 4 ] = ins( 14, 3, 0, 0x648);	// addi r3,0,0x648;
            err = noErr;
        }
    }

    if( err == noErr) {
        do {
            if(	(err = NDRVLoad( pef, propSize, &instance ))
            ) continue;
            [propTable createProperty:"AAPL,ndrvInst" flags:0
                value:&instance length:sizeof( NDRVInstance)];
            if(	(err = NDRVGetShimClass( ioDevice, instance, 0, classNames ))
            ) continue;

            err = [propTable createProperty:"AAPL,dk_Driver Name" flags:0
                        value:classNames length:strlen( classNames) ];
            err = [propTable createProperty:"AAPL,dk_Server Name" flags:0
                        value:classNames length:strlen( classNames) ];

            return( YES);

        } while( false);
    }

    return( NO);
}



unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.