2 * Copyright (C) 2002 Benno Rice
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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 Benno Rice ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * Copyright (C) 1993 Wolfgang Solfrank.
27 * Copyright (C) 1993 TooLs GmbH.
28 * All rights reserved.
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by TooLs GmbH.
41 * 4. The name of TooLs GmbH may not be used to endorse or promote products
42 * derived from this software without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
45 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
46 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
47 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
49 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
50 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
51 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
52 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
53 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 #include <sys/cdefs.h>
57 __FBSDID("$FreeBSD$");
59 #include <sys/param.h>
60 #include <sys/systm.h>
65 #include <vm/vm_map.h>
67 #include <machine/pcb.h>
68 #include <machine/sr.h>
70 int setfault(faultbuf); /* defined in locore.S */
73 * Makes sure that the right segment of userspace is mapped in.
76 set_user_sr(register_t vsid)
80 __asm __volatile ("mtsr %0,%1" :: "n"(USER_SR), "r"(vsid));
85 copyout(const void *kaddr, void *udaddr, size_t len)
94 td = PCPU_GET(curthread);
95 pm = &td->td_proc->p_vmspace->vm_pmap;
98 td->td_pcb->pcb_onfault = NULL;
106 p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
108 l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
112 set_user_sr(pm->pm_sr[(u_int)up >> ADDR_SR_SHFT]);
121 td->td_pcb->pcb_onfault = NULL;
126 copyin(const void *udaddr, void *kaddr, size_t len)
135 td = PCPU_GET(curthread);
136 pm = &td->td_proc->p_vmspace->vm_pmap;
139 td->td_pcb->pcb_onfault = NULL;
147 p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
149 l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
153 set_user_sr(pm->pm_sr[(u_int)up >> ADDR_SR_SHFT]);
162 td->td_pcb->pcb_onfault = NULL;
167 copyinstr(const void *udaddr, void *kaddr, size_t len, size_t *done)
177 td = PCPU_GET(curthread);
178 pm = &td->td_proc->p_vmspace->vm_pmap;
181 td->td_pcb->pcb_onfault = NULL;
190 for (l = 0; len-- > 0; l++) {
191 if ((c = fubyte(up++)) < 0) {
207 td->td_pcb->pcb_onfault = NULL;
212 subyte(void *addr, int byte)
219 td = PCPU_GET(curthread);
220 pm = &td->td_proc->p_vmspace->vm_pmap;
221 p = (char *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
224 td->td_pcb->pcb_onfault = NULL;
228 set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
232 td->td_pcb->pcb_onfault = NULL;
237 suword(void *addr, long word)
244 td = PCPU_GET(curthread);
245 pm = &td->td_proc->p_vmspace->vm_pmap;
246 p = (long *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
249 td->td_pcb->pcb_onfault = NULL;
253 set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
257 td->td_pcb->pcb_onfault = NULL;
262 suword32(void *addr, int32_t word)
264 return (suword(addr, (long)word));
269 fubyte(const void *addr)
277 td = PCPU_GET(curthread);
278 pm = &td->td_proc->p_vmspace->vm_pmap;
279 p = (u_char *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
282 td->td_pcb->pcb_onfault = NULL;
286 set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
290 td->td_pcb->pcb_onfault = NULL;
295 fuword(const void *addr)
302 td = PCPU_GET(curthread);
303 pm = &td->td_proc->p_vmspace->vm_pmap;
304 p = (long *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
307 td->td_pcb->pcb_onfault = NULL;
311 set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
315 td->td_pcb->pcb_onfault = NULL;
320 fuword32(const void *addr)
322 return ((int32_t)fuword(addr));
326 casuword32(volatile uint32_t *base, uint32_t oldval, uint32_t newval)
328 return (casuword((volatile u_long *)base, oldval, newval));
332 casuword(volatile u_long *addr, u_long old, u_long new)
339 td = PCPU_GET(curthread);
340 pm = &td->td_proc->p_vmspace->vm_pmap;
341 p = (u_long *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
343 set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
346 td->td_pcb->pcb_onfault = NULL;
351 (void) atomic_cmpset_32((volatile uint32_t *)p, old, new);
353 td->td_pcb->pcb_onfault = NULL;