check first XSPN result value in FW, add gcc_except_table, replace
self-made printf with one from the lib.
This commit is contained in:
		@@ -5,7 +5,6 @@ CXX_SRCS  = $(wildcard src/*.cpp)
 | 
			
		||||
HEADERS   = $(wildcard src/*.h)
 | 
			
		||||
CFLAGS    = -g -fno-builtin-printf -DUSE_PLIC -I./src
 | 
			
		||||
CXXFLAGS  = -fno-use-cxa-atexit
 | 
			
		||||
LDFLAGS   = -Wl,--wrap=printf
 | 
			
		||||
LDFLAGS  += -g -lstdc++ -fno-use-cxa-atexit -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) -mcmodel=medany
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -104,6 +104,11 @@ SECTIONS
 | 
			
		||||
    KEEP (*(.dtors))
 | 
			
		||||
  } >flash AT>flash :flash
 | 
			
		||||
 | 
			
		||||
  .except :
 | 
			
		||||
  {
 | 
			
		||||
  	*(.gcc_except_table.*)
 | 
			
		||||
  } >flash AT>flash :flash
 | 
			
		||||
  
 | 
			
		||||
  .lalign         :
 | 
			
		||||
  {
 | 
			
		||||
    . = ALIGN(4);
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							@@ -78,6 +78,12 @@ void platform_init(){
 | 
			
		||||
    set_csr(mie, MIP_MEIP);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool double_equals(double a, double b, double epsilon = 0.001)
 | 
			
		||||
{
 | 
			
		||||
    return std::abs(a - b) < epsilon;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*! \brief main function
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
@@ -125,10 +131,14 @@ int main() {
 | 
			
		||||
    delayUS(10);
 | 
			
		||||
 | 
			
		||||
    // read calculation results from the memory
 | 
			
		||||
    int result = *mem_base;
 | 
			
		||||
    printf("HW Result:0x%lx\n", result);
 | 
			
		||||
    result = *(mem_base+1);
 | 
			
		||||
    printf("HW Result:0x%lx\n", result);
 | 
			
		||||
    double * res_base = (double*)mem_base;
 | 
			
		||||
 | 
			
		||||
    if (double_equals(res_base[0], -3.5530456851)) {
 | 
			
		||||
        printf("XSPN reference value comparison PASSED\n");
 | 
			
		||||
    } else {
 | 
			
		||||
        printf("XSPN reference value comparison FAILED\n");
 | 
			
		||||
    	return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    printf("End of execution");
 | 
			
		||||
 
 | 
			
		||||
@@ -1,271 +0,0 @@
 | 
			
		||||
/* The functions in this file are only meant to support Dhrystone on an
 | 
			
		||||
 * embedded RV32 system and are obviously incorrect in general. */
 | 
			
		||||
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#undef putchar
 | 
			
		||||
int putchar(int ch)
 | 
			
		||||
{
 | 
			
		||||
  return write(STDOUT_FILENO, &ch, 1) == 1 ? ch : -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void sprintf_putch(int ch, void** data)
 | 
			
		||||
{
 | 
			
		||||
  char** pstr = (char**)data;
 | 
			
		||||
  **pstr = ch;
 | 
			
		||||
  (*pstr)++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static unsigned long getuint(va_list *ap, int lflag)
 | 
			
		||||
{
 | 
			
		||||
  if (lflag)
 | 
			
		||||
    return va_arg(*ap, unsigned long);
 | 
			
		||||
  else
 | 
			
		||||
    return va_arg(*ap, unsigned int);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static long getint(va_list *ap, int lflag)
 | 
			
		||||
{
 | 
			
		||||
  if (lflag)
 | 
			
		||||
    return va_arg(*ap, long);
 | 
			
		||||
  else
 | 
			
		||||
    return va_arg(*ap, int);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void printnum(void (*putch)(int, void**), void **putdat,
 | 
			
		||||
                    unsigned long num, unsigned base, int width, int padc)
 | 
			
		||||
{
 | 
			
		||||
  unsigned digs[sizeof(num)*8];
 | 
			
		||||
  int pos = 0;
 | 
			
		||||
 | 
			
		||||
  while (1)
 | 
			
		||||
  {
 | 
			
		||||
    digs[pos++] = num % base;
 | 
			
		||||
    if (num < base)
 | 
			
		||||
      break;
 | 
			
		||||
    num /= base;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  while (width-- > pos)
 | 
			
		||||
    putch(padc, putdat);
 | 
			
		||||
 | 
			
		||||
  while (pos-- > 0)
 | 
			
		||||
    putch(digs[pos] + (digs[pos] >= 10 ? 'a' - 10 : '0'), putdat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void print_double(void (*putch)(int, void**), void **putdat,
 | 
			
		||||
                                double num, int width, int prec)
 | 
			
		||||
{
 | 
			
		||||
  union {
 | 
			
		||||
    double d;
 | 
			
		||||
    uint64_t u;
 | 
			
		||||
  } u;
 | 
			
		||||
  u.d = num;
 | 
			
		||||
 | 
			
		||||
  if (u.u & (1ULL << 63)) {
 | 
			
		||||
    putch('-', putdat);
 | 
			
		||||
    u.u &= ~(1ULL << 63);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (int i = 0; i < prec; i++)
 | 
			
		||||
    u.d *= 10;
 | 
			
		||||
 | 
			
		||||
  char buf[32], *pbuf = buf;
 | 
			
		||||
  printnum(sprintf_putch, (void**)&pbuf, (unsigned long)u.d, 10, 0, 0);
 | 
			
		||||
  if (prec > 0) {
 | 
			
		||||
    for (int i = 0; i < prec; i++) {
 | 
			
		||||
      pbuf[-i] = pbuf[-i-1];
 | 
			
		||||
    }
 | 
			
		||||
    pbuf[-prec] = '.';
 | 
			
		||||
    pbuf++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (char* p = buf; p < pbuf; p++)
 | 
			
		||||
    putch(*p, putdat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_list ap)
 | 
			
		||||
{
 | 
			
		||||
  register const char* p;
 | 
			
		||||
  const char* last_fmt;
 | 
			
		||||
  register int ch, err;
 | 
			
		||||
  unsigned long num;
 | 
			
		||||
  int base, lflag, width, precision, altflag;
 | 
			
		||||
  char padc;
 | 
			
		||||
 | 
			
		||||
  while (1) {
 | 
			
		||||
    while ((ch = *(unsigned char *) fmt) != '%') {
 | 
			
		||||
      if (ch == '\0')
 | 
			
		||||
        return;
 | 
			
		||||
      fmt++;
 | 
			
		||||
      putch(ch, putdat);
 | 
			
		||||
    }
 | 
			
		||||
    fmt++;
 | 
			
		||||
 | 
			
		||||
    // Process a %-escape sequence
 | 
			
		||||
    last_fmt = fmt;
 | 
			
		||||
    padc = ' ';
 | 
			
		||||
    width = -1;
 | 
			
		||||
    precision = -1;
 | 
			
		||||
    lflag = 0;
 | 
			
		||||
    altflag = 0;
 | 
			
		||||
  reswitch:
 | 
			
		||||
    switch (ch = *(unsigned char *) fmt++) {
 | 
			
		||||
 | 
			
		||||
    // flag to pad on the right
 | 
			
		||||
    case '-':
 | 
			
		||||
      padc = '-';
 | 
			
		||||
      goto reswitch;
 | 
			
		||||
      
 | 
			
		||||
    // flag to pad with 0's instead of spaces
 | 
			
		||||
    case '0':
 | 
			
		||||
      padc = '0';
 | 
			
		||||
      goto reswitch;
 | 
			
		||||
 | 
			
		||||
    // width field
 | 
			
		||||
    case '1':
 | 
			
		||||
    case '2':
 | 
			
		||||
    case '3':
 | 
			
		||||
    case '4':
 | 
			
		||||
    case '5':
 | 
			
		||||
    case '6':
 | 
			
		||||
    case '7':
 | 
			
		||||
    case '8':
 | 
			
		||||
    case '9':
 | 
			
		||||
      for (precision = 0; ; ++fmt) {
 | 
			
		||||
        precision = precision * 10 + ch - '0';
 | 
			
		||||
        ch = *fmt;
 | 
			
		||||
        if (ch < '0' || ch > '9')
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
      goto process_precision;
 | 
			
		||||
 | 
			
		||||
    case '*':
 | 
			
		||||
      precision = va_arg(ap, int);
 | 
			
		||||
      goto process_precision;
 | 
			
		||||
 | 
			
		||||
    case '.':
 | 
			
		||||
      if (width < 0)
 | 
			
		||||
        width = 0;
 | 
			
		||||
      goto reswitch;
 | 
			
		||||
 | 
			
		||||
    case '#':
 | 
			
		||||
      altflag = 1;
 | 
			
		||||
      goto reswitch;
 | 
			
		||||
 | 
			
		||||
    process_precision:
 | 
			
		||||
      if (width < 0)
 | 
			
		||||
        width = precision, precision = -1;
 | 
			
		||||
      goto reswitch;
 | 
			
		||||
 | 
			
		||||
    // long flag
 | 
			
		||||
    case 'l':
 | 
			
		||||
      if (lflag)
 | 
			
		||||
        goto bad;
 | 
			
		||||
      goto reswitch;
 | 
			
		||||
 | 
			
		||||
    // character
 | 
			
		||||
    case 'c':
 | 
			
		||||
      putch(va_arg(ap, int), putdat);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    // double
 | 
			
		||||
    case 'f':
 | 
			
		||||
      print_double(putch, putdat, va_arg(ap, double), width, precision);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    // string
 | 
			
		||||
    case 's':
 | 
			
		||||
      if ((p = va_arg(ap, char *)) == NULL)
 | 
			
		||||
        p = "(null)";
 | 
			
		||||
      if (width > 0 && padc != '-')
 | 
			
		||||
        for (width -= strnlen(p, precision); width > 0; width--)
 | 
			
		||||
          putch(padc, putdat);
 | 
			
		||||
      for (; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width--) {
 | 
			
		||||
        putch(ch, putdat);
 | 
			
		||||
        p++;
 | 
			
		||||
      }
 | 
			
		||||
      for (; width > 0; width--)
 | 
			
		||||
        putch(' ', putdat);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    // (signed) decimal
 | 
			
		||||
    case 'd':
 | 
			
		||||
      num = getint(&ap, lflag);
 | 
			
		||||
      if ((long) num < 0) {
 | 
			
		||||
        putch('-', putdat);
 | 
			
		||||
        num = -(long) num;
 | 
			
		||||
      }
 | 
			
		||||
      base = 10;
 | 
			
		||||
      goto signed_number;
 | 
			
		||||
 | 
			
		||||
    // unsigned decimal
 | 
			
		||||
    case 'u':
 | 
			
		||||
      base = 10;
 | 
			
		||||
      goto unsigned_number;
 | 
			
		||||
 | 
			
		||||
    // (unsigned) octal
 | 
			
		||||
    case 'o':
 | 
			
		||||
      // should do something with padding so it's always 3 octits
 | 
			
		||||
      base = 8;
 | 
			
		||||
      goto unsigned_number;
 | 
			
		||||
 | 
			
		||||
    // pointer
 | 
			
		||||
    case 'p':
 | 
			
		||||
      lflag = 1;
 | 
			
		||||
      putch('0', putdat);
 | 
			
		||||
      putch('x', putdat);
 | 
			
		||||
      /* fall through to 'x' */
 | 
			
		||||
 | 
			
		||||
    // (unsigned) hexadecimal
 | 
			
		||||
    case 'x':
 | 
			
		||||
      base = 16;
 | 
			
		||||
    unsigned_number:
 | 
			
		||||
      num = getuint(&ap, lflag);
 | 
			
		||||
    signed_number:
 | 
			
		||||
      printnum(putch, putdat, num, base, width, padc);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    // escaped '%' character
 | 
			
		||||
    case '%':
 | 
			
		||||
      putch(ch, putdat);
 | 
			
		||||
      break;
 | 
			
		||||
      
 | 
			
		||||
    // unrecognized escape sequence - just print it literally
 | 
			
		||||
    default:
 | 
			
		||||
    bad:
 | 
			
		||||
      putch('%', putdat);
 | 
			
		||||
      fmt = last_fmt;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int __wrap_printf(const char* fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
  va_list ap;
 | 
			
		||||
  va_start(ap, fmt);
 | 
			
		||||
 | 
			
		||||
  vprintfmt((void*)putchar, 0, fmt, ap);
 | 
			
		||||
 | 
			
		||||
  va_end(ap);
 | 
			
		||||
  return 0; // incorrect return value, but who cares, anyway?
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int __wrap_sprintf(char* str, const char* fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
  va_list ap;
 | 
			
		||||
  char* str0 = str;
 | 
			
		||||
  va_start(ap, fmt);
 | 
			
		||||
 | 
			
		||||
  vprintfmt(sprintf_putch, (void**)&str, fmt, ap);
 | 
			
		||||
  *str = 0;
 | 
			
		||||
 | 
			
		||||
  va_end(ap);
 | 
			
		||||
  return str - str0;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user