| #include "print.h" |
| #include "serial.h" |
| #include "PlatformConfig.h" |
| extern int ModOfTwoNumbers(int Numerator, int Denominator); |
| extern int DivideTwoNumbers(int Numerator, int Denominator); |
| |
| static volatile unsigned char quiet = 0; |
| |
| #if CONFIG_SAVE_LOG_TO_MEM |
| static boot_log_t *pboot_log = (boot_log_t *)CONFIG_BOOT_LOG_ADDR; |
| |
| static void boot_log_write_mem(char *text, int size) |
| { |
| uint32_t bufsize; |
| static int boot_log_inited = -1; |
| |
| if (PlatformCheckEMMDStatus()) |
| return; |
| |
| bufsize = CONFIG_BOOT_LOG_SIZE - sizeof(pboot_log->buf_pos) - sizeof(pboot_log->magic); |
| if (boot_log_inited == -1) { |
| pboot_log->buf_pos = 0; |
| pboot_log->magic = BOOT_LOG_MAGIC; |
| boot_log_inited = 1; |
| } |
| |
| if (pboot_log->buf) { |
| if (pboot_log->buf_pos >= bufsize) |
| pboot_log->buf_pos = pboot_log->buf_pos % bufsize; |
| |
| if ((size >= bufsize)) |
| size = size % bufsize; |
| |
| if ((size + pboot_log->buf_pos <= bufsize)) |
| memcpy(&pboot_log->buf[pboot_log->buf_pos], text, size); |
| else { |
| unsigned int first = bufsize - pboot_log->buf_pos; |
| unsigned int second = size - first; |
| memcpy(&pboot_log->buf[pboot_log->buf_pos], text, first); |
| memcpy(&pboot_log->buf[pboot_log->buf_pos], text + first, second); |
| } |
| |
| pboot_log->buf_pos += size; /* Check overflow */ |
| if ((pboot_log->buf_pos >= bufsize)) |
| pboot_log->buf_pos -= size; |
| } |
| } |
| #endif |
| |
| static void normal_print_char(int c) |
| { |
| #if CONFIG_SAVE_LOG_TO_MEM |
| boot_log_write_mem((char *)&c, 1); |
| #endif |
| #if USE_SERIAL_DEBUG |
| (void) serial_write (c); |
| #endif |
| } |
| |
| static void quiet_print_char(int c) |
| { |
| #if CONFIG_SAVE_LOG_TO_MEM |
| boot_log_write_mem((char *)&c, 1); |
| #else |
| void(c); |
| #endif |
| } |
| |
| typedef void (*print_char)(int); |
| |
| print_char log_print_char = normal_print_char; |
| |
| int serial_get_quiet(void) |
| { |
| return quiet; |
| } |
| |
| void serial_set_quiet(int on) |
| { |
| quiet = on; |
| if (quiet) { |
| log_print_char = quiet_print_char; |
| } |
| else { |
| log_print_char = normal_print_char; |
| } |
| } |
| |
| static void printchar (char **str, int c) |
| { |
| if (str) { |
| **str = c; |
| ++(*str); |
| } |
| else { |
| (*log_print_char)(c); |
| } |
| } |
| |
| #define PAD_RIGHT 1 |
| #define PAD_ZERO 2 |
| |
| static int prints (char **out, const char *string, int width, int pad) |
| { |
| register int pc = 0, padchar = ' '; |
| if (width > 0) { |
| int len = 0; |
| const char *ptr; |
| for (ptr = string; *ptr; ++ptr) |
| |
| ++len; |
| if (len >= width) |
| width = 0; |
| else |
| width -= len; |
| if (pad & PAD_ZERO) |
| padchar = '0'; |
| } |
| if (!(pad & PAD_RIGHT)) { |
| for (; width > 0; --width) { |
| printchar (out, padchar); |
| ++pc; |
| } |
| } |
| for (; *string; ++string) { |
| printchar (out, *string); |
| ++pc; |
| } |
| for (; width > 0; --width) { |
| printchar (out, padchar); |
| ++pc; |
| } |
| return pc; |
| } |
| |
| #define PRINT_BUF_LEN 20 |
| static int printi (char **out, long long i, int b, int sg, int width, int pad, int letbase) |
| { |
| char print_buf[PRINT_BUF_LEN]; |
| char *s; |
| int t, neg = 0, pc = 0; |
| unsigned long long u = (unsigned long long) i; |
| if (i == 0) { |
| print_buf[0] = '0'; |
| print_buf[1] = '\0'; |
| return prints (out, print_buf, width, pad); |
| } |
| if (sg && b == 10 && i < 0) { |
| neg = 1; |
| u = (unsigned long long) -i; |
| } |
| s = print_buf + PRINT_BUF_LEN - 1; |
| *s = '\0'; |
| while (u) { |
| //t = u % b; //lint !e573 Warning 573: Signed-unsigned mix with divide |
| t = ModOfTwoNumbers(u, b); |
| if (t >= 10) |
| t += letbase - '0' - 10; |
| *--s = t + '0'; |
| //u /= b; //lint !e573 Warning 573: Signed-unsigned mix with divide |
| u = DivideTwoNumbers(u, b); |
| } |
| if (neg) { |
| if (width && (pad & PAD_ZERO)) { |
| printchar (out, '-'); |
| ++pc; |
| --width; |
| } |
| else { |
| *--s = '-'; |
| } |
| } |
| return pc + prints (out, s, width, pad); |
| } |
| |
| int print (char **out, int *varg, int align) |
| { |
| int post_decimal ; |
| int width, pad, l_num; |
| unsigned dec_width = 0 ; |
| int pc = 0; |
| int varg_bk = (int)(varg - align); |
| char *format = (char *) (*varg++); |
| char scr[2]; |
| for (; *format != 0; ++format) { |
| if (*format == '%') { |
| ++format; |
| width = pad = 0; |
| l_num = 0; |
| if (*format == '\0') |
| break; |
| if (*format == '%') |
| goto out; |
| if (*format == '-') { |
| ++format; |
| pad = PAD_RIGHT; |
| } |
| while (*format == '0') { |
| ++format; |
| pad |= PAD_ZERO; |
| } |
| post_decimal = 0 ; |
| if (*format == '.' || |
| (*format >= '0' && *format <= '9') || *format == '*') |
| { |
| |
| while (1) { |
| if (*format == '.') { |
| post_decimal = 1 ; |
| dec_width = 0 ; |
| format++ ; |
| } else if ((*format >= '0' && *format <= '9')) { |
| if (post_decimal) { |
| dec_width *= 10; |
| dec_width += *format - '0'; |
| } else { |
| width *= 10; |
| width += *format - '0'; |
| } |
| format++ ; |
| } else if(*format == '*'){ |
| if(post_decimal){ |
| dec_width = (int)(*varg++); |
| } |
| else |
| width = (int)(*varg++); |
| format++ ; |
| } else { |
| break; |
| } |
| } |
| } |
| while (*format == 'l' || *format == 'L') { |
| ++format; |
| ++l_num; |
| } |
| switch (*format) { |
| case 's': |
| { |
| char *s = *((char **) varg++); //lint !e740 |
| pc += prints (out, s ? s : "(null)", width, pad); |
| } |
| break; |
| case 'd': |
| case 'i': |
| if (l_num > 1) { |
| long long *llptr = (long long *)((((int)(varg) +7 -varg_bk) & (~7)) + varg_bk); |
| pc += printi (out, *llptr, 10, 1, width, pad, 'a'); |
| varg = (int *)(llptr + 1); |
| } else { |
| pc += printi (out, (long long)(*varg++), 10, 1, width, pad, 'a'); |
| } |
| break; |
| case 'x': |
| if (l_num > 1) { |
| long long *llptr = (long long *)((((int)(varg) +7 -varg_bk) & (~7)) + varg_bk); |
| pc += printi (out, *llptr, 16, 0, width, pad, 'a'); |
| varg = (int *)(llptr + 1); |
| } else { |
| pc += printi (out, (long long)((unsigned int)(*varg++)), 16, 0, width, pad, 'a'); |
| } |
| break; |
| case 'X': |
| if (l_num > 1) { |
| long long *llptr = (long long *)((((int)(varg) +7 -varg_bk) & (~7)) + varg_bk); |
| pc += printi (out, *llptr, 16, 0, width, pad, 'A'); |
| varg = (int *)(llptr + 1); |
| } else { |
| pc += printi (out, (long long)((unsigned int)(*varg++)), 16, 0, width, pad, 'A'); |
| } |
| break; |
| case 'u': |
| if (l_num > 1) { |
| long long *llptr = (long long *)((((int)(varg) +7 -varg_bk) & (~7)) + varg_bk); |
| pc += printi (out, *llptr, 10, 0, width, pad, 'a'); |
| varg = (int *)(llptr + 1); |
| } else { |
| pc += printi (out, (long long)((unsigned int)(*varg++)), 10, 0, width, pad, 'a'); |
| } |
| break; |
| case 'c': |
| /* char are converted to int then pushed on the stack */ |
| scr[0] = *varg++; |
| scr[1] = '\0'; |
| pc += prints (out, scr, width, pad); |
| break; |
| default: |
| printchar (out, '%'); |
| printchar (out, *format); |
| break; |
| } |
| } |
| else { |
| out: |
| printchar (out, *format); |
| ++pc; |
| } |
| } |
| if (out) |
| **out = '\0'; |
| return pc; |
| } |
| |
| int err_msg(const char *format, ...) |
| { |
| print_char saved_print_char; |
| saved_print_char = log_print_char; |
| log_print_char = normal_print_char; |
| int size; |
| int *varg = (int *) (char *) (&format); |
| size = print (0, varg, 0); |
| |
| log_print_char = saved_print_char; |
| return size; |
| } |
| |
| int obm_printf(const char *format, ...) |
| { |
| int size; |
| int *varg = (int *) (char *) (&format); |
| size = print (0, varg, 0); |
| |
| return size; |
| } |
| |
| int sprintf(char *str, const char *format, ...) |
| { |
| int size; |
| int *varg = (int *) (char *) (&format); |
| size = print (&str, varg, 0); |
| return size; |
| } |