From fda4d38959a307c91b9ddb86e035729d9569a031 Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Thu, 17 Apr 2008 14:39:33 +0000 Subject: [PATCH] 32-bit systems have a problem to allocate large amount of physical memory for Bochs simulation which makes simulation with 4G address space virtually impossible. But in most of the cases when 4G physical address space defined - it is not touched by default on every run so it is possible to allocate only really accessed blocks. This commit made all necessary preparations for it. --- bochs/iodev/crc32.cc | 11 ++++-- bochs/iodev/devices.cc | 15 +++---- bochs/iodev/dma.cc | 8 ++-- bochs/iodev/harddrv.cc | 24 ++++-------- bochs/iodev/iodev.h | 60 ++++++++++++++++------------ bochs/iodev/pciusb.cc | 14 +++---- bochs/memory/memory.cc | 53 +++++++++++++------------ bochs/memory/memory.h | 29 ++++++++++++-- bochs/memory/misc_mem.cc | 85 +++++++++++++++++++++------------------- 9 files changed, 167 insertions(+), 132 deletions(-) diff --git a/bochs/iodev/crc32.cc b/bochs/iodev/crc32.cc index 8a67e7318..2f073b943 100644 --- a/bochs/iodev/crc32.cc +++ b/bochs/iodev/crc32.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: crc32.cc,v 1.4 2001-10-03 13:10:38 bdenney Exp $ +// $Id: crc32.cc,v 1.5 2008-04-17 14:39:32 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // /* CRC-32 calculator @@ -12,7 +12,8 @@ CRC_Generator::CRC_Generator() { init(); } -void CRC_Generator::init(void) { +void CRC_Generator::init(void) +{ Bit32u POLYNOMIAL = 0x04c11db7; int i; @@ -25,7 +26,8 @@ void CRC_Generator::init(void) { } } -Bit32u CRC_Generator::reflect(Bit32u ref, Bit8u ch) { +Bit32u CRC_Generator::reflect(Bit32u ref, Bit8u ch) +{ Bit32u value(0); int i; @@ -37,7 +39,8 @@ Bit32u CRC_Generator::reflect(Bit32u ref, Bit8u ch) { return value; } -Bit32u CRC_Generator::get_CRC(Bit8u * buf, Bit32u buflen) { +Bit32u CRC_Generator::get_CRC(Bit8u * buf, Bit32u buflen) +{ Bit32u ulCRC(0xFFFFFFFF); Bit32u len(buflen); Bit8u * buffer=(Bit8u *) buf; diff --git a/bochs/iodev/devices.cc b/bochs/iodev/devices.cc index e6365e2f0..5f9766b5d 100644 --- a/bochs/iodev/devices.cc +++ b/bochs/iodev/devices.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: devices.cc,v 1.120 2008-02-15 22:05:42 sshwarts Exp $ +// $Id: devices.cc,v 1.121 2008-04-17 14:39:32 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2002 MandrakeSoft S.A. @@ -25,6 +25,8 @@ // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +///////////////////////////////////////////////////////////////////////// #include "bochs.h" @@ -122,7 +124,7 @@ void bx_devices_c::init(BX_MEM_C *newmem) unsigned i; const char def_name[] = "Default"; - BX_DEBUG(("Init $Id: devices.cc,v 1.120 2008-02-15 22:05:42 sshwarts Exp $")); + BX_DEBUG(("Init $Id: devices.cc,v 1.121 2008-04-17 14:39:32 sshwarts Exp $")); mem = newmem; /* set no-default handlers, will be overwritten by the real default handler */ @@ -985,7 +987,7 @@ bx_devices_c::outp(Bit16u addr, Bit32u value, unsigned io_len) } } -bx_bool bx_devices_c::is_serial_enabled() +bx_bool bx_devices_c::is_serial_enabled(void) { char pname[24]; @@ -997,7 +999,7 @@ bx_bool bx_devices_c::is_serial_enabled() return false; } -bx_bool bx_devices_c::is_usb_enabled() +bx_bool bx_devices_c::is_usb_enabled(void) { char pname[20]; @@ -1009,7 +1011,7 @@ bx_bool bx_devices_c::is_usb_enabled() return false; } -bx_bool bx_devices_c::is_parallel_enabled() +bx_bool bx_devices_c::is_parallel_enabled(void) { char pname[26]; @@ -1023,11 +1025,10 @@ bx_bool bx_devices_c::is_parallel_enabled() void bx_pci_device_stub_c::register_pci_state(bx_list_c *list, Bit8u *pci_conf) { - unsigned i; char name[6]; bx_list_c *pci = new bx_list_c(list, "pci_conf", 256); - for (i=0; i<256; i++) { + for (unsigned i=0; i<256; i++) { sprintf(name, "0x%02x", i); new bx_shadow_num_c(pci, name, &pci_conf[i], BASE_HEX); } diff --git a/bochs/iodev/dma.cc b/bochs/iodev/dma.cc index 7898c7b81..6c976e3c1 100644 --- a/bochs/iodev/dma.cc +++ b/bochs/iodev/dma.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: dma.cc,v 1.46 2008-02-15 22:05:42 sshwarts Exp $ +// $Id: dma.cc,v 1.47 2008-04-17 14:39:32 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2002 MandrakeSoft S.A. @@ -122,7 +122,7 @@ unsigned bx_dma_c::get_TC(void) void bx_dma_c::init(void) { unsigned c, i, j; - BX_DEBUG(("Init $Id: dma.cc,v 1.46 2008-02-15 22:05:42 sshwarts Exp $")); + BX_DEBUG(("Init $Id: dma.cc,v 1.47 2008-04-17 14:39:32 sshwarts Exp $")); /* 8237 DMA controller */ @@ -759,7 +759,7 @@ void bx_dma_c::raise_HLDA(void) else BX_PANIC(("no dmaWrite handler for channel %u.", channel)); - DEV_MEM_WRITE_PHYSICAL(phy_addr, 2, &data_word); + DEV_MEM_WRITE_PHYSICAL(phy_addr, 2, (Bit8u*) &data_word); BX_DBG_DMA_REPORT(phy_addr, 2, BX_WRITE, data_word); } @@ -776,7 +776,7 @@ void bx_dma_c::raise_HLDA(void) BX_DBG_DMA_REPORT(phy_addr, 1, BX_READ, data_byte); } else { - DEV_MEM_READ_PHYSICAL(phy_addr, 2, &data_word); + DEV_MEM_READ_PHYSICAL(phy_addr, 2, (Bit8u*) &data_word); if (BX_DMA_THIS h[channel].dmaRead16) BX_DMA_THIS h[channel].dmaRead16(&data_word); diff --git a/bochs/iodev/harddrv.cc b/bochs/iodev/harddrv.cc index 61285a7b8..904d378c1 100644 --- a/bochs/iodev/harddrv.cc +++ b/bochs/iodev/harddrv.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: harddrv.cc,v 1.210 2008-03-30 08:32:57 vruppert Exp $ +// $Id: harddrv.cc,v 1.211 2008-04-17 14:39:32 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2002 MandrakeSoft S.A. @@ -173,7 +173,7 @@ void bx_hard_drive_c::init(void) char ata_name[20]; bx_list_c *base; - BX_DEBUG(("Init $Id: harddrv.cc,v 1.210 2008-03-30 08:32:57 vruppert Exp $")); + BX_DEBUG(("Init $Id: harddrv.cc,v 1.211 2008-04-17 14:39:32 sshwarts Exp $")); for (channel=0; channelreadPhysicalPage(NULL, phy_addr, len, ptr) -#define DEV_MEM_WRITE_PHYSICAL(phy_addr, len, ptr) \ - BX_MEM(0)->writePhysicalPage(NULL, phy_addr, len, ptr) +// memory stub has an assumption that there are no memory accesses splitting 4K page +BX_CPP_INLINE void DEV_MEM_READ_PHYSICAL(bx_phy_address phy_addr, unsigned len, Bit8u *ptr) +{ + while(len > 0) { + unsigned remainingInPage = 0x1000 - (phy_addr & 0xfff); + if (len < remainingInPage) remainingInPage = len; + BX_MEM(0)->readPhysicalPage(NULL, phy_addr, remainingInPage, ptr); + ptr += remainingInPage; + phy_addr += remainingInPage; + len -= remainingInPage; + } +} + +// memory stub has an assumption that there are no memory accesses splitting 4K page +BX_CPP_INLINE void DEV_MEM_WRITE_PHYSICAL(bx_phy_address phy_addr, unsigned len, Bit8u *ptr) +{ + while(len > 0) { + unsigned remainingInPage = 0x1000 - (phy_addr & 0xfff); + if (len < remainingInPage) remainingInPage = len; + BX_MEM(0)->writePhysicalPage(NULL, phy_addr, remainingInPage, ptr); + ptr += remainingInPage; + phy_addr += remainingInPage; + len -= remainingInPage; + } +} #ifndef NO_DEVICE_INCLUDES diff --git a/bochs/iodev/pciusb.cc b/bochs/iodev/pciusb.cc index a4eb67ce5..5dd2fe3ff 100644 --- a/bochs/iodev/pciusb.cc +++ b/bochs/iodev/pciusb.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: pciusb.cc,v 1.62 2008-01-26 22:24:02 sshwarts Exp $ +// $Id: pciusb.cc,v 1.63 2008-04-17 14:39:32 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2004 MandrakeSoft S.A. @@ -734,7 +734,7 @@ void bx_pciusb_c::usb_timer(void) Bit32u item, address, lastvertaddr = 0, queue_num = 0; Bit32u frame, frm_addr = BX_USB_THIS hub[0].usb_frame_base.frame_base + (BX_USB_THIS hub[0].usb_frame_num.frame_num << 2); - DEV_MEM_READ_PHYSICAL(frm_addr, 4, &frame); + DEV_MEM_READ_PHYSICAL(frm_addr, 4, (Bit8u*) &frame); if ((frame & 1) == 0) { stack[stk].next = (frame & ~0xF); stack[stk].d = 0; @@ -754,14 +754,14 @@ void bx_pciusb_c::usb_timer(void) lastvertaddr = address + 4; // get HORZ slot stk++; - DEV_MEM_READ_PHYSICAL(address, 4, &item); + DEV_MEM_READ_PHYSICAL(address, 4, (Bit8u*) &item); stack[stk].next = item & ~0xF; stack[stk].d = HC_HORZ; stack[stk].q = (item & 0x0002) ? 1 : 0; stack[stk].t = (item & 0x0001) ? 1 : 0; // get VERT slot stk++; - DEV_MEM_READ_PHYSICAL(lastvertaddr, 4, &item); + DEV_MEM_READ_PHYSICAL(lastvertaddr, 4, (Bit8u*) &item); stack[stk].next = item & ~0xF; stack[stk].d = HC_VERT; stack[stk].q = (item & 0x0002) ? 1 : 0; @@ -772,7 +772,7 @@ void bx_pciusb_c::usb_timer(void) queue_num++; } else { // else is a TD address = stack[stk].next; - DEV_MEM_READ_PHYSICAL(address, 32, &td); + DEV_MEM_READ_PHYSICAL(address, 32, (Bit8u*) &td); bx_bool spd = (td.dword1 & (1<<29)) ? 1 : 0; stack[stk].next = td.dword0 & ~0xF; bx_bool depthbreadth = (td.dword0 & 0x0004) ? 1 : 0; // 1 = depth first, 0 = breadth first @@ -792,10 +792,10 @@ void bx_pciusb_c::usb_timer(void) } if (td.dword1 & (1<<22)) stalled = 1; - DEV_MEM_WRITE_PHYSICAL(address+4, 4, &td.dword1); // write back the status + DEV_MEM_WRITE_PHYSICAL(address+4, 4, (Bit8u*) &td.dword1); // write back the status // copy pointer for next queue item, in to vert queue head if ((stk > 0) && !shortpacket && (stack[stk].d == HC_VERT)) - DEV_MEM_WRITE_PHYSICAL(lastvertaddr, 4, &td.dword0); + DEV_MEM_WRITE_PHYSICAL(lastvertaddr, 4, (Bit8u*) &td.dword0); } } diff --git a/bochs/memory/memory.cc b/bochs/memory/memory.cc index bc3e0908c..27f99dbe0 100644 --- a/bochs/memory/memory.cc +++ b/bochs/memory/memory.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: memory.cc,v 1.64 2008-04-07 18:39:17 sshwarts Exp $ +// $Id: memory.cc,v 1.65 2008-04-17 14:39:32 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -23,7 +23,8 @@ // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - +// +///////////////////////////////////////////////////////////////////////// #include "bochs.h" #include "cpu/cpu.h" @@ -50,6 +51,9 @@ void BX_MEM_C::writePhysicalPage(BX_CPU_C *cpu, bx_phy_address addr, unsigned le struct memory_handler_struct *memory_handler = NULL; // Note: accesses should always be contained within a single page now + if ((addr>>12) != ((addr+len-1)>>12)) { + BX_PANIC(("writePhysicalPage: cross page access at address 0x%08x, len=%d", addr, len)); + } if (cpu != NULL) { #if BX_SUPPORT_IODEBUG @@ -112,22 +116,22 @@ mem_write: if ((a20addr & 0xfff80000) != 0x00080000 || (a20addr <= 0x0009ffff)) { if (len == 8) { - WriteHostQWordToLittleEndian(&BX_MEM_THIS vector[a20addr], *(Bit64u*)data); + WriteHostQWordToLittleEndian(BX_MEM_THIS get_vector(a20addr), *(Bit64u*)data); BX_DBG_DIRTY_PAGE(a20addr >> 12); return; } if (len == 4) { - WriteHostDWordToLittleEndian(&BX_MEM_THIS vector[a20addr], *(Bit32u*)data); + WriteHostDWordToLittleEndian(BX_MEM_THIS get_vector(a20addr), *(Bit32u*)data); BX_DBG_DIRTY_PAGE(a20addr >> 12); return; } if (len == 2) { - WriteHostWordToLittleEndian(&BX_MEM_THIS vector[a20addr], *(Bit16u*)data); + WriteHostWordToLittleEndian(BX_MEM_THIS get_vector(a20addr), *(Bit16u*)data); BX_DBG_DIRTY_PAGE(a20addr >> 12); return; } if (len == 1) { - * ((Bit8u *) (&BX_MEM_THIS vector[a20addr])) = * (Bit8u *) data; + * (BX_MEM_THIS get_vector(a20addr)) = * (Bit8u *) data; BX_DBG_DIRTY_PAGE(a20addr >> 12); return; } @@ -144,7 +148,7 @@ write_one: if ((a20addr & 0xfff80000) != 0x00080000 || (a20addr <= 0x0009ffff)) { // addr *not* in range 000A0000 .. 000FFFFF - BX_MEM_THIS vector[a20addr] = *data_ptr; + *(BX_MEM_THIS get_vector(a20addr)) = *data_ptr; BX_DBG_DIRTY_PAGE(a20addr >> 12); inc_one: if (len == 1) return; @@ -164,7 +168,7 @@ inc_one: if (a20addr <= 0x000bffff) { // devices are not allowed to access SMMRAM under VGA memory if (cpu) { - BX_MEM_THIS vector[a20addr] = *data_ptr; + *(BX_MEM_THIS get_vector(a20addr)) = *data_ptr; BX_DBG_DIRTY_PAGE(a20addr >> 12); } goto inc_one; @@ -181,7 +185,7 @@ inc_one: switch (DEV_pci_wr_memtype(a20addr)) { case 0x1: // Writes to ShadowRAM BX_DEBUG(("Writing to ShadowRAM: address %08x, data %02x", (unsigned) a20addr, *data_ptr)); - BX_MEM_THIS vector[a20addr] = *data_ptr; + *(BX_MEM_THIS get_vector(a20addr)) = *data_ptr; BX_DBG_DIRTY_PAGE(a20addr >> 12); goto inc_one; @@ -210,6 +214,9 @@ void BX_MEM_C::readPhysicalPage(BX_CPU_C *cpu, bx_phy_address addr, unsigned len struct memory_handler_struct *memory_handler = NULL; // Note: accesses should always be contained within a single page now + if ((addr>>12) != ((addr+len-1)>>12)) { + BX_PANIC(("readPhysicalPage: cross page access at address 0x%08x, len=%d", addr, len)); + } if (cpu != NULL) { #if BX_SUPPORT_IODEBUG @@ -264,19 +271,19 @@ mem_read: if ((a20addr & 0xfff80000) != 0x00080000 || (a20addr <= 0x0009ffff)) { if (len == 8) { - ReadHostQWordFromLittleEndian(&BX_MEM_THIS vector[a20addr], * (Bit64u*) data); + ReadHostQWordFromLittleEndian(BX_MEM_THIS get_vector(a20addr), * (Bit64u*) data); return; } if (len == 4) { - ReadHostDWordFromLittleEndian(&BX_MEM_THIS vector[a20addr], * (Bit32u*) data); + ReadHostDWordFromLittleEndian(BX_MEM_THIS get_vector(a20addr), * (Bit32u*) data); return; } if (len == 2) { - ReadHostWordFromLittleEndian(&BX_MEM_THIS vector[a20addr], * (Bit16u*) data); + ReadHostWordFromLittleEndian(BX_MEM_THIS get_vector(a20addr), * (Bit16u*) data); return; } if (len == 1) { - * (Bit8u *) data = * ((Bit8u *) (&BX_MEM_THIS vector[a20addr])); + * (Bit8u *) data = * (BX_MEM_THIS get_vector(a20addr)); return; } // len == other case can just fall thru to special cases handling @@ -292,7 +299,7 @@ read_one: if ((a20addr & 0xfff80000) != 0x00080000 || (a20addr <= 0x0009ffff)) { // addr *not* in range 00080000 .. 000FFFFF - *data_ptr = BX_MEM_THIS vector[a20addr]; + *data_ptr = *(BX_MEM_THIS get_vector(a20addr)); inc_one: if (len == 1) return; len--; @@ -310,7 +317,7 @@ inc_one: // SMMRAM if (a20addr <= 0x000bffff) { // devices are not allowed to access SMMRAM under VGA memory - if (cpu) *data_ptr = BX_MEM_THIS vector[a20addr]; + if (cpu) *data_ptr = *(BX_MEM_THIS get_vector(a20addr)); goto inc_one; } @@ -319,17 +326,15 @@ inc_one: { switch (DEV_pci_rd_memtype(a20addr)) { case 0x0: // Read from ROM - if ((a20addr & 0xfffe0000) == 0x000e0000) - { + if ((a20addr & 0xfffe0000) == 0x000e0000) { *data_ptr = BX_MEM_THIS rom[a20addr & BIOS_MASK]; } - else - { + else { *data_ptr = BX_MEM_THIS rom[(a20addr & EXROM_MASK) + BIOSROMSZ]; } goto inc_one; case 0x1: // Read from ShadowRAM - *data_ptr = BX_MEM_THIS vector[a20addr]; + *data_ptr = *(BX_MEM_THIS get_vector(a20addr)); goto inc_one; default: BX_PANIC(("readPhysicalPage: default case")); @@ -340,14 +345,12 @@ inc_one: #endif // #if BX_SUPPORT_PCI { if ((a20addr & 0xfffc0000) != 0x000c0000) { - *data_ptr = BX_MEM_THIS vector[a20addr]; + *data_ptr = *(BX_MEM_THIS get_vector(a20addr)); } - else if ((a20addr & 0xfffe0000) == 0x000e0000) - { + else if ((a20addr & 0xfffe0000) == 0x000e0000) { *data_ptr = BX_MEM_THIS rom[a20addr & BIOS_MASK]; } - else - { + else { *data_ptr = BX_MEM_THIS rom[(a20addr & EXROM_MASK) + BIOSROMSZ]; } goto inc_one; diff --git a/bochs/memory/memory.h b/bochs/memory/memory.h index 5671f4188..c04b51497 100644 --- a/bochs/memory/memory.h +++ b/bochs/memory/memory.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: memory.h,v 1.46 2008-04-07 18:39:17 sshwarts Exp $ +// $Id: memory.h,v 1.47 2008-04-17 14:39:33 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -25,6 +25,8 @@ // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +///////////////////////////////////////////////////////////////////////// #ifndef BX_MEM_H # define BX_MEM_H 1 @@ -41,7 +43,6 @@ class BX_CPU_C; // alignment of memory vector, must be a power of 2 -#define BX_MEM_VECTOR_ALIGN 4096 #define BIOSROMSZ (1 << 19) // 512KB BIOS ROM @0xfff80000, must be a power of 2 #define EXROMSIZE 0x20000 // ROMs 0xc0000-0xdffff (area 0xe0000-0xfffff=bios mapped) #define BIOS_MASK (BIOSROMSZ-1) @@ -88,7 +89,8 @@ public: BX_MEM_C(); ~BX_MEM_C(); - BX_MEM_SMF void alloc_vector_aligned (Bit32u bytes, Bit32u alignment) BX_CPP_AttrRegparmN(2); + + BX_MEM_SMF Bit8u* get_vector(bx_phy_address addr); BX_MEM_SMF void init_memory(Bit32u memsize); BX_MEM_SMF void cleanup_memory(void); BX_MEM_SMF void enable_smram(bx_bool enable, bx_bool restricted); @@ -101,9 +103,13 @@ public: BX_MEM_SMF void load_ROM(const char *path, bx_phy_address romaddress, Bit8u type); BX_MEM_SMF void load_RAM(const char *path, bx_phy_address romaddress, Bit8u type); BX_MEM_SMF Bit32u get_memory_in_k(void); +#if (BX_DEBUGGER || BX_DISASM || BX_GDBSTUB) BX_MEM_SMF bx_bool dbg_fetch_mem(BX_CPU_C *cpu, bx_phy_address addr, unsigned len, Bit8u *buf); +#endif +#if (BX_DEBUGGER || BX_GDBSTUB) BX_MEM_SMF bx_bool dbg_set_mem(bx_phy_address addr, unsigned len, Bit8u *buf); BX_MEM_SMF bx_bool dbg_crc32(bx_phy_address addr1, bx_phy_address addr2, Bit32u *crc); +#endif BX_MEM_SMF Bit8u* getHostMemAddr(BX_CPU_C *cpu, bx_phy_address a20Addr, unsigned op, unsigned access_type); BX_MEM_SMF bx_bool registerMemoryHandlers(void *param, memory_handler_t read_handler, memory_handler_t write_handler, bx_phy_address begin_addr, bx_phy_address end_addr); @@ -121,10 +127,25 @@ public: BX_MEM_SMF void register_state(void); }; -#if BX_PROVIDE_CPU_MEMORY==1 +#if BX_PROVIDE_CPU_MEMORY BOCHSAPI extern BX_MEM_C bx_mem; #endif +BX_CPP_INLINE Bit8u* BX_MEM_C::get_vector(bx_phy_address addr) +{ + return (BX_MEM_THIS vector + addr); +} + +BX_CPP_INLINE Bit32u BX_MEM_C::get_memory_in_k(void) +{ + return(BX_MEM_THIS megabytes * 1024); +} + +BX_CPP_INLINE Bit32u BX_MEM_C::get_num_allocated_pages(void) +{ + return(BX_MEM_THIS len >> 12); +} + #if BX_DEBUGGER # define BX_DBG_DIRTY_PAGE(page) BX_MEM(0)->dbg_dirty_pages[page] = 1; #else diff --git a/bochs/memory/misc_mem.cc b/bochs/memory/misc_mem.cc index 0dba4e096..9e3779e0a 100644 --- a/bochs/memory/misc_mem.cc +++ b/bochs/memory/misc_mem.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: misc_mem.cc,v 1.110 2008-02-15 22:05:43 sshwarts Exp $ +// $Id: misc_mem.cc,v 1.111 2008-04-17 14:39:33 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2002 MandrakeSoft S.A. @@ -25,24 +25,18 @@ // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +///////////////////////////////////////////////////////////////////////// #include "bochs.h" #include "cpu/cpu.h" #include "iodev/iodev.h" #define LOG_THIS BX_MEM(0)-> +#define BX_MEM_VECTOR_ALIGN 4096 + #if BX_PROVIDE_CPU_MEMORY -Bit32u BX_MEM_C::get_memory_in_k(void) -{ - return(BX_MEM_THIS megabytes * 1024); -} - -Bit32u BX_MEM_C::get_num_allocated_pages(void) -{ - return(BX_MEM_THIS len / 4096); -} - BX_MEM_C::BX_MEM_C() { char mem[6]; @@ -58,27 +52,19 @@ BX_MEM_C::BX_MEM_C() memory_handlers = NULL; } -void BX_CPP_AttrRegparmN(2) -BX_MEM_C::alloc_vector_aligned (Bit32u bytes, Bit32u alignment) +Bit8u* alloc_vector_aligned(Bit8u **actual_vector, Bit32u bytes, Bit32u alignment) { - if (BX_MEM_THIS actual_vector != NULL) { - BX_INFO (("freeing existing memory vector")); - delete [] BX_MEM_THIS actual_vector; - BX_MEM_THIS actual_vector = NULL; - BX_MEM_THIS vector = NULL; - } Bit64u test_mask = alignment - 1; - BX_MEM_THIS actual_vector = new Bit8u [(Bit32u)(bytes+test_mask)]; + *actual_vector = new Bit8u [(Bit32u)(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)(BX_MEM_THIS actual_vector + test_mask)) & ~test_mask; - BX_MEM_THIS vector = (Bit8u *)masked; + Bit64u masked = ((Bit64u)(*actual_vector + test_mask)) & ~test_mask; + Bit8u *vector = (Bit8u *) masked; // sanity check: no lost bits during pointer conversion - BX_ASSERT (sizeof(masked) >= sizeof(BX_MEM_THIS vector)); + BX_ASSERT (sizeof(masked) >= sizeof(vector)); // sanity check: after realignment, everything fits in allocated space - BX_ASSERT (BX_MEM_THIS vector+bytes <= BX_MEM_THIS actual_vector+bytes+test_mask); - BX_INFO (("allocated memory at %p. after alignment, vector=%p", - BX_MEM_THIS actual_vector, BX_MEM_THIS vector)); + BX_ASSERT (vector+bytes <= *actual_vector+bytes+test_mask); + return vector; } BX_MEM_C::~BX_MEM_C() @@ -90,9 +76,18 @@ void BX_MEM_C::init_memory(Bit32u memsize) { unsigned idx; - BX_DEBUG(("Init $Id: misc_mem.cc,v 1.110 2008-02-15 22:05:43 sshwarts Exp $")); + BX_DEBUG(("Init $Id: misc_mem.cc,v 1.111 2008-04-17 14:39:33 sshwarts Exp $")); + + if (BX_MEM_THIS actual_vector != NULL) { + BX_INFO (("freeing existing memory vector")); + delete [] BX_MEM_THIS actual_vector; + BX_MEM_THIS actual_vector = NULL; + BX_MEM_THIS vector = NULL; + } + BX_MEM_THIS vector = ::alloc_vector_aligned(&BX_MEM_THIS actual_vector, memsize + BIOSROMSZ + EXROMSIZE + 4096, BX_MEM_VECTOR_ALIGN); + BX_INFO (("allocated memory at %p. after alignment, vector=%p", + BX_MEM_THIS actual_vector, BX_MEM_THIS vector)); - alloc_vector_aligned(memsize+ BIOSROMSZ + EXROMSIZE + 4096, BX_MEM_VECTOR_ALIGN); BX_MEM_THIS len = memsize; BX_MEM_THIS megabytes = memsize / (1024*1024); BX_MEM_THIS memory_handlers = new struct memory_handler_struct *[4096]; @@ -346,7 +341,7 @@ void BX_MEM_C::load_RAM(const char *path, bx_phy_address ramaddress, Bit8u type) offset = ramaddress; while (size > 0) { - ret = read(fd, (bx_ptr_t) &BX_MEM_THIS vector[offset], size); + ret = read(fd, (bx_ptr_t) BX_MEM_THIS get_vector(offset), size); if (ret <= 0) { BX_PANIC(("RAM: read failed on RAM image: '%s'",path)); } @@ -371,7 +366,7 @@ bx_bool BX_MEM_C::dbg_fetch_mem(BX_CPU_C *cpu, bx_phy_address addr, unsigned len // Reading standard PCI/ISA Video Mem / SMMRAM if ((addr & 0xfffe0000) == 0x000a0000) { if (BX_MEM_THIS smram_enable || cpu->smm_mode()) - *buf = BX_MEM_THIS vector[addr]; + *buf = *(BX_MEM_THIS get_vector(addr)); else *buf = DEV_vga_mem_read(addr); } @@ -390,7 +385,7 @@ bx_bool BX_MEM_C::dbg_fetch_mem(BX_CPU_C *cpu, bx_phy_address addr, unsigned len } break; case 0x1: // Read from ShadowRAM - *buf = BX_MEM_THIS vector[addr]; + *buf = *(BX_MEM_THIS get_vector(addr)); break; default: BX_PANIC(("dbg_fetch_mem: default case")); @@ -400,7 +395,7 @@ bx_bool BX_MEM_C::dbg_fetch_mem(BX_CPU_C *cpu, bx_phy_address addr, unsigned len else if (addr < BX_MEM_THIS len) { if ((addr & 0xfffc0000) != 0x000c0000) { - *buf = BX_MEM_THIS vector[addr]; + *buf = *(BX_MEM_THIS get_vector(addr)); } else if ((addr & 0xfffe0000) == 0x000e0000) { @@ -437,7 +432,7 @@ bx_bool BX_MEM_C::dbg_set_mem(bx_phy_address addr, unsigned len, Bit8u *buf) // Write to standard PCI/ISA Video Mem / SMMRAM if ((addr & 0xfffe0000) == 0x000a0000) { if (BX_MEM_THIS smram_enable) - BX_MEM_THIS vector[addr] = *buf; + *(BX_MEM_THIS get_vector(addr)) = *buf; else DEV_vga_mem_write(addr, *buf); } @@ -448,7 +443,7 @@ bx_bool BX_MEM_C::dbg_set_mem(bx_phy_address addr, unsigned len, Bit8u *buf) case 0x0: // Ignore write to ROM break; case 0x1: // Write to ShadowRAM - BX_MEM_THIS vector[addr] = *buf; + *(BX_MEM_THIS get_vector(addr)) = *buf; break; default: BX_PANIC(("dbg_fetch_mem: default case")); @@ -457,14 +452,13 @@ bx_bool BX_MEM_C::dbg_set_mem(bx_phy_address addr, unsigned len, Bit8u *buf) #endif // #if BX_SUPPORT_PCI else if ((addr & 0xfffc0000) != 0x000c0000 && (addr < (bx_phy_address)(~BIOS_MASK))) { - BX_MEM_THIS vector[addr] = *buf; + *(BX_MEM_THIS get_vector(addr)) = *buf; } buf++; addr++; } return(1); } -#endif bx_bool BX_MEM_C::dbg_crc32(bx_phy_address addr1, bx_phy_address addr2, Bit32u *crc) { @@ -476,10 +470,19 @@ bx_bool BX_MEM_C::dbg_crc32(bx_phy_address addr1, bx_phy_address addr2, Bit32u * return(0); // error, specified address past last phy mem addr unsigned len = 1 + addr2 - addr1; - *crc = crc32(BX_MEM_THIS vector + addr1, len); + + // do not cross 4K boundary + while(1) { + unsigned remainsInPage = 0x1000 - (addr1 & 0xfff); + unsigned access_length = (len < remainsInPage) ? len : remainsInPage; + *crc = crc32(BX_MEM_THIS get_vector(addr1), access_length); + addr1 += access_length; + len -= access_length; + } return(1); } +#endif // // Return a host address corresponding to the guest physical memory @@ -520,7 +523,7 @@ Bit8u *BX_MEM_C::getHostMemAddr(BX_CPU_C *cpu, bx_phy_address a20Addr, unsigned if ((a20Addr & 0xfffe0000) == 0x000a0000 && (BX_MEM_THIS smram_available)) { if (BX_MEM_THIS smram_enable || cpu->smm_mode()) - return (Bit8u *) &BX_MEM_THIS vector[a20Addr]; + return BX_MEM_THIS get_vector(a20Addr); } } @@ -558,7 +561,7 @@ Bit8u *BX_MEM_C::getHostMemAddr(BX_CPU_C *cpu, bx_phy_address a20Addr, unsigned } break; case 0x1: // Read from ShadowRAM - return (Bit8u *) &BX_MEM_THIS vector[a20Addr]; + return BX_MEM_THIS get_vector(a20Addr); default: BX_PANIC(("getHostMemAddr(): default case")); return(NULL); @@ -568,7 +571,7 @@ Bit8u *BX_MEM_C::getHostMemAddr(BX_CPU_C *cpu, bx_phy_address a20Addr, unsigned else if(a20Addr < BX_MEM_THIS len) { if ((a20Addr & 0xfffc0000) != 0x000c0000) { - return (Bit8u *) &BX_MEM_THIS vector[a20Addr]; + return BX_MEM_THIS get_vector(a20Addr); } else if ((a20Addr & 0xfffe0000) == 0x000e0000) { @@ -610,7 +613,7 @@ Bit8u *BX_MEM_C::getHostMemAddr(BX_CPU_C *cpu, bx_phy_address a20Addr, unsigned else { if ((a20Addr & 0xfffc0000) != 0x000c0000) { - retAddr = (Bit8u *) &BX_MEM_THIS vector[a20Addr]; + retAddr = BX_MEM_THIS get_vector(a20Addr); } else {