|
|
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) 1993 NeXT Computer, Inc. ! 27: * ! 28: * PC support initialization. ! 29: * ! 30: * HISTORY ! 31: * ! 32: * 9 Mar 1993 ? at NeXT ! 33: * Created. ! 34: */ ! 35: ! 36: #import <mach/mach_types.h> ! 37: ! 38: #import <kern/kern_port.h> ! 39: ! 40: #import <vm/vm_kern.h> ! 41: ! 42: #import "PCprivate.h" ! 43: ! 44: kern_return_t ! 45: PCcreate( ! 46: port_t th_port, ! 47: vm_offset_t paddress, ! 48: boolean_t anywhere ! 49: ) ! 50: { ! 51: kern_return_t result; ! 52: task_t target_task = current_task(); ! 53: vm_offset_t address; ! 54: thread_t thread; ! 55: kern_port_t th_kport; ! 56: PCprivate_t priv; ! 57: ! 58: if (!suser()) ! 59: return (KERN_FAILURE); ! 60: ! 61: if (!anywhere) { ! 62: if (copyin(paddress, &address, sizeof (address))) ! 63: return (KERN_INVALID_ARGUMENT); ! 64: ! 65: address = trunc_page(address); ! 66: } ! 67: else ! 68: address = vm_map_min(target_task->map); ! 69: ! 70: if (!object_copyin( ! 71: target_task, ! 72: th_port, MSG_TYPE_PORT, ! 73: FALSE, (void *)&th_kport)) ! 74: return (KERN_INVALID_ARGUMENT); ! 75: ! 76: thread = convert_port_to_thread(th_kport); ! 77: ! 78: port_release(th_kport); ! 79: ! 80: if (thread == THREAD_NULL) ! 81: return (KERN_INVALID_ARGUMENT); ! 82: ! 83: if (thread->pcb->PCpriv) { ! 84: if (anywhere) { ! 85: address = thread->pcb->PCpriv->taskShared; ! 86: ! 87: if (copyout(&address, paddress, sizeof (address))) ! 88: result = KERN_INVALID_ARGUMENT; ! 89: else ! 90: result = KERN_SUCCESS; ! 91: } ! 92: else { ! 93: if (address == thread->pcb->PCpriv->taskShared) ! 94: result = KERN_SUCCESS; ! 95: else ! 96: result = KERN_INVALID_ADDRESS; ! 97: } ! 98: ! 99: thread_deallocate(thread); ! 100: ! 101: return (result); ! 102: } ! 103: ! 104: result = vm_map_find( ! 105: target_task->map, ! 106: VM_OBJECT_NULL, 0, ! 107: &address, round_page(sizeof (struct PCshared)), ! 108: anywhere); ! 109: ! 110: if (result != KERN_SUCCESS) { ! 111: thread_deallocate(thread); ! 112: ! 113: return (result); ! 114: } ! 115: ! 116: if (anywhere) { ! 117: if (copyout(&address, paddress, sizeof (address))) { ! 118: thread_deallocate(thread); ! 119: ! 120: return (KERN_INVALID_ARGUMENT); ! 121: } ! 122: } ! 123: ! 124: vm_map_reference(target_task->map); ! 125: ! 126: priv = (PCprivate_t)kalloc(sizeof (struct PCprivate)); ! 127: *priv = (struct PCprivate) { 0 }; ! 128: ! 129: (void) kmem_alloc_wired(kernel_map, ! 130: (PCshared_t *)&priv->shared, ! 131: sizeof (struct PCshared)); ! 132: priv->task = target_task->map; ! 133: priv->taskShared = address; ! 134: ! 135: pmap_enter_shared_range( ! 136: vm_map_pmap(priv->task), ! 137: priv->taskShared, ! 138: sizeof (struct PCshared), ! 139: (vm_offset_t)priv->shared); ! 140: ! 141: priv->shared->versionNumber = PCVERSIONNUMBER; ! 142: priv->shared->releaseNumber = PCRELEASENUMBER; ! 143: ! 144: thread->pcb->PCpriv = priv; ! 145: ! 146: thread_deallocate(thread); ! 147: ! 148: return (KERN_SUCCESS); ! 149: } ! 150: ! 151: void ! 152: PCdestroy( ! 153: thread_t thread ! 154: ) ! 155: { ! 156: PCprivate_t priv = thread->pcb->PCpriv; ! 157: ! 158: pmap_remove( ! 159: vm_map_pmap(priv->task), ! 160: priv->taskShared, ! 161: round_page(priv->taskShared + sizeof (struct PCshared))); ! 162: ! 163: (void) vm_map_remove( ! 164: priv->task, ! 165: priv->taskShared, ! 166: round_page(priv->taskShared + sizeof (struct PCshared))); ! 167: ! 168: vm_map_deallocate(priv->task); ! 169: ! 170: PCcancelAllTimers(thread); ! 171: ! 172: kmem_free( ! 173: kernel_map, ! 174: (vm_offset_t)priv->shared, ! 175: round_page(sizeof (struct PCshared))); ! 176: ! 177: kfree(priv, sizeof (struct PCprivate)); ! 178: } ! 179: ! 180: kern_return_t ! 181: PCldt( ! 182: port_t th_port, ! 183: vm_offset_t address, ! 184: vm_size_t size ! 185: ) ! 186: { ! 187: kern_return_t result; ! 188: thread_t thread; ! 189: kern_port_t th_kport; ! 190: thread_saved_state_t *saved_state; ! 191: ! 192: if (!suser()) ! 193: return (KERN_FAILURE); ! 194: ! 195: if (!object_copyin( ! 196: current_task(), ! 197: th_port, MSG_TYPE_PORT, ! 198: FALSE, (void *)&th_kport)) ! 199: return (KERN_INVALID_ARGUMENT); ! 200: ! 201: thread = convert_port_to_thread(th_kport); ! 202: ! 203: port_release(th_kport); ! 204: ! 205: if (thread == THREAD_NULL) ! 206: return (KERN_INVALID_ARGUMENT); ! 207: ! 208: saved_state = USER_REGS(thread); ! 209: ! 210: if (address == (vm_offset_t)-1 && size == (vm_offset_t)-1) ! 211: result = task_default_ldt(thread->task); ! 212: else ! 213: result = task_locate_ldt(thread->task, address, size); ! 214: ! 215: if (result == KERN_SUCCESS) { ! 216: saved_state->frame.cs = UCODE_SEL; ! 217: saved_state->frame.ss = UDATA_SEL; ! 218: saved_state->regs.ds = UDATA_SEL; ! 219: saved_state->regs.es = UDATA_SEL; ! 220: saved_state->regs.fs = NULL_SEL; ! 221: saved_state->regs.gs = NULL_SEL; ! 222: } ! 223: ! 224: thread_deallocate(thread); ! 225: ! 226: return (result); ! 227: } ! 228: ! 229: kern_return_t ! 230: PCcopyBIOSData( ! 231: vm_address_t dest ! 232: ) ! 233: { ! 234: if (dest == (vm_address_t)0) ! 235: return (KERN_INVALID_ARGUMENT); ! 236: ! 237: if (copyout((vm_address_t)BIOS_DATA_ADDR, dest, BIOS_DATA_SIZE)) ! 238: return (KERN_INVALID_ARGUMENT); ! 239: ! 240: return (KERN_SUCCESS); ! 241: } ! 242: ! 243: vm_size_t ! 244: PCsizeBIOSExtData(void) ! 245: { ! 246: return (CNV_MEM_END_ADDR - bios_extdata_addr()); ! 247: } ! 248: ! 249: kern_return_t ! 250: PCcopyBIOSExtData( ! 251: vm_address_t dest ! 252: ) ! 253: { ! 254: vm_address_t data = bios_extdata_addr(); ! 255: ! 256: if (dest == (vm_address_t)0) ! 257: return (KERN_INVALID_ARGUMENT); ! 258: ! 259: if (copyout(data, dest, CNV_MEM_END_ADDR - data)) ! 260: return (KERN_INVALID_ARGUMENT); ! 261: ! 262: return (KERN_SUCCESS); ! 263: } ! 264: ! 265: kern_return_t ! 266: PCmapBIOSRom( ! 267: port_t task_port, ! 268: vm_offset_t paddress, ! 269: boolean_t anywhere ! 270: ) ! 271: { ! 272: kern_return_t result; ! 273: vm_offset_t address; ! 274: task_t target_task; ! 275: kern_port_t task_kport; ! 276: ! 277: if (!anywhere) { ! 278: if (copyin(paddress, &address, sizeof (address))) ! 279: return (KERN_INVALID_ARGUMENT); ! 280: ! 281: address = trunc_page(address); ! 282: } ! 283: else ! 284: address = vm_map_min(target_task->map); ! 285: ! 286: if (!object_copyin( ! 287: current_task(), ! 288: task_port, MSG_TYPE_PORT, ! 289: FALSE, (void *)&task_kport)) ! 290: return (KERN_INVALID_ARGUMENT); ! 291: ! 292: target_task = convert_port_to_task(task_kport); ! 293: ! 294: port_release(task_kport); ! 295: ! 296: if (target_task == TASK_NULL) ! 297: return (KERN_INVALID_ARGUMENT); ! 298: ! 299: result = vm_map_find( ! 300: target_task->map, ! 301: VM_OBJECT_NULL, 0, ! 302: &address, round_page(BIOS_ROM_SIZE), ! 303: anywhere); ! 304: ! 305: if (result != KERN_SUCCESS) { ! 306: task_deallocate(target_task); ! 307: ! 308: return (result); ! 309: } ! 310: ! 311: if (anywhere) { ! 312: if (copyout(&address, paddress, sizeof (address))) { ! 313: task_deallocate(target_task); ! 314: ! 315: return (KERN_INVALID_ARGUMENT); ! 316: } ! 317: } ! 318: ! 319: { ! 320: vm_offset_t end = round_page(address + BIOS_ROM_SIZE); ! 321: vm_offset_t phys = trunc_page(BIOS_ROM_ADDR); ! 322: ! 323: while (address < end) { ! 324: pmap_enter( ! 325: vm_map_pmap(target_task->map), ! 326: address, ! 327: phys, ! 328: VM_PROT_READ, ! 329: TRUE); ! 330: ! 331: address += PAGE_SIZE; phys += PAGE_SIZE; ! 332: } ! 333: } ! 334: ! 335: task_deallocate(target_task); ! 336: ! 337: return (KERN_SUCCESS); ! 338: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.