Source: u-boot
Version: 2013.10-3
Severity: important
Tags: patch

Hello,

Description of problem:

Attached is a quilt patch which will allow this package to build on
kfreebsd, which was obtained by brute force. Here is the failure:
https://buildd.debian.org/status/fetch.php?pkg=u-boot&arch=kfreebsd-amd64&ver=2013.10-3&stamp=1384692375

Note that once that particular failure was resolved, there were
additional failures related to other header files later in build.

It also looks like the build failed for the same reasons on hurd:
https://buildd.debian.org/status/fetch.php?pkg=u-boot&arch=hurd-i386&ver=2013.10-3&stamp=1384681614

I suspect my changes may fix the problems seen there as well.

Description of solution:

I have copied many additional header files into the package source
which were not used previously, but are required now. These mostly
came from the linux-libc-dev, with some slight modification.

This is the way the upstream maintainers have maintained the package
for a while. The include/ directory already had many copies of header
files copied from the linux-libc-dev package contents.

Further testing needed:

I have not yet tested that the package produced by these patches work.
I will verify mkimage is able to run and produces correct output.

I have not looked at the downstream uses of the definitions from these
header files to see if they are actually used in this executable. I
expect many are not, in which case the #include may be commented out
for a simpler patch. However, if they are used, I do still need to
verify that the settings copied here are correct and will not cause
anything to subtly break or affect correct behavior during runtime.

Further work on patch needed:

I believe my patch will break builds happening under other kernels and
architectures. I have used a brute force strategy to get the package
to build on kfreebsd only. Next, I will be working my way back outward
from my solution to find which parts are really necessary, before I
clean it up to patch properly in a way only affecting kfreebsd. The
biggest issue here is that the asm directory varies by architecture.
Luckily, kfreebsd is only i386 and amd64, which seem to share headers.

Timeline for completion:

Within the next few days I will complete:
* testing of the built package and mkimage executable
* proper code review, deciding which changes are correct and needed
* cleaning up the patch to allow the package to build correctly on
  other architectures and kernels, which were already working, by
  only using these architecture-specific headers under kfreebsd

Thanks,
Ryan

-- 
Courtesy of linux-libc-dev package from i386 architecture,
copied from the /usr/include/i386-linux-gnu/ directory.

This is needed because our package source here includes a
file, include/linux/types.h, also copied from that package.

Patch by Ryan Niebur

