- remove panic condition "memory not suitably aligned" and replace with

an allocation scheme that is guaranteed to return a block that is
  aligned correctly.
- Kevin asked me to go ahead and align the memory to 4k page boundaries,
  so I did.  If we need to change this, just change BX_MEM_VECTOR_ALIGN
  in memory/memory.h (now 4096).
This commit is contained in:
Bryce Denney 2002-09-04 02:11:33 +00:00
parent 54bc40971c
commit 7b157bbf43
2 changed files with 39 additions and 21 deletions

View File

@ -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);

View File

@ -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);