Issue raised by Ding Xiaoliang dingsm@gmail.com:
I tried using or1ksim 0.3.0rc1 as a lib, utilized the upread, upwrite mechanism. DRAM is one of the modules need to be accessed via upread/upwrite.
Problem is: In the initialization, the simulator loads ELF file into DRAM via upwrite byte, the endianness seems wrong. I checked the generic.c , it detects environment endian to translate address and mask which does not work properly.
IMHO, the conversion here only depends on the CPU endian (OpenRISC endian), which is big-endian.
After modified the code with this patch, the system runs well.
Please check the patch.
----------------- PATCH -------------------------------------- diff -ru or1k.orig/peripheral/generic.c or1ksim-0.3.0rc1/peripheral/generic.c --- or1k.orig/peripheral/generic.c 2008-10-13 00:50:50.000000000 +0800 +++ or1ksim-0.3.0rc1/peripheral/generic.c 2008-10-31 12:35:36.000000000 +0800 @@ -41,6 +41,7 @@ #include "toplevel-support.h" #include "sim-cmd.h"
+#define CPU_BIGENDIAN
/! State associated with the generic device. / struct dev_generic @@ -123,7 +124,7 @@ unsigned long wordaddr = fulladdr & 0xfffffffc; unsigned long bitoff = (fulladdr & 0x00000003) << 3;
-#ifdef WORDS_BIGENDIAN +#ifdef CPU_BIGENDIAN unsigned long mask = 0x000000ff << (24 - bitoff); unsigned long res = ext_read (wordaddr, mask);
@@ -158,14 +159,13 @@ unsigned long wordaddr = fulladdr & 0xfffffffc; unsigned long bitoff = (fulladdr & 0x00000003) << 3;
-#ifdef WORDS_BIGENDIAN +#ifdef CPU_BIGENDIAN unsigned long mask = 0x000000ff << (24 - bitoff); unsigned long wordval = ((unsigned long int) value) << (24 - bitoff); #else unsigned long mask = 0x000000ff << bitoff; unsigned long wordval = ((unsigned long int) value) << bitoff;
ext_write (wordaddr, mask, wordval);
}
} / generic_write_byte() / @@ -200,7 +200,7 @@ unsigned long wordaddr = fulladdr & 0xfffffffc; unsigned long bitoff = (fulladdr & 0x00000003) << 3;
-#ifdef WORDS_BIGENDIAN +#ifdef CPU_BIGENDIAN unsigned long mask = 0x0000ffff << (16 - bitoff); unsigned long res = ext_read (wordaddr, mask);
@@ -240,7 +240,7 @@ unsigned long wordaddr = fulladdr & 0xfffffffc; unsigned long bitoff = (fulladdr & 0x00000003) << 3;
-#ifdef WORDS_BIGENDIAN +#ifdef CPU_BIGENDIAN unsigned long mask = 0x0000ffff << (16 - bitoff); unsigned long wordval = ((unsigned long int) value) << (16 - bitoff); #else
Thanks for finding this.<br> <br> I had misunderstood the meaning of WORDS_BIGENDIAN (part of autoconf) when I wrote generic.c. The documentation is not at all clear, but it seems to be giving the endianism of the host, not the target architecture. libtoplevel.c also has the same error.<br> <br> I would rather not hard code the endianism into one source file as you suggest. OpenRISC 1000 can be big-endian (the default) or little-endian, so this should be a configuration. Ideally it should be deduced automatically by configure from the endianism of the target, but at least it should be set using a configure "enable-" option.
This is fixed cleanly in Or1ksim 0.3.0rc2. The endianism of the target is determined from the name specified in the --target parameter to the configure script<br> <br> If the target name matches <tt>little</tt> then the target is assumed to be little endian, and the constant <tt>OR32_LITTLE_ENDIAN</tt> is defined. Otherwise (the default) the target is assumed to be big endian, and the constant <tt>OR32_BIG_ENDIAN</tt> is defined.<br> <br> Since the recommended target is <tt>or32-uclinux</tt>, the usual behavior will be big endian.<br> <br> Marking as CLOSED.