summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordlg <dlg@openbsd.org>2014-03-14 10:47:21 +0000
committerdlg <dlg@openbsd.org>2014-03-14 10:47:21 +0000
commitbf1745be90c87d01ce698ff0c5d23deb311c3971 (patch)
tree621e8caa1e464b7910c9d5353dc3ef421851f6e8 /sys
parent.depend is definitely not *appended* to Makefile. Its rules are also (diff)
downloadwireguard-openbsd-bf1745be90c87d01ce698ff0c5d23deb311c3971.tar.xz
wireguard-openbsd-bf1745be90c87d01ce698ff0c5d23deb311c3971.zip
provide an MI api for doing byteswapping loads and stores. some
archs have instrutions that can do this, and the rest that dont get to use wrappers around the byteswap(3) api. this provides MI backends for sparc64 and powerpc which get a big benefit from this because byteswapping in registers is really hard for them. the intended use case is for reading and writing bits of dma memory handed to and from hardware. discussed with miod@ guenther@ deraadt@ ok miod@ kettenis@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/powerpc/include/endian.h68
-rw-r--r--sys/arch/sparc64/include/endian.h73
-rw-r--r--sys/sys/endian.h74
3 files changed, 210 insertions, 5 deletions
diff --git a/sys/arch/powerpc/include/endian.h b/sys/arch/powerpc/include/endian.h
index 261a8a0ad08..e8cf414d5dc 100644
--- a/sys/arch/powerpc/include/endian.h
+++ b/sys/arch/powerpc/include/endian.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: endian.h,v 1.17 2011/08/22 18:22:07 deraadt Exp $ */
+/* $OpenBSD: endian.h,v 1.18 2014/03/14 10:47:21 dlg Exp $ */
/*-
* Copyright (c) 1997 Niklas Hallqvist. All rights reserved.
@@ -27,6 +27,72 @@
#ifndef _POWERPC_ENDIAN_H_
#define _POWERPC_ENDIAN_H_
+#ifdef _KERNEL
+
+static inline __uint16_t
+__mswap16(volatile __uint16_t *m)
+{
+ __uint16_t v;
+
+ __asm volatile("lhbrx %0, 0, %1"
+ : "=r" (v)
+ : "r" (m), "m" (*m));
+
+ return (v);
+}
+
+static inline __uint32_t
+__mswap32(volatile __uint32_t *m)
+{
+ __uint32_t v;
+
+ __asm volatile("lwbrx %0, 0, %1"
+ : "=r" (v)
+ : "r" (m), "m" (*m));
+
+ return (v);
+}
+
+static inline __uint64_t
+__mswap64(volatile __uint64_t *m)
+{
+ __uint32_t *a = (__uint32_t *)m;
+ __uint64_t v;
+
+ v = (__uint64_t)__mswap32(a + 1) << 32 |
+ (__uint64_t)__mswap32(a);
+
+ return (v);
+}
+
+static inline void
+__swapm16(volatile __uint16_t *m, __uint16_t v)
+{
+ __asm __volatile("sthbrx %1, 0, %2"
+ : "=m" (*m)
+ : "r" (v), "r" (m));
+}
+
+static inline void
+__swapm32(volatile __uint32_t *m, __uint32_t v)
+{
+ __asm __volatile("stwbrx %1, 0, %2"
+ : "=m" (*m)
+ : "r" (v), "r" (m));
+}
+
+static inline void
+__swapm64(volatile __uint64_t *m, __uint64_t v)
+{
+ __uint32_t *a = (__uint32_t *)m;
+
+ __swapm32(a + 1, v >> 32);
+ __swapm32(a, v);
+}
+
+#define MD_SWAPIO
+#endif /* _KERNEL */
+
#undef _BIG_ENDIAN /* XXX - gcc may define _BIG_ENDIAN too */
#define _BYTE_ORDER _BIG_ENDIAN
#include <sys/endian.h>
diff --git a/sys/arch/sparc64/include/endian.h b/sys/arch/sparc64/include/endian.h
index fbe3710afe3..21a57bac38c 100644
--- a/sys/arch/sparc64/include/endian.h
+++ b/sys/arch/sparc64/include/endian.h
@@ -1,9 +1,80 @@
-/* $OpenBSD: endian.h,v 1.3 2011/03/11 15:17:08 pirofti Exp $ */
+/* $OpenBSD: endian.h,v 1.4 2014/03/14 10:47:21 dlg Exp $ */
#ifndef _MACHINE_ENDIAN_H_
#define _MACHINE_ENDIAN_H_
#define _BYTE_ORDER _BIG_ENDIAN
+
+#ifdef _KERNEL
+
+#define ASI_P_L 0x88
+
+static inline __uint16_t
+__mswap16(volatile __uint16_t *m)
+{
+ __uint16_t v;
+
+ __asm __volatile("lduha [%1] %2, %0 ! %3"
+ : "=r" (v)
+ : "r" (m), "n" (ASI_P_L), "m" (*m));
+
+ return (v);
+}
+
+static inline __uint32_t
+__mswap32(volatile __uint32_t *m)
+{
+ __uint32_t v;
+
+ __asm __volatile("lduwa [%1] %2, %0 ! %3"
+ : "=r" (v)
+ : "r" (m), "n" (ASI_P_L), "m" (*m));
+
+ return (v);
+}
+
+static inline __uint64_t
+__mswap64(volatile __uint64_t *m)
+{
+ __uint64_t v;
+
+ __asm __volatile("ldxa [%1] %2, %0 ! %3"
+ : "=r" (v)
+ : "r" (m), "n" (ASI_P_L), "m" (*m));
+
+ return (v);
+}
+
+static inline void
+__swapm16(volatile __uint16_t *m, __uint16_t v)
+{
+ __asm __volatile("stha %1, [%2] %3 ! %0"
+ : "=m" (*m)
+ : "r" (v), "r" (m), "n" (ASI_P_L));
+}
+
+static inline void
+__swapm32(volatile __uint32_t *m, __uint32_t v)
+{
+ __asm __volatile("stwa %1, [%2] %3 ! %0"
+ : "=m" (*m)
+ : "r" (v), "r" (m), "n" (ASI_P_L));
+}
+
+static inline void
+__swapm64(volatile __uint64_t *m, __uint64_t v)
+{
+ __asm __volatile("stxa %1, [%2] %3 ! %0"
+ : "=m" (*m)
+ : "r" (v), "r" (m), "n" (ASI_P_L));
+}
+
+#undef ASI_P_L
+
+#define MD_SWAPIO
+
+#endif /* _KERNEL */
+
#include <sys/endian.h>
#define __STRICT_ALIGNMENT
diff --git a/sys/sys/endian.h b/sys/sys/endian.h
index 499ad153283..5d37a3af754 100644
--- a/sys/sys/endian.h
+++ b/sys/sys/endian.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: endian.h,v 1.20 2013/08/20 12:55:02 kettenis Exp $ */
+/* $OpenBSD: endian.h,v 1.21 2014/03/14 10:47:21 dlg Exp $ */
/*-
* Copyright (c) 1997 Niklas Hallqvist. All rights reserved.
@@ -207,7 +207,41 @@ __END_DECLS
#define ntohs(x) __swap16(x)
#define ntohl(x) __swap32(x)
-#endif /* _BYTE_ORDER */
+#ifdef _KERNEL
+
+#ifdef MD_SWAPIO
+
+#define bemtoh16(_x) __mswap16(_x)
+#define bemtoh32(_x) __mswap32(_x)
+#define bemtoh64(_x) __mswap64(_x)
+
+#define htobem16(_x, _v) __swapm16((_x), (_v))
+#define htobem32(_x, _v) __swapm32((_x), (_v))
+#define htobem64(_x, _v) __swapm64((_x), (_v))
+
+#else /* MD_SWAPIO */
+
+#define bemtoh16(_x) htobe16(*(__uint16_t *)(_x))
+#define bemtoh32(_x) htobe32(*(__uint32_t *)(_x))
+#define bemtoh64(_x) htobe64(*(__uint64_t *)(_x))
+
+#define htobem16(_x, _v) (*(__uint16_t *)(_x) = htobe16(_v))
+#define htobem32(_x, _v) (*(__uint32_t *)(_x) = htobe32(_v))
+#define htobem64(_x, _v) (*(__uint64_t *)(_x) = htole64(_v))
+
+#endif /* MD_SWAPIO */
+
+#define lemtoh16(_x) (*(__uint16_t *)(_x))
+#define lemtoh32(_x) (*(__uint32_t *)(_x))
+#define lemtoh64(_x) (*(__uint64_t *)(_x))
+
+#define htolem16(_x, _v) (*(__uint16_t *)(_x) = (__uint16_t)(_v))
+#define htolem32(_x, _v) (*(__uint32_t *)(_x) = (__uint32_t)(_v))
+#define htolem64(_x, _v) (*(__uint64_t *)(_x) = (__uint64_t)(_v))
+
+#endif /* _KERNEL */
+
+#endif /* _BYTE_ORDER == _LITTLE_ENDIAN */
#if _BYTE_ORDER == _BIG_ENDIAN
@@ -240,7 +274,41 @@ __END_DECLS
#define ntohs(x) ((__uint16_t)(x))
#define ntohl(x) ((__uint32_t)(x))
-#endif /* _BYTE_ORDER */
+#ifdef _KERNEL
+
+#ifdef MD_SWAPIO
+
+#define lemtoh16(_x) __mswap16(_x)
+#define lemtoh32(_x) __mswap32(_x)
+#define lemtoh64(_x) __mswap64(_x)
+
+#define htolem16(_x, _v) __swapm16((_x), (_v))
+#define htolem32(_x, _v) __swapm32((_x), (_v))
+#define htolem64(_x, _v) __swapm64((_x), (_v))
+
+#else /* MD_SWAPIO */
+
+#define lemtoh16(_x) htole16(*(__uint16_t *)(_x))
+#define lemtoh32(_x) htole32(*(__uint32_t *)(_x))
+#define lemtoh64(_x) htole64(*(__uint64_t *)(_x))
+
+#define htolem16(_x, _v) (*(__uint16_t *)(_x) = htole16(_v))
+#define htolem32(_x, _v) (*(__uint32_t *)(_x) = htole32(_v))
+#define htolem64(_x, _v) (*(__uint64_t *)(_x) = htole64(_v))
+
+#endif /* MD_SWAPIO */
+
+#define bemtoh16(_x) (*(__uint16_t *)(_x))
+#define bemtoh32(_x) (*(__uint32_t *)(_x))
+#define bemtoh64(_x) (*(__uint64_t *)(_x))
+
+#define htobem16(_x, _v) (*(__uint16_t *)(_x) = (__uint16_t)(_v))
+#define htobem32(_x, _v) (*(__uint32_t *)(_x) = (__uint32_t)(_v))
+#define htobem64(_x, _v) (*(__uint64_t *)(_x) = (__uint64_t)(_v))
+
+#endif /* _KERNEL */
+
+#endif /* _BYTE_ORDER == _BIG_ENDIAN */
#if __BSD_VISIBLE
#define NTOHL(x) (x) = ntohl((u_int32_t)(x))