From f29f9ef0210c29560dfcfb745795b70135faf926 Mon Sep 17 00:00:00 2001 From: Kevin Lawton Date: Thu, 5 Sep 2002 04:56:11 +0000 Subject: [PATCH] Fixed Big-endian case of --enable-guest2host-tlb. I macro'ized the direct reads/writes from native variables to the x86 (guest) memory image. Look at the end of bochs.h. Don't know if that's the right place to put them, but here you can extend these macros to platform-specific asm() code if you like, or just use the generic C code I supplied. Some platforms have special instructions for byte-order swapping etc. Also, you can't make any assumptions about the alignment of the pointers passed. --- bochs/bochs.h | 73 ++++++++++++++++++++++++++++++++++++++++++++- bochs/cpu/access.cc | 18 +++++------ bochs/cpu/paging.cc | 6 ++-- 3 files changed, 84 insertions(+), 13 deletions(-) diff --git a/bochs/bochs.h b/bochs/bochs.h index abdca309d..354c3ce51 100644 --- a/bochs/bochs.h +++ b/bochs/bochs.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: bochs.h,v 1.87 2002-09-05 02:31:23 kevinlawton Exp $ +// $Id: bochs.h,v 1.88 2002-09-05 04:56:11 kevinlawton Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2002 MandrakeSoft S.A. @@ -674,4 +674,75 @@ int bx_init_hardware (); #include "instrument.h" + +// These are some convenience macros which abstract out accesses between +// a variable in native byte ordering to/from guest (x86) memory, which is +// always in little endian format. You must deal with alignment (if your +// system cares) and endian rearranging. Don't assume anything. You could +// put some platform specific asm() statements here, to make use of native +// instructions to help perform these operations more efficiently than C++. + + +#ifdef __i386__ + +#define WriteHostWordToLittleEndian(hostPtr, nativeVar16) \ + *(hostPtr) = (nativeVar16) +#define WriteHostDWordToLittleEndian(hostPtr, nativeVar32) \ + *(hostPtr) = (nativeVar32) +#define WriteHostQWordToLittleEndian(hostPtr, nativeVar64) \ + *(hostPtr) = (nativeVar64) +#define ReadHostWordFromLittleEndian(hostPtr, nativeVar16) \ + (nativeVar16) = *(hostPtr) +#define ReadHostDWordFromLittleEndian(hostPtr, nativeVar32) \ + (nativeVar32) = *(hostPtr) +#define ReadHostQWordFromLittleEndian(hostPtr, nativeVar64) \ + (nativeVar64) = *(hostPtr) + +#else + +#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); \ + } + +#endif + + + #endif /* BX_BOCHS_H */ diff --git a/bochs/cpu/access.cc b/bochs/cpu/access.cc index 80bf1d587..7a8c24971 100644 --- a/bochs/cpu/access.cc +++ b/bochs/cpu/access.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: access.cc,v 1.17 2002-09-05 02:31:24 kevinlawton Exp $ +// $Id: access.cc,v 1.18 2002-09-05 04:56:11 kevinlawton Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -346,7 +346,7 @@ accessOK: hostPageAddr = accessBits & 0xfffff000; if (hostPageAddr) { hostAddr = (Bit16u*) (hostPageAddr | pageOffset); - *hostAddr = *data; + WriteHostWordToLittleEndian(hostAddr, *data); return; } } @@ -400,7 +400,7 @@ accessOK: hostPageAddr = accessBits & 0xfffff000; if (hostPageAddr) { hostAddr = (Bit32u*) (hostPageAddr | pageOffset); - *hostAddr = *data; + WriteHostDWordToLittleEndian(hostAddr, *data); return; } } @@ -506,7 +506,7 @@ accessOK: hostPageAddr = accessBits & 0xfffff000; if (hostPageAddr) { hostAddr = (Bit16u*) (hostPageAddr | pageOffset); - *data = *hostAddr; + ReadHostWordFromLittleEndian(hostAddr, *data); return; } } @@ -561,7 +561,7 @@ accessOK: hostPageAddr = accessBits & 0xfffff000; if (hostPageAddr) { hostAddr = (Bit32u*) (hostPageAddr | pageOffset); - *data = *hostAddr; + ReadHostDWordFromLittleEndian(hostAddr, *data); return; } } @@ -677,7 +677,7 @@ accessOK: hostPageAddr = accessBits & 0xfffff000; if (hostPageAddr) { hostAddr = (Bit16u*) (hostPageAddr | pageOffset); - *data = *hostAddr; + ReadHostWordFromLittleEndian(hostAddr, *data); BX_CPU_THIS_PTR address_xlation.paddress1 = BX_CPU_THIS_PTR TLB.entry[tlbIndex].ppf | pageOffset; BX_CPU_THIS_PTR address_xlation.pages = 1; @@ -733,7 +733,7 @@ accessOK: hostPageAddr = accessBits & 0xfffff000; if (hostPageAddr) { hostAddr = (Bit32u*) (hostPageAddr | pageOffset); - *data = *hostAddr; + ReadHostDWordFromLittleEndian(hostAddr, *data); BX_CPU_THIS_PTR address_xlation.paddress1 = BX_CPU_THIS_PTR TLB.entry[tlbIndex].ppf | pageOffset; BX_CPU_THIS_PTR address_xlation.pages = 1; @@ -856,7 +856,7 @@ accessOK: hostPageAddr = accessBits & 0xfffff000; if (hostPageAddr) { hostAddr = (Bit64u*) (hostPageAddr | pageOffset); - *hostAddr = *data; + WriteHostQWordToLittleEndian(hostAddr, *data); return; } } @@ -910,7 +910,7 @@ accessOK: hostPageAddr = accessBits & 0xfffff000; if (hostPageAddr) { hostAddr = (Bit64u*) (hostPageAddr | pageOffset); - *data = *hostAddr; + ReadHostQWordFromLittleEndian(hostAddr, *data); return; } } diff --git a/bochs/cpu/paging.cc b/bochs/cpu/paging.cc index 01f1bd767..af3ca6088 100644 --- a/bochs/cpu/paging.cc +++ b/bochs/cpu/paging.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: paging.cc,v 1.14 2002-09-05 03:09:59 kevinlawton Exp $ +// $Id: paging.cc,v 1.15 2002-09-05 04:56:11 kevinlawton Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -672,7 +672,7 @@ pageTableWalk: // will be returned, and it's OK to OR zero in anyways. BX_CPU_THIS_PTR TLB.entry[TLB_index].accessBits |= (Bit32u) BX_CPU_THIS_PTR mem->getHostMemAddr(A20ADDR(ppf), rw); -#endif // BX_SupportGuest2HostTLB +#endif return(paddress); @@ -846,7 +846,7 @@ pageTableWalk: #if BX_SupportGuest2HostTLB BX_CPU_THIS_PTR TLB.entry[TLB_index].accessBits |= (Bit32u) BX_CPU_THIS_PTR mem->getHostMemAddr(A20ADDR(ppf), BX_READ); -#endif // BX_SupportGuest2HostTLB +#endif return(paddress);