Bochs/bochs/memory/misc_mem.cc

614 lines
17 KiB
C++
Raw Normal View History

/////////////////////////////////////////////////////////////////////////
// $Id: misc_mem.cc,v 1.66 2005-10-28 06:33:53 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
//
// MandrakeSoft S.A.
// 43, rue d'Aboukir
// 75002 Paris - France
// http://www.linux-mandrake.com/
// http://www.mandrakesoft.com/
//
// I/O memory handlers API Copyright (C) 2003 by Frank Cornelis
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// 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 "iodev/iodev.h"
#define LOG_THIS BX_MEM(0)->
#if BX_PROVIDE_CPU_MEMORY
2004-10-21 22:20:40 +04:00
Bit32u BX_MEM_C::get_memory_in_k(void)
{
return(BX_MEM_THIS megabytes * 1024);
}
// BX_MEM_C constructor
BX_MEM_C::BX_MEM_C(void)
{
char mem[6];
snprintf(mem, 6, "MEM%d", BX_SIM_ID);
2001-06-27 23:16:01 +04:00
put(mem);
settype(MEMLOG);
vector = NULL;
actual_vector = NULL;
len = 0;
megabytes = 0;
memory_handlers = NULL;
}
void BX_CPP_AttrRegparmN(2)
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;
2005-06-07 23:26:21 +04:00
actual_vector = new Bit8u [(unsigned int)(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));
}
// BX_MEM_C destructor
BX_MEM_C::~BX_MEM_C(void)
{
if (this-> vector != NULL) {
delete [] actual_vector;
actual_vector = NULL;
vector = NULL;
delete [] memory_handlers;
memory_handlers = NULL;
}
else {
BX_DEBUG(("(%u) memory not freed as it wasn't allocated!", BX_SIM_ID));
}
}
2004-10-21 22:20:40 +04:00
void BX_MEM_C::init_memory(int memsize)
{
int idx;
BX_DEBUG(("Init $Id: misc_mem.cc,v 1.66 2005-10-28 06:33:53 vruppert Exp $"));
// you can pass 0 if memory has been allocated already through
// the constructor, or the desired size of memory if it hasn't
// BX_INFO(("%.2fMB", (float)(BX_MEM_THIS megabytes) ));
if (BX_MEM_THIS vector == NULL) {
// memory not already allocated, do now...
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 *[1024 * 1024];
BX_MEM_THIS rom = &BX_MEM_THIS vector[memsize];
BX_MEM_THIS bogus = &BX_MEM_THIS vector[memsize + BIOSROMSZ + EXROMSIZE];
memset(BX_MEM_THIS rom, 0xff, BIOSROMSZ + EXROMSIZE);
memset(BX_MEM_THIS bogus, 0xff, 4096);
for (idx = 0; idx < 1024 * 1024; idx++)
BX_MEM_THIS memory_handlers[idx] = NULL;
for (idx = 0; idx < 65; idx++)
BX_MEM_THIS rom_present[idx] = 0;
BX_INFO(("%.2fMB", (float)(BX_MEM_THIS megabytes) ));
}
#if BX_DEBUGGER
if (megabytes > BX_MAX_DIRTY_PAGE_TABLE_MEGS) {
BX_INFO(("Error: memory larger than dirty page table can handle"));
BX_PANIC(("Error: increase BX_MAX_DIRTY_PAGE_TABLE_MEGS"));
}
#endif
}
2004-10-21 22:20:40 +04:00
//
// Values for type:
// 0 : System Bios
// 1 : VGA Bios
// 2 : Optional ROM Bios
//
2004-10-21 22:20:40 +04:00
void BX_MEM_C::load_ROM(const char *path, Bit32u romaddress, Bit8u type)
{
struct stat stat_buf;
int fd, ret, i, start_idx, end_idx;
unsigned long size, max_size, offset;
if (*path == '\0') {
if (type == 2) {
BX_PANIC(( "ROM: Optional ROM image undefined"));
}
else if (type == 1) {
BX_PANIC(( "ROM: VGA BIOS image undefined"));
}
else {
BX_PANIC(( "ROM: System BIOS image undefined"));
}
return;
}
// read in ROM BIOS image file
fd = open(path, O_RDONLY
#ifdef O_BINARY
| O_BINARY
#endif
);
if (fd < 0) {
if (type < 2) {
BX_PANIC(( "ROM: couldn't open ROM image file '%s'.", path));
}
else {
BX_ERROR(( "ROM: couldn't open ROM image file '%s'.", path));
}
return;
}
ret = fstat(fd, &stat_buf);
if (ret) {
if (type < 2) {
BX_PANIC(( "ROM: couldn't stat ROM image file '%s'.", path));
}
else {
BX_ERROR(( "ROM: couldn't stat ROM image file '%s'.", path));
}
return;
}
2005-06-07 23:26:21 +04:00
size = (unsigned long)stat_buf.st_size;
if (type > 0) {
max_size = 0x10000;
} else {
max_size = BIOSROMSZ;
}
if (size > max_size) {
close(fd);
BX_PANIC(("ROM: ROM image too large"));
return;
}
if (type == 0) {
if ( (romaddress + size) != 0x100000 && (romaddress + size) ) {
close(fd);
BX_PANIC(("ROM: System BIOS must end at 0xfffff"));
return;
}
offset = romaddress & BIOS_MASK;
if (romaddress < 0xf0000 ) {
BX_MEM_THIS rom_present[64] = 1;
}
} else {
if ((size % 512) != 0) {
close(fd);
BX_PANIC(("ROM: ROM image size must be multiple of 512 (size = %ld)", size));
return;
}
if ((romaddress % 2048) != 0) {
close(fd);
BX_PANIC(("ROM: ROM image must start at a 2k boundary"));
return;
}
if ((romaddress < 0xc0000) ||
(((romaddress + size) > 0xdffff) && (romaddress != 0xe0000))) {
close(fd);
BX_PANIC(("ROM: ROM address space out of range"));
return;
}
start_idx = ((romaddress - 0xc0000) >> 11);
end_idx = start_idx + (size >> 11) + (((size % 2048) > 0) ? 1 : 0);
if (romaddress < 0xe0000) {
offset = (romaddress & EXROM_MASK) + BIOSROMSZ;
} else {
offset = romaddress & BIOS_MASK;
}
for (i = start_idx; i < end_idx; i++) {
if (BX_MEM_THIS rom_present[i]) {
close(fd);
BX_PANIC(("ROM: address space 0x%x already in use", (i * 2048) + 0xc0000));
return;
} else {
BX_MEM_THIS rom_present[i] = 1;
}
}
}
while (size > 0) {
ret = read(fd, (bx_ptr_t) &BX_MEM_THIS rom[offset], size);
if (ret <= 0) {
BX_PANIC(( "ROM: read failed on BIOS image: '%s'",path));
}
size -= ret;
offset += ret;
}
close(fd);
offset -= stat_buf.st_size;
if ((romaddress != 0xe0000) || ((rom[offset] == 0x55) && (rom[offset] == 0xaa))) {
Bit8u checksum = 0;
for (i = 0; i < stat_buf.st_size; i++) {
checksum += BX_MEM_THIS rom[offset + i];
}
if (checksum != 0) {
if (type == 1) {
BX_PANIC(( "ROM: checksum error in VGABIOS image: '%s'", path));
} else {
BX_ERROR(( "ROM: checksum error in BIOS image: '%s'", path));
}
}
}
2001-08-31 20:06:32 +04:00
BX_INFO(("rom at 0x%05x/%u ('%s')",
(unsigned) romaddress,
(unsigned) stat_buf.st_size,
path));
}
void BX_MEM_C::load_RAM(const char *path, Bit32u ramaddress, Bit8u type)
{
struct stat stat_buf;
int fd, ret;
unsigned long size, offset;
if (*path == '\0') {
BX_PANIC(( "RAM: Optional RAM image undefined"));
return;
}
// read in RAM BIOS image file
fd = open(path, O_RDONLY
#ifdef O_BINARY
| O_BINARY
#endif
);
if (fd < 0) {
BX_PANIC(( "RAM: couldn't open RAM image file '%s'.", path));
return;
}
ret = fstat(fd, &stat_buf);
if (ret) {
BX_PANIC(( "RAM: couldn't stat RAM image file '%s'.", path));
return;
}
size = (unsigned long)stat_buf.st_size;
offset = ramaddress;
while (size > 0) {
ret = read(fd, (bx_ptr_t) &BX_MEM_THIS vector[offset], size);
if (ret <= 0) {
BX_PANIC(( "RAM: read failed on RAM image: '%s'",path));
}
size -= ret;
offset += ret;
}
close(fd);
BX_INFO(("ram at 0x%05x/%u ('%s')",
(unsigned) ramaddress,
(unsigned) stat_buf.st_size,
path));
}
#endif // #if BX_PROVIDE_CPU_MEMORY
#if ( BX_DEBUGGER || BX_DISASM || BX_GDBSTUB)
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
bx_bool
BX_MEM_C::dbg_fetch_mem(Bit32u addr, unsigned len, Bit8u *buf)
{
bx_bool ret = 1;
for (; len>0; len--) {
if ( (addr & 0xfffe0000) == 0x000a0000 )
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
*buf = DEV_vga_mem_read(addr);
#if BX_SUPPORT_PCI
else if ( bx_options.Oi440FXSupport->get () &&
((addr & 0xfffc0000) == 0x000c0000) )
{
switch (DEV_pci_rd_memtype (addr)) {
case 0x0: // Read from ROM
if ( (addr & 0xfffe0000) == 0x000e0000 )
{
*buf = rom[addr & BIOS_MASK];
}
else
{
*buf = rom[(addr & EXROM_MASK) + BIOSROMSZ];
}
break;
case 0x1: // Read from ShadowRAM
*buf = vector[addr];
break;
default:
BX_PANIC(("dbg_fetch_mem: default case"));
}
}
#endif // #if BX_SUPPORT_PCI
else if (addr < BX_MEM_THIS len)
{
if ( (addr & 0xfffc0000) != 0x000c0000 ) {
*buf = vector[addr];
}
else if ( (addr & 0xfffe0000) == 0x000e0000 )
{
*buf = rom[addr & BIOS_MASK];
}
else
{
*buf = rom[(addr & EXROM_MASK) + BIOSROMSZ];
}
}
else if (addr >= ~BIOS_MASK)
{
*buf = rom[addr & BIOS_MASK];
}
else
{
*buf = 0xff;
ret = 0; // error, beyond limits of memory
}
buf++;
addr++;
}
return ret;
}
#endif
#if BX_DEBUGGER || BX_GDBSTUB
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
bx_bool
BX_MEM_C::dbg_set_mem(Bit32u addr, unsigned len, Bit8u *buf)
{
if ( (addr + len) > this->len ) {
return(0); // error, beyond limits of memory
}
for (; len>0; len--) {
if ( (addr & 0xfffe0000) == 0x000a0000 )
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
DEV_vga_mem_write(addr, *buf);
#if BX_SUPPORT_PCI
else if ( bx_options.Oi440FXSupport->get () &&
((addr & 0xfffc0000) == 0x000c0000) )
{
switch (DEV_pci_wr_memtype (addr)) {
case 0x0: // Ignore write to ROM
break;
case 0x1: // Write to ShadowRAM
vector[addr] = *buf;
break;
default:
BX_PANIC(("dbg_fetch_mem: default case"));
}
}
#endif // #if BX_SUPPORT_PCI
else if ( (addr & 0xfffc0000) != 0x000c0000 && (addr < ~BIOS_MASK) )
{
vector[addr] = *buf;
}
buf++;
addr++;
}
return(1);
}
#endif
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
bx_bool
BX_MEM_C::dbg_crc32(unsigned long (*f)(unsigned char *buf, int len),
Bit32u addr1, Bit32u addr2, Bit32u *crc)
{
unsigned len;
*crc = 0;
if (addr1 > addr2)
return(0);
if (addr2 >= this->len) {
return(0); // error, specified address past last phy mem addr
}
len = 1 + addr2 - addr1;
*crc = f(vector + addr1, len);
return(1);
}
//
// Return a host address corresponding to the guest physical memory
// address (with A20 already applied), given that the calling
// code will perform an 'op' operation. This address will be
// used for direct access to guest memory as an acceleration by
// a few instructions, like REP {MOV, INS, OUTS, etc}.
// Values of 'op' are { BX_READ, BX_WRITE, BX_RW }.
//
// The other assumption is that the calling code _only_ accesses memory
// directly within the page that encompasses the address requested.
//
Bit8u * BX_CPP_AttrRegparmN(3)
BX_MEM_C::getHostMemAddr(BX_CPU_C *cpu, Bit32u a20Addr, unsigned op)
{
2004-10-21 22:20:40 +04:00
#if BX_SUPPORT_APIC
bx_generic_apic_c *local_apic = &cpu->local_apic;
if (local_apic->get_base () == (a20Addr & ~0xfff))
return(NULL); // Vetoed! APIC address space
bx_generic_apic_c *ioapic = bx_devices.ioapic;
if (ioapic->get_base () == (a20Addr & ~0xfff))
return(NULL); // Vetoed! IOAPIC address space
#endif
struct memory_handler_struct *memory_handler = memory_handlers[a20Addr >> 20];
while (memory_handler) {
if (memory_handler->begin <= a20Addr &&
memory_handler->end >= a20Addr) {
return(NULL); // Vetoed! memory handler for vram, mmio and PCI PnP
}
memory_handler = memory_handler->next;
}
if (op == BX_READ) {
if ( (a20Addr & 0xfffe0000) == 0x000a0000 )
return(NULL); // Vetoed! Mem mapped IO (VGA)
#if BX_SUPPORT_PCI
else if ( bx_options.Oi440FXSupport->get () &&
((a20Addr & 0xfffc0000) == 0x000c0000) )
{
switch (DEV_pci_rd_memtype (a20Addr)) {
case 0x0: // Read from ROM
if ( (a20Addr & 0xfffe0000) == 0x000e0000 )
{
return( (Bit8u *) & rom[a20Addr & BIOS_MASK]);
}
else
{
return( (Bit8u *) & rom[(a20Addr & EXROM_MASK) + BIOSROMSZ]);
}
break;
case 0x1: // Read from ShadowRAM
return( (Bit8u *) & vector[a20Addr]);
default:
BX_PANIC(("getHostMemAddr(): default case"));
return(0);
}
}
#endif
else if (a20Addr < BX_MEM_THIS len)
{
if ( (a20Addr & 0xfffc0000) != 0x000c0000 ) {
return( (Bit8u *) & vector[a20Addr]);
}
else if ( (a20Addr & 0xfffe0000) == 0x000e0000 )
{
return( (Bit8u *) & rom[a20Addr & BIOS_MASK]);
}
else
{
return( (Bit8u *) & rom[(a20Addr & EXROM_MASK) + BIOSROMSZ]);
}
}
else if (a20Addr >= (Bit32u)~BIOS_MASK)
{
return( (Bit8u *) & rom[a20Addr & BIOS_MASK]);
}
else
{
// Error, requested addr is out of bounds.
return( (Bit8u *) & bogus[a20Addr & 0x0fff]);
}
}
else
{ // op == {BX_WRITE, BX_RW}
Bit8u *retAddr;
if ( a20Addr >= BX_MEM_THIS len )
return(NULL); // Error, requested addr is out of bounds.
else if ( (a20Addr & 0xfffe0000) == 0x000a0000 )
return(NULL); // Vetoed! Mem mapped IO (VGA)
else if (a20Addr >= (Bit32u)~BIOS_MASK)
return(NULL); // Vetoed! ROMs
#if BX_SUPPORT_PCI
else if ( bx_options.Oi440FXSupport->get () &&
((a20Addr & 0xfffc0000) == 0x000c0000) )
{
switch (DEV_pci_wr_memtype (a20Addr)) {
case 0x0: // Vetoed! ROMs
return(NULL);
case 0x1: // Write to ShadowRAM
retAddr = (Bit8u *) & vector[a20Addr];
break;
default:
BX_PANIC(("getHostMemAddr(): default case"));
return(0);
}
2004-10-21 22:20:40 +04:00
}
#endif
else
{
if ( (a20Addr & 0xfffc0000) != 0x000c0000 ) {
retAddr = (Bit8u *) & vector[a20Addr];
}
else
{
return(NULL); // Vetoed! ROMs
}
}
#if BX_SUPPORT_ICACHE
pageWriteStampTable.decWriteStamp(a20Addr);
#endif
return(retAddr);
}
}
/*
* One needs to provide both a read_handler and a write_handler.
* XXX: maybe we should check for overlapping memory handlers
*/
bx_bool
BX_MEM_C::registerMemoryHandlers(memory_handler_t read_handler, void *read_param,
memory_handler_t write_handler, void *write_param,
unsigned long begin_addr, unsigned long end_addr)
{
if (end_addr < begin_addr)
return false;
if (!read_handler)
return false;
if (!write_handler)
return false;
for (unsigned page_idx = begin_addr >> 20; page_idx <= end_addr >> 20; page_idx++) {
struct memory_handler_struct *memory_handler = new struct memory_handler_struct;
memory_handler->next = memory_handlers[page_idx];
memory_handlers[page_idx] = memory_handler;
memory_handler->read_handler = read_handler;
memory_handler->write_handler = write_handler;
memory_handler->read_param = read_param;
memory_handler->write_param = write_param;
memory_handler->begin = begin_addr;
memory_handler->end = end_addr;
}
return true;
}
bx_bool
BX_MEM_C::unregisterMemoryHandlers(memory_handler_t read_handler, memory_handler_t write_handler,
unsigned long begin_addr, unsigned long end_addr)
{
bx_bool ret = true;
for (unsigned page_idx = begin_addr >> 20; page_idx <= end_addr >> 20; page_idx++) {
struct memory_handler_struct *memory_handler = memory_handlers[page_idx];
struct memory_handler_struct *prev = NULL;
while (memory_handler &&
memory_handler->read_handler != read_handler &&
memory_handler->write_handler != write_handler &&
memory_handler->begin != begin_addr &&
memory_handler->end != end_addr) {
prev = memory_handler;
memory_handler = memory_handler->next;
}
if (!memory_handler) {
ret = false; // we should have found it
continue; // anyway, try the other pages
}
if (prev)
prev->next = memory_handler->next;
else
memory_handlers[page_idx] = memory_handler->next;
delete memory_handler;
}
return ret;
}