Firmware for MNT ZZ9000 graphics and ARM coprocessor card for Amiga computers.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

memalign.h 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /* SPDX-License-Identifier: GPL-2.0+ */
  2. /*
  3. * Copyright (c) 2015 Google, Inc
  4. */
  5. #ifndef __ALIGNMEM_H
  6. #define __ALIGNMEM_H
  7. #include <xil_types.h>
  8. #define uswap_16(x) \
  9. ((((x) & 0xff00) >> 8) | \
  10. (((x) & 0x00ff) << 8))
  11. #define uswap_32(x) \
  12. ((((x) & 0xff000000) >> 24) | \
  13. (((x) & 0x00ff0000) >> 8) | \
  14. (((x) & 0x0000ff00) << 8) | \
  15. (((x) & 0x000000ff) << 24))
  16. #define cpu_to_le16(x) (x)
  17. #define cpu_to_le32(x) (x)
  18. #define cpu_to_le64(x) (x)
  19. #define le16_to_cpu(x) (x)
  20. #define le32_to_cpu(x) (x)
  21. #define le64_to_cpu(x) (x)
  22. #define cpu_to_be32(x) uswap_32(x)
  23. #define be32_to_cpu(x) uswap_32(x)
  24. #define roundup(x, y) ( \
  25. { \
  26. const typeof(y) __y = y; \
  27. (((x) + (__y - 1)) / __y) * __y; \
  28. }\
  29. )
  30. #define min(a, b) (((a) < (b)) ? (a) : (b))
  31. #define min3(x, y, z) min((typeof(x))min(x, y), z)
  32. extern void __bad_unaligned_access_size(void);
  33. static inline u16 get_unaligned_le16(const u8 *p)
  34. {
  35. return p[0] | p[1] << 8;
  36. }
  37. static inline u32 get_unaligned_le32(const u8 *p)
  38. {
  39. return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
  40. }
  41. static inline u64 get_unaligned_le64(const u8 *p)
  42. {
  43. return (u64)get_unaligned_le32(p + 4) << 32 |
  44. get_unaligned_le32(p);
  45. }
  46. static inline void put_unaligned_le16(u16 val, u8 *p)
  47. {
  48. *p++ = val;
  49. *p++ = val >> 8;
  50. }
  51. static inline void put_unaligned_le32(u32 val, u8 *p)
  52. {
  53. put_unaligned_le16(val >> 16, p + 2);
  54. put_unaligned_le16(val, p);
  55. }
  56. static inline void put_unaligned_le64(u64 val, u8 *p)
  57. {
  58. put_unaligned_le32(val >> 32, p + 4);
  59. put_unaligned_le32(val, p);
  60. }
  61. #define get_unaligned(ptr) ((typeof(*(ptr)))({ \
  62. __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \
  63. __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_le16((const u8 *)(ptr)), \
  64. __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_le32((const u8 *)(ptr)), \
  65. __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_le64((const u8 *)(ptr)), \
  66. __bad_unaligned_access_size())))); \
  67. }))
  68. #define put_unaligned(val, ptr) ({ \
  69. void *__gu_p = (ptr); \
  70. switch (sizeof(*(ptr))) { \
  71. case 1: \
  72. *(u8 *)__gu_p = (u8)(val); \
  73. break; \
  74. case 2: \
  75. put_unaligned_le16((u16)(val), __gu_p); \
  76. break; \
  77. case 4: \
  78. put_unaligned_le32((u32)(val), __gu_p); \
  79. break; \
  80. case 8: \
  81. put_unaligned_le64((u64)(val), __gu_p); \
  82. break; \
  83. default: \
  84. __bad_unaligned_access_size(); \
  85. break; \
  86. } \
  87. (void)0; })
  88. #define le16_to_cpus(x) do { (void)(x); } while (0)
  89. #define ROUND(a,b) (((a) + (b) - 1) & ~((b) - 1))
  90. #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
  91. #define ALIGN(x,a) __ALIGN_MASK((x),(typeof(x))(a)-1)
  92. #define ALIGN_END_ADDR(type, ptr, size) ((unsigned long)(ptr) + roundup((size) * sizeof(type), USB_DMA_MINALIGN))
  93. /*
  94. * ARCH_DMA_MINALIGN is defined in asm/cache.h for each architecture. It
  95. * is used to align DMA buffers.
  96. */
  97. #ifndef __ASSEMBLY__
  98. //#include <asm/cache.h>
  99. #include <malloc.h>
  100. /*
  101. * The ALLOC_CACHE_ALIGN_BUFFER macro is used to allocate a buffer on the
  102. * stack that meets the minimum architecture alignment requirements for DMA.
  103. * Such a buffer is useful for DMA operations where flushing and invalidating
  104. * the cache before and after a read and/or write operation is required for
  105. * correct operations.
  106. *
  107. * When called the macro creates an array on the stack that is sized such
  108. * that:
  109. *
  110. * 1) The beginning of the array can be advanced enough to be aligned.
  111. *
  112. * 2) The size of the aligned portion of the array is a multiple of the minimum
  113. * architecture alignment required for DMA.
  114. *
  115. * 3) The aligned portion contains enough space for the original number of
  116. * elements requested.
  117. *
  118. * The macro then creates a pointer to the aligned portion of this array and
  119. * assigns to the pointer the address of the first element in the aligned
  120. * portion of the array.
  121. *
  122. * Calling the macro as:
  123. *
  124. * ALLOC_CACHE_ALIGN_BUFFER(uint32_t, buffer, 1024);
  125. *
  126. * Will result in something similar to saying:
  127. *
  128. * uint32_t buffer[1024];
  129. *
  130. * The following differences exist:
  131. *
  132. * 1) The resulting buffer is guaranteed to be aligned to the value of
  133. * ARCH_DMA_MINALIGN.
  134. *
  135. * 2) The buffer variable created by the macro is a pointer to the specified
  136. * type, and NOT an array of the specified type. This can be very important
  137. * if you want the address of the buffer, which you probably do, to pass it
  138. * to the DMA hardware. The value of &buffer is different in the two cases.
  139. * In the macro case it will be the address of the pointer, not the address
  140. * of the space reserved for the buffer. However, in the second case it
  141. * would be the address of the buffer. So if you are replacing hard coded
  142. * stack buffers with this macro you need to make sure you remove the & from
  143. * the locations where you are taking the address of the buffer.
  144. *
  145. * Note that the size parameter is the number of array elements to allocate,
  146. * not the number of bytes.
  147. *
  148. * This macro can not be used outside of function scope, or for the creation
  149. * of a function scoped static buffer. It can not be used to create a cache
  150. * line aligned global buffer.
  151. */
  152. #define PAD_COUNT(s, pad) (((s) - 1) / (pad) + 1)
  153. #define PAD_SIZE(s, pad) (PAD_COUNT(s, pad) * pad)
  154. #define ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, pad) \
  155. char __##name[ROUND(PAD_SIZE((size) * sizeof(type), pad), align) \
  156. + (align - 1)]; \
  157. \
  158. type *name = (type *)ALIGN((uintptr_t)__##name, align)
  159. #define ALLOC_ALIGN_BUFFER(type, name, size, align) \
  160. ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, 1)
  161. #define ALLOC_CACHE_ALIGN_BUFFER_PAD(type, name, size, pad) \
  162. ALLOC_ALIGN_BUFFER_PAD(type, name, size, ARCH_DMA_MINALIGN, pad)
  163. #define ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \
  164. ALLOC_ALIGN_BUFFER(type, name, size, ARCH_DMA_MINALIGN)
  165. /*
  166. * DEFINE_CACHE_ALIGN_BUFFER() is similar to ALLOC_CACHE_ALIGN_BUFFER, but it's
  167. * purpose is to allow allocating aligned buffers outside of function scope.
  168. * Usage of this macro shall be avoided or used with extreme care!
  169. */
  170. #define DEFINE_ALIGN_BUFFER(type, name, size, align) \
  171. static char __##name[ALIGN(size * sizeof(type), align)] \
  172. __aligned(align); \
  173. \
  174. static type *name = (type *)__##name
  175. #define DEFINE_CACHE_ALIGN_BUFFER(type, name, size) \
  176. DEFINE_ALIGN_BUFFER(type, name, size, ARCH_DMA_MINALIGN)
  177. /**
  178. * malloc_cache_aligned() - allocate a memory region aligned to cache line size
  179. *
  180. * This allocates memory at a cache-line boundary. The amount allocated may
  181. * be larger than requested as it is rounded up to the nearest multiple of the
  182. * cache-line size. This ensured that subsequent cache operations on this
  183. * memory (flush, invalidate) will not affect subsequently allocated regions.
  184. *
  185. * @size: Minimum number of bytes to allocate
  186. *
  187. * @return pointer to new memory region, or NULL if there is no more memory
  188. * available.
  189. */
  190. /*static inline void *malloc_cache_aligned(size_t size)
  191. {
  192. return memalign(ARCH_DMA_MINALIGN, ALIGN(size, ARCH_DMA_MINALIGN));
  193. }*/
  194. #endif
  195. #endif /* __ALIGNMEM_H */