Index: u-boot-2013.10/include/asm/posix_types.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ u-boot-2013.10/include/asm/posix_types.h	2013-11-30 00:27:04.000000000 +0100
@@ -0,0 +1,5 @@
+# ifdef __i386__
+#  include "posix_types_32.h"
+# else
+#  include "posix_types_64.h"
+# endif
Index: u-boot-2013.10/include/asm/posix_types_32.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ u-boot-2013.10/include/asm/posix_types_32.h	2013-11-30 00:50:40.000000000 +0100
@@ -0,0 +1,49 @@
+#ifndef _ASM_X86_POSIX_TYPES_32_H
+#define _ASM_X86_POSIX_TYPES_32_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+#include <sys/_types.h>
+// RYAN52: THIS PACKAGE NEEDS THE FOLLOWING COMMENTED OUT DUE TO CONFLICT IN /usr/include/sys/_types.h
+//typedef unsigned long	__kernel_ino_t;
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned short	__kernel_mode_t;
+typedef unsigned short	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
+typedef unsigned short	__kernel_uid_t;
+typedef unsigned short	__kernel_gid_t;
+typedef unsigned int	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_timer_t;
+typedef int		__kernel_clockid_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+typedef unsigned short	__kernel_old_uid_t;
+typedef unsigned short	__kernel_old_gid_t;
+typedef unsigned short	__kernel_old_dev_t;
+
+#ifdef __GNUC__
+typedef long long	__kernel_loff_t;
+#endif
+
+typedef struct {
+	int	val[2];
+} __kernel_fsid_t;
+
+
+#endif /* _ASM_X86_POSIX_TYPES_32_H */
Index: u-boot-2013.10/include/asm/posix_types_64.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ u-boot-2013.10/include/asm/posix_types_64.h	2013-11-30 00:50:36.000000000 +0100
@@ -0,0 +1,49 @@
+#ifndef _ASM_X86_POSIX_TYPES_64_H
+#define _ASM_X86_POSIX_TYPES_64_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+#include <sys/_types.h>
+// RYAN52: THIS PACKAGE NEEDS THE FOLLOWING COMMENTED OUT DUE TO CONFLICT IN /usr/include/sys/_types.h
+//typedef unsigned long	__kernel_ino_t;
+typedef unsigned int	__kernel_mode_t;
+typedef unsigned long	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef int		__kernel_ipc_pid_t;
+typedef unsigned int	__kernel_uid_t;
+typedef unsigned int	__kernel_gid_t;
+typedef unsigned long	__kernel_size_t;
+typedef long		__kernel_ssize_t;
+typedef long		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_timer_t;
+typedef int		__kernel_clockid_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+
+#ifdef __GNUC__
+typedef long long	__kernel_loff_t;
+#endif
+
+typedef struct {
+	int	val[2];
+} __kernel_fsid_t;
+
+typedef unsigned short __kernel_old_uid_t;
+typedef unsigned short __kernel_old_gid_t;
+typedef __kernel_uid_t __kernel_uid32_t;
+typedef __kernel_gid_t __kernel_gid32_t;
+
+typedef unsigned long	__kernel_old_dev_t;
+
+
+#endif /* _ASM_X86_POSIX_TYPES_64_H */
Index: u-boot-2013.10/Makefile
===================================================================
--- u-boot-2013.10.orig/Makefile	2013-10-16 19:08:12.000000000 +0200
+++ u-boot-2013.10/Makefile	2013-11-30 00:27:41.000000000 +0100
@@ -925,7 +925,7 @@
 	@rm -f $(obj)tools/xway-swap-bytes
 	@rm -f $(obj)arch/powerpc/cpu/mpc824x/bedbug_603e.c
 	@rm -f $(obj)arch/powerpc/cpu/mpc83xx/ddr-gen?.c
