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