1 /*	$OpenBSD: process_machdep.c,v 1.8 2004/03/02 23:45:27 miod Exp $	*/
2 /*	$NetBSD: process_machdep.c,v 1.6 1996/03/14 21:09:26 christos Exp $ */
3 
4 /*
5  * Copyright (c) 1993 The Regents of the University of California.
6  * Copyright (c) 1993 Jan-Simon Pendry
7  * All rights reserved.
8  *
9  * This code is derived from software contributed to Berkeley by
10  * Jan-Simon Pendry.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * from: Id: procfs_i386.c,v 4.1 1993/12/17 10:47:45 jsp Rel
37  */
38 
39 /*
40  * This file may seem a bit stylized, but that so that it's easier to port.
41  * Functions to be implemented here are:
42  *
43  * process_read_regs(proc, regs)
44  *	Get the current user-visible register set from the process
45  *	and copy it into the regs structure (<machine/reg.h>).
46  *	The process is stopped at the time read_regs is called.
47  *
48  * process_write_regs(proc, regs)
49  *	Update the current register set from the passed in regs
50  *	structure.  Take care to avoid clobbering special CPU
51  *	registers or privileged bits in the PSL.
52  *	The process is stopped at the time write_regs is called.
53  *
54  * process_sstep(proc)
55  *	Arrange for the process to trap after executing a single instruction.
56  *
57  * process_set_pc(proc)
58  *	Set the process's program counter.
59  */
60 
61 #include <sys/param.h>
62 #include <sys/systm.h>
63 #include <sys/time.h>
64 #include <sys/kernel.h>
65 #include <sys/proc.h>
66 #include <sys/user.h>
67 #include <sys/vnode.h>
68 #include <machine/psl.h>
69 #include <machine/reg.h>
70 #include <machine/frame.h>
71 #include <sys/ptrace.h>
72 
73 int
process_read_regs(p,regs)74 process_read_regs(p, regs)
75 	struct proc *p;
76 	struct reg *regs;
77 {
78 	/* NOTE: struct reg == struct trapframe */
79 	bcopy(p->p_md.md_tf, (caddr_t)regs, sizeof(struct reg));
80 	return (0);
81 }
82 
83 int
process_read_fpregs(p,regs)84 process_read_fpregs(p, regs)
85 	struct proc	*p;
86 	struct fpreg	*regs;
87 {
88 	extern struct fpstate	initfpstate;
89 	struct fpstate		*statep = &initfpstate;
90 
91 	/* NOTE: struct fpreg == struct fpstate */
92 	if (p->p_md.md_fpstate)
93 		statep = p->p_md.md_fpstate;
94 	bcopy(statep, regs, sizeof(struct fpreg));
95 	return 0;
96 }
97 
98 #ifdef PTRACE
99 
100 int
process_write_regs(p,regs)101 process_write_regs(p, regs)
102 	struct proc *p;
103 	struct reg *regs;
104 {
105 	int	psr = p->p_md.md_tf->tf_psr & ~PSR_ICC;
106 
107 	if (((regs->r_pc | regs->r_npc) & 0x03) != 0)
108 		return (EINVAL);
109 
110 	bcopy((caddr_t)regs, p->p_md.md_tf, sizeof(struct reg));
111 	p->p_md.md_tf->tf_psr = psr | (regs->r_psr & PSR_ICC);
112 	return (0);
113 }
114 
115 int
process_sstep(p,sstep)116 process_sstep(p, sstep)
117 	struct proc *p;
118 	int sstep;
119 {
120 	if (sstep)
121 		return EINVAL;
122 	return (0);
123 }
124 
125 int
process_set_pc(p,addr)126 process_set_pc(p, addr)
127 	struct proc *p;
128 	caddr_t addr;
129 {
130 	if (((u_int)addr & 0x03) != 0)
131 		return (EINVAL);
132 
133 	p->p_md.md_tf->tf_pc = (u_int)addr;
134 	p->p_md.md_tf->tf_npc = (u_int)addr + 4;
135 	return (0);
136 }
137 
138 int
process_write_fpregs(p,regs)139 process_write_fpregs(p, regs)
140 	struct proc	*p;
141 	struct fpreg	*regs;
142 {
143 	if (p->p_md.md_fpstate == NULL)
144 		return EINVAL;
145 
146 	bcopy(regs, p->p_md.md_fpstate, sizeof(struct fpreg));
147 	return 0;
148 }
149 
150 register_t
process_get_wcookie(p)151 process_get_wcookie(p)
152 	struct proc *p;
153 {
154 	return p->p_addr->u_pcb.pcb_wcookie;
155 }
156 
157 #endif	/* PTRACE */
158