OpenCores
Issue List
WORDS_BIGENDIAN does not work in generic.c #31
Closed jeremybennett opened this issue over 15 years ago
jeremybennett commented over 15 years ago

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;

#endif

   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

jeremybennett commented over 15 years ago

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.

jeremybennett commented over 15 years ago

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.

jeremybennett was assigned over 15 years ago
jeremybennett closed this over 15 years ago

Assignee
jeremybennett
Labels
Bug