Annotation of driverkit/libDriver/Kernel/generalFuncsPrivate.m, revision 1.1

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: /*     Copyright (c) 1991 NeXT Computer, Inc.  All rights reserved. 
        !            25:  *
        !            26:  * generalFuncsPrivate.m - Kernel internal (KERNEL_PRIVATE) portion of 
        !            27:  * generalFuncs module.
        !            28:  *
        !            29:  * HISTORY
        !            30:  * 31-Oct-91    Doug Mitchell at NeXT
        !            31:  *      Created.
        !            32:  */
        !            33: 
        !            34: #define ARCH_PRIVATE   1
        !            35: 
        !            36: #import <mach/mach_types.h>
        !            37: 
        !            38: #import <objc/objc.h> 
        !            39: #import <driverkit/generalFuncs.h>
        !            40: #import <driverkit/kernelDriver.h>
        !            41: #import <stdarg.h>
        !            42: #import <kern/sched.h>
        !            43: #import <machkit/NXLock.h>
        !            44: #import <machine/param.h>
        !            45: 
        !            46: #import <mach/vm_param.h>
        !            47: 
        !            48: extern void    *_io_vm_task(void *);
        !            49: extern void    *_io_vm_task_self(void);
        !            50: extern void    *_io_vm_task_pmap(vm_task_t     task);
        !            51: extern void    *_io_vm_task_current(void);
        !            52: extern void    *_io_vm_task_buf(void *);
        !            53: extern void    *_io_convert_port_in(port_t port);
        !            54: extern port_t  _io_convert_port_out(void *kport);
        !            55: extern port_t  _io_host_priv_self(void);
        !            56: extern void    *_io_get_kern_port(port_name_t port);
        !            57: extern port_name_t     _io_task_get_port(void *kport);
        !            58: 
        !            59:        
        !            60: 
        !            61: 
        !            62: /*
        !            63:  * Static variables for this module.
        !            64:  */
        !            65: static IOThreadFunc threadArgFcn;
        !            66: static void *threadArgArg;
        !            67: static int libInitialized;
        !            68: 
        !            69: /*
        !            70:  * globals shared with libDriver's libIO.m and the kern_dev server.
        !            71:  */
        !            72: port_name_t IOTask;                    // IOTask's version of its own 
        !            73:                                        //    task_t
        !            74: task_t IOTask_kern;                    // kernel internal version of IOTask
        !            75: 
        !            76: static id threadArgLock;               // NXLock 
        !            77: 
        !            78: 
        !            79: #ifdef DEBUG
        !            80: extern void iotaskTest();
        !            81: #endif DEBUG;
        !            82: 
        !            83: /*
        !            84:  * Local prototypes.
        !            85:  */
        !            86: static void ioThreadStart();
        !            87: 
        !            88: void IOInitGeneralFuncs(void)
        !            89: {
        !            90:        if(libInitialized) {
        !            91:                return; 
        !            92:        }
        !            93: 
        !            94:        threadArgLock = [NXLock new];
        !            95: 
        !            96:        libInitialized = 1;
        !            97: }
        !            98: 
        !            99: /*
        !           100:  * We pass an argument to a new thread by saving fcn and arg in some
        !           101:  * locked variables and starting the thread at ioThreadStart(). This
        !           102:  * function retrives fcn and arg and makes the appropriate call.
        !           103:  *
        !           104:  * Note in the kernel, IOThread == thread_t. 
        !           105:  */
        !           106: IOThread IOForkThread(IOThreadFunc fcn, void *arg)
        !           107: {
        !           108:        IOThread thread;
        !           109:        /*
        !           110:         * We do the lock, ioThreadStart() does the unlock.
        !           111:         */
        !           112:        [threadArgLock lock];
        !           113:        threadArgFcn = fcn;
        !           114:        threadArgArg = arg;
        !           115:        thread = (IOThread)kernel_thread(IOTask_kern, ioThreadStart);
        !           116:        (void) thread_priority(thread, MAXPRI_USER, FALSE);
        !           117:        return(thread);
        !           118: }
        !           119: 
        !           120: /*
        !           121:  * All kernel IOThreads start here.
        !           122:  */
        !           123: static void ioThreadStart()
        !           124: {
        !           125:        IOThreadFunc fcn = threadArgFcn;
        !           126:        void *arg = threadArgArg;
        !           127: 
        !           128:        [threadArgLock unlock];
        !           129:        
        !           130:        (void) thread_wire(1, (thread_t)current_thread_EXTERNAL(), TRUE);
        !           131: 
        !           132:        (*fcn)(arg);
        !           133:        
        !           134:        /*
        !           135:         * And just in case...
        !           136:         */
        !           137:        IOExitThread();
        !           138: }
        !           139: 
        !           140: IOReturn
        !           141: IOSetThreadPriority(IOThread iothread, int priority)
        !           142: {
        !           143:     thread_t           thread = (thread_t)iothread;
        !           144:     kern_return_t      result;
        !           145:     
        !           146:     result = thread_priority(thread, priority, FALSE);
        !           147:     if (result == KERN_INVALID_ARGUMENT)
        !           148:        return (IO_R_INVALID_ARG);
        !           149:     else if (result == KERN_FAILURE)
        !           150:        return (IO_R_PRIVILEGE);
        !           151:        
        !           152:     return (IO_R_SUCCESS);
        !           153: }
        !           154: 
        !           155: IOReturn
        !           156: IOSetThreadPolicy(IOThread iothread, int policy)
        !           157: {
        !           158:     thread_t           thread = (thread_t)iothread;
        !           159:     int                        policy_data;
        !           160:     kern_return_t      result;
        !           161:     
        !           162:     if (policy == POLICY_FIXEDPRI)
        !           163:        policy_data = min_quantum;
        !           164:     else
        !           165:        policy_data = 0;
        !           166:     
        !           167:     result = thread_policy(thread, policy, policy_data);
        !           168:     if (result == KERN_INVALID_ARGUMENT)
        !           169:        return (IO_R_INVALID_ARG);
        !           170:     else if (result == KERN_FAILURE)
        !           171:        return (IO_R_PRIVILEGE);
        !           172:        
        !           173:     return (IO_R_SUCCESS);
        !           174: }
        !           175: 
        !           176: void IOSuspendThread(IOThread thread)
        !           177: {
        !           178:        thread_suspend((thread_t)thread);
        !           179: }
        !           180: 
        !           181: void IOResumeThread(IOThread thread)
        !           182: {
        !           183:        thread_resume((thread_t)thread);
        !           184: }
        !           185: 
        !           186: volatile void IOExitThread()
        !           187: {
        !           188:        thread_terminate((thread_t)current_thread_EXTERNAL());
        !           189:        (volatile void)thread_halt_self(); 
        !           190: }
        !           191: 
        !           192: 
        !           193: /*
        !           194:  * This returns the kernel's map under the assumption that this function 
        !           195:  * is called in preparation for setting up a DMA via IOEnqueueDmaInt(). 
        !           196:  * The IOTask itself can not access memory in its vm_map (IOTask_kern->map).
        !           197:  * For actual VM operations using the Mach API, use task_self().
        !           198:  */
        !           199: vm_task_t IOVmTaskSelf()
        !           200: {
        !           201:        return((vm_task_t)_io_vm_task_self());
        !           202: }
        !           203: 
        !           204: /*
        !           205:  * Returns the current task's vm_task_t.
        !           206:  */
        !           207: vm_task_t IOVmTaskCurrent()
        !           208: {
        !           209: 
        !           210:        return ((vm_task_t)_io_vm_task_current());
        !           211: }
        !           212: 
        !           213: /*
        !           214:  * Set the current thread's UNIX errno.
        !           215:  */
        !           216: void IOSetUNIXError(int errno)
        !           217: {
        !           218: #warning u.u_error passing disabled
        !           219: #if 0
        !           220:        u.u_error = errno;
        !           221: #endif 0
        !           222: }
        !           223:  
        !           224: /*
        !           225:  * Get an IOTask version of a kern_port_t. 
        !           226:  */
        !           227: port_name_t IOTaskGetPort(port_t kern_port)
        !           228: {
        !           229:        void *                  kport = (void *)kern_port;
        !           230: 
        !           231:        return (_io_task_get_port(kport));
        !           232: }
        !           233: 
        !           234: /* 
        !           235:  * Get a kern_port_t version of an IOTask port.
        !           236:  */
        !           237: port_t IOGetKernPort(port_name_t userPort)
        !           238: {
        !           239:        return ((port_t)_io_get_kern_port(userPort));
        !           240: }
        !           241: 
        !           242: 
        !           243: /*
        !           244:  * Convert any kind of port to any other kind.
        !           245:  * Returns PORT_NULL on error.
        !           246:  */
        !           247: port_t IOConvertPort(port_t inPort,    // to be converted
        !           248:        IOIPCSpace from,                // IPC space of inPort
        !           249:        IOIPCSpace to)                  // IPCSpace of returned port
        !           250: {
        !           251:        void *          inPortKern;
        !           252:        port_t          outPort;
        !           253:        
        !           254:        /*
        !           255:         * First get a kern_port_t version of inPort.
        !           256:         */
        !           257:        switch(from) {
        !           258:            case IO_Kernel:
        !           259:                inPortKern = (void *)inPort;
        !           260:                break;
        !           261:            case IO_KernelIOTask:
        !           262:                inPortKern = (void *)IOGetKernPort(inPort);
        !           263:                break;
        !           264:            case IO_CurrentTask:
        !           265:                        inPortKern = _io_convert_port_in(inPort);
        !           266:                if(!inPortKern) {
        !           267:                        IOLog("IOConvertPort: Bad Port\n");
        !           268:                        return PORT_NULL;
        !           269:                }
        !           270:                break;
        !           271:        }
        !           272:        
        !           273:        /*
        !           274:         * Now convert as appropriate.
        !           275:         */
        !           276:        switch(to) {
        !           277:            case IO_Kernel:
        !           278:                outPort = (port_t)inPortKern;
        !           279:                break;
        !           280:            case IO_KernelIOTask:
        !           281:                outPort = IOTaskGetPort((port_t)inPortKern);
        !           282:                break;
        !           283:            case IO_CurrentTask:
        !           284:                outPort = _io_convert_port_out(inPortKern);
        !           285:                break;
        !           286:        }
        !           287:        return outPort;
        !           288: }
        !           289: 
        !           290: /*
        !           291:  * Returns vm_task_t associated with a struct buf. 
        !           292:  */
        !           293: vm_task_t IOVmTaskForBuf(struct buf *buf)
        !           294: {
        !           295:        return ((vm_task_t)_io_vm_task_buf(buf));
        !           296: }
        !           297: 
        !           298: /*
        !           299:  * Obtain the IOTask version of host_priv_self() (the privileged host port).
        !           300:  */
        !           301: 
        !           302: port_t IOHostPrivSelf()
        !           303: {
        !           304:        return (_io_host_priv_self());
        !           305: }
        !           306: 
        !           307: /*
        !           308:  *  Find a physical address (if any) for the specified virtual address.
        !           309:  */
        !           310: IOReturn IOPhysicalFromVirtual(vm_task_t task, 
        !           311:        vm_address_t virtualAddress,
        !           312:        unsigned *physicalAddress)
        !           313: {
        !           314:        *physicalAddress = pmap_extract(_io_vm_task_pmap(task),
        !           315:                virtualAddress);
        !           316:        if(*physicalAddress == 0) {
        !           317:                return IO_R_INVALID_ARG;
        !           318:        }
        !           319:        else {
        !           320:                return IO_R_SUCCESS;
        !           321:        }
        !           322: }
        !           323: 
        !           324: /*
        !           325:  * Create a mapping in the IOTask address map
        !           326:  * for the specified physical region.  Assumes
        !           327:  * that the physical memory is already wired.
        !           328:  */
        !           329: IOReturn
        !           330: IOMapPhysicalIntoIOTask(
        !           331:     unsigned           physicalAddress,
        !           332:     unsigned           length,
        !           333:     vm_address_t       *virtualAddressP
        !           334: )
        !           335: {
        !           336:     kern_return_t      result;
        !           337:     vm_offset_t                vAddr;
        !           338:     
        !           339:     result = vm_allocate(_io_vm_task_self(), virtualAddressP, length, TRUE);
        !           340:     if (result != KERN_SUCCESS)
        !           341:        return (IO_R_NO_SPACE);
        !           342:        
        !           343:     vAddr = *virtualAddressP;
        !           344:     vAddr = trunc_page(vAddr);
        !           345:     length = round_page(length);
        !           346:     
        !           347:     physicalAddress = trunc_page(physicalAddress);
        !           348:     
        !           349:     while (length > 0) {
        !           350:        pmap_enter(_io_vm_task_pmap((vm_task_t)_io_vm_task_self()),
        !           351:                vAddr, physicalAddress, VM_PROT_READ|VM_PROT_WRITE, TRUE);
        !           352:                
        !           353:        vAddr += PAGE_SIZE; length -= PAGE_SIZE; physicalAddress += PAGE_SIZE;
        !           354:     }
        !           355:     
        !           356:     return (IO_R_SUCCESS);
        !           357: }
        !           358: 
        !           359: IOReturn
        !           360: IOMapPhysicalIntoIOTaskUnaligned(
        !           361:     unsigned           physicalAddress,
        !           362:     unsigned           length,
        !           363:     vm_address_t       *virtualAddressP
        !           364: )
        !           365: {
        !           366:     IOReturn           result;
        !           367: 
        !           368:     /* Recompute the length based on the actual region requested */
        !           369:     length = round_page(physicalAddress + length) - physicalAddress;
        !           370: 
        !           371:     result = IOMapPhysicalIntoIOTask(physicalAddress, length, virtualAddressP);
        !           372:     if (result == IO_R_SUCCESS) {
        !           373:        /* Now remap the alloced pointer to point to the right place */ 
        !           374:        *virtualAddressP += physicalAddress - trunc_page(physicalAddress);
        !           375:     }
        !           376:     return result;
        !           377: }
        !           378: 
        !           379: /*
        !           380:  * Destroy a mapping created by
        !           381:  * IOTaskCreateVirtualFromPhysical()
        !           382:  */
        !           383: IOReturn
        !           384: IOUnmapPhysicalFromIOTask(
        !           385:     vm_address_t       virtualAddress,
        !           386:     unsigned           length
        !           387: )
        !           388: {
        !           389:     (void) vm_deallocate(_io_vm_task_self(), virtualAddress, length);
        !           390: 
        !           391:     return (IO_R_SUCCESS);
        !           392: }
        !           393: 
        !           394: /* end of generalFuncsPrivate.m */

unix.superglobalmegacorp.com

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