cxgbe/t4_tom: Read the chip's DDP page sizes and save them in a
[freebsd-src.git] / sys / i386 / i386 / ptrace_machdep.c
blob12bafe55e16ca9fe2674f9825f9019134aba10d9
1 /*-
2 * Copyright (c) 2005 Doug Rabson
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
31 #include "opt_cpu.h"
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/malloc.h>
36 #include <sys/proc.h>
37 #include <sys/ptrace.h>
38 #include <machine/frame.h>
39 #include <machine/md_var.h>
40 #include <machine/pcb.h>
42 #if !defined(CPU_DISABLE_SSE) && defined(I686_CPU)
43 #define CPU_ENABLE_SSE
44 #endif
46 #ifdef CPU_ENABLE_SSE
47 static int
48 cpu_ptrace_xstate(struct thread *td, int req, void *addr, int data)
50 struct ptrace_xstate_info info;
51 char *savefpu;
52 int error;
54 if (!use_xsave)
55 return (EOPNOTSUPP);
57 switch (req) {
58 case PT_GETXSTATE_OLD:
59 npxgetregs(td);
60 savefpu = (char *)(get_pcb_user_save_td(td) + 1);
61 error = copyout(savefpu, addr,
62 cpu_max_ext_state_size - sizeof(union savefpu));
63 break;
65 case PT_SETXSTATE_OLD:
66 if (data > cpu_max_ext_state_size - sizeof(union savefpu)) {
67 error = EINVAL;
68 break;
70 savefpu = malloc(data, M_TEMP, M_WAITOK);
71 error = copyin(addr, savefpu, data);
72 if (error == 0) {
73 npxgetregs(td);
74 error = npxsetxstate(td, savefpu, data);
76 free(savefpu, M_TEMP);
77 break;
79 case PT_GETXSTATE_INFO:
80 if (data != sizeof(info)) {
81 error = EINVAL;
82 break;
84 info.xsave_len = cpu_max_ext_state_size;
85 info.xsave_mask = xsave_mask;
86 error = copyout(&info, addr, data);
87 break;
89 case PT_GETXSTATE:
90 npxgetregs(td);
91 savefpu = (char *)(get_pcb_user_save_td(td));
92 error = copyout(savefpu, addr, cpu_max_ext_state_size);
93 break;
95 case PT_SETXSTATE:
96 if (data < sizeof(union savefpu) ||
97 data > cpu_max_ext_state_size) {
98 error = EINVAL;
99 break;
101 savefpu = malloc(data, M_TEMP, M_WAITOK);
102 error = copyin(addr, savefpu, data);
103 if (error == 0)
104 error = npxsetregs(td, (union savefpu *)savefpu,
105 savefpu + sizeof(union savefpu), data -
106 sizeof(union savefpu));
107 free(savefpu, M_TEMP);
108 break;
110 default:
111 error = EINVAL;
112 break;
115 return (error);
117 #endif
119 static int
120 cpu_ptrace_xmm(struct thread *td, int req, void *addr, int data)
122 #ifdef CPU_ENABLE_SSE
123 struct savexmm *fpstate;
124 int error;
126 if (!cpu_fxsr)
127 return (EINVAL);
129 fpstate = &get_pcb_user_save_td(td)->sv_xmm;
130 switch (req) {
131 case PT_GETXMMREGS:
132 npxgetregs(td);
133 error = copyout(fpstate, addr, sizeof(*fpstate));
134 break;
136 case PT_SETXMMREGS:
137 npxgetregs(td);
138 error = copyin(addr, fpstate, sizeof(*fpstate));
139 fpstate->sv_env.en_mxcsr &= cpu_mxcsr_mask;
140 break;
142 case PT_GETXSTATE_OLD:
143 case PT_SETXSTATE_OLD:
144 case PT_GETXSTATE_INFO:
145 case PT_GETXSTATE:
146 case PT_SETXSTATE:
147 error = cpu_ptrace_xstate(td, req, addr, data);
148 break;
150 default:
151 return (EINVAL);
154 return (error);
155 #else
156 return (EINVAL);
157 #endif
161 cpu_ptrace(struct thread *td, int req, void *addr, int data)
163 struct segment_descriptor *sdp, sd;
164 register_t r;
165 int error;
167 switch (req) {
168 case PT_GETXMMREGS:
169 case PT_SETXMMREGS:
170 case PT_GETXSTATE_OLD:
171 case PT_SETXSTATE_OLD:
172 case PT_GETXSTATE_INFO:
173 case PT_GETXSTATE:
174 case PT_SETXSTATE:
175 error = cpu_ptrace_xmm(td, req, addr, data);
176 break;
178 case PT_GETFSBASE:
179 case PT_GETGSBASE:
180 sdp = req == PT_GETFSBASE ? &td->td_pcb->pcb_fsd :
181 &td->td_pcb->pcb_gsd;
182 r = sdp->sd_hibase << 24 | sdp->sd_lobase;
183 error = copyout(&r, addr, sizeof(r));
184 break;
186 case PT_SETFSBASE:
187 case PT_SETGSBASE:
188 error = copyin(addr, &r, sizeof(r));
189 if (error != 0)
190 break;
191 fill_based_sd(&sd, r);
192 if (req == PT_SETFSBASE) {
193 td->td_pcb->pcb_fsd = sd;
194 td->td_frame->tf_fs = GSEL(GUFS_SEL, SEL_UPL);
195 } else {
196 td->td_pcb->pcb_gsd = sd;
197 td->td_pcb->pcb_gs = GSEL(GUGS_SEL, SEL_UPL);
199 break;
201 default:
202 return (EINVAL);
205 return (error);