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