alt_log_printf.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /* alt_log_printf.h
  2. *
  3. * ALT_LOG is designed to provide extra logging/debugging messages from HAL
  4. * through a different port than stdout. It is enabled by the ALT_LOG_ENABLE
  5. * define, which needs to supplied at compile time. When logging is turned off,
  6. * code size is unaffected. Thus, this should be transparent to the user
  7. * when it is not actively turned on, and should not affect projects in any way.
  8. *
  9. * There are macros sprinkled within different components, such as the jtag uart
  10. * and timer, in the HAL code. They are always named ALT_LOG_<name>, and can be
  11. * safely ignored if ALT_LOG is turned off.
  12. *
  13. * To turn on ALT_LOG, ALT_LOG_ENABLE must be defined, and ALT_LOG_PORT_TYPE and
  14. * ALT_LOG_PORT_BASE must be set in system.h. This is done through editing
  15. * <project>.ptf, by editing the alt_log_port_type & alt_log_port_base settings.
  16. * See the documentation html file for examples.
  17. *
  18. * When it is turned on, it will output extra HAL messages to a port specified
  19. * in system.h. This can be a UART or JTAG UART port. By default it will
  20. * output boot messages, detailing every step of the boot process.
  21. *
  22. * Extra logging is designed to be enabled by flags, which are defined in
  23. * alt_log_printf.c. The default value is that all flags are off, so only the
  24. * boot up logging messages show up. ALT_LOG_FLAGS can be set to enable certain
  25. * groupings of flags, and that grouping is done in this file. Each flag can
  26. * also be overridden with a -D at compile time.
  27. *
  28. * This header file includes the necessary prototypes for using the alt_log
  29. * functions. It also contains all the macros that are used to remove the code
  30. * from alt log is turned off. Also, the macros in other HAL files are defined
  31. * here at the bottom. These macros all call some C function that is in
  32. * alt_log_printf.c.
  33. *
  34. * The logging has functions for printing in C (ALT_LOG_PRINTF) and in assembly
  35. * (ALT_LOG_PUTS). This was needed because the assembly printing occurs before
  36. * the device is initialized. The assembly function corrupts register R4-R7,
  37. * which are not used in the normal boot process. For this reason, do not call
  38. * the assembly function in C.
  39. *
  40. * author: gkwan
  41. */
  42. #ifndef __ALT_LOG_PRINTF_H__
  43. #define __ALT_LOG_PRINTF_H__
  44. #include <system.h>
  45. /* Global switch to turn on logging functions */
  46. #ifdef ALT_LOG_ENABLE
  47. /* ALT_LOG_PORT_TYPE values as defined in system.h. They are defined as
  48. * numbers here first becasue the C preprocessor does not handle string
  49. * comparisons. */
  50. #define ALTERA_AVALON_JTAG_UART 1
  51. #define ALTERA_AVALON_UART 0
  52. /* If this .h file is included by an assembly file, skip over include files
  53. * that won't compile in assembly. */
  54. #ifndef ALT_ASM_SRC
  55. #include <stdarg.h>
  56. #include "sys/alt_alarm.h"
  57. #include "sys/alt_dev.h"
  58. #ifdef __ALTERA_AVALON_JTAG_UART
  59. #include "altera_avalon_jtag_uart.h"
  60. #endif
  61. #endif /* ALT_ASM_SRC */
  62. /* These are included for the port register offsets and masks, needed
  63. * to write to the port. Only include if the port type is set correctly,
  64. * otherwise error. If alt_log is turned on and the port to output to is
  65. * incorrect or does not exist, then should exit. */
  66. #if ALT_LOG_PORT_TYPE == ALTERA_AVALON_JTAG_UART
  67. #ifdef __ALTERA_AVALON_JTAG_UART
  68. #include <altera_avalon_jtag_uart_regs.h>
  69. #else
  70. #error ALT_LOG: JTAG_UART port chosen, but no JTAG_UART in system.
  71. #endif
  72. #elif ALT_LOG_PORT_TYPE == ALTERA_AVALON_UART
  73. #ifdef __ALTERA_AVALON_UART
  74. #include <altera_avalon_uart_regs.h>
  75. #else
  76. #error ALT_LOG: UART Port chosen, but no UART in system.
  77. #endif
  78. #else
  79. #error ALT_LOG: alt_log_port_type declaration invalid!
  80. #endif
  81. /* ALT_LOG_ENABLE turns on the basic printing function */
  82. #define ALT_LOG_PRINTF(...) do {alt_log_printf_proc(__VA_ARGS__);} while (0)
  83. /* Assembly macro for printing in assembly, calls tx_log_str
  84. * which is in alt_log_macro.S.
  85. * If alt_log_boot_on_flag is 0, skips the printing */
  86. #define ALT_LOG_PUTS(str) movhi r4, %hiadj(alt_log_boot_on_flag) ; \
  87. addi r4, r4, %lo(alt_log_boot_on_flag) ; \
  88. ldwio r5, 0(r4) ; \
  89. beq r0, r5, 0f ; \
  90. movhi r4, %hiadj(str) ; \
  91. addi r4, r4, %lo(str) ; \
  92. call tx_log_str ; \
  93. 0:
  94. /* These defines are here to faciliate the use of one output function
  95. * (alt_log_txchar) to print to both the JTAG UART or the UART. Depending
  96. * on the port type, the status register, read mask, and output register
  97. * are set to the appropriate value for the port. */
  98. #if ALT_LOG_PORT_TYPE == ALTERA_AVALON_JTAG_UART
  99. #define ALT_LOG_PRINT_REG_RD IORD_ALTERA_AVALON_JTAG_UART_CONTROL
  100. #define ALT_LOG_PRINT_MSK ALTERA_AVALON_JTAG_UART_CONTROL_WSPACE_MSK
  101. #define ALT_LOG_PRINT_TXDATA_WR IOWR_ALTERA_AVALON_JTAG_UART_DATA
  102. #define ALT_LOG_PRINT_REG_OFFSET (ALTERA_AVALON_JTAG_UART_CONTROL_REG*0x4)
  103. #define ALT_LOG_PRINT_TXDATA_REG_OFFSET (ALTERA_AVALON_JTAG_UART_DATA_REG*0x4)
  104. #elif ALT_LOG_PORT_TYPE == ALTERA_AVALON_UART
  105. #define ALT_LOG_PRINT_REG_RD IORD_ALTERA_AVALON_UART_STATUS
  106. #define ALT_LOG_PRINT_MSK ALTERA_AVALON_UART_STATUS_TRDY_MSK
  107. #define ALT_LOG_PRINT_TXDATA_WR IOWR_ALTERA_AVALON_UART_TXDATA
  108. #define ALT_LOG_PRINT_REG_OFFSET (ALTERA_AVALON_UART_STATUS_REG*0x4)
  109. #define ALT_LOG_PRINT_TXDATA_REG_OFFSET (ALTERA_AVALON_UART_TXDATA_REG*0x4)
  110. #endif /* ALT_LOG_PORT */
  111. /* Grouping of flags via ALT_LOG_FLAGS. Each specific flag can be set via
  112. * -D at compile time, or else they'll be set to a default value according
  113. * to ALT_LOG_FLAGS. ALT_LOG_FLAGS = 0 or not set is the default, where
  114. * only the boot messages will be printed. As ALT_LOG_FLAGS increase, they
  115. * increase in intrusiveness to the program, and will affect performance.
  116. *
  117. * Flag Level 1 - turns on system clock and JTAG UART startup status
  118. * 2 - turns on write echo and JTAG_UART alarm (periodic report)
  119. * 3 - turns on JTAG UART ISR logging - will slow performance
  120. * significantly.
  121. * -1 - All logging output is off, but if ALT_LOG_ENABLE is
  122. * defined all logging function is built and code size
  123. * remains constant
  124. *
  125. * Flag settings - 1 = on, 0 = off. */
  126. /* This flag turns on "boot" messages for printing. This includes messages
  127. * during crt0.S, then alt_main, and finally alt_exit. */
  128. #ifndef ALT_LOG_BOOT_ON_FLAG_SETTING
  129. #if ALT_LOG_FLAGS == 1
  130. #define ALT_LOG_BOOT_ON_FLAG_SETTING 0x1
  131. #elif ALT_LOG_FLAGS == 2
  132. #define ALT_LOG_BOOT_ON_FLAG_SETTING 0x1
  133. #elif ALT_LOG_FLAGS == 3
  134. #define ALT_LOG_BOOT_ON_FLAG_SETTING 0x1
  135. #elif ALT_LOG_FLAGS == -1 /* silent mode */
  136. #define ALT_LOG_BOOT_ON_FLAG_SETTING 0x0
  137. #else /* default setting */
  138. #define ALT_LOG_BOOT_ON_FLAG_SETTING 0x1
  139. #endif
  140. #endif /* ALT_LOG_BOOT_ON_FLAG_SETTING */
  141. #ifndef ALT_LOG_SYS_CLK_ON_FLAG_SETTING
  142. #if ALT_LOG_FLAGS == 1
  143. #define ALT_LOG_SYS_CLK_ON_FLAG_SETTING 0x1
  144. #elif ALT_LOG_FLAGS == 2
  145. #define ALT_LOG_SYS_CLK_ON_FLAG_SETTING 0x1
  146. #elif ALT_LOG_FLAGS == 3
  147. #define ALT_LOG_SYS_CLK_ON_FLAG_SETTING 0x1
  148. #elif ALT_LOG_FLAGS == -1 /* silent mode */
  149. #define ALT_LOG_SYS_CLK_ON_FLAG_SETTING 0x0
  150. #else /* default setting */
  151. #define ALT_LOG_SYS_CLK_ON_FLAG_SETTING 0x0
  152. #endif
  153. #endif /* ALT_LOG_SYS_CLK_ON_FLAG_SETTING */
  154. #ifndef ALT_LOG_WRITE_ON_FLAG_SETTING
  155. #if ALT_LOG_FLAGS == 1
  156. #define ALT_LOG_WRITE_ON_FLAG_SETTING 0x0
  157. #elif ALT_LOG_FLAGS == 2
  158. #define ALT_LOG_WRITE_ON_FLAG_SETTING 0x1
  159. #elif ALT_LOG_FLAGS == 3
  160. #define ALT_LOG_WRITE_ON_FLAG_SETTING 0x1
  161. #elif ALT_LOG_FLAGS == -1 /* silent mode */
  162. #define ALT_LOG_WRITE_ON_FLAG_SETTING 0x0
  163. #else /* default setting */
  164. #define ALT_LOG_WRITE_ON_FLAG_SETTING 0x0
  165. #endif
  166. #endif /* ALT_LOG_WRITE_ON_FLAG_SETTING */
  167. #ifndef ALT_LOG_JTAG_UART_ALARM_ON_FLAG_SETTING
  168. #ifndef __ALTERA_AVALON_JTAG_UART
  169. #define ALT_LOG_JTAG_UART_ALARM_ON_FLAG_SETTING 0x0
  170. #elif ALT_LOG_FLAGS == 1
  171. #define ALT_LOG_JTAG_UART_ALARM_ON_FLAG_SETTING 0x0
  172. #elif ALT_LOG_FLAGS == 2
  173. #define ALT_LOG_JTAG_UART_ALARM_ON_FLAG_SETTING 0x1
  174. #elif ALT_LOG_FLAGS == 3
  175. #define ALT_LOG_JTAG_UART_ALARM_ON_FLAG_SETTING 0x1
  176. #elif ALT_LOG_FLAGS == -1 /* silent mode */
  177. #define ALT_LOG_JTAG_UART_ALARM_ON_FLAG_SETTING 0x0
  178. #else /* default setting */
  179. #define ALT_LOG_JTAG_UART_ALARM_ON_FLAG_SETTING 0x0
  180. #endif
  181. #endif /* ALT_LOG_JTAG_UART_ALARM_ON_FLAG_SETTING */
  182. #ifndef ALT_LOG_JTAG_UART_STARTUP_INFO_ON_FLAG_SETTING
  183. #ifndef __ALTERA_AVALON_JTAG_UART
  184. #define ALT_LOG_JTAG_UART_STARTUP_INFO_ON_FLAG_SETTING 0x0
  185. #elif ALT_LOG_FLAGS == 1
  186. #define ALT_LOG_JTAG_UART_STARTUP_INFO_ON_FLAG_SETTING 0x1
  187. #elif ALT_LOG_FLAGS == 2
  188. #define ALT_LOG_JTAG_UART_STARTUP_INFO_ON_FLAG_SETTING 0x1
  189. #elif ALT_LOG_FLAGS == 3
  190. #define ALT_LOG_JTAG_UART_STARTUP_INFO_ON_FLAG_SETTING 0x1
  191. #elif ALT_LOG_FLAGS == -1 /* silent mode */
  192. #define ALT_LOG_JTAG_UART_STARTUP_INFO_ON_FLAG_SETTING 0x0
  193. #else /* default setting */
  194. #define ALT_LOG_JTAG_UART_STARTUP_INFO_ON_FLAG_SETTING 0x0
  195. #endif
  196. #endif /* ALT_LOG_JTAG_UART_STARTUP_INFO_FLAG_SETTING */
  197. #ifndef ALT_LOG_JTAG_UART_ISR_ON_FLAG_SETTING
  198. #ifndef __ALTERA_AVALON_JTAG_UART
  199. #define ALT_LOG_JTAG_UART_ISR_ON_FLAG_SETTING 0x0
  200. #elif ALT_LOG_FLAGS == 1
  201. #define ALT_LOG_JTAG_UART_ISR_ON_FLAG_SETTING 0x0
  202. #elif ALT_LOG_FLAGS == 2
  203. #define ALT_LOG_JTAG_UART_ISR_ON_FLAG_SETTING 0x0
  204. #elif ALT_LOG_FLAGS == 3
  205. #define ALT_LOG_JTAG_UART_ISR_ON_FLAG_SETTING 0x1
  206. #elif ALT_LOG_FLAGS == -1 /* silent mode */
  207. #define ALT_LOG_JTAG_UART_ISR_ON_FLAG_SETTING 0x0
  208. #else /* default setting */
  209. #define ALT_LOG_JTAG_UART_ISR_ON_FLAG_SETTING 0x0
  210. #endif
  211. #endif /* ALT_LOG_JTAG_UART_ISR_ON_FLAG_SETTING */
  212. #ifndef ALT_ASM_SRC
  213. /* Function Prototypes */
  214. void alt_log_txchar(int c,char *uartBase);
  215. void alt_log_private_printf(const char *fmt,int base,va_list args);
  216. void alt_log_repchar(char c,int r,int base);
  217. int alt_log_printf_proc(const char *fmt, ... );
  218. void alt_log_system_clock();
  219. #ifdef __ALTERA_AVALON_JTAG_UART
  220. alt_u32 altera_avalon_jtag_uart_report_log(void * context);
  221. void alt_log_jtag_uart_startup_info(altera_avalon_jtag_uart_state* dev, int base);
  222. void alt_log_jtag_uart_print_control_reg(altera_avalon_jtag_uart_state* dev, \
  223. int base, const char* header);
  224. void alt_log_jtag_uart_isr_proc(int base, altera_avalon_jtag_uart_state* dev);
  225. #endif
  226. void alt_log_write(const void *ptr, size_t len);
  227. /* extern all global variables */
  228. /* CASE:368514 - The boot message flag is linked into the sdata section
  229. * because if it is zero, it would otherwise be placed in the bss section.
  230. * alt_log examines this variable before the BSS is cleared in the boot-up
  231. * process.
  232. */
  233. extern volatile alt_u32 alt_log_boot_on_flag __attribute__ ((section (".sdata")));
  234. extern volatile alt_u8 alt_log_write_on_flag;
  235. extern volatile alt_u8 alt_log_sys_clk_on_flag;
  236. extern volatile alt_u8 alt_log_jtag_uart_alarm_on_flag;
  237. extern volatile alt_u8 alt_log_jtag_uart_isr_on_flag;
  238. extern volatile alt_u8 alt_log_jtag_uart_startup_info_on_flag;
  239. extern volatile int alt_log_sys_clk_count;
  240. extern volatile int alt_system_clock_in_sec;
  241. extern alt_alarm alt_log_jtag_uart_alarm_1;
  242. #endif /* ALT_ASM_SRC */
  243. /* Below are the MACRO defines used in various HAL files. They check
  244. * if their specific flag is turned on; if it is, then it executes its
  245. * code.
  246. *
  247. * To keep this file reasonable, most of these macros calls functions,
  248. * which are defined in alt_log_printf.c. Look there for implementation
  249. * details. */
  250. /* Boot Messages Logging */
  251. #define ALT_LOG_PRINT_BOOT(...) \
  252. do { if (alt_log_boot_on_flag==1) {ALT_LOG_PRINTF(__VA_ARGS__);} \
  253. } while (0)
  254. /* JTAG UART Logging */
  255. /* number of ticks before alarm runs logging function */
  256. #ifndef ALT_LOG_JTAG_UART_TICKS_DIVISOR
  257. #define ALT_LOG_JTAG_UART_TICKS_DIVISOR 10
  258. #endif
  259. #ifndef ALT_LOG_JTAG_UART_TICKS
  260. #define ALT_LOG_JTAG_UART_TICKS \
  261. (alt_ticks_per_second()/ALT_LOG_JTAG_UART_TICKS_DIVISOR)
  262. #endif
  263. /* if there's a JTAG UART defined, then enable these macros */
  264. #ifdef __ALTERA_AVALON_JTAG_UART
  265. /* Macro in altera_avalon_jtag_uart.c, to register the alarm function.
  266. * Also, the startup register info is also printed here, as this is
  267. * called within the device driver initialization. */
  268. #define ALT_LOG_JTAG_UART_ALARM_REGISTER(dev, base) \
  269. do { if (alt_log_jtag_uart_alarm_on_flag==1) { \
  270. alt_alarm_start(&alt_log_jtag_uart_alarm_1, \
  271. ALT_LOG_JTAG_UART_TICKS, &altera_avalon_jtag_uart_report_log,\
  272. dev);} \
  273. if (alt_log_jtag_uart_startup_info_on_flag==1) {\
  274. alt_log_jtag_uart_startup_info(dev, base);} \
  275. } while (0)
  276. /* JTAG UART IRQ Logging (when buffer is empty)
  277. * Inserted in the ISR in altera_avalon_jtag_uart.c */
  278. #define ALT_LOG_JTAG_UART_ISR_FUNCTION(base, dev) \
  279. do { alt_log_jtag_uart_isr_proc(base, dev); } while (0)
  280. /* else, define macros to nothing. Or else the jtag_uart specific types
  281. * will throw compiler errors */
  282. #else
  283. #define ALT_LOG_JTAG_UART_ALARM_REGISTER(dev, base)
  284. #define ALT_LOG_JTAG_UART_ISR_FUNCTION(base, dev)
  285. #endif
  286. /* System clock logging
  287. * How often (in seconds) the system clock logging prints.
  288. * The default value is every 1 second */
  289. #ifndef ALT_LOG_SYS_CLK_INTERVAL_MULTIPLIER
  290. #define ALT_LOG_SYS_CLK_INTERVAL_MULTIPLIER 1
  291. #endif
  292. #ifndef ALT_LOG_SYS_CLK_INTERVAL
  293. #define ALT_LOG_SYS_CLK_INTERVAL \
  294. (alt_ticks_per_second()*ALT_LOG_SYS_CLK_INTERVAL_MULTIPLIER)
  295. #endif
  296. /* System clock logging - prints a message every interval (set above)
  297. * to show that the system clock is alive.
  298. * This macro is used in altera_avalon_timer_sc.c */
  299. #define ALT_LOG_SYS_CLK_HEARTBEAT() \
  300. do { alt_log_system_clock(); } while (0)
  301. /* alt_write_logging - echos a message every time write() is called,
  302. * displays the first ALT_LOG_WRITE_ECHO_LEN characters.
  303. * This macro is used in alt_write.c */
  304. #ifndef ALT_LOG_WRITE_ECHO_LEN
  305. #define ALT_LOG_WRITE_ECHO_LEN 15
  306. #endif
  307. #define ALT_LOG_WRITE_FUNCTION(ptr,len) \
  308. do { alt_log_write(ptr,len); } while (0)
  309. #else /* ALT_LOG_ENABLE not defined */
  310. /* logging is off, set all relevant macros to null */
  311. #define ALT_LOG_PRINT_BOOT(...)
  312. #define ALT_LOG_PRINTF(...)
  313. #define ALT_LOG_JTAG_UART_ISR_FUNCTION(base, dev)
  314. #define ALT_LOG_JTAG_UART_ALARM_REGISTER(dev, base)
  315. #define ALT_LOG_SYS_CLK_HEARTBEAT()
  316. #define ALT_LOG_PUTS(str)
  317. #define ALT_LOG_WRITE_FUNCTION(ptr,len)
  318. #endif /* ALT_LOG_ENABLE */
  319. #endif /* __ALT_LOG_PRINTF_H__ */