Annotation of kernel/driverkit/KernBusMemory.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: /*
                     26:  * Copyright (c) 1994 NeXT Computer, Inc.
                     27:  *
                     28:  * Kernel Bus Generic Memory Resource Object(s).
                     29:  *
                     30:  * HISTORY
                     31:  *
                     32:  * 15 Mar 1994 ? at NeXT
                     33:  *     Created.
                     34:  */
                     35: 
                     36: #import <mach/mach_types.h>
                     37: #import <vm/vm_kern.h>
                     38: 
                     39: #import <driverkit/KernBusMemory.h>
                     40: 
                     41: @implementation KernBusMemoryRange
                     42: 
                     43: - mapToAddress:                (vm_offset_t)destAddr
                     44:        inTarget:       (task_t)task
                     45:        cache:          (IOCache)cache
                     46: {
                     47:     Range              subRange = [self range];
                     48: 
                     49:     subRange.base = 0;
                     50: 
                     51:     return [[KernBusMemoryRangeMapping alloc]
                     52:                                    initWithRange:self
                     53:                                    subRange:subRange
                     54:                                    atAddress:destAddr
                     55:                                    inTarget:task
                     56:                                    cache:cache];
                     57: }
                     58: 
                     59: - mapInTarget:         (task_t)task
                     60:        cache:          (IOCache)cache
                     61: {
                     62:     Range              subRange = [self range];
                     63: 
                     64:     subRange.base = 0;
                     65: 
                     66:     return [[KernBusMemoryRangeMapping alloc]
                     67:                                    initWithRange:self
                     68:                                    subRange:subRange
                     69:                                    inTarget:task
                     70:                                    cache:cache];
                     71: }
                     72: 
                     73: @end
                     74: 
                     75: #if ppc
                     76: #include <machdep/ppc/proc_reg.h>
                     77: #endif
                     78: 
                     79: @implementation KernBusMemoryRangeMapping
                     80: 
                     81: - initWithRange:       range
                     82:        subRange:       (Range)subRange
                     83:        atAddress:      (vm_offset_t)address
                     84:        inTarget:       (task_t)task
                     85:        cache:          (IOCache)cache
                     86: {
                     87:     Range              mappedRange;
                     88: 
                     89:     if (task == TASK_NULL)
                     90:        return [self free];
                     91: 
                     92:     if ([super initWithRange:range subRange:subRange] == nil)
                     93:        return nil;
                     94: 
                     95:     mappedRange = [self mappedRange];  // absolute physical range
                     96: 
                     97: #if ppc
                     98: 
                     99:     if( (task->map->pmap == kernel_pmap)
                    100:     &&  (IO_CacheOff    == cache)
                    101:     &&  (address        == PEMapSegment( mappedRange.base, mappedRange.length)) ) {
                    102: 
                    103:        _address = address;
                    104:        _task = TASK_NULL;
                    105:        return self;
                    106: 
                    107:     } else {
                    108: 
                    109:        vm_offset_t     spa, epa;
                    110:     
                    111:        spa = mappedRange.base & 0xfffff000;
                    112:        epa = (mappedRange.base + mappedRange.length + 0xfff) & 0xfffff000;
                    113:        // non fatal - it may overlap another range
                    114:        pmap_add_physical_memory( spa, epa, FALSE, PTE_WIMG_IO);
                    115:     }
                    116: 
                    117: #endif
                    118: 
                    119:     if (_KernBusMemoryCreateMapping(
                    120:                                mappedRange.base,
                    121:                                mappedRange.length, // will not work if == 0
                    122:                                &address,
                    123:                                task,
                    124:                                NO,
                    125:                                cache) != KERN_SUCCESS)
                    126:        return [self free];
                    127: 
                    128:     _task = task;
                    129:     _address = address;
                    130:     
                    131:     return self;
                    132: }
                    133: 
                    134: - initWithRange:       range
                    135:        subRange:       (Range)subRange
                    136:        inTarget:       (task_t)task
                    137:        cache:          (IOCache)cache
                    138: {
                    139:     Range              mappedRange;
                    140:     
                    141:     if (task == TASK_NULL)
                    142:        return [self free];
                    143: 
                    144:     if ([super initWithRange:range subRange:subRange] == nil)
                    145:        return nil;
                    146: 
                    147:     mappedRange = [self mappedRange];  // absolute physical range
                    148: 
                    149: #if ppc
                    150: 
                    151:     if( (task->map->pmap == kernel_pmap)
                    152:     &&  (IO_CacheOff    == cache)
                    153:     &&  (_address       =  PEMapSegment( mappedRange.base, mappedRange.length)) ) {
                    154: 
                    155:        _task = TASK_NULL;
                    156:        return self;
                    157: 
                    158:     } else {
                    159: 
                    160:        vm_offset_t     spa, epa;
                    161:     
                    162:        spa = mappedRange.base & 0xfffff000;
                    163:        epa = (mappedRange.base + mappedRange.length + 0xfff) & 0xfffff000;
                    164:        // non fatal - it may overlap another range
                    165:        pmap_add_physical_memory( spa, epa, FALSE, PTE_WIMG_IO);
                    166:     }
                    167: 
                    168: #endif
                    169: 
                    170:     if (_KernBusMemoryCreateMapping(
                    171:                                mappedRange.base,
                    172:                                mappedRange.length, // will not work if == 0
                    173:                                &_address,
                    174:                                task,
                    175:                                YES,
                    176:                                cache) != KERN_SUCCESS)
                    177:        return [self free];
                    178: 
                    179:     _task = task;
                    180: 
                    181:     return self;
                    182: }
                    183: 
                    184: - free
                    185: {
                    186:     Range              mappedRange = [self mappedRange];
                    187: 
                    188:     if (_task != TASK_NULL)
                    189:        (void) vm_deallocate(_task->map, _address, mappedRange.length);
                    190: 
                    191:     return [super free];
                    192: }
                    193: 
                    194: - (task_t)task
                    195: {
                    196:     return _task;
                    197: }
                    198: 
                    199: - (vm_offset_t)address
                    200: {
                    201:     return _address;
                    202: }
                    203: 
                    204: @end
                    205: 
                    206: kern_return_t
                    207: _KernBusMemoryCreateMapping(
                    208:     vm_offset_t                physAddr,
                    209:     vm_size_t          length,
                    210:     vm_offset_t                *destAddr,
                    211:     task_t             task,
                    212:     BOOL               findSpace,
                    213:     IOCache            cache
                    214: )
                    215: {
                    216:     kern_return_t      result;
                    217:     vm_map_t           map = task->map;
                    218:     vm_offset_t                virtAddr;
                    219:     cache_spec_t       caching;
                    220:        
                    221:     vm_map_reference(map);
                    222:     
                    223:     if (findSpace)
                    224:        *destAddr = vm_map_min(map);
                    225:     else
                    226:        *destAddr = trunc_page(*destAddr);
                    227:     
                    228:     length = round_page(length);
                    229: 
                    230:     result = vm_map_find(
                    231:                        map,
                    232:                        VM_OBJECT_NULL, (vm_offset_t) 0,
                    233:                        destAddr, length,
                    234:                        findSpace);
                    235:                        
                    236:     if (result != KERN_SUCCESS) {
                    237:        vm_map_deallocate(map);
                    238:        return result;
                    239:     }
                    240:     
                    241:     virtAddr = trunc_page(*destAddr);
                    242:     
                    243:     (void) vm_map_inherit(
                    244:                        map,
                    245:                        virtAddr, virtAddr + length,
                    246:                        VM_INHERIT_NONE);
                    247:                        
                    248:     physAddr = trunc_page(physAddr);
                    249:        
                    250:     switch (cache) {
                    251:     
                    252:     case IO_CacheOff:
                    253:        caching = cache_disable;
                    254:        break;
                    255:        
                    256:     case IO_WriteThrough:
                    257:        caching = cache_writethrough;
                    258:        break;
                    259:        
                    260:     default:
                    261:        caching = cache_default;
                    262:        break;
                    263:     }
                    264:     
                    265:     while (length > 0) {
                    266:        pmap_enter_cache_spec(
                    267:                            vm_map_pmap(map),
                    268:                            virtAddr,
                    269:                            physAddr,
                    270:                            VM_PROT_READ | VM_PROT_WRITE,
                    271:                            TRUE,
                    272:                            caching);
                    273:                            
                    274:        virtAddr += PAGE_SIZE; length -= PAGE_SIZE; physAddr += PAGE_SIZE;
                    275:     }
                    276:     
                    277:     vm_map_deallocate(map);
                    278:     
                    279:     return KERN_SUCCESS;
                    280: }

unix.superglobalmegacorp.com

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