Re: bochs on sparc/solaris

"Stanislav" <[email protected]>
Newsgroups gmane.comp.emulators.bochs.devel
Message-ID <[email protected]>
There are several ways to workaround this.

First and preferable is to find appropriate compiler extension to mark
memory access as unaligned.
Smth like:

+#define WriteHostWordToLittleEndian(hostPtr,  nativeVar16) \
+    *((Bit16u UNALIGNED*)(hostPtr)) = bswap16(nativeVar16)

Second is to rewrite the memory access macros (for all data sizes) to
read/write data in byte granularity ad then to collect them into register.
It was in old Bochs versions before but was removed because we assumed that
almost all BE systems already support unaligned access.
Here is the block (taken from Bochs 2.1 sources):

#define WriteHostWordToLittleEndian(hostPtr,  nativeVar16) { \
    ((Bit8u *)(hostPtr))[0] = (Bit8u)  (nativeVar16); \
    ((Bit8u *)(hostPtr))[1] = (Bit8u) ((nativeVar16)>>8); \
    }
#define WriteHostDWordToLittleEndian(hostPtr, nativeVar32) { \
    ((Bit8u *)(hostPtr))[0] = (Bit8u)  (nativeVar32); \
    ((Bit8u *)(hostPtr))[1] = (Bit8u) ((nativeVar32)>>8); \
    ((Bit8u *)(hostPtr))[2] = (Bit8u) ((nativeVar32)>>16); \
    ((Bit8u *)(hostPtr))[3] = (Bit8u) ((nativeVar32)>>24); \
    }
#define WriteHostQWordToLittleEndian(hostPtr, nativeVar64) { \
    ((Bit8u *)(hostPtr))[0] = (Bit8u)  (nativeVar64); \
    ((Bit8u *)(hostPtr))[1] = (Bit8u) ((nativeVar64)>>8); \
    ((Bit8u *)(hostPtr))[2] = (Bit8u) ((nativeVar64)>>16); \
    ((Bit8u *)(hostPtr))[3] = (Bit8u) ((nativeVar64)>>24); \
    ((Bit8u *)(hostPtr))[4] = (Bit8u) ((nativeVar64)>>32); \
    ((Bit8u *)(hostPtr))[5] = (Bit8u) ((nativeVar64)>>40); \
    ((Bit8u *)(hostPtr))[6] = (Bit8u) ((nativeVar64)>>48); \
    ((Bit8u *)(hostPtr))[7] = (Bit8u) ((nativeVar64)>>56); \
    }
#define ReadHostWordFromLittleEndian(hostPtr, nativeVar16) { \
    (nativeVar16) =  ((Bit16u) ((Bit8u *)(hostPtr))[0]) | \
                    (((Bit16u) ((Bit8u *)(hostPtr))[1])<<8) ; \
    }
#define ReadHostDWordFromLittleEndian(hostPtr, nativeVar32) { \
    (nativeVar32) =  ((Bit32u) ((Bit8u *)(hostPtr))[0]) | \
                    (((Bit32u) ((Bit8u *)(hostPtr))[1])<<8) | \
                    (((Bit32u) ((Bit8u *)(hostPtr))[2])<<16) | \
                    (((Bit32u) ((Bit8u *)(hostPtr))[3])<<24); \
    }
#define ReadHostQWordFromLittleEndian(hostPtr, nativeVar64) { \
    (nativeVar64) =  ((Bit64u) ((Bit8u *)(hostPtr))[0]) | \
                    (((Bit64u) ((Bit8u *)(hostPtr))[1])<<8) | \
                    (((Bit64u) ((Bit8u *)(hostPtr))[2])<<16) | \
                    (((Bit64u) ((Bit8u *)(hostPtr))[3])<<24) | \
                    (((Bit64u) ((Bit8u *)(hostPtr))[4])<<32) | \
                    (((Bit64u) ((Bit8u *)(hostPtr))[5])<<40) | \
                    (((Bit64u) ((Bit8u *)(hostPtr))[6])<<48) | \
                    (((Bit64u) ((Bit8u *)(hostPtr))[7])<<56); \
    }

Miht be we need to put it back with some kind of detection if unaligned
access is supported.
Do you have any idea how to detect it at configure ?

Stanislav

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Brad
Walker
Sent: Friday, December 28, 2012 1:40 AM
To: Stanislav
Cc: Volker Ruppert; [email protected]
Subject: Re: [Bochs-developers] bochs on sparc/solaris

Okay, I tried a few things today.. And had various levels of success.

First, I think you are correct about the alignment. It is common for CPU to
not handle unaligned memory accesses in the CPU hardware. Most cpus that
worked this way have completed died off. But, SPARC is still like this. Over
the years a lot of software has been fixed to not have this problem as it
can really wreck performance on the x86 processor pipeline. This is why I
think it's always a good thing to port software to a different platform/cpu
combination. It increases the robustness and fleshes out problems like
these. But, I'm digressing now.

