klibc.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*!
  2. * Copyright (C) Fraunhofer-Institut for Photonic Microsystems (IPMS)
  3. * Maria-Reiche-Str. 2
  4. * 01109 Dresden
  5. *
  6. * Unauthorized copying of this file, via any medium is strictly prohibited
  7. * Proprietary and confidential
  8. *
  9. * \file klibc.h
  10. * \author zimmerli
  11. * \date 2020-01-20
  12. * \brief Kernel Libc-like helper functions
  13. *
  14. */
  15. #ifndef KLIBC_H_
  16. #define KLIBC_H_
  17. #include <stdint.h>
  18. #include <stdbool.h>
  19. #include <kernel/base/kernel.h>
  20. // ----------------------------------------------------------------
  21. #define INCL_KLIBC_DEBUGSUPPORT
  22. // ----------------------------------------------------------------
  23. // network byte order <-> host byte order
  24. static inline uint16_t klibc_htons(uint16_t value)
  25. {
  26. return (((value & 0xFF) << 8 | (value >> 8)) & 0xFFFF);
  27. }
  28. static inline uint32_t klibc_htonl(uint32_t value)
  29. {
  30. return (((value & 0x000000FF) << 24) | ((value & 0x0000FF00) << 8) | ((value & 0x00FF0000) >> 8) | ((value & 0xFF000000) >> 24));
  31. }
  32. #define klibc_ntohs(value) klibc_htons(value)
  33. #define klibc_ntohl(value) klibc_htonl(value)
  34. // ----------------------------------------------------------------
  35. // debug support
  36. #ifdef INCL_KLIBC_DEBUGSUPPORT
  37. /**
  38. * \brief Minimum-Maximum tupel
  39. */
  40. typedef struct {
  41. int32_t min;
  42. int32_t max;
  43. } klibc_minmax_t;
  44. static inline void klibc_minmax_clear(klibc_minmax_t *minmax)
  45. {
  46. minmax->min = INT32_MAX;
  47. minmax->max = INT32_MIN;
  48. }
  49. static inline void klibc_minmax_update(klibc_minmax_t *minmax, int32_t v)
  50. {
  51. if (v < minmax->min)
  52. minmax->min = v;
  53. if (v > minmax->max)
  54. minmax->max = v;
  55. }
  56. /**
  57. * \brief ring buffer of int32_t
  58. */
  59. typedef struct {
  60. int sz;
  61. int wp;
  62. int32_t *buf;
  63. } klibc_ringlog_s32;
  64. static inline void klibc_ringlog_add(klibc_ringlog_s32 *log, int32_t v)
  65. {
  66. log->wp++;
  67. if (log->wp >= log->sz)
  68. log->wp = 0;
  69. log->buf[log->wp] = v;
  70. }
  71. #define KLIBC_RINGLOGS32(name, size) \
  72. int32_t name##_buf[size]; \
  73. klibc_ringlog_s32 name = { .sz = size, .wp = 0, .buf = name##_buf };
  74. #endif // INCL_KLIBC_DEBUGSUPPORT
  75. // ----------------------------------------------------------------
  76. // light weight List
  77. typedef struct list_data {
  78. void *data;
  79. uint8_t idx; //1...
  80. struct list_data *prev;
  81. struct list_data *next;
  82. } list_data_t;
  83. list_data_t *list_create(void);
  84. void list_free(list_data_t *top, bool free_data);
  85. uint8_t list_size(list_data_t *top);
  86. list_data_t *list_next(list_data_t *top, list_data_t *data);
  87. list_data_t *list_prev(list_data_t *top, list_data_t *data);
  88. bool list_end(list_data_t *top, list_data_t *data);
  89. list_data_t *list_add(list_data_t *top, void *data);
  90. list_data_t *list_get(list_data_t *top, uint8_t idx);
  91. void list_del(list_data_t *top, void *data);
  92. void list_del_entry(list_data_t *top, list_data_t *entry);
  93. //void list_del_idx(list_data_t *top, uint8_t idx);
  94. // ----------------------------------------------------------------
  95. // ----------------------------------------------------------------
  96. /*
  97. * unaligned access support:
  98. *
  99. * reduced performance compared to aligned access
  100. */
  101. static inline uint16_t _get_unaligned_le16(uint8_t *p)
  102. {
  103. return p[0] | p[1] << 8;
  104. }
  105. static inline uint32_t _get_unaligned_le32(uint8_t *p)
  106. {
  107. return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
  108. }
  109. static inline void _put_unaligned_le16(uint16_t val, uint8_t *p)
  110. {
  111. *p++ = val;
  112. *p++ = val >> 8;
  113. }
  114. static inline void _put_unaligned_le32(uint32_t val, uint8_t *p)
  115. {
  116. _put_unaligned_le16(val >> 16, p + 2);
  117. _put_unaligned_le16(val, p);
  118. }
  119. static inline uint16_t __get_unaligned_le16(addr_t addr)
  120. {
  121. return _get_unaligned_le16((uint8_t *)addr);
  122. }
  123. static inline uint32_t __get_unaligned_le32(addr_t addr)
  124. {
  125. return _get_unaligned_le32((uint8_t *)addr);
  126. }
  127. static inline void __put_unaligned_le16(uint16_t val, addr_t addr)
  128. {
  129. _put_unaligned_le16(val, (uint8_t *)addr);
  130. }
  131. static inline void __put_unaligned_le32(uint32_t val, addr_t addr)
  132. {
  133. _put_unaligned_le16(val >> 16, (uint8_t *)addr + 2);
  134. _put_unaligned_le16(val, (uint8_t *)addr);
  135. }
  136. static inline void __put_unaligned_le64(uint64_t val, addr_t addr)
  137. {
  138. _put_unaligned_le32(val >> 32, (uint8_t *)addr + 4);
  139. _put_unaligned_le32(val, (uint8_t *)addr);
  140. }
  141. static inline uint16_t _get_unaligned_be16(uint8_t *p)
  142. {
  143. return p[1] | p[0] << 8;
  144. }
  145. static inline uint32_t _get_unaligned_be32(uint8_t *p)
  146. {
  147. return p[3] | p[2] << 8 | p[1] << 16 | p[0] << 24;
  148. }
  149. static inline void _put_unaligned_be16(uint16_t val, uint8_t *p)
  150. {
  151. *p++ = val >> 8;
  152. *p++ = val;
  153. }
  154. static inline uint16_t __get_unaligned_be16(addr_t addr)
  155. {
  156. return _get_unaligned_be16((uint8_t *)addr);
  157. }
  158. static inline uint32_t __get_unaligned_be32(addr_t addr)
  159. {
  160. return _get_unaligned_be32((uint8_t *)addr);
  161. }
  162. static inline void __put_unaligned_be16(uint16_t val, addr_t addr)
  163. {
  164. _put_unaligned_be16(val, (uint8_t *)addr);
  165. }
  166. static inline void __put_unaligned_be32(uint32_t val, addr_t addr)
  167. {
  168. _put_unaligned_be16(val >> 16, (uint8_t *)addr);
  169. _put_unaligned_be16(val, (uint8_t *)addr + 2);
  170. }
  171. // math
  172. #define kmin(a, b) (a < b ? a : b)
  173. #define kmax(a, b) (a > b ? a : b)
  174. // misc
  175. #define gen_enum_val(val) val,
  176. #define gen_enum_str(str) #str
  177. #define gen_enum_astr(str) #str,
  178. #define gen_enum_hstr(str) #str "|"
  179. #define def_enum(storagecls, name) \
  180. typedef enum { \
  181. name(gen_enum_val, gen_enum_val) no_##name \
  182. } name##_t; \
  183. \
  184. storagecls char *name##_to_str(uint32_t e); \
  185. storagecls uint32_t name##_from_str(char *str);
  186. #define impl_enum(storagecls, name) \
  187. storagecls const uint32_t max_##name = no_##name; \
  188. \
  189. storagecls char *name##_str[no_##name + 1] = { name(gen_enum_astr, gen_enum_astr) name(gen_enum_hstr, gen_enum_str) }; \
  190. \
  191. storagecls char *name##_to_str(uint32_t e) \
  192. { \
  193. if (e < 0 || e > no_##name) \
  194. return name##_str[no_##name]; \
  195. return name##_str[e]; \
  196. } \
  197. \
  198. storagecls uint32_t name##_from_str(char *str) \
  199. { \
  200. for (int i = 0; i < no_##name; i++) \
  201. if (strcmp(str, name##_str[i]) == 0) \
  202. return i; \
  203. return no_##name; \
  204. }
  205. #define gen_enum(storagecls, name) def_enum(storagecls, name) impl_enum(storagecls, name)
  206. char *ltrim(const char *str);
  207. list_data_t *split(const char *str, const char *delim);
  208. #endif /* KLIBC_H_ */