-	@rm -fr $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
+	#rm -fr $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
 	@rm -fr $(obj)include/generated
 	@[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -name "*" -type l -print | xargs rm -f
 	@rm -f $(obj)dts/*.tmp
Index: u-boot-2013.10/include/asm-generic/int-ll64.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ u-boot-2013.10/include/asm-generic/int-ll64.h	2013-11-30 00:33:06.000000000 +0100
@@ -0,0 +1,39 @@
+/*
+ * asm-generic/int-ll64.h
+ *
+ * Integer declarations for architectures which use "long long"
+ * for 64-bit types.
+ */
+
+#ifndef _ASM_GENERIC_INT_LL64_H
+#define _ASM_GENERIC_INT_LL64_H
+
+#include <asm/bitsperlong.h>
+
+#ifndef __ASSEMBLY__
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#ifdef __GNUC__
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
+#else
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+
+#endif /* _ASM_GENERIC_INT_LL64_H */
Index: u-boot-2013.10/include/asm-generic/types.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ u-boot-2013.10/include/asm-generic/types.h	2013-11-30 00:33:14.000000000 +0100
@@ -0,0 +1,15 @@
+#ifndef _ASM_GENERIC_TYPES_H
+#define _ASM_GENERIC_TYPES_H
+/*
+ * int-ll64 is used practically everywhere now,
+ * so use it as a reasonable default.
+ */
+#include <asm-generic/int-ll64.h>
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_GENERIC_TYPES_H */
Index: u-boot-2013.10/include/asm/bitsperlong.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ u-boot-2013.10/include/asm/bitsperlong.h	2013-11-30 00:36:55.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef __ASM_X86_BITSPERLONG_H
+#define __ASM_X86_BITSPERLONG_H
+
+#ifdef __x86_64__
+# define __BITS_PER_LONG 64
+#else
+# define __BITS_PER_LONG 32
+#endif
+
+#include <asm-generic/bitsperlong.h>
+
+#endif /* __ASM_X86_BITSPERLONG_H */
+
Index: u-boot-2013.10/include/asm/types.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ u-boot-2013.10/include/asm/types.h	2013-11-30 00:36:59.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef _ASM_X86_TYPES_H
+#define _ASM_X86_TYPES_H
+
+#include <asm-generic/types.h>
+
+#endif /* _ASM_X86_TYPES_H */
Index: u-boot-2013.10/include/asm-generic/bitsperlong.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ u-boot-2013.10/include/asm-generic/bitsperlong.h	2013-11-30 00:34:22.000000000 +0100
@@ -0,0 +1,15 @@
+#ifndef __ASM_GENERIC_BITS_PER_LONG
+#define __ASM_GENERIC_BITS_PER_LONG
+
+/*
+ * There seems to be no way of detecting this automatically from user
+ * space, so 64 bit architectures should override this in their
+ * bitsperlong.h. In particular, an architecture that supports
+ * both 32 and 64 bit user space must not rely on CONFIG_64BIT
+ * to decide it, but rather check a compiler provided macro.
+ */
+#ifndef __BITS_PER_LONG
+#define __BITS_PER_LONG 32
+#endif
+
+#endif /* __ASM_GENERIC_BITS_PER_LONG */
Index: u-boot-2013.10/include/asm/byteorder.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ u-boot-2013.10/include/asm/byteorder.h	2013-11-30 00:39:56.000000000 +0100
@@ -0,0 +1,6 @@
+#ifndef _ASM_X86_BYTEORDER_H
+#define _ASM_X86_BYTEORDER_H
+
+#include <linux/byteorder/little_endian.h>
+
+#endif /* _ASM_X86_BYTEORDER_H */
Index: u-boot-2013.10/include/asm/swab.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ u-boot-2013.10/include/asm/swab.h	2013-11-30 00:41:44.000000000 +0100
@@ -0,0 +1,61 @@
+#ifndef _ASM_X86_SWAB_H
+#define _ASM_X86_SWAB_H
+
+#include <linux/types.h>
+
+
+static __inline__ __u32 __arch_swab32(__u32 val)
+{
+#ifdef __i386__
+# ifdef CONFIG_X86_BSWAP
+	__asm__("bswap %0" : "=r" (val) : "0" (val));
+# else
+	__asm__("xchgb %b0,%h0\n\t"	/* swap lower bytes	*/
+	    "rorl $16,%0\n\t"	/* swap words		*/
+	    "xchgb %b0,%h0"	/* swap higher bytes	*/
+	    : "=q" (val)
+	    : "0" (val));
+# endif
+
+#else /* __i386__ */
+	__asm__("bswapl %0"
+	    : "=r" (val)
+	    : "0" (val));
+#endif
+	return val;
+}
+#define __arch_swab32 __arch_swab32
+
+static __inline__ __u64 __arch_swab64(__u64 val)
+{
+#ifdef __i386__
+	union {
+		struct {
+			__u32 a;
+			__u32 b;
+		} s;
+		__u64 u;
+	} v;
+	v.u = val;
+# ifdef CONFIG_X86_BSWAP
+	__asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1"
+	    : "=r" (v.s.a), "=r" (v.s.b)
+	    : "0" (v.s.a), "1" (v.s.b));
+# else
+	v.s.a = __arch_swab32(v.s.a);
+	v.s.b = __arch_swab32(v.s.b);
+	__asm__("xchgl %0,%1"
+	    : "=r" (v.s.a), "=r" (v.s.b)
+	    : "0" (v.s.a), "1" (v.s.b));
+# endif
+	return v.u;
+#else /* __i386__ */
+	__asm__("bswapq %0"
+	    : "=r" (val)
+	    : "0" (val));
+	return val;
+#endif
+}
+#define __arch_swab64 __arch_swab64
+
+#endif /* _ASM_X86_SWAB_H */
Index: u-boot-2013.10/include/linux/byteorder/little_endian.h
===================================================================
--- u-boot-2013.10.orig/include/linux/byteorder/little_endian.h	2013-10-16 19:08:12.000000000 +0200
+++ u-boot-2013.10/include/linux/byteorder/little_endian.h	2013-11-30 00:40:01.000000000 +0100
@@ -7,86 +7,84 @@
 #ifndef __LITTLE_ENDIAN_BITFIELD
 #define __LITTLE_ENDIAN_BITFIELD
 #endif
-#define	__BYTE_ORDER	__LITTLE_ENDIAN
 
-#include <linux/compiler.h>
 #include <linux/types.h>
