i am using or1k-elf (newlib) and needed a way to inject lots of data into 
or1ksim for regression tests.  on real but simple hardware i could program a 
flash memory from a file and test against it many times until my code passes.  
so i figured to emulate this behavior by providing another initialization 
method for memory blocks.  the configuration syntax is simple:

section memory
  type = file
  name = "/tmp/FLASH"
  mc = 0
  ce = 3
  baseaddr = 0xe0000000
  size = 0x00400000 /* 4 MB */
  delayr = 1
  delayw = -1
end

enjoy the patch attached.

:{)}
Index: configure.ac
===================================================================
--- configure.ac	(revision 856)
+++ configure.ac	(working copy)
@@ -99,7 +99,7 @@
 		 sys/ptem.h sys/pte.h sys/stream.h sys/stropts.h sys/select.h \
 		 termcap.h termios.h termio.h sys/file.h locale.h getopt.h    \
 		 net/ethernet.h sys/ethernet.h malloc.h inttypes.h libintl.h  \
-                 limits.h linux/if_tun.h)
+                 limits.h linux/if_tun.h arpa/inet.h)
 AC_CHECK_FUNCS(strcasecmp select setenv putenv tcgetattr setlocale lstat)
 AC_CHECK_FUNCS(grantpt unlockpt ptsname on_exit)
 AC_CHECK_FUNCS(basename)
Index: doc/or1ksim.texi
===================================================================
--- doc/or1ksim.texi	(revision 856)
+++ doc/or1ksim.texi	(working copy)
@@ -1935,7 +1935,7 @@
 
 @table @code
 
-@item type=random|pattern|unknown|zero|exitnops
+@item type=random|pattern|unknown|zero|exitnops|file
 @cindex @code{type} (memory configuration)
 Specifies the values to which memory should be initialized.  The
 default value is @code{unknown}.
@@ -1978,6 +1978,13 @@
 simulation. This is useful for causing immediate end of simulation
 when PC corruption occurs.
 
+@item file
+@cindex @code{type=file} (memory configuration)
+Set the memory values to be the contents of the file specified by
+@code{name}.  If the file is smaller than @code{size} the remaining
+values are initialized to 0.  If the file is larger than @code{size}
+only @code{size} values are initialized to avoid overflow.
+
 @end table
 
 @item random_seed = @var{value}
Index: peripheral/memory.c
===================================================================
--- peripheral/memory.c	(revision 856)
+++ peripheral/memory.c	(working copy)
@@ -33,6 +33,13 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <time.h>
+#include <fcntl.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
 
 /* Package includes */
 #include "arch.h"
@@ -64,7 +71,8 @@
     MT_UNKNOWN,
     MT_PATTERN,
     MT_RANDOM,
-    MT_EXITNOPS
+    MT_EXITNOPS,
+    MT_FILE,
   } type;
 };
 
@@ -226,6 +234,37 @@
 	  break;
 	}
       break;
+    case MT_FILE:
+      seed = open(mem->name, O_RDONLY, 0);
+      if (-1 == seed) {
+	perror(mem->name);
+	exit(1);
+      }
+      i = read(seed, mem_area, mem->size);
+      if (-1 == i) {
+	perror(mem->name);
+	close(seed);
+	exit(1);
+      }
+      close(seed);
+      memset(mem_area+i, 0, mem->size-i);
+      /* check host vs target byte ordering
+       * probably fails with OR32_LITTLE_ENDIAN on PDP_ENDIAN */
+      if (OR32_BIG_ENDIAN ^ (*(uint32_t*)"\1\2\3\4" == 0x01020304)) {
+	while (i > 0) {
+	  uint32_t x = htonl(*(uint32_t*)mem_area);
+#ifdef OR32_LITTLE_ENDIAN
+	  x = ((x & 0xff000000) >> 24 |
+	       (x & 0x00ff0000) >> 8 |
+	       (x & 0x0000ff00) << 8 |
+	       (x & 0x000000ff) << 24);
+#endif
+	  *(uint32_t*)mem_area = x;
+	  mem_area += sizeof(uint32_t);
+	  i -= sizeof(uint32_t);
+	}
+      }
+      break;
     default:
       fprintf (stderr, "Invalid memory configuration type.\n");
       exit (1);
@@ -266,7 +305,7 @@
 /*---------------------------------------------------------------------------*/
 /*!Set the memory type
 
-   Value must be one of unknown, random, pattern or zero (case
+   Value must be one of unknown, random, pattern, zero, exitnops or file (case
    insensitive). Unrecognized values are ignored with a warning.
 
    @param[in] val  The value to use
@@ -299,6 +338,10 @@
       mem->type = MT_EXITNOPS;
       mem->pattern = 0;
     }
+  else if (0 == strcasecmp (val.str_val, "file"))
+    {
+      mem->type = MT_FILE;
+    }
   else
     {
       fprintf (stderr, "Warning: memory type invalid. Ignored");
Index: sim.cfg
===================================================================
--- sim.cfg	(revision 856)
+++ sim.cfg	(working copy)
@@ -130,7 +130,7 @@
 
 /* Memory section
 
-   type        = unknown|random|unknown|pattern
+   type        = unknown|random|pattern|zero|exitnops|file
    random_seed = <value> (default: -1)
    pattern     = <value> (default: 0)
    baseaddr    = <hex_value> (default: 0)
_______________________________________________
OpenRISC mailing list
[email protected]
http://lists.openrisc.net/listinfo/openrisc

Reply via email to