19b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** @file 29b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneySerial conole output and string formating. 39b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 49b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyCopyright (c) 2013-2015 Intel Corporation. 59b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 69b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyThis program and the accompanying materials 79b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyare licensed and made available under the terms and conditions of the BSD License 89b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneywhich accompanies this distribution. The full text of the license may be found at 99b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyhttp://opensource.org/licenses/bsd-license.php 109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#include "memory_options.h" 169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#include "general_definitions.h" 179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Resource programmed to PCI bridge, 1MB bound alignment is needed. 199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// The default value is overwritten by MRC parameter, assuming code 209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// relocated to eSRAM. 219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint32_t UartMmioBase = 0; 229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Serial port registers based on SerialPortLib.c 249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#define R_UART_BAUD_THR 0 259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#define R_UART_LSR 20 269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#define B_UART_LSR_RXRDY BIT0 289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#define B_UART_LSR_TXRDY BIT5 299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#define B_UART_LSR_TEMT BIT6 309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Print mask see DPF and D_Xxxx 329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#define DPF_MASK DpfPrintMask 339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Select class of messages enabled for printing 359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint32_t DpfPrintMask = 369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney D_ERROR | 379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney D_INFO | 389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // D_REGRD | 399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // D_REGWR | 409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // D_FCALL | 419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // D_TRN | 429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 0; 439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#ifdef NDEBUG 459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Don't generate debug code 469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid dpf( uint32_t mask, char_t* bla, ...) 479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint8_t mgetc(void) 529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return 0; 549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint8_t mgetch(void) 579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return 0; 599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#else 629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#ifdef SIM 649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Use Vpi console in simulation environment 659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#include <vpi_user.h> 669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid dpf( uint32_t mask, char_t* bla, ...) 689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney va_list va; 709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if( 0 == (mask & DPF_MASK)) return; 729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney va_start( va, bla); 749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney vpi_vprintf( bla, va); 759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney va_end(va); 769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#else 799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#ifdef EMU 819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Use standard console in windows environment 829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#include <stdio.h> 839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#endif 849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Read character from serial port 869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint8_t mgetc(void) 879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#ifdef EMU 899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Emulation in Windows environment uses console 919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney getchar(); 929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#else 949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t c; 959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney while ((*(volatile uint8_t*) (UartMmioBase + R_UART_LSR) & B_UART_LSR_RXRDY) == 0); 979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney c = *(volatile uint8_t*) (UartMmioBase + R_UART_BAUD_THR); 989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return c; 1009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#endif 1019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 1029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint8_t mgetch(void) 1059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 1069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#ifdef EMU 1079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return 0; 1089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#else 1099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t c = 0; 1109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if((*(volatile uint8_t*) (UartMmioBase + R_UART_LSR) & B_UART_LSR_RXRDY) != 0) 1129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 1139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney c = *(volatile uint8_t*) (UartMmioBase + R_UART_BAUD_THR); 1149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 1159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return c; 1179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#endif 1189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 1199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Print single character 1219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneystatic void printc( 1229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t c) 1239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 1249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#ifdef EMU 1259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Emulation in Windows environment uses console output 1279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney putchar(c); 1289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#else 1309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Use MMIO access to serial port on PCI 1339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // while( 0 == (0x20 & inp(0x3f8 + 5))); 1349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // outp(0x3f8 + 0, c); 1359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney while (0 1379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney == (B_UART_LSR_TEMT & *((volatile uint8_t*) (UartMmioBase + R_UART_LSR)))) 1389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ; 1399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *((volatile uint8_t*) (UartMmioBase + R_UART_BAUD_THR)) = c; 1409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#endif 1419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 1429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Print 0 terminated string on serial console 1449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneystatic void printstr( 1459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney char_t *str) 1469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 1479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney while (*str) 1489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 1499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney printc(*str++); 1509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 1519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 1529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Print 64bit number as hex string on serial console 1539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// the width parameters allows skipping leading zeros 1549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneystatic void printhexx( 1559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint64_t val, 1569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t width) 1579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 1589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t i; 1599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t c; 1609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t empty = 1; 1619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 64bit number has 16 characters in hex representation 1639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (i = 16; i > 0; i--) 1649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 1659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney c = *(((uint8_t *)&val) + ((i - 1) >> 1)); 1669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (((i - 1) & 1) != 0) 1679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney c = c >> 4; 1689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney c = c & 0x0F; 1699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (c > 9) 1719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney c += 'A' - 10; 1729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else 1739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney c += '0'; 1749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (c != '0') 1769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 1779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // end of leading zeros 1789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney empty = 0; 1799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 1809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // don't print leading zero 1829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (!empty || i <= width) 1839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 1849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney printc(c); 1859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 1869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 1879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 1889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Print 32bit number as hex string on serial console 1899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// the width parameters allows skipping leading zeros 1909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneystatic void printhex( 1919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t val, 1929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t width) 1939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 1949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t i; 1959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t c; 1969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t empty = 1; 1979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 32bit number has 8 characters in hex representation 1999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (i = 8; i > 0; i--) 2009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 2019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney c = (uint8_t) ((val >> 28) & 0x0F); 2029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (c > 9) 2039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney c += 'A' - 10; 2049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else 2059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney c += '0'; 2069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney val = val << 4; 2089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (c != '0') 2109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 2119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // end of leading zeros 2129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney empty = 0; 2139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // don't print leading zero 2169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (!empty || i <= width) 2179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 2189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney printc(c); 2199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 2229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Print 32bit number as decimal string on serial console 2239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// the width parameters allows skipping leading zeros 2249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneystatic void printdec( 2259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t val, 2269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t width) 2279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 2289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t i; 2299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t c = 0; 2309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t empty = 1; 2319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Ten digits is enough for 32bit number in decimal 2339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t buf[10]; 2349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (i = 0; i < sizeof(buf); i++) 2369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 2379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney c = (uint8_t) (val % 10); 2389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney buf[i] = c + '0'; 2399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney val = val / 10; 2409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney while (i > 0) 2439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 2449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney c = buf[--i]; 2459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (c != '0') 2479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 2489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // end of leading zeros 2499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney empty = 0; 2509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // don't print leading zero 2539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (!empty || i < width) 2549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 2559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney printc(c); 2569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 2599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Consume numeric substring leading the given string 2619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Return pointer to the first non-numeric character 2629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Buffer reference by width is updated with number 2639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// converted from the numeric substring. 2649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneystatic char_t *getwidth( 2659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney char_t *bla, 2669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t *width) 2679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 2689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t val = 0; 2699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney while (*bla >= '0' && *bla <= '9') 2719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 2729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney val = val * 10 + *bla - '0'; 2739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney bla += 1; 2749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (val > 0) 2779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 2789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *width = val; 2799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return bla; 2819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 2829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Consume print format designator from the head of given string 2849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Return pointer to first character after format designator 2859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// input fmt 2869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// ----- --- 2879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// s -> s 2889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// d -> d 2899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// X -> X 2909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// llX -> L 2919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneystatic char_t *getformat( 2929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney char_t *bla, 2939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t *fmt) 2949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 2959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (bla[0] == 's') 2969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 2979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney bla += 1; 2989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *fmt = 's'; 2999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else if (bla[0] == 'd') 3019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 3029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney bla += 1; 3039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *fmt = 'd'; 3049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else if (bla[0] == 'X' || bla[0] == 'x') 3069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 3079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney bla += 1; 3089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *fmt = 'X'; 3099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else if (bla[0] == 'l' && bla[1] == 'l' && bla[2] == 'X') 3119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 3129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney bla += 3; 3139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *fmt = 'L'; 3149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return bla; 3179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 3189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Simplified implementation of standard printf function 3209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// The output is directed to serial console. Only selected 3219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// class of messages is printed (mask has to match DpfPrintMask) 3229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Supported print formats: %[n]s,%[n]d,%[n]X,,%[n]llX 3239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// The width is ignored for %s format. 3249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid dpf( 3259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t mask, 3269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney char_t* bla, 3279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ...) 3289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 3299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t* arg = (uint32_t*) (&bla + 1); 3309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Check UART MMIO base configured 3329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (0 == UartMmioBase) 3339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 3349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Check event not masked 3369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (0 == (mask & DPF_MASK)) 3379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 3389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (;;) 3409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 3419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t x = *bla++; 3429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (x == 0) 3439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 3449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (x == '\n') 3469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 3479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney printc('\r'); 3489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney printc('\n'); 3499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else if (x == '%') 3519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 3529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t fmt = 0; 3539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t width = 1; 3549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney bla = getwidth(bla, &width); 3569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney bla = getformat(bla, &fmt); 3579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Print value 3599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (fmt == 'd') 3609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 3619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney printdec(*arg, width); 3629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney arg += 1; 3639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else if (fmt == 'X') 3659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 3669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney printhex(*arg, width); 3679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney arg += 1; 3689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else if (fmt == 'L') 3709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 3719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney printhexx(*(uint64_t*) arg, width); 3729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney arg += 2; 3739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else if (fmt == 's') 3759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 3769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney printstr(*(char**) arg); 3779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney arg += 1; 3789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else 3819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 3829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney printc(x); 3839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 3869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#endif //SIM 3889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#endif //NDEBUG 389