Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef __ASM_GENERIC_UNALIGNED_H
0003 #define __ASM_GENERIC_UNALIGNED_H
0004 
0005 /*
0006  * This is the most generic implementation of unaligned accesses
0007  * and should work almost anywhere.
0008  */
0009 #include <linux/unaligned/packed_struct.h>
0010 #include <asm/byteorder.h>
0011 
0012 #define __get_unaligned_t(type, ptr) ({                     \
0013     const struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr);  \
0014     __pptr->x;                              \
0015 })
0016 
0017 #define __put_unaligned_t(type, val, ptr) do {                  \
0018     struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr);        \
0019     __pptr->x = (val);                          \
0020 } while (0)
0021 
0022 #define get_unaligned(ptr)  __get_unaligned_t(typeof(*(ptr)), (ptr))
0023 #define put_unaligned(val, ptr) __put_unaligned_t(typeof(*(ptr)), (val), (ptr))
0024 
0025 static inline u16 get_unaligned_le16(const void *p)
0026 {
0027     return le16_to_cpu(__get_unaligned_t(__le16, p));
0028 }
0029 
0030 static inline u32 get_unaligned_le32(const void *p)
0031 {
0032     return le32_to_cpu(__get_unaligned_t(__le32, p));
0033 }
0034 
0035 static inline u64 get_unaligned_le64(const void *p)
0036 {
0037     return le64_to_cpu(__get_unaligned_t(__le64, p));
0038 }
0039 
0040 static inline void put_unaligned_le16(u16 val, void *p)
0041 {
0042     __put_unaligned_t(__le16, cpu_to_le16(val), p);
0043 }
0044 
0045 static inline void put_unaligned_le32(u32 val, void *p)
0046 {
0047     __put_unaligned_t(__le32, cpu_to_le32(val), p);
0048 }
0049 
0050 static inline void put_unaligned_le64(u64 val, void *p)
0051 {
0052     __put_unaligned_t(__le64, cpu_to_le64(val), p);
0053 }
0054 
0055 static inline u16 get_unaligned_be16(const void *p)
0056 {
0057     return be16_to_cpu(__get_unaligned_t(__be16, p));
0058 }
0059 
0060 static inline u32 get_unaligned_be32(const void *p)
0061 {
0062     return be32_to_cpu(__get_unaligned_t(__be32, p));
0063 }
0064 
0065 static inline u64 get_unaligned_be64(const void *p)
0066 {
0067     return be64_to_cpu(__get_unaligned_t(__be64, p));
0068 }
0069 
0070 static inline void put_unaligned_be16(u16 val, void *p)
0071 {
0072     __put_unaligned_t(__be16, cpu_to_be16(val), p);
0073 }
0074 
0075 static inline void put_unaligned_be32(u32 val, void *p)
0076 {
0077     __put_unaligned_t(__be32, cpu_to_be32(val), p);
0078 }
0079 
0080 static inline void put_unaligned_be64(u64 val, void *p)
0081 {
0082     __put_unaligned_t(__be64, cpu_to_be64(val), p);
0083 }
0084 
0085 static inline u32 __get_unaligned_be24(const u8 *p)
0086 {
0087     return p[0] << 16 | p[1] << 8 | p[2];
0088 }
0089 
0090 static inline u32 get_unaligned_be24(const void *p)
0091 {
0092     return __get_unaligned_be24(p);
0093 }
0094 
0095 static inline u32 __get_unaligned_le24(const u8 *p)
0096 {
0097     return p[0] | p[1] << 8 | p[2] << 16;
0098 }
0099 
0100 static inline u32 get_unaligned_le24(const void *p)
0101 {
0102     return __get_unaligned_le24(p);
0103 }
0104 
0105 static inline void __put_unaligned_be24(const u32 val, u8 *p)
0106 {
0107     *p++ = val >> 16;
0108     *p++ = val >> 8;
0109     *p++ = val;
0110 }
0111 
0112 static inline void put_unaligned_be24(const u32 val, void *p)
0113 {
0114     __put_unaligned_be24(val, p);
0115 }
0116 
0117 static inline void __put_unaligned_le24(const u32 val, u8 *p)
0118 {
0119     *p++ = val;
0120     *p++ = val >> 8;
0121     *p++ = val >> 16;
0122 }
0123 
0124 static inline void put_unaligned_le24(const u32 val, void *p)
0125 {
0126     __put_unaligned_le24(val, p);
0127 }
0128 
0129 static inline void __put_unaligned_be48(const u64 val, __u8 *p)
0130 {
0131     *p++ = val >> 40;
0132     *p++ = val >> 32;
0133     *p++ = val >> 24;
0134     *p++ = val >> 16;
0135     *p++ = val >> 8;
0136     *p++ = val;
0137 }
0138 
0139 static inline void put_unaligned_be48(const u64 val, void *p)
0140 {
0141     __put_unaligned_be48(val, p);
0142 }
0143 
0144 static inline u64 __get_unaligned_be48(const u8 *p)
0145 {
0146     return (u64)p[0] << 40 | (u64)p[1] << 32 | (u64)p[2] << 24 |
0147         p[3] << 16 | p[4] << 8 | p[5];
0148 }
0149 
0150 static inline u64 get_unaligned_be48(const void *p)
0151 {
0152     return __get_unaligned_be48(p);
0153 }
0154 
0155 #endif /* __ASM_GENERIC_UNALIGNED_H */