Annotation of sys/arch/i386/i386/process_machdep.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: process_machdep.c,v 1.22 2007/05/08 20:26:54 deraadt Exp $ */
! 2: /* $NetBSD: process_machdep.c,v 1.22 1996/05/03 19:42:25 christos Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1995, 1996 Charles M. Hannum. All rights reserved.
! 6: * Copyright (c) 1993 The Regents of the University of California.
! 7: * Copyright (c) 1993 Jan-Simon Pendry
! 8: * All rights reserved.
! 9: *
! 10: * This code is derived from software contributed to Berkeley by
! 11: * Jan-Simon Pendry.
! 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:
! 38: * Id: procfs_i386.c,v 4.1 1993/12/17 10:47:45 jsp Rel
! 39: */
! 40:
! 41: /*
! 42: * This file may seem a bit stylized, but that so that it's easier to port.
! 43: * Functions to be implemented here are:
! 44: *
! 45: * process_read_regs(proc, regs)
! 46: * Get the current user-visible register set from the process
! 47: * and copy it into the regs structure (<machine/reg.h>).
! 48: * The process is stopped at the time read_regs is called.
! 49: *
! 50: * process_write_regs(proc, regs)
! 51: * Update the current register set from the passed in regs
! 52: * structure. Take care to avoid clobbering special CPU
! 53: * registers or privileged bits in the PSL.
! 54: * The process is stopped at the time write_regs is called.
! 55: *
! 56: * process_sstep(proc)
! 57: * Arrange for the process to trap after executing a single instruction.
! 58: *
! 59: * process_set_pc(proc)
! 60: * Set the process's program counter.
! 61: */
! 62:
! 63: #include <sys/param.h>
! 64: #include <sys/systm.h>
! 65: #include <sys/time.h>
! 66: #include <sys/kernel.h>
! 67: #include <sys/proc.h>
! 68: #include <sys/user.h>
! 69: #include <sys/vnode.h>
! 70: #include <sys/ptrace.h>
! 71:
! 72: #include <machine/psl.h>
! 73: #include <machine/reg.h>
! 74: #include <machine/segments.h>
! 75:
! 76: #ifdef VM86
! 77: #include <machine/vm86.h>
! 78: #endif
! 79:
! 80: #include "npx.h"
! 81:
! 82: static __inline struct trapframe *process_frame(struct proc *);
! 83: static __inline union savefpu *process_fpframe(struct proc *);
! 84: void process_fninit_xmm(struct savexmm *);
! 85:
! 86: static __inline struct trapframe *
! 87: process_frame(struct proc *p)
! 88: {
! 89:
! 90: return (p->p_md.md_regs);
! 91: }
! 92:
! 93: static __inline union savefpu *
! 94: process_fpframe(struct proc *p)
! 95: {
! 96:
! 97: return (&p->p_addr->u_pcb.pcb_savefpu);
! 98: }
! 99:
! 100: void
! 101: process_xmm_to_s87(const struct savexmm *sxmm, struct save87 *s87)
! 102: {
! 103: int i;
! 104:
! 105: /* FPU control/status */
! 106: s87->sv_env.en_cw = sxmm->sv_env.en_cw;
! 107: s87->sv_env.en_sw = sxmm->sv_env.en_sw;
! 108: /* tag word handled below */
! 109: s87->sv_env.en_fip = sxmm->sv_env.en_fip;
! 110: s87->sv_env.en_fcs = sxmm->sv_env.en_fcs;
! 111: s87->sv_env.en_opcode = sxmm->sv_env.en_opcode;
! 112: s87->sv_env.en_foo = sxmm->sv_env.en_foo;
! 113: s87->sv_env.en_fos = sxmm->sv_env.en_fos;
! 114:
! 115: /* Tag word and registers. */
! 116: for (i = 0; i < 8; i++) {
! 117: if (sxmm->sv_env.en_tw & (1U << i))
! 118: s87->sv_env.en_tw &= ~(3U << (i * 2));
! 119: else
! 120: s87->sv_env.en_tw |= (3U << (i * 2));
! 121:
! 122: if (sxmm->sv_ex_tw & (1U << i))
! 123: s87->sv_ex_tw &= ~(3U << (i * 2));
! 124: else
! 125: s87->sv_ex_tw |= (3U << (i * 2));
! 126:
! 127: memcpy(&s87->sv_ac[i].fp_bytes, &sxmm->sv_ac[i].fp_bytes,
! 128: sizeof(s87->sv_ac[i].fp_bytes));
! 129: }
! 130:
! 131: s87->sv_ex_sw = sxmm->sv_ex_sw;
! 132: }
! 133:
! 134: void
! 135: process_fninit_xmm(struct savexmm *sxmm)
! 136: {
! 137: /*
! 138: * The initial control word was already set by setregs(), so
! 139: * save it temporarily.
! 140: */
! 141: uint32_t mxcsr = sxmm->sv_env.en_mxcsr;
! 142: uint16_t cw = sxmm->sv_env.en_cw;
! 143:
! 144: /* XXX Don't zero XMM regs? */
! 145: memset(sxmm, 0, sizeof(*sxmm));
! 146: sxmm->sv_env.en_cw = cw;
! 147: sxmm->sv_env.en_mxcsr = mxcsr;
! 148: sxmm->sv_env.en_sw = 0x0000;
! 149: sxmm->sv_env.en_tw = 0x00;
! 150: }
! 151:
! 152: int
! 153: process_read_regs(struct proc *p, struct reg *regs)
! 154: {
! 155: struct trapframe *tf = process_frame(p);
! 156:
! 157: #ifdef VM86
! 158: if (tf->tf_eflags & PSL_VM) {
! 159: regs->r_gs = tf->tf_vm86_gs & 0xffff;
! 160: regs->r_fs = tf->tf_vm86_fs & 0xffff;
! 161: regs->r_es = tf->tf_vm86_es & 0xffff;
! 162: regs->r_ds = tf->tf_vm86_ds & 0xffff;
! 163: regs->r_eflags = get_vflags(p);
! 164: } else
! 165: #endif
! 166: {
! 167: regs->r_gs = tf->tf_gs & 0xffff;
! 168: regs->r_fs = tf->tf_fs & 0xffff;
! 169: regs->r_es = tf->tf_es & 0xffff;
! 170: regs->r_ds = tf->tf_ds & 0xffff;
! 171: regs->r_eflags = tf->tf_eflags;
! 172: }
! 173: regs->r_edi = tf->tf_edi;
! 174: regs->r_esi = tf->tf_esi;
! 175: regs->r_ebp = tf->tf_ebp;
! 176: regs->r_ebx = tf->tf_ebx;
! 177: regs->r_edx = tf->tf_edx;
! 178: regs->r_ecx = tf->tf_ecx;
! 179: regs->r_eax = tf->tf_eax;
! 180: regs->r_eip = tf->tf_eip;
! 181: regs->r_cs = tf->tf_cs & 0xffff;
! 182: regs->r_esp = tf->tf_esp;
! 183: regs->r_ss = tf->tf_ss & 0xffff;
! 184:
! 185: return (0);
! 186: }
! 187:
! 188: int
! 189: process_read_fpregs(struct proc *p, struct fpreg *regs)
! 190: {
! 191: union savefpu *frame = process_fpframe(p);
! 192:
! 193: if (p->p_md.md_flags & MDP_USEDFPU) {
! 194: #if NNPX > 0
! 195: npxsave_proc(p, 1);
! 196: #endif
! 197: } else {
! 198: /* Fake a FNINIT. */
! 199: if (i386_use_fxsave) {
! 200: process_fninit_xmm(&frame->sv_xmm);
! 201: } else {
! 202: /*
! 203: * The initial control word was already set by
! 204: * setregs(), so save it temporarily.
! 205: */
! 206: uint16_t cw = frame->sv_87.sv_env.en_cw;
! 207:
! 208: memset(&frame->sv_87, 0, sizeof(frame->sv_87));
! 209: frame->sv_87.sv_env.en_cw = cw;
! 210: frame->sv_87.sv_env.en_sw = 0x0000;
! 211: frame->sv_87.sv_env.en_tw = 0xffff;
! 212: }
! 213: p->p_md.md_flags |= MDP_USEDFPU;
! 214: }
! 215:
! 216: if (i386_use_fxsave) {
! 217: struct save87 s87;
! 218:
! 219: /* XXX Yuck */
! 220: process_xmm_to_s87(&frame->sv_xmm, &s87);
! 221: memcpy(regs, &s87, sizeof(*regs));
! 222: } else
! 223: memcpy(regs, &frame->sv_87, sizeof(*regs));
! 224:
! 225: return (0);
! 226: }
! 227:
! 228: #ifdef PTRACE
! 229:
! 230: void
! 231: process_s87_to_xmm(const struct save87 *s87, struct savexmm *sxmm)
! 232: {
! 233: int i;
! 234:
! 235: /* FPU control/status */
! 236: sxmm->sv_env.en_cw = s87->sv_env.en_cw;
! 237: sxmm->sv_env.en_sw = s87->sv_env.en_sw;
! 238: /* tag word handled below */
! 239: sxmm->sv_env.en_fip = s87->sv_env.en_fip;
! 240: sxmm->sv_env.en_fcs = s87->sv_env.en_fcs;
! 241: sxmm->sv_env.en_opcode = s87->sv_env.en_opcode;
! 242: sxmm->sv_env.en_foo = s87->sv_env.en_foo;
! 243: sxmm->sv_env.en_fos = s87->sv_env.en_fos;
! 244:
! 245: /* Tag word and registers. */
! 246: for (i = 0; i < 8; i++) {
! 247: if (((s87->sv_env.en_tw >> (i * 2)) & 3) == 3)
! 248: sxmm->sv_env.en_tw &= ~(1U << i);
! 249: else
! 250: sxmm->sv_env.en_tw |= (1U << i);
! 251:
! 252: if (((s87->sv_ex_tw >> (i * 2)) & 3) == 3)
! 253: sxmm->sv_ex_tw &= ~(1U << i);
! 254: else
! 255: sxmm->sv_ex_tw |= (1U << i);
! 256:
! 257: memcpy(&sxmm->sv_ac[i].fp_bytes, &s87->sv_ac[i].fp_bytes,
! 258: sizeof(sxmm->sv_ac[i].fp_bytes));
! 259: }
! 260:
! 261: sxmm->sv_ex_sw = s87->sv_ex_sw;
! 262: }
! 263:
! 264: int
! 265: process_write_regs(struct proc *p, struct reg *regs)
! 266: {
! 267: struct trapframe *tf = process_frame(p);
! 268:
! 269: #ifdef VM86
! 270: if (tf->tf_eflags & PSL_VM) {
! 271: tf->tf_vm86_gs = regs->r_gs & 0xffff;
! 272: tf->tf_vm86_fs = regs->r_fs & 0xffff;
! 273: tf->tf_vm86_es = regs->r_es & 0xffff;
! 274: tf->tf_vm86_ds = regs->r_ds & 0xffff;
! 275: set_vflags(p, regs->r_eflags);
! 276: } else
! 277: #endif
! 278: {
! 279: /*
! 280: * Check for security violations.
! 281: */
! 282: if (((regs->r_eflags ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 ||
! 283: !USERMODE(regs->r_cs, regs->r_eflags))
! 284: return (EINVAL);
! 285:
! 286: tf->tf_gs = regs->r_gs & 0xffff;
! 287: tf->tf_fs = regs->r_fs & 0xffff;
! 288: tf->tf_es = regs->r_es & 0xffff;
! 289: tf->tf_ds = regs->r_ds & 0xffff;
! 290: tf->tf_eflags = regs->r_eflags;
! 291: }
! 292: tf->tf_edi = regs->r_edi;
! 293: tf->tf_esi = regs->r_esi;
! 294: tf->tf_ebp = regs->r_ebp;
! 295: tf->tf_ebx = regs->r_ebx;
! 296: tf->tf_edx = regs->r_edx;
! 297: tf->tf_ecx = regs->r_ecx;
! 298: tf->tf_eax = regs->r_eax;
! 299: tf->tf_eip = regs->r_eip;
! 300: tf->tf_cs = regs->r_cs & 0xffff;
! 301: tf->tf_esp = regs->r_esp;
! 302: tf->tf_ss = regs->r_ss & 0xffff;
! 303:
! 304: return (0);
! 305: }
! 306:
! 307: int
! 308: process_write_fpregs(struct proc *p, struct fpreg *regs)
! 309: {
! 310: union savefpu *frame = process_fpframe(p);
! 311:
! 312: if (p->p_md.md_flags & MDP_USEDFPU) {
! 313: #if NNPX > 0
! 314: npxsave_proc(p, 0);
! 315: #endif
! 316: } else
! 317: p->p_md.md_flags |= MDP_USEDFPU;
! 318:
! 319: if (i386_use_fxsave) {
! 320: struct save87 s87;
! 321:
! 322: /* XXX Yuck. */
! 323: memcpy(&s87, regs, sizeof(*regs));
! 324: process_s87_to_xmm(&s87, &frame->sv_xmm);
! 325: } else
! 326: memcpy(&frame->sv_87, regs, sizeof(*regs));
! 327:
! 328: return (0);
! 329: }
! 330:
! 331: int
! 332: process_read_xmmregs(struct proc *p, struct xmmregs *regs)
! 333: {
! 334: union savefpu *frame = process_fpframe(p);
! 335:
! 336: if (!i386_use_fxsave)
! 337: return (EINVAL);
! 338:
! 339: if (p->p_md.md_flags & MDP_USEDFPU) {
! 340: #if NNPX > 0
! 341: npxsave_proc(p, 1);
! 342: #endif
! 343: } else {
! 344: /* Fake a FNINIT. */
! 345: process_fninit_xmm(&frame->sv_xmm);
! 346: p->p_md.md_flags |= MDP_USEDFPU;
! 347: }
! 348:
! 349: memcpy(regs, &frame->sv_xmm, sizeof(*regs));
! 350: return (0);
! 351: }
! 352:
! 353: int
! 354: process_write_xmmregs(struct proc *p, const struct xmmregs *regs)
! 355: {
! 356: union savefpu *frame = process_fpframe(p);
! 357:
! 358: if (!i386_use_fxsave)
! 359: return (EINVAL);
! 360:
! 361: if (p->p_md.md_flags & MDP_USEDFPU) {
! 362: #if NNPX > 0
! 363: npxsave_proc(p, 0);
! 364: #endif
! 365: } else
! 366: p->p_md.md_flags |= MDP_USEDFPU;
! 367:
! 368: memcpy(&frame->sv_xmm, regs, sizeof(*regs));
! 369: return (0);
! 370: }
! 371:
! 372: int
! 373: process_sstep(struct proc *p, int sstep)
! 374: {
! 375: struct trapframe *tf = process_frame(p);
! 376:
! 377: if (sstep)
! 378: tf->tf_eflags |= PSL_T;
! 379: else
! 380: tf->tf_eflags &= ~PSL_T;
! 381:
! 382: return (0);
! 383: }
! 384:
! 385: int
! 386: process_set_pc(struct proc *p, caddr_t addr)
! 387: {
! 388: struct trapframe *tf = process_frame(p);
! 389:
! 390: tf->tf_eip = (int)addr;
! 391:
! 392: return (0);
! 393: }
! 394:
! 395: #endif /* PTRACE */
CVSweb