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

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

1.1     ! nbrk        1: /*     $OpenBSD: vm_machdep.c,v 1.7 2007/06/20 17:29:35 miod Exp $     */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2005 Michael Shalayeff
        !             5:  * All rights reserved.
        !             6:  *
        !             7:  * Permission to use, copy, modify, and distribute this software for any
        !             8:  * purpose with or without fee is hereby granted, provided that the above
        !             9:  * copyright notice and this permission notice appear in all copies.
        !            10:  *
        !            11:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            12:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            13:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            14:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            15:  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
        !            16:  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
        !            17:  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            18:  */
        !            19:
        !            20:
        !            21: #include <sys/param.h>
        !            22: #include <sys/systm.h>
        !            23: #include <sys/proc.h>
        !            24: #include <sys/signalvar.h>
        !            25: #include <sys/malloc.h>
        !            26: #include <sys/buf.h>
        !            27: #include <sys/vnode.h>
        !            28: #include <sys/user.h>
        !            29: #include <sys/ptrace.h>
        !            30: #include <sys/exec.h>
        !            31: #include <sys/core.h>
        !            32:
        !            33: #include <machine/psl.h>
        !            34: #include <machine/pmap.h>
        !            35: #include <machine/pcb.h>
        !            36:
        !            37: #include <uvm/uvm.h>
        !            38:
        !            39:
        !            40: /*
        !            41:  * Dump the machine specific header information at the start of a core dump.
        !            42:  */
        !            43: int
        !            44: cpu_coredump(p, vp, cred, core)
        !            45:        struct proc *p;
        !            46:        struct vnode *vp;
        !            47:        struct ucred *cred;
        !            48:        struct core *core;
        !            49: {
        !            50:        struct md_coredump md_core;
        !            51:        struct coreseg cseg;
        !            52:        off_t off;
        !            53:        int error;
        !            54:
        !            55:        CORE_SETMAGIC(*core, COREMAGIC, MID_HPPA20, 0);
        !            56:        core->c_hdrsize = ALIGN(sizeof(*core));
        !            57:        core->c_seghdrsize = ALIGN(sizeof(cseg));
        !            58:        core->c_cpusize = sizeof(md_core);
        !            59:
        !            60:        process_read_regs(p, &md_core.md_reg);
        !            61:        process_read_fpregs(p, &md_core.md_fpreg);
        !            62:
        !            63:        CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_HPPA20, CORE_CPU);
        !            64:        cseg.c_addr = 0;
        !            65:        cseg.c_size = core->c_cpusize;
        !            66:
        !            67: #define        write(vp, addr, n) \
        !            68:        vn_rdwr(UIO_WRITE, (vp), (caddr_t)(addr), (n), off, \
        !            69:            UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, NULL, p)
        !            70:
        !            71:        off = core->c_hdrsize;
        !            72:        if ((error = write(vp, &cseg, core->c_seghdrsize)))
        !            73:                return error;
        !            74:        off += core->c_seghdrsize;
        !            75:        if ((error = write(vp, &md_core, sizeof md_core)))
        !            76:                return error;
        !            77:
        !            78: #undef write
        !            79:        core->c_nseg++;
        !            80:
        !            81:        return error;
        !            82: }
        !            83:
        !            84: void
        !            85: cpu_fork(p1, p2, stack, stacksize, func, arg)
        !            86:        struct proc *p1, *p2;
        !            87:        void *stack;
        !            88:        size_t stacksize;
        !            89:        void (*func)(void *);
        !            90:        void *arg;
        !            91: {
        !            92:        extern paddr_t fpu_curpcb;      /* from locore.S */
        !            93:        extern register_t switch_tramp_p;
        !            94:        extern u_int fpu_enable;
        !            95:
        !            96:        struct pcb *pcbp;
        !            97:        struct trapframe *tf;
        !            98:        register_t sp, osp;
        !            99:        paddr_t pa;
        !           100:
        !           101: #ifdef DIAGNOSTIC
        !           102:        if (round_page(sizeof(struct user) + sizeof(*tf)) > PAGE_SIZE)
        !           103:                panic("USPACE too small for user");
        !           104: #endif
        !           105:        if (p1->p_md.md_regs->tf_cr30 == fpu_curpcb) {
        !           106:                mtctl(fpu_enable, CR_CCR);
        !           107:                fpu_save(fpu_curpcb);
        !           108:                mtctl(0, CR_CCR);
        !           109:        }
        !           110:
        !           111:        pcbp = &p2->p_addr->u_pcb;
        !           112:        bcopy(&p1->p_addr->u_pcb, pcbp, sizeof(*pcbp));
        !           113:        /* space is cached for the copy{in,out}'s pleasure */
        !           114:        pcbp->pcb_space = p2->p_vmspace->vm_map.pmap->pm_space;
        !           115:        pcbp->pcb_uva = (vaddr_t)p2->p_addr;
        !           116:        /* reset any of the pending FPU exceptions from parent */
        !           117:        pcbp->pcb_fpregs[0] = HPPA_FPU_FORK(pcbp->pcb_fpregs[0]);
        !           118:        pcbp->pcb_fpregs[1] = 0;
        !           119:        pcbp->pcb_fpregs[2] = 0;
        !           120:        pcbp->pcb_fpregs[3] = 0;
        !           121:        fdcache(HPPA_SID_KERNEL, (vaddr_t)&pcbp->pcb_fpregs[0], 8 * 4);
        !           122:
        !           123:        sp = (register_t)p2->p_addr + PAGE_SIZE;
        !           124:        p2->p_md.md_regs = tf = (struct trapframe *)sp;
        !           125:        sp += sizeof(struct trapframe);
        !           126:        bcopy(p1->p_md.md_regs, tf, sizeof(*tf));
        !           127:
        !           128:        /*
        !           129:         * Stash the physical for the pcb of U for later perusal
        !           130:         */
        !           131:        if (!pmap_extract(pmap_kernel(), (vaddr_t)p2->p_addr, &pa))
        !           132:                panic("pmap_extract(%p) failed", p2->p_addr);
        !           133:
        !           134:        tf->tf_cr30 = pa;
        !           135:
        !           136:        tf->tf_sr0 = tf->tf_sr1 = tf->tf_sr2 = tf->tf_sr3 =
        !           137:        tf->tf_sr4 = tf->tf_sr5 = tf->tf_sr6 =
        !           138:        tf->tf_iisq[0] = tf->tf_iisq[1] =
        !           139:                p2->p_vmspace->vm_map.pmap->pm_space;
        !           140:        tf->tf_pidr1 = tf->tf_pidr2 = pmap_sid2pid(tf->tf_sr0);
        !           141:
        !           142:        /*
        !           143:         * theoretically these could be inherited from the father,
        !           144:         * but just in case.
        !           145:         */
        !           146:        tf->tf_sr7 = HPPA_SID_KERNEL;
        !           147:        tf->tf_eiem = mfctl(CR_EIEM);
        !           148:        tf->tf_ipsw = PSL_C | PSL_Q | PSL_P | PSL_D | PSL_I /* | PSL_L */;
        !           149:
        !           150:        /*
        !           151:         * If specified, give the child a different stack.
        !           152:         */
        !           153:        if (stack != NULL)
        !           154:                tf->tf_sp = (register_t)stack;
        !           155:
        !           156:        /*
        !           157:         * Build stack frames for the cpu_switch & co.
        !           158:         */
        !           159:        osp = sp + HPPA_FRAME_SIZE;
        !           160:        *(register_t*)(osp - HPPA_FRAME_SIZE) = 0;
        !           161:        *(register_t*)(osp + HPPA_FRAME_RP) = switch_tramp_p;
        !           162:        *(register_t*)(osp) = (osp - HPPA_FRAME_SIZE);
        !           163:
        !           164:        sp = osp + HPPA_FRAME_SIZE + 20*8; /* frame + calee-save registers */
        !           165:        *(register_t*)(sp - HPPA_FRAME_SIZE + 0) = (register_t)arg;
        !           166:        *(register_t*)(sp - HPPA_FRAME_SIZE + 8) = KERNMODE(func);
        !           167:        *(register_t*)(sp - HPPA_FRAME_SIZE + 16) = 0;  /* cpl */
        !           168:        pcbp->pcb_ksp = sp;
        !           169:        fdcache(HPPA_SID_KERNEL, (vaddr_t)p2->p_addr, sp - (vaddr_t)p2->p_addr);
        !           170: }
        !           171:
        !           172: void
        !           173: cpu_exit(p)
        !           174:        struct proc *p;
        !           175: {
        !           176:        extern paddr_t fpu_curpcb;      /* from locore.S */
        !           177:        struct trapframe *tf = p->p_md.md_regs;
        !           178:
        !           179:        if (fpu_curpcb == tf->tf_cr30) {
        !           180:                fpu_exit();
        !           181:                fpu_curpcb = 0;
        !           182:        }
        !           183:
        !           184:        exit2(p);
        !           185:        cpu_switch(p);
        !           186: }
        !           187:
        !           188: void
        !           189: cpu_wait(p)
        !           190:        struct proc *p;
        !           191: {
        !           192: }
        !           193:
        !           194: /*
        !           195:  * Map an IO request into kernel virtual address space.
        !           196:  */
        !           197: void
        !           198: vmapbuf(bp, len)
        !           199:        struct buf *bp;
        !           200:        vsize_t len;
        !           201: {
        !           202:        struct pmap *pm = vm_map_pmap(&bp->b_proc->p_vmspace->vm_map);
        !           203:        vaddr_t kva, uva;
        !           204:        vsize_t size, off;
        !           205:
        !           206: #ifdef DIAGNOSTIC
        !           207:        if ((bp->b_flags & B_PHYS) == 0)
        !           208:                panic("vmapbuf");
        !           209: #endif
        !           210:        bp->b_saveaddr = bp->b_data;
        !           211:        uva = trunc_page((vaddr_t)bp->b_data);
        !           212:        off = (vaddr_t)bp->b_data - uva;
        !           213:        size = round_page(off + len);
        !           214:
        !           215:        /*
        !           216:         * We do it on our own here to be able to specify an offset to uvm_map
        !           217:         * so that we can get all benefits of PMAP_PREFER.
        !           218:         * - art@
        !           219:         */
        !           220:        kva = uvm_km_valloc_prefer_wait(phys_map, size, uva);
        !           221:        fdcache(pm->pm_space, uva, size);
        !           222:        bp->b_data = (caddr_t)(kva + off);
        !           223:        while (size > 0) {
        !           224:                paddr_t pa;
        !           225:
        !           226:                if (pmap_extract(pm, uva, &pa) == FALSE)
        !           227:                        panic("vmapbuf: null page frame");
        !           228:                else
        !           229:                        pmap_kenter_pa(kva, pa, UVM_PROT_RW);
        !           230:                uva += PAGE_SIZE;
        !           231:                kva += PAGE_SIZE;
        !           232:                size -= PAGE_SIZE;
        !           233:        }
        !           234:        pmap_update(pmap_kernel());
        !           235: }
        !           236:
        !           237: /*
        !           238:  * Unmap IO request from the kernel virtual address space.
        !           239:  */
        !           240: void
        !           241: vunmapbuf(bp, len)
        !           242:        struct buf *bp;
        !           243:        vsize_t len;
        !           244: {
        !           245:        vaddr_t addr, off;
        !           246:
        !           247: #ifdef DIAGNOSTIC
        !           248:        if ((bp->b_flags & B_PHYS) == 0)
        !           249:                panic("vunmapbuf");
        !           250: #endif
        !           251:        addr = trunc_page((vaddr_t)bp->b_data);
        !           252:        off = (vaddr_t)bp->b_data - addr;
        !           253:        len = round_page(off + len);
        !           254:        pmap_kremove(addr, len);
        !           255:        pmap_update(pmap_kernel());
        !           256:        uvm_km_free_wakeup(phys_map, addr, len);
        !           257:        bp->b_data = bp->b_saveaddr;
        !           258:        bp->b_saveaddr = NULL;
        !           259: }

CVSweb