[BACK]Return to vm_machdep.c CVS log [TXT][DIR] Up to [local] / sys / arch / hp300 / hp300

Annotation of sys/arch/hp300/hp300/vm_machdep.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: vm_machdep.c,v 1.43 2007/05/27 20:59:25 miod Exp $    */
        !             2: /*     $NetBSD: vm_machdep.c,v 1.60 2001/07/06 05:53:35 chs Exp $      */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1988 University of Utah.
        !             6:  * Copyright (c) 1982, 1986, 1990, 1993
        !             7:  *     The Regents of the University of California.  All rights reserved.
        !             8:  *
        !             9:  * This code is derived from software contributed to Berkeley by
        !            10:  * the Systems Programming Group of the University of Utah Computer
        !            11:  * Science Department.
        !            12:  *
        !            13:  * Redistribution and use in source and binary forms, with or without
        !            14:  * modification, are permitted provided that the following conditions
        !            15:  * are met:
        !            16:  * 1. Redistributions of source code must retain the above copyright
        !            17:  *    notice, this list of conditions and the following disclaimer.
        !            18:  * 2. Redistributions in binary form must reproduce the above copyright
        !            19:  *    notice, this list of conditions and the following disclaimer in the
        !            20:  *    documentation and/or other materials provided with the distribution.
        !            21:  * 3. Neither the name of the University nor the names of its contributors
        !            22:  *    may be used to endorse or promote products derived from this software
        !            23:  *    without specific prior written permission.
        !            24:  *
        !            25:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            28:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            29:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            30:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            31:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            32:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            33:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            34:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            35:  * SUCH DAMAGE.
        !            36:  *
        !            37:  * from: Utah $Hdr: vm_machdep.c 1.21 91/04/06$
        !            38:  *
        !            39:  *     @(#)vm_machdep.c        8.6 (Berkeley) 1/12/94
        !            40:  */
        !            41:
        !            42: #include <sys/param.h>
        !            43: #include <sys/systm.h>
        !            44: #include <sys/proc.h>
        !            45: #include <sys/signalvar.h>
        !            46: #include <sys/malloc.h>
        !            47: #include <sys/buf.h>
        !            48: #include <sys/vnode.h>
        !            49: #include <sys/user.h>
        !            50: #include <sys/core.h>
        !            51: #include <sys/exec.h>
        !            52: #include <sys/ptrace.h>
        !            53:
        !            54: #include <machine/frame.h>
        !            55: #include <machine/cpu.h>
        !            56: #include <machine/pte.h>
        !            57: #include <machine/reg.h>
        !            58:
        !            59: #include <uvm/uvm_extern.h>
        !            60:
        !            61: /*
        !            62:  * Finish a fork operation, with process p2 nearly set up.
        !            63:  * Copy and update the pcb and trap frame, making the child ready to run.
        !            64:  *
        !            65:  * Rig the child's kernel stack so that it will start out in
        !            66:  * proc_trampoline() and call child_return() with p2 as an
        !            67:  * argument. This causes the newly-created child process to go
        !            68:  * directly to user level with an apparent return value of 0 from
        !            69:  * fork(), while the parent process returns normally.
        !            70:  *
        !            71:  * p1 is the process being forked; if p1 == &proc0, we are creating
        !            72:  * a kernel thread, and the return path and argument are specified with
        !            73:  * `func' and `arg'.
        !            74:  *
        !            75:  * If an alternate user-level stack is requested (with non-zero values
        !            76:  * in both the stack and stacksize args), set up the user stack pointer
        !            77:  * accordingly.
        !            78:  */
        !            79: void
        !            80: cpu_fork(p1, p2, stack, stacksize, func, arg)
        !            81:        struct proc *p1, *p2;
        !            82:        void *stack;
        !            83:        size_t stacksize;
        !            84:        void (*func)(void *);
        !            85:        void *arg;
        !            86: {
        !            87:        struct pcb *pcb = &p2->p_addr->u_pcb;
        !            88:        struct trapframe *tf;
        !            89:        struct switchframe *sf;
        !            90:        extern struct pcb *curpcb;
        !            91:
        !            92:        p2->p_md.md_flags = p1->p_md.md_flags;
        !            93:
        !            94:        /* Copy pcb from proc p1 to p2. */
        !            95:        if (p1 == curproc) {
        !            96:                /* Sync the PCB before we copy it. */
        !            97:                savectx(curpcb);
        !            98:        }
        !            99: #ifdef DIAGNOSTIC
        !           100:        else if (p1 != &proc0)
        !           101:                panic("cpu_fork: curproc");
        !           102: #endif
        !           103:        *pcb = p1->p_addr->u_pcb;
        !           104:
        !           105:        /*
        !           106:         * Copy the trap frame.
        !           107:         */
        !           108:        tf = (struct trapframe *)((u_int)p2->p_addr + USPACE) - 1;
        !           109:        p2->p_md.md_regs = (int *)tf;
        !           110:        *tf = *(struct trapframe *)p1->p_md.md_regs;
        !           111:
        !           112:        /*
        !           113:         * If specified, give the child a different stack.
        !           114:         */
        !           115:        if (stack != NULL)
        !           116:                tf->tf_regs[15] = (u_int)stack + stacksize;
        !           117:
        !           118:        sf = (struct switchframe *)tf - 1;
        !           119:        sf->sf_pc = (u_int)proc_trampoline;
        !           120:        pcb->pcb_regs[6] = (int)func;           /* A2 */
        !           121:        pcb->pcb_regs[7] = (int)arg;            /* A3 */
        !           122:        pcb->pcb_regs[11] = (int)sf;            /* SSP */
        !           123:        pcb->pcb_ps = PSL_LOWIPL;               /* start kthreads at IPL 0 */
        !           124: }
        !           125:
        !           126: /*
        !           127:  * cpu_exit is called as the last action during exit.
        !           128:  *
        !           129:  * Block context switches and then call switch_exit() which will
        !           130:  * switch to another process thus we never return.
        !           131:  */
        !           132: void
        !           133: cpu_exit(p)
        !           134:        struct proc *p;
        !           135: {
        !           136:
        !           137:        (void) splhigh();
        !           138:        switch_exit(p);
        !           139:        /* NOTREACHED */
        !           140: }
        !           141:
        !           142: /*
        !           143:  * Dump the machine specific header information at the start of a core dump.
        !           144:  */
        !           145: struct md_core {
        !           146:        struct reg intreg;
        !           147:        struct fpreg freg;
        !           148: };
        !           149: int
        !           150: cpu_coredump(p, vp, cred, chdr)
        !           151:        struct proc *p;
        !           152:        struct vnode *vp;
        !           153:        struct ucred *cred;
        !           154:        struct core *chdr;
        !           155: {
        !           156:        struct md_core md_core;
        !           157:        struct coreseg cseg;
        !           158:        int error;
        !           159:
        !           160:        CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0);
        !           161:        chdr->c_hdrsize = ALIGN(sizeof(*chdr));
        !           162:        chdr->c_seghdrsize = ALIGN(sizeof(cseg));
        !           163:        chdr->c_cpusize = sizeof(md_core);
        !           164:
        !           165:        /* Save integer registers. */
        !           166:        error = process_read_regs(p, &md_core.intreg);
        !           167:        if (error)
        !           168:                return error;
        !           169:
        !           170:        if (fputype) {
        !           171:                /* Save floating point registers. */
        !           172:                error = process_read_fpregs(p, &md_core.freg);
        !           173:                if (error)
        !           174:                        return error;
        !           175:        } else {
        !           176:                /* Make sure these are clear. */
        !           177:                bzero((caddr_t)&md_core.freg, sizeof(md_core.freg));
        !           178:        }
        !           179:
        !           180:        CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU);
        !           181:        cseg.c_addr = 0;
        !           182:        cseg.c_size = chdr->c_cpusize;
        !           183:
        !           184:        error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize,
        !           185:            (off_t)chdr->c_hdrsize, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred,
        !           186:            NULL, p);
        !           187:        if (error)
        !           188:                return error;
        !           189:
        !           190:        error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&md_core, sizeof(md_core),
        !           191:            (off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE,
        !           192:            IO_NODELOCKED|IO_UNIT, cred, NULL, p);
        !           193:        if (error)
        !           194:                return error;
        !           195:
        !           196:        chdr->c_nseg++;
        !           197:        return 0;
        !           198: }
        !           199:
        !           200: /*
        !           201:  * Map a user I/O request into kernel virtual address space.
        !           202:  * Note: the pages are already locked by uvm_vslock(), so we
        !           203:  * do not need to pass an access_type to pmap_enter().
        !           204:  */
        !           205: void
        !           206: vmapbuf(bp, len)
        !           207:        struct buf *bp;
        !           208:        vsize_t len;
        !           209: {
        !           210:        struct pmap *upmap, *kpmap;
        !           211:        vaddr_t uva;            /* User VA (map from) */
        !           212:        vaddr_t kva;            /* Kernel VA (new to) */
        !           213:        paddr_t pa;             /* physical address */
        !           214:        vsize_t off;
        !           215:
        !           216:        if ((bp->b_flags & B_PHYS) == 0)
        !           217:                panic("vmapbuf");
        !           218:
        !           219:        uva = trunc_page((vaddr_t)(bp->b_saveaddr = bp->b_data));
        !           220:        off = (vaddr_t)bp->b_data - uva;
        !           221:        len = round_page(off + len);
        !           222:        kva = uvm_km_valloc_wait(phys_map, len);
        !           223:        bp->b_data = (caddr_t)(kva + off);
        !           224:
        !           225:        upmap = vm_map_pmap(&bp->b_proc->p_vmspace->vm_map);
        !           226:        kpmap = vm_map_pmap(phys_map);
        !           227:        do {
        !           228:                if (pmap_extract(upmap, uva, &pa) == FALSE)
        !           229:                        panic("vmapbuf: null page frame");
        !           230:                pmap_enter(kpmap, kva, pa, VM_PROT_READ|VM_PROT_WRITE,
        !           231:                    VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
        !           232:                uva += PAGE_SIZE;
        !           233:                kva += PAGE_SIZE;
        !           234:                len -= PAGE_SIZE;
        !           235:        } while (len);
        !           236:        pmap_update(pmap_kernel());
        !           237: }
        !           238:
        !           239: /*
        !           240:  * Unmap a previously-mapped user I/O request.
        !           241:  */
        !           242: void
        !           243: vunmapbuf(bp, len)
        !           244:        struct buf *bp;
        !           245:        vsize_t len;
        !           246: {
        !           247:        vaddr_t kva;
        !           248:        vsize_t off;
        !           249:
        !           250:        if ((bp->b_flags & B_PHYS) == 0)
        !           251:                panic("vunmapbuf");
        !           252:
        !           253:        kva = trunc_page((vaddr_t)(bp->b_data));
        !           254:        off = (vaddr_t)bp->b_data - kva;
        !           255:        len = round_page(off + len);
        !           256:
        !           257:        pmap_remove(vm_map_pmap(phys_map), kva, kva + len);
        !           258:        pmap_update(pmap_kernel());
        !           259:        uvm_km_free_wakeup(phys_map, kva, len);
        !           260:        bp->b_data = bp->b_saveaddr;
        !           261:        bp->b_saveaddr = 0;
        !           262: }

CVSweb