summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/aim/copyinout.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/powerpc/aim/copyinout.c')
-rw-r--r--sys/powerpc/aim/copyinout.c260
1 files changed, 260 insertions, 0 deletions
diff --git a/sys/powerpc/aim/copyinout.c b/sys/powerpc/aim/copyinout.c
new file mode 100644
index 0000000..c1ec6d3
--- /dev/null
+++ b/sys/powerpc/aim/copyinout.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2002 Benno Rice
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*-
+ * Copyright (C) 1993 Wolfgang Solfrank.
+ * Copyright (C) 1993 TooLs GmbH.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+
+/*
+ * Makes sure that the right segment of userspace is mapped in.
+ */
+static __inline void
+set_user_sr(register_t vsid)
+{
+
+ isync();
+ __asm __volatile ("mtsr %0,%1" :: "n"(USER_SR), "r"(vsid));
+ isync();
+}
+
+int
+copyout(const void *kaddr, void *udaddr, size_t len)
+{
+ struct thread *td;
+ pmap_t pm;
+ const char *kp;
+ char *up, *p;
+ size_t l;
+
+ td = PCPU_GET(curthread);
+ pm = &td->td_proc->p_vmspace->vm_pmap;
+
+ kp = kaddr;
+ up = udaddr;
+
+ while (len > 0) {
+ p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
+
+ l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
+ if (l > len)
+ l = len;
+
+ set_user_sr(pm->pm_sr[(u_int)up >> ADDR_SR_SHFT]);
+
+ bcopy(kp, p, l);
+
+ up += l;
+ kp += l;
+ len -= l;
+ }
+
+ return (0);
+}
+
+int
+copyin(const void *udaddr, void *kaddr, size_t len)
+{
+ struct thread *td;
+ pmap_t pm;
+ const char *up;
+ char *kp, *p;
+ size_t l;
+
+ td = PCPU_GET(curthread);
+ pm = &td->td_proc->p_vmspace->vm_pmap;
+
+ kp = kaddr;
+ up = udaddr;
+
+ while (len > 0) {
+ p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
+
+ l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
+ if (l > len)
+ l = len;
+
+ set_user_sr(pm->pm_sr[(u_int)up >> ADDR_SR_SHFT]);
+
+ bcopy(p, kp, l);
+
+ up += l;
+ kp += l;
+ len -= l;
+ }
+
+ return (0);
+}
+
+int
+copyinstr(const void *udaddr, void *kaddr, size_t len, size_t *done)
+{
+ struct thread *td;
+ pmap_t pm;
+ const char *up;
+ char *kp;
+ size_t l;
+ int rv, c;
+
+ td = PCPU_GET(curthread);
+ pm = &td->td_proc->p_vmspace->vm_pmap;
+
+ kp = kaddr;
+ up = udaddr;
+
+ rv = ENAMETOOLONG;
+
+ for (l = 0; len-- > 0; l++) {
+ if ((c = fubyte(up++)) < 0) {
+ rv = EFAULT;
+ break;
+ }
+
+ if (!(*kp++ = c)) {
+ l++;
+ rv = 0;
+ break;
+ }
+ }
+
+ if (done != NULL) {
+ *done = l;
+ }
+
+ return (rv);
+}
+
+int
+subyte(void *addr, int byte)
+{
+ struct thread *td;
+ pmap_t pm;
+ char *p;
+
+ td = PCPU_GET(curthread);
+ pm = &td->td_proc->p_vmspace->vm_pmap;
+ p = (char *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
+
+ set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
+
+ *p = (char)byte;
+
+ return (0);
+}
+
+int
+suibyte(void *addr, int byte)
+{
+
+ return (subyte(addr, byte));
+}
+
+int
+suword(void *addr, long word)
+{
+ struct thread *td;
+ pmap_t pm;
+ long *p;
+
+ td = PCPU_GET(curthread);
+ pm = &td->td_proc->p_vmspace->vm_pmap;
+ p = (long *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
+
+ set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
+
+ *p = word;
+
+ return (0);
+}
+
+int
+fubyte(const void *addr)
+{
+ struct thread *td;
+ pmap_t pm;
+ char *p;
+
+ td = PCPU_GET(curthread);
+ pm = &td->td_proc->p_vmspace->vm_pmap;
+ p = (char *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
+
+ set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
+
+ return ((int)*p);
+}
+
+long
+fuword(const void *addr)
+{
+ struct thread *td;
+ pmap_t pm;
+ long *p;
+
+ td = PCPU_GET(curthread);
+ pm = &td->td_proc->p_vmspace->vm_pmap;
+ p = (long *)((u_int)USER_ADDR + ((u_int)addr & ~SEGMENT_MASK));
+
+ set_user_sr(pm->pm_sr[(u_int)addr >> ADDR_SR_SHFT]);
+
+ return (*p);
+}
OpenPOWER on IntegriCloud