diff --git a/bochs/memory/memory.h b/bochs/memory/memory.h index 707f60fda..493cb1db0 100644 --- a/bochs/memory/memory.h +++ b/bochs/memory/memory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: memory.h,v 1.8 2002-09-01 20:12:09 kevinlawton Exp $ +// $Id: memory.h,v 1.9 2002-09-04 02:11:33 bdenney Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -37,12 +37,14 @@ # define BX_MEM_THIS this-> #endif - +// alignment of memory vector, must be a power of 2 +#define BX_MEM_VECTOR_ALIGN 4096 class BX_MEM_C : public logfunctions { public: - Bit8u *vector; + Bit8u *actual_vector; + Bit8u *vector; // aligned correctly size_t len; size_t megabytes; // (len in Megabytes) #if BX_PCI_SUPPORT @@ -58,6 +60,7 @@ public: BX_MEM_C(void); BX_MEM_C(size_t memsize); ~BX_MEM_C(void); + BX_MEM_SMF void alloc_vector_aligned (size_t bytes, size_t alignment); BX_MEM_SMF void init_memory(int memsize); BX_MEM_SMF void read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data); BX_MEM_SMF void write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data); diff --git a/bochs/memory/misc_mem.cc b/bochs/memory/misc_mem.cc index 96f8ed438..80f85c1e9 100644 --- a/bochs/memory/misc_mem.cc +++ b/bochs/memory/misc_mem.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: misc_mem.cc,v 1.27 2002-09-03 16:44:33 bdenney Exp $ +// $Id: misc_mem.cc,v 1.28 2002-09-04 02:11:33 bdenney Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2002 MandrakeSoft S.A. @@ -61,21 +61,39 @@ BX_MEM_C::BX_MEM_C(void) +#if BX_PROVIDE_CPU_MEMORY +void +BX_MEM_C::alloc_vector_aligned (size_t bytes, size_t alignment) +{ + if (actual_vector != NULL) { + BX_INFO (("freeing existing memory vector")); + delete [] actual_vector; + actual_vector = NULL; + vector = NULL; + } + Bit64u test_mask = alignment - 1; + actual_vector = new Bit8u [bytes+test_mask]; + // round address forward to nearest multiple of alignment. Alignment + // MUST BE a power of two for this to work. + Bit64u masked = ((Bit64u) actual_vector + test_mask) & ~test_mask; + vector = (Bit8u *)masked; + // sanity check: no lost bits during pointer conversion + BX_ASSERT (sizeof(masked) >= sizeof(vector)); + // sanity check: after realignment, everything fits in allocated space + BX_ASSERT (vector+bytes <= actual_vector+bytes+test_mask); + BX_INFO (("allocated memory at %p. after alignment, vector=%p", + actual_vector, vector)); +} +#endif + #if BX_PROVIDE_CPU_MEMORY // BX_MEM_C constructor BX_MEM_C::BX_MEM_C(size_t memsize) { - vector = new Bit8u[memsize]; + // Alloc 8 extra bytes so that the realignment operation is safe. + alloc_vector_aligned (memsize, BX_MEM_VECTOR_ALIGN); len = memsize; megabytes = len / (1024*1024); - if ( ((unsigned) vector) & 0x7 ) { - // Memory needs to be at least aligned to 8-byte boundaries for - // the TLB method of storing the host page address in the same - // field as 'combined_access' because the bottom 3 bits are used - // to cache access values. - delete [] vector; - BX_PANIC( ("BX_MEM_C constructor: memory not suitably aligned.") ); - } } #endif // #if BX_PROVIDE_CPU_MEMORY @@ -85,7 +103,9 @@ BX_MEM_C::BX_MEM_C(size_t memsize) BX_MEM_C::~BX_MEM_C(void) { if (this-> vector != NULL) { - delete [] this->vector; + delete [] actual_vector; + actual_vector = NULL; + vector = NULL; } else { BX_DEBUG(("(%u) memory not freed as it wasn't allocated!", BX_SIM_ID)); @@ -98,21 +118,16 @@ BX_MEM_C::~BX_MEM_C(void) void BX_MEM_C::init_memory(int memsize) { - BX_DEBUG(("Init $Id: misc_mem.cc,v 1.27 2002-09-03 16:44:33 bdenney Exp $")); + BX_DEBUG(("Init $Id: misc_mem.cc,v 1.28 2002-09-04 02:11:33 bdenney Exp $")); // you can pass 0 if memory has been allocated already through // the constructor, or the desired size of memory if it hasn't if (BX_MEM_THIS vector == NULL) { // memory not already allocated, do now... - BX_MEM_THIS vector = new Bit8u[memsize]; + alloc_vector_aligned (memsize, BX_MEM_VECTOR_ALIGN); BX_MEM_THIS len = memsize; BX_MEM_THIS megabytes = memsize / (1024*1024); BX_INFO(("%.2fMB", (float)(BX_MEM_THIS megabytes) )); - if ( ((unsigned) vector) & 0x7 ) { - // See note above, similar check. - delete [] vector; - BX_PANIC( ("BX_MEM_C constructor: memory not suitably aligned.") ); - } } // initialize all memory to 0x00 memset(BX_MEM_THIS vector, 0x00, BX_MEM_THIS len);