-#include <linux/byteorder/swab.h>
+#include <linux/swab.h>
 
-#define __constant_htonl(x) ((__force __be32)___constant_swab32((x)))
-#define __constant_ntohl(x) ___constant_swab32((__force __be32)(x))
-#define __constant_htons(x) ((__force __be16)___constant_swab16((x)))
-#define __constant_ntohs(x) ___constant_swab16((__force __be16)(x))
-#define __constant_cpu_to_le64(x) ((__force __le64)(__u64)(x))
-#define __constant_le64_to_cpu(x) ((__force __u64)(__le64)(x))
-#define __constant_cpu_to_le32(x) ((__force __le32)(__u32)(x))
-#define __constant_le32_to_cpu(x) ((__force __u32)(__le32)(x))
-#define __constant_cpu_to_le16(x) ((__force __le16)(__u16)(x))
-#define __constant_le16_to_cpu(x) ((__force __u16)(__le16)(x))
-#define __constant_cpu_to_be64(x) ((__force __be64)___constant_swab64((x)))
-#define __constant_be64_to_cpu(x) ___constant_swab64((__force __u64)(__be64)(x))
-#define __constant_cpu_to_be32(x) ((__force __be32)___constant_swab32((x)))
-#define __constant_be32_to_cpu(x) ___constant_swab32((__force __u32)(__be32)(x))
-#define __constant_cpu_to_be16(x) ((__force __be16)___constant_swab16((x)))
-#define __constant_be16_to_cpu(x) ___constant_swab16((__force __u16)(__be16)(x))
-#define __cpu_to_le64(x) ((__force __le64)(__u64)(x))
-#define __le64_to_cpu(x) ((__force __u64)(__le64)(x))
-#define __cpu_to_le32(x) ((__force __le32)(__u32)(x))
-#define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
-#define __cpu_to_le16(x) ((__force __le16)(__u16)(x))
-#define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
-#define __cpu_to_be64(x) ((__force __be64)__swab64((x)))
-#define __be64_to_cpu(x) __swab64((__force __u64)(__be64)(x))
-#define __cpu_to_be32(x) ((__force __be32)__swab32((x)))
-#define __be32_to_cpu(x) __swab32((__force __u32)(__be32)(x))
-#define __cpu_to_be16(x) ((__force __be16)__swab16((x)))
-#define __be16_to_cpu(x) __swab16((__force __u16)(__be16)(x))
+#define __constant_htonl(x) ((__be32)___constant_swab32((x)))
+#define __constant_ntohl(x) ___constant_swab32((__be32)(x))
+#define __constant_htons(x) ((__be16)___constant_swab16((x)))
+#define __constant_ntohs(x) ___constant_swab16((__be16)(x))
+#define __constant_cpu_to_le64(x) ((__le64)(__u64)(x))
+#define __constant_le64_to_cpu(x) ((__u64)(__le64)(x))
+#define __constant_cpu_to_le32(x) ((__le32)(__u32)(x))
+#define __constant_le32_to_cpu(x) ((__u32)(__le32)(x))
+#define __constant_cpu_to_le16(x) ((__le16)(__u16)(x))
+#define __constant_le16_to_cpu(x) ((__u16)(__le16)(x))
+#define __constant_cpu_to_be64(x) ((__be64)___constant_swab64((x)))
+#define __constant_be64_to_cpu(x) ___constant_swab64((__u64)(__be64)(x))
+#define __constant_cpu_to_be32(x) ((__be32)___constant_swab32((x)))
+#define __constant_be32_to_cpu(x) ___constant_swab32((__u32)(__be32)(x))
+#define __constant_cpu_to_be16(x) ((__be16)___constant_swab16((x)))
+#define __constant_be16_to_cpu(x) ___constant_swab16((__u16)(__be16)(x))
+#define __cpu_to_le64(x) ((__le64)(__u64)(x))
+#define __le64_to_cpu(x) ((__u64)(__le64)(x))
+#define __cpu_to_le32(x) ((__le32)(__u32)(x))
+#define __le32_to_cpu(x) ((__u32)(__le32)(x))
+#define __cpu_to_le16(x) ((__le16)(__u16)(x))
+#define __le16_to_cpu(x) ((__u16)(__le16)(x))
+#define __cpu_to_be64(x) ((__be64)__swab64((x)))
+#define __be64_to_cpu(x) __swab64((__u64)(__be64)(x))
+#define __cpu_to_be32(x) ((__be32)__swab32((x)))
+#define __be32_to_cpu(x) __swab32((__u32)(__be32)(x))
+#define __cpu_to_be16(x) ((__be16)__swab16((x)))
+#define __be16_to_cpu(x) __swab16((__u16)(__be16)(x))
 
