Annotation of driverkit/libDriver/Kernel/IOBuffer.m, revision 1.1.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.