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