-static inline __le64 __cpu_to_le64p(const __u64 *p)
+static __inline__ __le64 __cpu_to_le64p(const __u64 *p)
 {
-	return (__force __le64)*p;
+	return (__le64)*p;
 }
-static inline __u64 __le64_to_cpup(const __le64 *p)
+static __inline__ __u64 __le64_to_cpup(const __le64 *p)
 {
-	return (__force __u64)*p;
+	return (__u64)*p;
 }
-static inline __le32 __cpu_to_le32p(const __u32 *p)
+static __inline__ __le32 __cpu_to_le32p(const __u32 *p)
 {
-	return (__force __le32)*p;
+	return (__le32)*p;
 }
-static inline __u32 __le32_to_cpup(const __le32 *p)
+static __inline__ __u32 __le32_to_cpup(const __le32 *p)
 {
-	return (__force __u32)*p;
+	return (__u32)*p;
 }
-static inline __le16 __cpu_to_le16p(const __u16 *p)
+static __inline__ __le16 __cpu_to_le16p(const __u16 *p)
 {
-	return (__force __le16)*p;
+	return (__le16)*p;
 }
-static inline __u16 __le16_to_cpup(const __le16 *p)
+static __inline__ __u16 __le16_to_cpup(const __le16 *p)
 {
-	return (__force __u16)*p;
+	return (__u16)*p;
 }
-static inline __be64 __cpu_to_be64p(const __u64 *p)
+static __inline__ __be64 __cpu_to_be64p(const __u64 *p)
 {
-	return (__force __be64)__swab64p(p);
+	return (__be64)__swab64p(p);
 }
-static inline __u64 __be64_to_cpup(const __be64 *p)
+static __inline__ __u64 __be64_to_cpup(const __be64 *p)
 {
 	return __swab64p((__u64 *)p);
 }
-static inline __be32 __cpu_to_be32p(const __u32 *p)
+static __inline__ __be32 __cpu_to_be32p(const __u32 *p)
 {
-	return (__force __be32)__swab32p(p);
+	return (__be32)__swab32p(p);
 }
-static inline __u32 __be32_to_cpup(const __be32 *p)
+static __inline__ __u32 __be32_to_cpup(const __be32 *p)
 {
 	return __swab32p((__u32 *)p);
 }
-static inline __be16 __cpu_to_be16p(const __u16 *p)
+static __inline__ __be16 __cpu_to_be16p(const __u16 *p)
 {
-	return (__force __be16)__swab16p(p);
+	return (__be16)__swab16p(p);
 }
-static inline __u16 __be16_to_cpup(const __be16 *p)
+static __inline__ __u16 __be16_to_cpup(const __be16 *p)
 {
 	return __swab16p((__u16 *)p);
 }
@@ -103,8 +101,5 @@
 #define __cpu_to_be16s(x) __swab16s((x))
 #define __be16_to_cpus(x) __swab16s((x))
 
-#ifdef __KERNEL__
-#include <linux/byteorder/generic.h>
-#endif
 
 #endif /* _LINUX_BYTEORDER_LITTLE_ENDIAN_H */
