Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #ifndef __ASM_SH_UNALIGNED_SH4A_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #define __ASM_SH_UNALIGNED_SH4A_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * SH-4A has support for unaligned 32-bit loads, and 32-bit loads only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Support for 64-bit accesses are done through shifting and masking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * relative to the endianness. Unaligned stores are not supported by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * instruction encoding, so these continue to use the packed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * struct.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * The same note as with the movli.l/movco.l pair applies here, as long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * as the load is guaranteed to be inlined, nothing else will hook in to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * r0 and we get the return value for free.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * NOTE: Due to the fact we require r0 encoding, care should be taken to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * avoid mixing these heavily with other r0 consumers, such as the atomic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * ops. Failure to adhere to this can result in the compiler running out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * of spill registers and blowing up when building at low optimization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * levels. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34777.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/unaligned/packed_struct.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) static inline u16 sh4a_get_unaligned_cpu16(const u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #ifdef __LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	return p[0] | p[1] << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	return p[0] << 8 | p[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) static __always_inline u32 sh4a_get_unaligned_cpu32(const u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	unsigned long unaligned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	__asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		"movua.l	@%1, %0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		 : "=z" (unaligned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		 : "r" (p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	return unaligned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * Even though movua.l supports auto-increment on the read side, it can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  * only store to r0 due to instruction encoding constraints, so just let
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * the compiler sort it out on its own.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) static inline u64 sh4a_get_unaligned_cpu64(const u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #ifdef __LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	return (u64)sh4a_get_unaligned_cpu32(p + 4) << 32 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		    sh4a_get_unaligned_cpu32(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	return (u64)sh4a_get_unaligned_cpu32(p) << 32 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		    sh4a_get_unaligned_cpu32(p + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) static inline u16 get_unaligned_le16(const void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	return le16_to_cpu(sh4a_get_unaligned_cpu16(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) static inline u32 get_unaligned_le32(const void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	return le32_to_cpu(sh4a_get_unaligned_cpu32(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) static inline u64 get_unaligned_le64(const void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	return le64_to_cpu(sh4a_get_unaligned_cpu64(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) static inline u16 get_unaligned_be16(const void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	return be16_to_cpu(sh4a_get_unaligned_cpu16(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) static inline u32 get_unaligned_be32(const void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	return be32_to_cpu(sh4a_get_unaligned_cpu32(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) static inline u64 get_unaligned_be64(const void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	return be64_to_cpu(sh4a_get_unaligned_cpu64(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) static inline void nonnative_put_le16(u16 val, u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	*p++ = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	*p++ = val >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static inline void nonnative_put_le32(u32 val, u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	nonnative_put_le16(val, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	nonnative_put_le16(val >> 16, p + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static inline void nonnative_put_le64(u64 val, u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	nonnative_put_le32(val, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	nonnative_put_le32(val >> 32, p + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static inline void nonnative_put_be16(u16 val, u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	*p++ = val >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	*p++ = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static inline void nonnative_put_be32(u32 val, u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	nonnative_put_be16(val >> 16, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	nonnative_put_be16(val, p + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static inline void nonnative_put_be64(u64 val, u8 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	nonnative_put_be32(val >> 32, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	nonnative_put_be32(val, p + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static inline void put_unaligned_le16(u16 val, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #ifdef __LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	__put_unaligned_cpu16(val, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	nonnative_put_le16(val, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static inline void put_unaligned_le32(u32 val, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #ifdef __LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	__put_unaligned_cpu32(val, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	nonnative_put_le32(val, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static inline void put_unaligned_le64(u64 val, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #ifdef __LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	__put_unaligned_cpu64(val, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	nonnative_put_le64(val, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static inline void put_unaligned_be16(u16 val, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #ifdef __BIG_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	__put_unaligned_cpu16(val, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	nonnative_put_be16(val, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static inline void put_unaligned_be32(u32 val, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #ifdef __BIG_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	__put_unaligned_cpu32(val, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	nonnative_put_be32(val, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static inline void put_unaligned_be64(u64 val, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #ifdef __BIG_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	__put_unaligned_cpu64(val, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	nonnative_put_be64(val, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  * While it's a bit non-obvious, even though the generic le/be wrappers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  * use the __get/put_xxx prefixing, they actually wrap in to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  * non-prefixed get/put_xxx variants as provided above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #include <linux/unaligned/generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #ifdef __LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) # define get_unaligned __get_unaligned_le
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) # define put_unaligned __put_unaligned_le
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) # define get_unaligned __get_unaligned_be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) # define put_unaligned __put_unaligned_be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #endif /* __ASM_SH_UNALIGNED_SH4A_H */