summaryrefslogtreecommitdiffstats
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
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@
-rw-r--r--share/man/man9/Makefile8
-rw-r--r--share/man/man9/bemtoh32.9143
-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
5 files changed, 359 insertions, 7 deletions
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 73099014139..a24c99083e4 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.201 2014/02/09 15:40:24 jmc Exp $
+# $OpenBSD: Makefile,v 1.202 2014/03/14 10:47:21 dlg Exp $
# $NetBSD: Makefile,v 1.4 1996/01/09 03:23:01 thorpej Exp $
# Makefile for section 9 (kernel function and variable) manual pages.
@@ -7,7 +7,7 @@ MAN= altq.9 aml_evalnode.9 atomic_add_int.9 atomic_cas_uint.9 \
atomic_dec_int.9 atomic_inc_int.9 atomic_setbits_int.9 \
atomic_sub_int.9 atomic_swap_uint.9 \
audio.9 autoconf.9 \
- bio_register.9 boot.9 buffercache.9 bus_dma.9 bus_space.9 \
+ bemtoh32.9 bio_register.9 boot.9 buffercache.9 bus_dma.9 bus_space.9 \
copy.9 crypto.9 delay.9 \
disk.9 disklabel.9 dma_alloc.9 dohooks.9 dopowerhooks.9 \
domountroothooks.9 doshutdownhooks.9 dostartuphooks.9 \
@@ -61,6 +61,10 @@ MLINKS+=autoconf.9 config_init.9 autoconf.9 config_search.9 \
autoconf.9 config_attach.9 autoconf.9 config_detach.9 \
autoconf.9 config_activate.9 autoconf.9 config_deactivate.9 \
autoconf.9 config_defer.9
+MLINKS+=bemtoh32.9 bemtoh16.9 bemtoh32.9 bemtoh64.9 \
+ bemtoh32.9 htobem16.9 bemtoh32.9 htobem32.9 bemtoh32.9 htobem64.9 \
+ bemtoh32.9 lemtoh16.9 bemtoh32.9 lemtoh32.9 bemtoh32.9 lemtoh64.9 \
+ bemtoh32.9 htolem16.9 bemtoh32.9 htolem32.9 bemtoh32.9 htolem64.9
MLINKS+=bio_register.9 bio_unregister.9
MLINKS+=buffercache.9 bread.9 buffercache.9 breadn.9 \
buffercache.9 bwrite.9 buffercache.9 bawrite.9 \
diff --git a/share/man/man9/bemtoh32.9 b/share/man/man9/bemtoh32.9
new file mode 100644
index 00000000000..347aed4d332
--- /dev/null
+++ b/share/man/man9/bemtoh32.9
@@ -0,0 +1,143 @@
+.\" $OpenBSD: bemtoh32.9,v 1.3 2014/03/14 10:47:21 dlg Exp $
+.\"
+.\" Copyright (c) 2014 David Gwynne <dlg@openbsd.org>
+.\" All rights reserved.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: March 14 2014 $
+.Dt BEMTOH32 9
+.Os
+.Sh NAME
+.Nm bemtoh16 ,
+.Nm bemtoh32 ,
+.Nm bemtoh64 ,
+.Nm lemtoh16 ,
+.Nm lemtoh32 ,
+.Nm lemtoh64 ,
+.Nm htobem16 ,
+.Nm htobem32 ,
+.Nm htobem64 ,
+.Nm htobem16 ,
+.Nm htobem32 ,
+.Nm htobem64
+.Nd byte swapping memory load and store operations
+.Sh SYNOPSIS
+.In sys/types.h
+.Ft uint16_t
+.Fn bemtoh16 "uint16_t *m"
+.Ft uint32_t
+.Fn bemtoh32 "uint32_t *m"
+.Ft uint64_t
+.Fn bemtoh64 "uint64_t *m"
+.Ft uint16_t
+.Fn lemtoh16 "uint16_t *m"
+.Ft uint32_t
+.Fn lemtoh32 "uint32_t *m"
+.Ft uint64_t
+.Fn lemtoh64 "uint64_t *m"
+.Ft void
+.Fn htobem16 "uint16_t *m, uint16_t v"
+.Ft void
+.Fn htobem32 "uint32_t *m, uint32_t v"
+.Ft void
+.Fn htobem64 "uint64_t *m, uint64_t v"
+.Ft void
+.Fn htolem16 "uint16_t *m, uint16_t v"
+.Ft void
+.Fn htolem32 "uint32_t *m, uint32_t v"
+.Ft void
+.Fn htolem64 "uint64_t *m, uint64_t v"
+.Sh DESCRIPTION
+This API provides a way to take advantage of an architectures ability
+to load and store words in memory of different endians.
+If an architecture has no specialised support for these operations
+they will be implemented as a wrapper around the
+.Xr byteorder 3
+API.
+.Pp
+These operations are subject to the same alignment restrictions as
+the hosts normal memory loads and stores.
+.Pp
+.Fn bemtoh16 ,
+.Fn bemtoh32 ,
+and
+.Fn bemtoh64
+read a big endian value from the memory located at
+.Fa m
+into the hosts native byte order.
+.Fn lemtoh16 ,
+.Fn lemtoh32 ,
+and
+.Fn lemtoh64
+read a little endian value from the memory located at
+.Fa m
+into the hosts native byte order.
+.Pp
+.Fn htobem16 ,
+.Fn htobem32 ,
+and
+.Fn htobem64
+store the hosts native byte ordered value of
+.Fa v
+as a big endian value in the memory located at
+.Fa m .
+.Fn htolem16 ,
+.Fn htolem32 ,
+and
+.Fn htolem64
+store the hosts native byte ordered value of
+.Fa v
+as a little endian value in the memory located at
+.Fa m .
+.Sh CONTEXT
+.Fn bemtoh16 ,
+.Fn bemtoh32 ,
+.Fn bemtoh64 ,
+.Fn lemtoh16 ,
+.Fn lemtoh32 ,
+.Fn lemtoh64 ,
+.Fn htobem16 ,
+.Fn htobem32 ,
+.Fn htobem64 ,
+.Fn htolem16 ,
+.Fn htolem32 ,
+and
+.Fn htolem64
+can be called during autoconf, from process context, or from interrupt
+context.
+.Sh RETURN VALUES
+.Fn bemtoh16 ,
+.Fn bemtoh32 ,
+.Fn bemtoh64 ,
+.Fn lemtoh16 ,
+.Fn lemtoh32 ,
+and
+.Fn lemtoh64
+return the hosts native byte ordered value of the memory at
+.Fa m
+after the appropriate byteswapping has occurred.
+.Pp
+.Fn htobem16 ,
+.Fn htobem32 ,
+.Fn htobem64 ,
+.Fn htolem16 ,
+.Fn htolem32 ,
+and
+.Fn htolem64
+do not return a value.
+.Sh SEE ALSO
+.Xr byteorder 3
+.Sh HISTORY
+These functions first appeared in
+.Ox 5.6 .
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))