blob: 5e4509fa470188c9794d62e204bfd0e35681e4b4 [file] [log] [blame]
#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;
}