162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef __ASM_GENERIC_UNALIGNED_H 362306a36Sopenharmony_ci#define __ASM_GENERIC_UNALIGNED_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci/* 662306a36Sopenharmony_ci * This is the most generic implementation of unaligned accesses 762306a36Sopenharmony_ci * and should work almost anywhere. 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci#include <linux/unaligned/packed_struct.h> 1062306a36Sopenharmony_ci#include <asm/byteorder.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#define __get_unaligned_t(type, ptr) ({ \ 1362306a36Sopenharmony_ci const struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr); \ 1462306a36Sopenharmony_ci __pptr->x; \ 1562306a36Sopenharmony_ci}) 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#define __put_unaligned_t(type, val, ptr) do { \ 1862306a36Sopenharmony_ci struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr); \ 1962306a36Sopenharmony_ci __pptr->x = (val); \ 2062306a36Sopenharmony_ci} while (0) 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define get_unaligned(ptr) __get_unaligned_t(typeof(*(ptr)), (ptr)) 2362306a36Sopenharmony_ci#define put_unaligned(val, ptr) __put_unaligned_t(typeof(*(ptr)), (val), (ptr)) 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistatic inline u16 get_unaligned_le16(const void *p) 2662306a36Sopenharmony_ci{ 2762306a36Sopenharmony_ci return le16_to_cpu(__get_unaligned_t(__le16, p)); 2862306a36Sopenharmony_ci} 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cistatic inline u32 get_unaligned_le32(const void *p) 3162306a36Sopenharmony_ci{ 3262306a36Sopenharmony_ci return le32_to_cpu(__get_unaligned_t(__le32, p)); 3362306a36Sopenharmony_ci} 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic inline u64 get_unaligned_le64(const void *p) 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci return le64_to_cpu(__get_unaligned_t(__le64, p)); 3862306a36Sopenharmony_ci} 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_cistatic inline void put_unaligned_le16(u16 val, void *p) 4162306a36Sopenharmony_ci{ 4262306a36Sopenharmony_ci __put_unaligned_t(__le16, cpu_to_le16(val), p); 4362306a36Sopenharmony_ci} 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistatic inline void put_unaligned_le32(u32 val, void *p) 4662306a36Sopenharmony_ci{ 4762306a36Sopenharmony_ci __put_unaligned_t(__le32, cpu_to_le32(val), p); 4862306a36Sopenharmony_ci} 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_cistatic inline void put_unaligned_le64(u64 val, void *p) 5162306a36Sopenharmony_ci{ 5262306a36Sopenharmony_ci __put_unaligned_t(__le64, cpu_to_le64(val), p); 5362306a36Sopenharmony_ci} 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cistatic inline u16 get_unaligned_be16(const void *p) 5662306a36Sopenharmony_ci{ 5762306a36Sopenharmony_ci return be16_to_cpu(__get_unaligned_t(__be16, p)); 5862306a36Sopenharmony_ci} 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistatic inline u32 get_unaligned_be32(const void *p) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci return be32_to_cpu(__get_unaligned_t(__be32, p)); 6362306a36Sopenharmony_ci} 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_cistatic inline u64 get_unaligned_be64(const void *p) 6662306a36Sopenharmony_ci{ 6762306a36Sopenharmony_ci return be64_to_cpu(__get_unaligned_t(__be64, p)); 6862306a36Sopenharmony_ci} 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cistatic inline void put_unaligned_be16(u16 val, void *p) 7162306a36Sopenharmony_ci{ 7262306a36Sopenharmony_ci __put_unaligned_t(__be16, cpu_to_be16(val), p); 7362306a36Sopenharmony_ci} 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistatic inline void put_unaligned_be32(u32 val, void *p) 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci __put_unaligned_t(__be32, cpu_to_be32(val), p); 7862306a36Sopenharmony_ci} 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_cistatic inline void put_unaligned_be64(u64 val, void *p) 8162306a36Sopenharmony_ci{ 8262306a36Sopenharmony_ci __put_unaligned_t(__be64, cpu_to_be64(val), p); 8362306a36Sopenharmony_ci} 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_cistatic inline u32 __get_unaligned_be24(const u8 *p) 8662306a36Sopenharmony_ci{ 8762306a36Sopenharmony_ci return p[0] << 16 | p[1] << 8 | p[2]; 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistatic inline u32 get_unaligned_be24(const void *p) 9162306a36Sopenharmony_ci{ 9262306a36Sopenharmony_ci return __get_unaligned_be24(p); 9362306a36Sopenharmony_ci} 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_cistatic inline u32 __get_unaligned_le24(const u8 *p) 9662306a36Sopenharmony_ci{ 9762306a36Sopenharmony_ci return p[0] | p[1] << 8 | p[2] << 16; 9862306a36Sopenharmony_ci} 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_cistatic inline u32 get_unaligned_le24(const void *p) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci return __get_unaligned_le24(p); 10362306a36Sopenharmony_ci} 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cistatic inline void __put_unaligned_be24(const u32 val, u8 *p) 10662306a36Sopenharmony_ci{ 10762306a36Sopenharmony_ci *p++ = (val >> 16) & 0xff; 10862306a36Sopenharmony_ci *p++ = (val >> 8) & 0xff; 10962306a36Sopenharmony_ci *p++ = val & 0xff; 11062306a36Sopenharmony_ci} 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_cistatic inline void put_unaligned_be24(const u32 val, void *p) 11362306a36Sopenharmony_ci{ 11462306a36Sopenharmony_ci __put_unaligned_be24(val, p); 11562306a36Sopenharmony_ci} 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_cistatic inline void __put_unaligned_le24(const u32 val, u8 *p) 11862306a36Sopenharmony_ci{ 11962306a36Sopenharmony_ci *p++ = val & 0xff; 12062306a36Sopenharmony_ci *p++ = (val >> 8) & 0xff; 12162306a36Sopenharmony_ci *p++ = (val >> 16) & 0xff; 12262306a36Sopenharmony_ci} 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistatic inline void put_unaligned_le24(const u32 val, void *p) 12562306a36Sopenharmony_ci{ 12662306a36Sopenharmony_ci __put_unaligned_le24(val, p); 12762306a36Sopenharmony_ci} 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistatic inline void __put_unaligned_be48(const u64 val, u8 *p) 13062306a36Sopenharmony_ci{ 13162306a36Sopenharmony_ci *p++ = (val >> 40) & 0xff; 13262306a36Sopenharmony_ci *p++ = (val >> 32) & 0xff; 13362306a36Sopenharmony_ci *p++ = (val >> 24) & 0xff; 13462306a36Sopenharmony_ci *p++ = (val >> 16) & 0xff; 13562306a36Sopenharmony_ci *p++ = (val >> 8) & 0xff; 13662306a36Sopenharmony_ci *p++ = val & 0xff; 13762306a36Sopenharmony_ci} 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_cistatic inline void put_unaligned_be48(const u64 val, void *p) 14062306a36Sopenharmony_ci{ 14162306a36Sopenharmony_ci __put_unaligned_be48(val, p); 14262306a36Sopenharmony_ci} 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_cistatic inline u64 __get_unaligned_be48(const u8 *p) 14562306a36Sopenharmony_ci{ 14662306a36Sopenharmony_ci return (u64)p[0] << 40 | (u64)p[1] << 32 | (u64)p[2] << 24 | 14762306a36Sopenharmony_ci p[3] << 16 | p[4] << 8 | p[5]; 14862306a36Sopenharmony_ci} 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_cistatic inline u64 get_unaligned_be48(const void *p) 15162306a36Sopenharmony_ci{ 15262306a36Sopenharmony_ci return __get_unaligned_be48(p); 15362306a36Sopenharmony_ci} 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci#endif /* __ASM_GENERIC_UNALIGNED_H */ 156