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.

This commit is contained in:
Stanislav Shwartsman 2008-04-17 14:39:33 +00:00
parent 72cefc818f
commit fda4d38959
9 changed files with 167 additions and 132 deletions

View File

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

View File

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

View File

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

View File

@ -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; channel<BX_MAX_ATA_CHANNEL; channel++) {
sprintf(ata_name, "ata.%d.resources", channel);
@ -815,9 +815,7 @@ Bit32u bx_hard_drive_c::read(Bit32u address, unsigned io_len)
#if BX_SupportRepeatSpeedups
if (DEV_bulk_io_quantum_requested()) {
unsigned transferLen, quantumsMax;
quantumsMax =
(BX_SELECTED_CONTROLLER(channel).buffer_size - BX_SELECTED_CONTROLLER(channel).buffer_index) / io_len;
quantumsMax = (BX_SELECTED_CONTROLLER(channel).buffer_size - BX_SELECTED_CONTROLLER(channel).buffer_index) / io_len;
if (quantumsMax == 0)
BX_PANIC(("IO read(0x%04x): not enough space for read", address));
DEV_bulk_io_quantum_transferred() = DEV_bulk_io_quantum_requested();
@ -825,8 +823,7 @@ Bit32u bx_hard_drive_c::read(Bit32u address, unsigned io_len)
DEV_bulk_io_quantum_transferred() = quantumsMax;
transferLen = io_len * DEV_bulk_io_quantum_transferred();
memcpy((Bit8u*) DEV_bulk_io_host_addr(),
&BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index],
transferLen);
&BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index], transferLen);
DEV_bulk_io_host_addr() += transferLen;
BX_SELECTED_CONTROLLER(channel).buffer_index += transferLen;
value32 = 0; // Value returned not important;
@ -1279,20 +1276,15 @@ void bx_hard_drive_c::write(Bit32u address, Bit32u value, unsigned io_len)
#if BX_SupportRepeatSpeedups
if (DEV_bulk_io_quantum_requested()) {
unsigned transferLen, quantumsMax;
quantumsMax =
(BX_SELECTED_CONTROLLER(channel).buffer_size - BX_SELECTED_CONTROLLER(channel).buffer_index) / io_len;
quantumsMax = (BX_SELECTED_CONTROLLER(channel).buffer_size - BX_SELECTED_CONTROLLER(channel).buffer_index) / io_len;
if (quantumsMax == 0)
BX_PANIC(("IO write(0x%04x): not enough space for write", address));
DEV_bulk_io_quantum_transferred() =
DEV_bulk_io_quantum_requested();
DEV_bulk_io_quantum_transferred() = DEV_bulk_io_quantum_requested();
if (quantumsMax < DEV_bulk_io_quantum_transferred())
DEV_bulk_io_quantum_transferred() = quantumsMax;
transferLen = io_len * DEV_bulk_io_quantum_transferred();
memcpy(
&BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index],
(Bit8u*) DEV_bulk_io_host_addr(),
transferLen);
memcpy(&BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index],
(Bit8u*) DEV_bulk_io_host_addr(), transferLen);
DEV_bulk_io_host_addr() += transferLen;
BX_SELECTED_CONTROLLER(channel).buffer_index += transferLen;
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: iodev.h,v 1.91 2008-02-15 22:05:42 sshwarts Exp $
// $Id: iodev.h,v 1.92 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
//
/////////////////////////////////////////////////////////////////////////
#ifndef IODEV_H
#define IODEV_H
@ -45,7 +47,6 @@
#define BX_MAX_IRQS 16
#define BX_NO_IRQ -1
class bx_pit_c;
#if BX_SUPPORT_APIC
class bx_ioapic_c;
@ -57,11 +58,9 @@ class bx_iodebug_c;
class bx_g2h_c;
#endif
typedef Bit32u (*bx_read_handler_t)(void *, Bit32u, unsigned);
typedef void (*bx_write_handler_t)(void *, Bit32u, Bit32u, unsigned);
#if BX_USE_DEV_SMF
# define BX_DEV_SMF static
# define BX_DEV_THIS bx_devices.
@ -283,7 +282,7 @@ public:
{
STUBFUNC(pci, register_pci_handlers); return 0;
}
virtual bx_bool is_pci_device (const char *name) {
virtual bx_bool is_pci_device(const char *name) {
return 0;
}
virtual bx_bool pci_set_base_mem(void *this_ptr, memory_handler_t f1, memory_handler_t f2,
@ -299,12 +298,8 @@ public:
return 0;
}
virtual Bit8u rd_memType (Bit32u addr) {
return 0;
}
virtual Bit8u wr_memType (Bit32u addr) {
return 0;
}
virtual Bit8u rd_memType(Bit32u addr) { return 0; }
virtual Bit8u wr_memType(Bit32u addr) { return 0; }
virtual void print_i440fx_state(void) {}
};
@ -354,12 +349,8 @@ public:
STUBFUNC(pciusb, usb_key_enq);
return 0;
}
virtual bx_bool usb_keyboard_connected() {
return 0;
}
virtual bx_bool usb_mouse_connected() {
return 0;
}
virtual bx_bool usb_keyboard_connected() { return 0; }
virtual bx_bool usb_mouse_connected() { return 0; }
};
#endif
@ -533,15 +524,36 @@ private:
static void default_write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
int timer_handle;
bx_bool is_serial_enabled ();
bx_bool is_usb_enabled ();
bx_bool is_parallel_enabled ();
bx_bool is_serial_enabled();
bx_bool is_usb_enabled();
bx_bool is_parallel_enabled();
};
#define DEV_MEM_READ_PHYSICAL(phy_addr, len, ptr) \
BX_MEM(0)->readPhysicalPage(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

View File

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

View File

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

View File

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

View File

@ -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
{