summaryrefslogtreecommitdiff
path: root/sys/arch/sh
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2023-08-14 07:40:09 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2023-08-14 07:40:09 +0000
commit82883a6765d9116edd2795a1a63d0731aff3390d (patch)
treec58e9a1f35caaa9c792b7e08379e2e178de2cf2e /sys/arch/sh
parent3ee07197baa20f3bfcc9ac9503f375febff5c82e (diff)
Add a copyin32() implementation.
Diffstat (limited to 'sys/arch/sh')
-rw-r--r--sys/arch/sh/sh/locore_subr.S52
1 files changed, 51 insertions, 1 deletions
diff --git a/sys/arch/sh/sh/locore_subr.S b/sys/arch/sh/sh/locore_subr.S
index 5ee3cd907a5..97ed4c4fbef 100644
--- a/sys/arch/sh/sh/locore_subr.S
+++ b/sys/arch/sh/sh/locore_subr.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore_subr.S,v 1.15 2023/01/31 15:18:55 deraadt Exp $ */
+/* $OpenBSD: locore_subr.S,v 1.16 2023/08/14 07:40:08 miod Exp $ */
/* $NetBSD: locore_subr.S,v 1.28 2006/01/23 22:52:09 uwe Exp $ */
/*
@@ -665,6 +665,56 @@ ENTRY(_copyin)
.long memcpy
SET_ENTRY_SIZE(_copyin)
+/*
+ * int copyin32(const void *usrc, void *kdst)
+ */
+ENTRY(copyin32)
+ mov.l r14, @-r15
+ sts.l pr, @-r15
+ mov r15, r14
+
+ mov #3, r3
+ mov #EFAULT, r0 /* assume there was a problem */
+ and r4, r3
+ tst r3, r3
+ bf 2f /* punt if not aligned */
+
+ mov.l .L_copyin32_VM_MAXUSER_ADDRESS, r1
+ cmp/hi r1, r4 /* bomb if uaddr isn't in user space */
+ bt 2f
+
+ mov.l .L_copyin32_curpcb, r1 /* set fault handler */
+ mov.l @r1, r2
+ mov.l .L_copyin32_onfault, r3
+ mov.l r3, @(PCB_ONFAULT,r2)
+
+ mov.l @r4, r1
+ mov #0, r0
+ mov.l r1, @r5
+ mov.l r0, @(PCB_ONFAULT,r2)
+2:
+ mov r14, r15
+ lds.l @r15+, pr
+ rts
+ mov.l @r15+, r14
+
+3:
+ mov.l .L_copyin32_curpcb, r1 /* clear fault handler */
+ mov.l @r1, r2
+ mov #0, r1
+ mov.l r1, @(PCB_ONFAULT,r2)
+
+ bra 2b
+ mov #EFAULT, r0
+
+ .align 2
+.L_copyin32_onfault:
+ .long 3b
+.L_copyin32_VM_MAXUSER_ADDRESS:
+ .long VM_MAXUSER_ADDRESS - 4 /* sizeof(uint32_t) */
+.L_copyin32_curpcb:
+ .long curpcb
+ SET_ENTRY_SIZE(copyin32)
/*
* LINTSTUB: Func: int copyoutstr(const void *ksrc, void *udst, size_t maxlen, size_t *lencopied)