summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2014-03-14 10:47:22 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2014-03-14 10:47:22 +0000
commit2d885fe86ccebb33f3d9e3c029ca1b6cade18f6b (patch)
treecd6175643df2bb53584a3385d297f140a0ecc2aa /sys/arch/sparc64
parenta8b9d12405176b7cd22cd2eb8edd582212af10e2 (diff)
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/arch/sparc64')
-rw-r--r--sys/arch/sparc64/include/endian.h73
1 files changed, 72 insertions, 1 deletions
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