...
00000000000i[     ] reset of 'extfpuirq' plugin device by virtual method
00000000000i[     ] reset of 'parallel' plugin device by virtual method
00000000000i[     ] reset of 'serial' plugin device by virtual method
00000000000i[XGUI ] Mouse capture off
[Switching to Thread 1 (LWP 1)]

Breakpoint 1, FetchWORD (iptr=0x104b82ff1 "\340") at fetchdecode.h:42
42         ReadHostWordFromLittleEndian(iptr, data);
1: x/i $pc
=> 0x100143768 <FetchWORD(Bit8u const*)+8>:     ldx  [ %fp + 0x87f ], %g1
(gdb) stepi
0x000000010014376c      42         ReadHostWordFromLittleEndian(iptr, data);
1: x/i $pc
=> 0x10014376c <FetchWORD(Bit8u const*)+12>:    lduh  [ %g1 ], %g1
(gdb) p/x $g1
$6 = 0x104b82ff1
(gdb) bt
#0  0x000000010014376c in FetchWORD (iptr=0x104b82ff1 "\340") at
fetchdecode.h:42
#1  0x0000000100142730 in BX_CPU_C::fetchDecode32 (iptr=0x104b82ff1 "\340",
i=0x100a43240,
    remainingInPage=15) at fetchdecode.cc:1810
#2  0x000000010014046c in BX_CPU_C::serveICacheMiss (entry=0x0,
eipBiased=4080, pAddr=4294967280)
    at icache.cc:103
#3  0x000000010013d934 in BX_CPU_C::getICacheEntry () at cpu.cc:233
#4  0x000000010013d604 in BX_CPU_C::cpu_loop () at cpu.cc:95
#5  0x0000000100061660 in bx_begin_simulation (argc=3,
argv=0xffffffff7ffff1e8) at main.cc:1026
#6  0x000000010020f84c in bx_real_sim_c::begin_simulation (this=0x10294bcd0,
argc=3,
    argv=0xffffffff7ffff1e8) at siminterface.cc:858
#7  0x000000010021a1d0 in bx_config_interface (menu=8) at textconfig.cc:432
#8  0x000000010021a798 in bx_config_interface (menu=1) at textconfig.cc:476
#9  0x000000010021ea1c in ci_callback (userdata=0x0, command=CI_START) at
textconfig.cc:1095
#10 0x000000010020f7e4 in bx_real_sim_c::configuration_interface
(this=0x10294bcd0,
    ignore=0x100271b30 "textconfig", command=CI_START) at
siminterface.cc:851
#11 0x000000010005f504 in bxmain () at main.cc:296
#12 0x000000010005f62c in main (argc=3, argv=0xffffffff7ffff1e8) at
main.cc:511
(gdb) stepi

Program received signal SIGSEGV, Segmentation fault.
0x000000010014376c in FetchWORD (iptr=0x104b82ff1 "\340") at
fetchdecode.h:42
42         ReadHostWordFromLittleEndian(iptr, data);
1: x/i $pc
=> 0x10014376c <FetchWORD(Bit8u const*)+12>:    lduh  [ %g1 ], %g1
(gdb) list
37      //
38
39      BX_CPP_INLINE Bit16u FetchWORD(const Bit8u *iptr)
40      {
41         Bit16u data;
42         ReadHostWordFromLittleEndian(iptr, data);
43         return data;
44      }
45
46      BX_CPP_INLINE Bit32u FetchDWORD(const Bit8u *iptr)
(gdb)

There is no option to GCC to tell it to use a library or trap to handle
unaligned memory accesses. I think at one time, years ago, there was an
option.

But, the Oracle Solaris compiler does have this option. So I tried to use
this compiler to build Bochs but was unsuccessful in building.

So I'm kinda stuck.

Ideas/comments?

BTW, thanks for the help.

-brad w.

On Thu, Dec 27, 2012 at 8:33 AM, Stanislav <[email protected]> wrote:
> I could have some guess already.
>
> I see that the ReadHostWordFromLittleEndian trying to read a word from 
> non-aligned address.
> Does Sparc architecture supports unaligned accesses ?
> I now many big endian architectures have this issue and require some 
> compiler switch to work it around.
>


------------------------------------------------------------------------------
Master HTML5, CSS3, ASP.NET, MVC, AJAX, Knockout.js, Web API and
much more. Get web development skills now with LearnDevNow -
350+ hours of step-by-step video tutorials by Microsoft MVPs and experts.
SALE $99.99 this month only -- learn more at:
http://p.sf.net/sfu/learnmore_122812
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.