+++ /dev/null
-/** @file\r
-Serial conole output and string formating.\r
-\r
-Copyright (c) 2013-2015 Intel Corporation.\r
-\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-#include "memory_options.h"\r
-#include "general_definitions.h"\r
-\r
-// Resource programmed to PCI bridge, 1MB bound alignment is needed.\r
-// The default value is overwritten by MRC parameter, assuming code\r
-// relocated to eSRAM.\r
-uint32_t UartMmioBase = 0;\r
-\r
-// Serial port registers based on SerialPortLib.c\r
-#define R_UART_BAUD_THR 0\r
-#define R_UART_LSR 20\r
-\r
-#define B_UART_LSR_RXRDY BIT0\r
-#define B_UART_LSR_TXRDY BIT5\r
-#define B_UART_LSR_TEMT BIT6\r
-\r
-// Print mask see DPF and D_Xxxx\r
-#define DPF_MASK DpfPrintMask\r
-\r
-// Select class of messages enabled for printing\r
-uint32_t DpfPrintMask =\r
- D_ERROR |\r
- D_INFO |\r
- // D_REGRD |\r
- // D_REGWR |\r
- // D_FCALL |\r
- // D_TRN |\r
- 0;\r
-\r
-#ifdef NDEBUG\r
-// Don't generate debug code\r
-void dpf( uint32_t mask, char_t* bla, ...)\r
-{\r
- return;\r
-}\r
-\r
-uint8_t mgetc(void)\r
-{\r
- return 0;\r
-}\r
-\r
-uint8_t mgetch(void)\r
-{\r
- return 0;\r
-}\r
-\r
-#else\r
-\r
-#ifdef SIM\r
-// Use Vpi console in simulation environment\r
-#include <vpi_user.h>\r
-\r
-void dpf( uint32_t mask, char_t* bla, ...)\r
-{\r
- va_list va;\r
-\r
- if( 0 == (mask & DPF_MASK)) return;\r
-\r
- va_start( va, bla);\r
- vpi_vprintf( bla, va);\r
- va_end(va);\r
-}\r
-\r
-#else\r
-\r
-#ifdef EMU\r
-// Use standard console in windows environment\r
-#include <stdio.h>\r
-#endif\r
-\r
-// Read character from serial port\r
-uint8_t mgetc(void)\r
-{\r
-#ifdef EMU\r
-\r
- // Emulation in Windows environment uses console\r
- getchar();\r
-\r
-#else\r
- uint8_t c;\r
-\r
- while ((*(volatile uint8_t*) (UartMmioBase + R_UART_LSR) & B_UART_LSR_RXRDY) == 0);\r
- c = *(volatile uint8_t*) (UartMmioBase + R_UART_BAUD_THR);\r
-\r
- return c;\r
-#endif\r
-}\r
-\r
-\r
-uint8_t mgetch(void)\r
-{\r
-#ifdef EMU\r
- return 0;\r
-#else\r
- uint8_t c = 0;\r
-\r
- if((*(volatile uint8_t*) (UartMmioBase + R_UART_LSR) & B_UART_LSR_RXRDY) != 0)\r
- {\r
- c = *(volatile uint8_t*) (UartMmioBase + R_UART_BAUD_THR);\r
- }\r
-\r
- return c;\r
-#endif\r
-}\r
-\r
-// Print single character\r
-static void printc(\r
- uint8_t c)\r
-{\r
-#ifdef EMU\r
-\r
- // Emulation in Windows environment uses console output\r
- putchar(c);\r
-\r
-#else\r
-\r
- //\r
- // Use MMIO access to serial port on PCI\r
- // while( 0 == (0x20 & inp(0x3f8 + 5)));\r
- // outp(0x3f8 + 0, c);\r
- //\r
- while (0\r
- == (B_UART_LSR_TEMT & *((volatile uint8_t*) (UartMmioBase + R_UART_LSR))))\r
- ;\r
- *((volatile uint8_t*) (UartMmioBase + R_UART_BAUD_THR)) = c;\r
-#endif\r
-}\r
-\r
-// Print 0 terminated string on serial console\r
-static void printstr(\r
- char_t *str)\r
-{\r
- while (*str)\r
- {\r
- printc(*str++);\r
- }\r
-}\r
-// Print 64bit number as hex string on serial console\r
-// the width parameters allows skipping leading zeros\r
-static void printhexx(\r
- uint64_t val,\r
- uint32_t width)\r
-{\r
- uint32_t i;\r
- uint8_t c;\r
- uint8_t empty = 1;\r
-\r
- // 64bit number has 16 characters in hex representation\r
- for (i = 16; i > 0; i--)\r
- {\r
- c = *(((uint8_t *)&val) + ((i - 1) >> 1));\r
- if (((i - 1) & 1) != 0)\r
- c = c >> 4;\r
- c = c & 0x0F;\r
-\r
- if (c > 9)\r
- c += 'A' - 10;\r
- else\r
- c += '0';\r
-\r
- if (c != '0')\r
- {\r
- // end of leading zeros\r
- empty = 0;\r
- }\r
-\r
- // don't print leading zero\r
- if (!empty || i <= width)\r
- {\r
- printc(c);\r
- }\r
- }\r
-}\r
-// Print 32bit number as hex string on serial console\r
-// the width parameters allows skipping leading zeros\r
-static void printhex(\r
- uint32_t val,\r
- uint32_t width)\r
-{\r
- uint32_t i;\r
- uint8_t c;\r
- uint8_t empty = 1;\r
-\r
- // 32bit number has 8 characters in hex representation\r
- for (i = 8; i > 0; i--)\r
- {\r
- c = (uint8_t) ((val >> 28) & 0x0F);\r
- if (c > 9)\r
- c += 'A' - 10;\r
- else\r
- c += '0';\r
-\r
- val = val << 4;\r
-\r
- if (c != '0')\r
- {\r
- // end of leading zeros\r
- empty = 0;\r
- }\r
-\r
- // don't print leading zero\r
- if (!empty || i <= width)\r
- {\r
- printc(c);\r
- }\r
- }\r
-}\r
-// Print 32bit number as decimal string on serial console\r
-// the width parameters allows skipping leading zeros\r
-static void printdec(\r
- uint32_t val,\r
- uint32_t width)\r
-{\r
- uint32_t i;\r
- uint8_t c = 0;\r
- uint8_t empty = 1;\r
-\r
- // Ten digits is enough for 32bit number in decimal\r
- uint8_t buf[10];\r
-\r
- for (i = 0; i < sizeof(buf); i++)\r
- {\r
- c = (uint8_t) (val % 10);\r
- buf[i] = c + '0';\r
- val = val / 10;\r
- }\r
-\r
- while (i > 0)\r
- {\r
- c = buf[--i];\r
-\r
- if (c != '0')\r
- {\r
- // end of leading zeros\r
- empty = 0;\r
- }\r
-\r
- // don't print leading zero\r
- if (!empty || i < width)\r
- {\r
- printc(c);\r
- }\r
- }\r
-}\r
-\r
-// Consume numeric substring leading the given string\r
-// Return pointer to the first non-numeric character\r
-// Buffer reference by width is updated with number\r
-// converted from the numeric substring.\r
-static char_t *getwidth(\r
- char_t *bla,\r
- uint32_t *width)\r
-{\r
- uint32_t val = 0;\r
-\r
- while (*bla >= '0' && *bla <= '9')\r
- {\r
- val = val * 10 + *bla - '0';\r
- bla += 1;\r
- }\r
-\r
- if (val > 0)\r
- {\r
- *width = val;\r
- }\r
- return bla;\r
-}\r
-\r
-// Consume print format designator from the head of given string\r
-// Return pointer to first character after format designator\r
-// input fmt\r
-// ----- ---\r
-// s -> s\r
-// d -> d\r
-// X -> X\r
-// llX -> L\r
-static char_t *getformat(\r
- char_t *bla,\r
- uint8_t *fmt)\r
-{\r
- if (bla[0] == 's')\r
- {\r
- bla += 1;\r
- *fmt = 's';\r
- }\r
- else if (bla[0] == 'd')\r
- {\r
- bla += 1;\r
- *fmt = 'd';\r
- }\r
- else if (bla[0] == 'X' || bla[0] == 'x')\r
- {\r
- bla += 1;\r
- *fmt = 'X';\r
- }\r
- else if (bla[0] == 'l' && bla[1] == 'l' && bla[2] == 'X')\r
- {\r
- bla += 3;\r
- *fmt = 'L';\r
- }\r
-\r
- return bla;\r
-}\r
-\r
-// Simplified implementation of standard printf function\r
-// The output is directed to serial console. Only selected\r
-// class of messages is printed (mask has to match DpfPrintMask)\r
-// Supported print formats: %[n]s,%[n]d,%[n]X,,%[n]llX\r
-// The width is ignored for %s format.\r
-void dpf(\r
- uint32_t mask,\r
- char_t* bla,\r
- ...)\r
-{\r
- uint32_t* arg = (uint32_t*) (&bla + 1);\r
-\r
- // Check UART MMIO base configured\r
- if (0 == UartMmioBase)\r
- return;\r
-\r
- // Check event not masked\r
- if (0 == (mask & DPF_MASK))\r
- return;\r
-\r
- for (;;)\r
- {\r
- uint8_t x = *bla++;\r
- if (x == 0)\r
- break;\r
-\r
- if (x == '\n')\r
- {\r
- printc('\r');\r
- printc('\n');\r
- }\r
- else if (x == '%')\r
- {\r
- uint8_t fmt = 0;\r
- uint32_t width = 1;\r
-\r
- bla = getwidth(bla, &width);\r
- bla = getformat(bla, &fmt);\r
-\r
- // Print value\r
- if (fmt == 'd')\r
- {\r
- printdec(*arg, width);\r
- arg += 1;\r
- }\r
- else if (fmt == 'X')\r
- {\r
- printhex(*arg, width);\r
- arg += 1;\r
- }\r
- else if (fmt == 'L')\r
- {\r
- printhexx(*(uint64_t*) arg, width);\r
- arg += 2;\r
- }\r
- else if (fmt == 's')\r
- {\r
- printstr(*(char**) arg);\r
- arg += 1;\r
- }\r
- }\r
- else\r
- {\r
- printc(x);\r
- }\r
- }\r
-}\r
-\r
-#endif //SIM\r
-#endif //NDEBUG\r