Index: u-boot-2013.10/include/linux/swab.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ u-boot-2013.10/include/linux/swab.h	2013-11-30 00:41:59.000000000 +0100
@@ -0,0 +1,282 @@
+#ifndef _LINUX_SWAB_H
+#define _LINUX_SWAB_H
+
+#include <linux/types.h>
+
+#include <asm/swab.h>
+
+/*
+ * casts are necessary for constants, because we never know how for sure
+ * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
+ */
+#define ___constant_swab16(x) ((__u16)(				\
+	(((__u16)(x) & (__u16)0x00ffU) << 8) |			\
+	(((__u16)(x) & (__u16)0xff00U) >> 8)))
+
+#define ___constant_swab32(x) ((__u32)(				\
+	(((__u32)(x) & (__u32)0x000000ffUL) << 24) |		\
+	(((__u32)(x) & (__u32)0x0000ff00UL) <<  8) |		\
+	(((__u32)(x) & (__u32)0x00ff0000UL) >>  8) |		\
+	(((__u32)(x) & (__u32)0xff000000UL) >> 24)))
+
+#define ___constant_swab64(x) ((__u64)(				\
+	(((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) |	\
+	(((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) |	\
+	(((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) |	\
+	(((__u64)(x) & (__u64)0x00000000ff000000ULL) <<  8) |	\
+	(((__u64)(x) & (__u64)0x000000ff00000000ULL) >>  8) |	\
+	(((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) |	\
+	(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) |	\
+	(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56)))
+
+#define ___constant_swahw32(x) ((__u32)(			\
+	(((__u32)(x) & (__u32)0x0000ffffUL) << 16) |		\
+	(((__u32)(x) & (__u32)0xffff0000UL) >> 16)))
+
+#define ___constant_swahb32(x) ((__u32)(			\
+	(((__u32)(x) & (__u32)0x00ff00ffUL) << 8) |		\
+	(((__u32)(x) & (__u32)0xff00ff00UL) >> 8)))
+
+/*
+ * Implement the following as inlines, but define the interface using
+ * macros to allow constant folding when possible:
+ * ___swab16, ___swab32, ___swab64, ___swahw32, ___swahb32
+ */
+
+static __inline__ __u16 __fswab16(__u16 val)
+{
+#ifdef __arch_swab16
+	return __arch_swab16(val);
+#else
+	return ___constant_swab16(val);
+#endif
+}
+
+static __inline__ __u32 __fswab32(__u32 val)
+{
+#ifdef __arch_swab32
+	return __arch_swab32(val);
+#else
+	return ___constant_swab32(val);
+#endif
+}
+
+static __inline__ __u64 __fswab64(__u64 val)
+{
+#ifdef __arch_swab64
+	return __arch_swab64(val);
+#elif defined(__SWAB_64_THRU_32__)
+	__u32 h = val >> 32;
+	__u32 l = val & ((1ULL << 32) - 1);
+	return (((__u64)__fswab32(l)) << 32) | ((__u64)(__fswab32(h)));
+#else
+	return ___constant_swab64(val);
+#endif
+}
+
+static __inline__ __u32 __fswahw32(__u32 val)
+{
+#ifdef __arch_swahw32
+	return __arch_swahw32(val);
+#else
+	return ___constant_swahw32(val);
+#endif
+}
+
+static __inline__ __u32 __fswahb32(__u32 val)
+{
+#ifdef __arch_swahb32
+	return __arch_swahb32(val);
+#else
+	return ___constant_swahb32(val);
+#endif
+}
+
+/**
+ * __swab16 - return a byteswapped 16-bit value
+ * @x: value to byteswap
+ */
+#define __swab16(x)				\
+	(__builtin_constant_p((__u16)(x)) ?	\
+	___constant_swab16(x) :			\
+	__fswab16(x))
+
+/**
+ * __swab32 - return a byteswapped 32-bit value
+ * @x: value to byteswap
+ */
+#define __swab32(x)				\
+	(__builtin_constant_p((__u32)(x)) ?	\
+	___constant_swab32(x) :			\
+	__fswab32(x))
+
+/**
+ * __swab64 - return a byteswapped 64-bit value
+ * @x: value to byteswap
+ */
+#define __swab64(x)				\
+	(__builtin_constant_p((__u64)(x)) ?	\
+	___constant_swab64(x) :			\
+	__fswab64(x))
+
+/**
+ * __swahw32 - return a word-swapped 32-bit value
+ * @x: value to wordswap
+ *
+ * __swahw32(0x12340000) is 0x00001234
+ */
+#define __swahw32(x)				\
+	(__builtin_constant_p((__u32)(x)) ?	\
+	___constant_swahw32(x) :		\
+	__fswahw32(x))
+
+/**
+ * __swahb32 - return a high and low byte-swapped 32-bit value
+ * @x: value to byteswap
+ *
+ * __swahb32(0x12345678) is 0x34127856
+ */
+#define __swahb32(x)				\
+	(__builtin_constant_p((__u32)(x)) ?	\
+	___constant_swahb32(x) :		\
+	__fswahb32(x))
+
+/**
+ * __swab16p - return a byteswapped 16-bit value from a pointer
+ * @p: pointer to a naturally-aligned 16-bit value
+ */
+static __inline__ __u16 __swab16p(const __u16 *p)
+{
+#ifdef __arch_swab16p
+	return __arch_swab16p(p);
+#else
+	return __swab16(*p);
+#endif
+}
+
+/**
+ * __swab32p - return a byteswapped 32-bit value from a pointer
+ * @p: pointer to a naturally-aligned 32-bit value
+ */
+static __inline__ __u32 __swab32p(const __u32 *p)
+{
+#ifdef __arch_swab32p
+	return __arch_swab32p(p);
+#else
+	return __swab32(*p);
+#endif
+}
+
+/**
+ * __swab64p - return a byteswapped 64-bit value from a pointer
+ * @p: pointer to a naturally-aligned 64-bit value
+ */
+static __inline__ __u64 __swab64p(const __u64 *p)
+{
+#ifdef __arch_swab64p
+	return __arch_swab64p(p);
+#else
+	return __swab64(*p);
+#endif
+}
+
+/**
+ * __swahw32p - return a wordswapped 32-bit value from a pointer
+ * @p: pointer to a naturally-aligned 32-bit value
+ *
+ * See __swahw32() for details of wordswapping.
+ */
+static __inline__ __u32 __swahw32p(const __u32 *p)
+{
+#ifdef __arch_swahw32p
+	return __arch_swahw32p(p);
+#else
+	return __swahw32(*p);
+#endif
+}
+
+/**
+ * __swahb32p - return a high and low byteswapped 32-bit value from a pointer
+ * @p: pointer to a naturally-aligned 32-bit value
+ *
+ * See __swahb32() for details of high/low byteswapping.
+ */
+static __inline__ __u32 __swahb32p(const __u32 *p)
+{
+#ifdef __arch_swahb32p
+	return __arch_swahb32p(p);
+#else
+	return __swahb32(*p);
+#endif
+}
+
+/**
+ * __swab16s - byteswap a 16-bit value in-place
+ * @p: pointer to a naturally-aligned 16-bit value
+ */
+static __inline__ void __swab16s(__u16 *p)
+{
+#ifdef __arch_swab16s
+	__arch_swab16s(p);
+#else
+	*p = __swab16p(p);
+#endif
+}
+/**
+ * __swab32s - byteswap a 32-bit value in-place
+ * @p: pointer to a naturally-aligned 32-bit value
+ */
+static __inline__ void __swab32s(__u32 *p)
+{
+#ifdef __arch_swab32s
+	__arch_swab32s(p);
+#else
+	*p = __swab32p(p);
+#endif
+}
+
+/**
+ * __swab64s - byteswap a 64-bit value in-place
+ * @p: pointer to a naturally-aligned 64-bit value
+ */
+static __inline__ void __swab64s(__u64 *p)
+{
+#ifdef __arch_swab64s
+	__arch_swab64s(p);
+#else
+	*p = __swab64p(p);
+#endif
+}
+
+/**
+ * __swahw32s - wordswap a 32-bit value in-place
+ * @p: pointer to a naturally-aligned 32-bit value
+ *
+ * See __swahw32() for details of wordswapping
+ */
+static __inline__ void __swahw32s(__u32 *p)
+{
+#ifdef __arch_swahw32s
+	__arch_swahw32s(p);
+#else
+	*p = __swahw32p(p);
+#endif
+}
+
+/**
+ * __swahb32s - high and low byteswap a 32-bit value in-place
+ * @p: pointer to a naturally-aligned 32-bit value
+ *
+ * See __swahb32() for details of high and low byte swapping
+ */
+static __inline__ void __swahb32s(__u32 *p)
+{
+#ifdef __arch_swahb32s
+	__arch_swahb32s(p);
+#else
+	*p = __swahb32p(p);
+#endif
+}
+
+
+#endif /* _LINUX_SWAB_H */

Reply via email to