|
|
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 (c) 1991 NeXT Computer, Inc. All rights reserved. ! 26: * ! 27: * File: vm/vm_mem_region.c ! 28: * ! 29: * This file contains machine independent code for managing ! 30: * physical memory regions. ! 31: * ! 32: * 18-Mar-91 Mike DeMoney and Peter King ([email protected]) ! 33: * Created. ! 34: */ ! 35: #import <kern/assert.h> ! 36: #import <mach/vm_param.h> ! 37: #import <vm/vm_page.h> ! 38: #import <kernserv/macro_help.h> ! 39: #import <kern/assert.h> ! 40: ! 41: /* ! 42: * vm_mem_ppi -- convert a physical page number into a phys page index. ! 43: * Returns the page ordinal in the set of "populated" pages. ! 44: */ ! 45: unsigned vm_mem_ppi(vm_offset_t pa) ! 46: { ! 47: mem_region_t region; ! 48: unsigned pages_so_far; ! 49: ! 50: pages_so_far = 0; ! 51: for (region = &mem_region[0]; region < &mem_region[num_regions]; ! 52: region++) { ! 53: if (pa >= region->first_phys_addr ! 54: && pa < region->last_phys_addr) { ! 55: return (pages_so_far + ! 56: atop(pa - region->first_phys_addr)); ! 57: } ! 58: ASSERT(region->num_pages == atop(region->last_phys_addr ! 59: - region->first_phys_addr)); ! 60: pages_so_far += region->num_pages; ! 61: } ! 62: panic("mem_ppi"); ! 63: /*NOTREACHED*/ ! 64: } ! 65: ! 66: boolean_t vm_valid_page( ! 67: vm_offset_t pa ! 68: ) { ! 69: mem_region_t region; ! 70: ! 71: for (region = &mem_region[0]; region < &mem_region[num_regions]; ! 72: region++) { ! 73: if (pa >= region->first_phys_addr ! 74: && pa < region->last_phys_addr) { ! 75: return TRUE; ! 76: } ! 77: } ! 78: return FALSE; ! 79: } ! 80: ! 81: /* ! 82: * vm_phys_to_vm_page: ! 83: * ! 84: * Translates physical address to vm_page pointer. ! 85: */ ! 86: vm_page_t vm_phys_to_vm_page (vm_offset_t pa) ! 87: { ! 88: mem_region_t rp; ! 89: ! 90: for (rp = mem_region; rp < &mem_region[num_regions]; rp += 1) { ! 91: if (pa >= rp->first_phys_addr && pa < rp->last_phys_addr) { ! 92: return &rp->vm_page_array[atop(pa) - rp->first_page]; ! 93: } ! 94: } ! 95: return 0; ! 96: } ! 97: ! 98: /* ! 99: * vm_region_to_vm_page: ! 100: * ! 101: * Translates physical address to vm_page pointer. ! 102: */ ! 103: vm_page_t ! 104: vm_region_to_vm_page (pa) ! 105: register vm_offset_t pa; ! 106: { ! 107: return (vm_phys_to_vm_page(pa)); ! 108: } ! 109: ! 110: vm_offset_t vm_alloc_from_regions( ! 111: vm_size_t size, ! 112: vm_size_t align ! 113: ) { ! 114: vm_offset_t first_addr; ! 115: mem_region_t rp; ! 116: extern ! 117: vm_offset_t virtual_avail; ! 118: ! 119: /* Alignment must be power of 2 */ ! 120: ASSERT((align & (align - 1)) == 0); ! 121: ! 122: /* ! 123: * Search for region with enough space. ! 124: * Simple first fit for now. ! 125: */ ! 126: for (rp = mem_region; rp < &mem_region[num_regions]; rp += 1) { ! 127: ! 128: /* Align current first_addr to requested alignment */ ! 129: first_addr = ((rp->first_phys_addr + (align - 1)) ! 130: & ~(align - 1)); ! 131: ! 132: if (first_addr + size <= rp->last_phys_addr) { ! 133: rp->first_phys_addr = first_addr + size; ! 134: #ifdef ppc ! 135: if (round_page(rp->first_phys_addr) > virtual_avail) ! 136: virtual_avail = round_page(rp->first_phys_addr); ! 137: #endif ! 138: ! 139: return (vm_offset_t) first_addr; ! 140: } ! 141: } ! 142: panic("vm_mem_alloc_from_regions"); ! 143: /*NOTREACHED*/ ! 144: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.