xos_syslog.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /** @file */
  2. // xos_syslog.h - XOS Event logging module.
  3. // Copyright (c) 2003-2015 Cadence Design Systems, Inc.
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining
  6. // a copy of this software and associated documentation files (the
  7. // "Software"), to deal in the Software without restriction, including
  8. // without limitation the rights to use, copy, modify, merge, publish,
  9. // distribute, sublicense, and/or sell copies of the Software, and to
  10. // permit persons to whom the Software is furnished to do so, subject to
  11. // the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included
  14. // in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  19. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  20. // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  21. // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  22. // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. // NOTE: Do not include this file directly in your application. Including
  24. // xos.h will automatically include this file.
  25. #ifndef __XOS_SYSLOG_H__
  26. #define __XOS_SYSLOG_H__
  27. #include "xos_types.h"
  28. #ifdef __cplusplus
  29. extern "C" {
  30. #endif
  31. //-----------------------------------------------------------------------------
  32. // The XOS system log is an array of fixed size entries. The size of the log
  33. // is determined by the application, and memory for the log must be provided
  34. // at init time. Every time the log function is called, an entry is made in
  35. // the log and the next pointer advanced. When the log is full, it will wrap
  36. // around and start overwriting the oldest entries.
  37. // Logging can be done from C/C++ code as well as assembly code, and at any
  38. // interrupt level, even from high level interrupt handlers.
  39. //-----------------------------------------------------------------------------
  40. //-----------------------------------------------------------------------------
  41. // Defines.
  42. //-----------------------------------------------------------------------------
  43. #define XOS_SYSLOG_ENABLED 0x0001
  44. ///----------------------------------------------------------------------------
  45. ///
  46. /// Use this macro to compute how much memory to allocate for the syslog.
  47. ///
  48. ///----------------------------------------------------------------------------
  49. #define XOS_SYSLOG_SIZE(num_entries) \
  50. ( sizeof(XosSysLog) + ((num_entries - 1) * sizeof(XosSysLogEntry)) )
  51. ///----------------------------------------------------------------------------
  52. ///
  53. /// System log entry structure.
  54. ///
  55. ///----------------------------------------------------------------------------
  56. typedef struct XosSysLogEntry {
  57. uint32_t timestamp; ///< Timestamp in clock cycles
  58. uint32_t param1; ///< User defined value
  59. uint32_t param2; ///< User defined value
  60. struct XosSysLogEntry * next; ///< Link to next entry
  61. } XosSysLogEntry;
  62. ///----------------------------------------------------------------------------
  63. ///
  64. /// System log structure.
  65. ///
  66. ///----------------------------------------------------------------------------
  67. typedef struct XosSysLog {
  68. uint16_t flags; ///< Flags
  69. uint16_t size; ///< Number of entries
  70. XosSysLogEntry * next; ///< Next write position
  71. XosSysLogEntry entries[1]; ///< First entry
  72. } XosSysLog;
  73. //-----------------------------------------------------------------------------
  74. // Pointer to syslog area.
  75. //-----------------------------------------------------------------------------
  76. extern XosSysLog * xos_syslog;
  77. //----------------------------------------------------------------------------
  78. ///
  79. /// Initialize the syslog. Initializing the log also enables it. The system
  80. /// log always wraps around when full and overwrites the oldest entries.
  81. ///
  82. /// \param log_mem Pointer to allocated memory for the log.
  83. ///
  84. /// \param num_entries The number of entries that the log can contain.
  85. ///
  86. /// \return Returns nothing.
  87. ///
  88. //----------------------------------------------------------------------------
  89. static inline void
  90. xos_syslog_init(void * log_mem, uint16_t num_entries)
  91. {
  92. uint16_t i;
  93. xos_syslog = (XosSysLog *) log_mem;
  94. xos_syslog->size = num_entries;
  95. xos_syslog->next = xos_syslog->entries;
  96. for (i = 0; i < num_entries - 1; i++) {
  97. xos_syslog->entries[i].next = &(xos_syslog->entries[i+1]);
  98. xos_syslog->entries[i].timestamp = 0;
  99. }
  100. xos_syslog->entries[i].next = xos_syslog->entries;
  101. xos_syslog->entries[i].timestamp = 0;
  102. xos_syslog->flags = XOS_SYSLOG_ENABLED;
  103. }
  104. ///----------------------------------------------------------------------------
  105. ///
  106. /// Reset the syslog. All entries made up to now are abandoned and the write
  107. /// pointer is set to the first entry location.
  108. ///
  109. /// No parameters.
  110. ///
  111. /// \return Returns nothing.
  112. ///
  113. ///----------------------------------------------------------------------------
  114. static inline void
  115. xos_syslog_clear()
  116. {
  117. #if XCHAL_HAVE_INTERRUPTS
  118. uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
  119. #endif
  120. xos_syslog_init(xos_syslog, xos_syslog->size);
  121. #if XCHAL_HAVE_INTERRUPTS
  122. xos_restore_int_pri_level(ps);
  123. #endif
  124. }
  125. ///----------------------------------------------------------------------------
  126. ///
  127. /// Enable logging to the syslog. This function needs to be called only if
  128. /// logging had been previously disabled via xos_syslog_disable(), since
  129. /// initializing the syslog automatically enables it.
  130. ///
  131. /// No parameters.
  132. ///
  133. /// \return Returns nothing.
  134. ///
  135. ///----------------------------------------------------------------------------
  136. static inline void
  137. xos_syslog_enable()
  138. {
  139. #if XCHAL_HAVE_INTERRUPTS
  140. uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
  141. #endif
  142. xos_syslog->flags |= XOS_SYSLOG_ENABLED;
  143. #if XCHAL_HAVE_INTERRUPTS
  144. xos_restore_int_pri_level(ps);
  145. #endif
  146. }
  147. ///----------------------------------------------------------------------------
  148. ///
  149. /// Disable logging to the syslog. It is sometimes useful to disable logging
  150. /// while the log is being examined or dumped.
  151. ///
  152. /// No parameters.
  153. ///
  154. /// \return Returns nothing.
  155. ///
  156. ///----------------------------------------------------------------------------
  157. static inline void
  158. xos_syslog_disable()
  159. {
  160. #if XCHAL_HAVE_INTERRUPTS
  161. uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
  162. #endif
  163. xos_syslog->flags &= ~XOS_SYSLOG_ENABLED;
  164. #if XCHAL_HAVE_INTERRUPTS
  165. xos_restore_int_pri_level(ps);
  166. #endif
  167. }
  168. ///----------------------------------------------------------------------------
  169. ///
  170. /// Write an entry into the syslog. This function does disable all interrupts
  171. /// since logging can be done from interrupt handlers as well. It will write
  172. /// into the log only if the log exists and is enabled.
  173. ///
  174. /// \param param1 User defined value.
  175. ///
  176. /// \param param2 User defined value.
  177. ///
  178. /// \return Returns nothing.
  179. ///
  180. ///----------------------------------------------------------------------------
  181. static inline void
  182. xos_syslog_write(uint32_t param1, uint32_t param2)
  183. {
  184. if (xos_syslog != XOS_NULL) {
  185. #if XCHAL_HAVE_INTERRUPTS
  186. uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
  187. #endif
  188. if ((xos_syslog->flags & XOS_SYSLOG_ENABLED) != 0) {
  189. XosSysLogEntry * next = xos_syslog->next;
  190. next->timestamp = xos_get_ccount();
  191. next->param1 = param1;
  192. next->param2 = param2;
  193. xos_syslog->next = next->next;
  194. }
  195. #if XCHAL_HAVE_INTERRUPTS
  196. xos_restore_int_pri_level(ps);
  197. #endif
  198. }
  199. }
  200. ///----------------------------------------------------------------------------
  201. ///
  202. /// Read the first (oldest) entry in the syslog. Will return an error if the
  203. /// log has not been created or is empty. Storage to copy the entry must be
  204. /// provided by the caller.
  205. ///
  206. /// \param entry Pointer to storage where the entry data will be
  207. /// copied. This pointer must be passed to
  208. /// xos_syslog_get_next().
  209. ///
  210. /// \return Returns XOS_OK on success, else error code.
  211. ///
  212. ///----------------------------------------------------------------------------
  213. static inline int32_t
  214. xos_syslog_get_first(XosSysLogEntry * entry)
  215. {
  216. if (xos_syslog == XOS_NULL) {
  217. return XOS_ERR_NOT_FOUND;
  218. }
  219. if (entry != XOS_NULL) {
  220. #if XCHAL_HAVE_INTERRUPTS
  221. uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
  222. #endif
  223. XosSysLogEntry * next = xos_syslog->next;
  224. // 'next' should be pointing to the next entry to be overwritten, if we
  225. // have wrapped. This means it is the oldest entry. However if this entry
  226. // has a zero timestamp then we have not wrapped, in which case we must
  227. // look at the first entry in the list.
  228. if (next->timestamp == 0) {
  229. next = xos_syslog->entries;
  230. }
  231. *entry = *next;
  232. #if XCHAL_HAVE_INTERRUPTS
  233. xos_restore_int_pri_level(ps);
  234. #endif
  235. return entry->timestamp ? XOS_OK : XOS_ERR_NOT_FOUND;
  236. }
  237. return XOS_ERR_INVALID_PARAMETER;
  238. }
  239. ///----------------------------------------------------------------------------
  240. ///
  241. /// Get the next sequential entry from the syslog. This function must be called
  242. /// only after xos_syslog_get_first() has been called.
  243. ///
  244. /// \param entry Pointer to storage where entry data will be copied.
  245. /// Must be the same pointer that was passed in the call
  246. /// to xos_syslog_get_first(), as it is used to keep track
  247. /// of the current position.
  248. ///
  249. /// \return Returns XOS_OK on success, else error code.
  250. ///
  251. ///----------------------------------------------------------------------------
  252. static inline int32_t
  253. xos_syslog_get_next(XosSysLogEntry * entry)
  254. {
  255. if (entry != XOS_NULL) {
  256. #if XCHAL_HAVE_INTERRUPTS
  257. uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS);
  258. #endif
  259. XosSysLogEntry * next = entry->next;
  260. int32_t ret = XOS_OK;
  261. // Make sure we're not pointing past the last entry.
  262. if ((next != XOS_NULL) && (next != xos_syslog->next) && (next->timestamp != 0)) {
  263. *entry = *next;
  264. }
  265. else {
  266. ret = XOS_ERR_NOT_FOUND;
  267. }
  268. #if XCHAL_HAVE_INTERRUPTS
  269. xos_restore_int_pri_level(ps);
  270. #endif
  271. return ret;
  272. }
  273. return XOS_ERR_INVALID_PARAMETER;
  274. }
  275. #ifdef __cplusplus
  276. }
  277. #endif
  278. #endif // __XOS_SYSLOG_H__