Annotation of kernel/machdep/i386/pc_support/PCinit.c, 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) 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: }

unix.superglobalmegacorp.com

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