diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2014-03-14 10:47:22 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2014-03-14 10:47:22 +0000 |
commit | 2d885fe86ccebb33f3d9e3c029ca1b6cade18f6b (patch) | |
tree | cd6175643df2bb53584a3385d297f140a0ecc2aa /sys/arch/sparc64 | |
parent | a8b9d12405176b7cd22cd2eb8edd582212af10e2 (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.h | 73 |
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 |