Annotation of driverkit/libDriver/Kernel/IOBuffer.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: /*
        !            25:  * Copyright 1994 NeXT Computer, Inc.
        !            26:  * All rights reserved.
        !            27:  *
        !            28:  */
        !            29: 
        !            30: #if NOTYET
        !            31: 
        !            32: /* Clean this up later. */
        !            33: #define KERNEL_PRIVATE 1 
        !            34: #define ARCH_PRIVATE   1 
        !            35: 
        !            36: #import <driverkit/IOBuffer.h>
        !            37: #import <driverkit/generalFuncs.h>
        !            38: #import <vm/vm_map.h>
        !            39: #import <mach/vm_param.h>
        !            40: 
        !            41: #define MIN(a,b) ((a) < (b) ? (a) : (b))
        !            42: 
        !            43: /*
        !            44:  * Helper functions
        !            45:  */
        !            46: static BOOL checkAlignmentFromVirtual(
        !            47:     IOVirtualAddress   vaddr,
        !            48:     IOAddressMap       map,
        !            49:     int                        size,
        !            50:     IOAlignment        align
        !            51: );
        !            52: static BOOL checkAlignmentFromPhysical(
        !            53:     IOPhysicalAddress  paddr,
        !            54:     int                        size,
        !            55:     IOAlignment        align
        !            56: );
        !            57: static BOOL checkAlignmentFromSize(
        !            58:     int                        size,
        !            59:     IOAlignment        align
        !            60: );
        !            61: static unsigned int
        !            62: maskFromAlignment(
        !            63:     IOAlignment                align
        !            64: );
        !            65: static unsigned int
        !            66: alignmentFromAddress(
        !            67:     IOVirtualAddress   addr
        !            68: );
        !            69: static void
        !            70: copyData(
        !            71:     IOVirtualAddress src,
        !            72:     IOAddressMap srcMap,
        !            73:     IOVirtualAddress dst,
        !            74:     IOAddressMap dstMap,
        !            75:     unsigned int totalLength
        !            76: );
        !            77: 
        !            78: 
        !            79: 
        !            80: @implementation IOBuffer
        !            81: 
        !            82: -initWithSize:(unsigned int)newSize
        !            83: {
        !            84:     return [self initWithSize:newSize attributes:IOBuf_None
        !            85:             alignment:IOBufferAlignMin];
        !            86: }
        !            87: 
        !            88: -initWithSize:(unsigned int)newSize
        !            89:  attributes:(IOBufferAttributes)newAttrs
        !            90:  alignment:(IOAlignment)align
        !            91: {
        !            92:     if (checkAlignmentFromSize(newSize, align) == NO) {
        !            93:        return nil;
        !            94:     }
        !            95:     
        !            96:     size = newSize;
        !            97:     alignment = align;
        !            98:     if ([[self class] allocMemoryWithSize:newSize
        !            99:                attributes:newAttrs
        !           100:                alignment:align
        !           101:                allocedAddress:&allocedData
        !           102:                dataAddress:(IOVirtualAddress *)&data
        !           103:                allocedSize:&allocedSize
        !           104:                newAttributes:&attributes
        !           105:                newMap:&map] == NO) {
        !           106:        return nil;
        !           107:     }
        !           108: 
        !           109:     attributes = newAttrs | IOBuf_Wired | IOBuf_Contiguous | IOBuf_WiredStatic;
        !           110: 
        !           111:     map = (IOAddressMap)IOVmTaskSelf();
        !           112:     
        !           113:     return self;
        !           114: }
        !           115: 
        !           116: 
        !           117: -initFromVirtualAddress:(IOVirtualAddress)addr
        !           118:  addressMap:(IOAddressMap)newMap
        !           119:  size:(unsigned int)newSize
        !           120: {
        !           121:     data = (void *)addr;
        !           122:     map = newMap;
        !           123: 
        !           124:     alignment = MIN(alignmentFromAddress(addr),
        !           125:                    alignmentFromAddress(newSize));
        !           126:     size = newSize;
        !           127:        
        !           128:     return self;
        !           129: }
        !           130: 
        !           131: 
        !           132: -initFromPhysicalAddress:(IOPhysicalAddress)addr
        !           133:  size:(unsigned int)newSize
        !           134: {
        !           135:     data = (void *)addr;
        !           136:     
        !           137:     alignment = MIN(alignmentFromAddress(addr),
        !           138:                     alignmentFromAddress(newSize));
        !           139:     return nil;
        !           140: }
        !           141: 
        !           142: -free
        !           143: {
        !           144:     (void)[self unwireMemory];
        !           145:     if (allocedData) {
        !           146:        [[self class] freeMemory:allocedData
        !           147:              size:allocedSize
        !           148:              map:map
        !           149:              attributes:attributes];
        !           150:     }
        !           151:     return [super free];
        !           152: }
        !           153: 
        !           154: -(BOOL)copyFromBuffer:(IOBuffer *)sourceBuffer
        !           155: {
        !           156:     int length, sourceSize;
        !           157:     BOOL rtn;
        !           158:     IORange source, dest;
        !           159:     
        !           160:     sourceSize = [sourceBuffer size];
        !           161:     source.size = dest.size = MIN(sourceSize, size);
        !           162:     source.start = dest.start = 0;
        !           163:     rtn = [self copyFromBuffer:sourceBuffer
        !           164:                source:source
        !           165:                destination:dest];
        !           166:     if ((rtn == YES) && (sourceSize < source.size)) {
        !           167:        bzero((char *)data + sourceSize, source.size - sourceSize);
        !           168:     }
        !           169:     return rtn;
        !           170: }
        !           171: 
        !           172: -(BOOL)copyFromBuffer:(IOBuffer *)sourceBuffer
        !           173:        source:(IORange)srcRange
        !           174:        destination:(IORange)dstRange
        !           175: {
        !           176:     int sourceSize, destSize;
        !           177:     IOVirtualRange sourceAddrRange, destAddrRange;
        !           178:     
        !           179:     if ([self isWired] == NO || [sourceBuffer isWired] == NO)
        !           180:        return NO;
        !           181: 
        !           182:     sourceSize = [sourceBuffer size] - srcRange.start;
        !           183:     destSize = [self size] - dstRange.start;
        !           184:     if ((srcRange.size > sourceSize) || (srcRange.size > destSize))
        !           185:        return NO;
        !           186:        
        !           187:     if ([sourceBuffer getVirtualAddress:&sourceAddrRange
        !           188:                      at:srcRange.start] == NO) {
        !           189:        return NO;
        !           190:     }
        !           191:     if ([self getVirtualAddress:&destAddrRange
        !           192:                      at:dstRange.start] == NO) {
        !           193:        return NO;
        !           194:     }
        !           195:     copyData(sourceAddrRange.start, [sourceBuffer addressMap],
        !           196:             destAddrRange.start, map, srcRange.size);
        !           197: 
        !           198:     return YES;
        !           199: }
        !           200: 
        !           201: -(IOAddressMap)addressMap
        !           202: {
        !           203:     return map;
        !           204: }
        !           205: 
        !           206: 
        !           207: -(BOOL)wireMemory
        !           208: {
        !           209:     if ([self isWired])
        !           210:        return YES;
        !           211:     
        !           212:     if (vm_map_pageable(map, trunc_page((char *)data),
        !           213:                             round_page((char *)data + size), FALSE)
        !           214:            == KERN_SUCCESS) {
        !           215:        attributes |= IOBuf_Wired;
        !           216:        return YES;
        !           217:     }
        !           218: 
        !           219:     return NO;
        !           220: }
        !           221: 
        !           222: -(BOOL)unwireMemory
        !           223: {
        !           224:     if ([self isWired] == NO)
        !           225:        return YES;
        !           226:     if (!(attributes & IOBuf_WiredStatic) &&
        !           227:         (vm_map_pageable(map, trunc_page((char *)data),
        !           228:                              round_page((char *)data + size), TRUE)
        !           229:            == KERN_SUCCESS)) {
        !           230:        attributes &= ~IOBuf_Wired;
        !           231:        return YES;
        !           232:     }
        !           233:     return NO;
        !           234: }
        !           235: 
        !           236: -(BOOL)getVirtualAddress:(IOVirtualRange *)virtualRangePtr
        !           237:  at:(unsigned int)offset
        !           238: {
        !           239:     if (offset >= size)
        !           240:        return NO;
        !           241:     if (virtualRangePtr != NULL) {
        !           242:        virtualRangePtr->start = (IOVirtualAddress)((char *)data + offset);
        !           243:        virtualRangePtr->size = size - offset;
        !           244:     }
        !           245:     return YES;
        !           246: }
        !           247: 
        !           248: -(BOOL)getPhysicalAddress:(IOPhysicalRange *)physicalRangePtr
        !           249:  at:(unsigned int)offset
        !           250: {
        !           251:     IOPhysicalAddress paddr;
        !           252:     char *vaddr;
        !           253:     int cbytes = 0;
        !           254:     IOPhysicalAddress nextContPage, nextPhysPage;
        !           255:     char *nextVirtPage, *curVirtPage;
        !           256:     int bytesLeftInPage, curByteCount;
        !           257:     
        !           258:     if ((offset >= size) || ![self isWired])
        !           259:        return NO;
        !           260:        
        !           261:     vaddr = (char *)data + offset;
        !           262:     paddr = (IOPhysicalAddress) pmap_resident_extract(
        !           263:        vm_map_pmap((vm_map_t)map), vaddr);
        !           264: 
        !           265:     if (physicalRangePtr != NULL) {
        !           266:        curByteCount = size - offset;
        !           267:        curVirtPage = (char *)trunc_page(vaddr);
        !           268:        nextContPage = (IOPhysicalAddress)trunc_page(paddr) + PAGE_SIZE;
        !           269:        bytesLeftInPage = nextContPage - paddr;
        !           270:        
        !           271:        while (curByteCount > 0) {
        !           272:            if (bytesLeftInPage >= curByteCount ){
        !           273:                    cbytes += curByteCount;
        !           274:                    break;
        !           275:            } else {
        !           276:                cbytes += bytesLeftInPage;
        !           277: 
        !           278:                nextPhysPage = (IOPhysicalAddress) pmap_resident_extract(
        !           279:                    vm_map_pmap((vm_map_t)map),
        !           280:                    (curVirtPage + PAGE_SIZE));
        !           281: 
        !           282:                if (nextPhysPage == nextContPage){
        !           283:                    curByteCount -= bytesLeftInPage;
        !           284:                    bytesLeftInPage = PAGE_SIZE;
        !           285:                    curVirtPage += PAGE_SIZE;
        !           286:                    nextContPage += PAGE_SIZE;                          
        !           287:                } else {
        !           288:                    break;
        !           289:                }
        !           290:            } 
        !           291:        }
        !           292:     }
        !           293:     if (physicalRangePtr != NULL) {
        !           294:        physicalRangePtr->start = paddr;
        !           295:        physicalRangePtr->size = cbytes;
        !           296:     }
        !           297:     return YES;
        !           298: }
        !           299: 
        !           300: -(IOBufferAttributes)attributes
        !           301: {
        !           302:     return attributes;
        !           303: }
        !           304: 
        !           305: -(BOOL)isContiguous
        !           306: {
        !           307:     return ((attributes & IOBuf_Contiguous) ? YES : NO);
        !           308: }
        !           309: 
        !           310: -(BOOL)isWired
        !           311: {
        !           312:     return ((attributes & IOBuf_Wired) ? YES : NO);
        !           313: }
        !           314: 
        !           315: -(unsigned int)size
        !           316: {
        !           317:     return size;
        !           318: }
        !           319: 
        !           320: -(void *)data
        !           321: {
        !           322:     return data;
        !           323: }
        !           324: 
        !           325: -(IOAlignment)alignment
        !           326: {
        !           327:     return alignment;
        !           328: }
        !           329: 
        !           330: -(IORange)range
        !           331: {
        !           332:     return userRange;
        !           333: }
        !           334: 
        !           335: 
        !           336: -(void)setRange:(IORange)newRange
        !           337: {
        !           338:     userRange = newRange;
        !           339: }
        !           340: 
        !           341: 
        !           342: +(BOOL)allocMemoryWithSize:(int)memSize
        !           343:        attributes:(IOBufferAttributes)attr
        !           344:        alignment:(IOAlignment)align
        !           345:        allocedAddress:(IOVirtualAddress *)allocPtr
        !           346:        dataAddress:(IOVirtualAddress *)dataPtr
        !           347:        allocedSize:(int *)sizePtr
        !           348:        newAttributes:(IOBufferAttributes *)newAttrPtr
        !           349:        newMap:(IOAddressMap *)mapPtr
        !           350: {
        !           351:     IOVirtualAddress vaddr;
        !           352:     int alignSize, newSize;
        !           353:     
        !           354:     alignSize = IOAlignmentToSize(align);
        !           355:     newSize = memSize + 2 * alignSize;
        !           356:     
        !           357:     /* an optimization that relies on IOMalloc returning aligned pages. */
        !           358:     if (newSize > PAGE_SIZE && memSize <= PAGE_SIZE)
        !           359:        newSize = PAGE_SIZE;
        !           360:     
        !           361:     vaddr = (IOVirtualAddress)IOMalloc(newSize);
        !           362:     if (vaddr == 0)
        !           363:        return FALSE;
        !           364: 
        !           365:     *allocPtr = vaddr;
        !           366:     if (newSize != memSize)
        !           367:        *dataPtr = (vaddr + alignSize - 1) & ~(alignSize - 1);
        !           368:     else
        !           369:        *dataPtr = vaddr;
        !           370:     *sizePtr = newSize;
        !           371:     *newAttrPtr = IOBuf_Wired | IOBuf_WiredStatic | IOBuf_Contiguous;
        !           372:     *mapPtr = (IOAddressMap)IOVmTaskSelf();
        !           373:     return TRUE;
        !           374: }
        !           375: 
        !           376: 
        !           377: +(BOOL)freeMemory:(IOVirtualAddress)addr
        !           378:        size:(int)memsize
        !           379:        map:(IOAddressMap)memmap
        !           380:        attributes:(IOBufferAttributes)attr
        !           381: {
        !           382:     IOFree((void *)addr, memsize);
        !           383:     return TRUE;
        !           384: }
        !           385: 
        !           386: @end
        !           387: 
        !           388: /*
        !           389:  * Helper functions
        !           390:  */
        !           391:  
        !           392: /*
        !           393:  * Returns TRUE if the address meets the specified aligment requirement.
        !           394:  */
        !           395: static BOOL checkAlignmentFromVirtual(
        !           396:     IOVirtualAddress   vaddr,
        !           397:     IOAddressMap       map,
        !           398:     int                        size,
        !           399:     IOAlignment        align
        !           400: )
        !           401: {
        !           402:     IOPhysicalAddress paddr;
        !           403:     
        !           404:     paddr = (IOPhysicalAddress) pmap_resident_extract(
        !           405:        vm_map_pmap((vm_map_t)map), vaddr);
        !           406: 
        !           407:     return checkAlignmentFromPhysical(paddr, size, align);
        !           408: }
        !           409: 
        !           410: static BOOL checkAlignmentFromPhysical(
        !           411:     IOPhysicalAddress  paddr,
        !           412:     int                        size,
        !           413:     IOAlignment                align
        !           414: )
        !           415: {
        !           416:     unsigned int mask;
        !           417:     
        !           418:     if (align > IOBufferAlignMax)
        !           419:        return NO;
        !           420: 
        !           421:     mask = maskFromAlignment(align);
        !           422:     if ((paddr & mask) || (size & mask))
        !           423:        return NO;
        !           424: 
        !           425:     return YES;
        !           426: }
        !           427: 
        !           428: static BOOL checkAlignmentFromSize(
        !           429:     int                        size,
        !           430:     IOAlignment        align
        !           431: )
        !           432: {
        !           433:     unsigned int mask;
        !           434:     if (align > IOBufferAlignMax)
        !           435:        return NO;
        !           436:     mask = maskFromAlignment(align);
        !           437:     if (size & mask)
        !           438:        return NO;
        !           439:     return YES;
        !           440: }
        !           441: 
        !           442: static unsigned int
        !           443: maskFromAlignment(
        !           444:     IOAlignment                align
        !           445: )
        !           446: {
        !           447:     unsigned int mask;
        !           448:     
        !           449:     for (mask = 0; align; align--) {
        !           450:        mask = (mask << 1) | 1;
        !           451:     }
        !           452:     return mask;
        !           453: }
        !           454: 
        !           455: static unsigned int
        !           456: alignmentFromAddress(
        !           457:     unsigned int       addr
        !           458: )
        !           459: {
        !           460:     unsigned int alignment;
        !           461:     
        !           462:     for (alignment=0; alignment < PAGE_SHIFT; alignment++) {
        !           463:        if (addr & 0x01)
        !           464:            return alignment;
        !           465:        addr >>= 1;
        !           466:     }
        !           467:     return alignment;
        !           468: }
        !           469: 
        !           470: static void
        !           471: copyData(
        !           472:     IOVirtualAddress src,
        !           473:     IOAddressMap srcMap,
        !           474:     IOVirtualAddress dst,
        !           475:     IOAddressMap dstMap,
        !           476:     unsigned int totalLength
        !           477: )
        !           478: {
        !           479:     IOPhysicalAddress physSrc, physDst;
        !           480:     int currentLength;
        !           481:     int leftInSrc, leftInDst;
        !           482:     const unsigned int pageMask = PAGE_SIZE - 1;
        !           483: 
        !           484:     while (totalLength) {
        !           485:        physSrc = (IOPhysicalAddress) pmap_resident_extract(
        !           486:            vm_map_pmap((vm_map_t)srcMap), src);
        !           487:        physDst = (IOPhysicalAddress) pmap_resident_extract(
        !           488:            vm_map_pmap((vm_map_t)dstMap), dst);
        !           489:        leftInSrc = PAGE_SIZE - (physSrc & pageMask);
        !           490:        leftInDst = PAGE_SIZE - (physDst & pageMask);
        !           491:        currentLength = MIN(leftInSrc, leftInDst);
        !           492:        currentLength = MIN(totalLength, currentLength);
        !           493:        bcopy(pmap_phys_to_kern(physSrc),
        !           494:              pmap_phys_to_kern(physDst),
        !           495:              currentLength);
        !           496:        totalLength -= currentLength;
        !           497:        src += currentLength;
        !           498:        dst += currentLength;
        !           499:     }
        !           500: }
        !           501: 
        !           502: #endif NOTYET
        !           503: 

unix.superglobalmegacorp.com

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