Fixed dbg_fetch_mem() and dbg_set_mem() similar to other memory access methods.

- Always apply the A20 setting to the requested address.
- Fixed the conditions for SMRAM access.
- Added support for memory handlers and removed direct VGA memory access.
- Added support for reading from BIOS flash memory.
This commit is contained in:
Volker Ruppert 2020-12-08 19:52:39 +00:00
parent 4e23b04d15
commit 4d6a88ec94
6 changed files with 100 additions and 48 deletions

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2019 The Bochs Project
// Copyright (C) 2001-2020 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -2716,7 +2716,7 @@ void bx_dbg_setpmem_command(bx_phy_address paddr, unsigned len, Bit32u val)
return;
}
if (! BX_MEM(0)->dbg_set_mem(paddr, len, buf)) {
if (! BX_MEM(0)->dbg_set_mem(BX_CPU(dbg_cpu), paddr, len, buf)) {
dbg_printf("Error: setpmem: could not set memory, out of physical bounds?\n");
}
}

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2017 The Bochs Project Team
// Copyright (C) 2002-2020 The Bochs Project Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -420,7 +420,7 @@ static int access_linear(Bit64u laddress,
if (!valid) return(0);
if (rw & 1) {
valid = BX_MEM(0)->dbg_set_mem(phys, len, data);
valid = BX_MEM(0)->dbg_set_mem(BX_CPU(0), phys, len, data);
} else {
valid = BX_MEM(0)->dbg_fetch_mem(BX_CPU(0), phys, len, data);
}

View File

@ -8,7 +8,7 @@
//
// Modified by Bruce Ewing
//
// Copyright (C) 2008-2019 The Bochs Project
// Copyright (C) 2008-2020 The Bochs Project
#include "config.h"
@ -2786,7 +2786,7 @@ void SetMemLine(int L)
{
// convert the hex to a byte, and try to store the byte in bochs physmem
sscanf (s,"%2X", (unsigned int*)&newval);
if (bx_mem.dbg_set_mem( (bx_phy_address) h, 1, &newval) == FALSE)
if (bx_mem.dbg_set_mem(BX_CPU(CurrentCPU), (bx_phy_address) h, 1, &newval) == FALSE)
err = 2;
else
*u++ = newval; // update DataDump array so it will refresh on the screen

View File

@ -151,7 +151,7 @@ public:
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_set_mem(BX_CPU_C *cpu, 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

View File

@ -578,57 +578,86 @@ void BX_MEM_C::load_RAM(const char *path, bx_phy_address ramaddress)
#if (BX_DEBUGGER || BX_DISASM || BX_GDBSTUB)
bx_bool BX_MEM_C::dbg_fetch_mem(BX_CPU_C *cpu, bx_phy_address addr, unsigned len, Bit8u *buf)
{
bx_bool ret = 1;
bx_phy_address a20addr = A20ADDR(addr);
struct memory_handler_struct *memory_handler = NULL;
bx_bool ret = 1, use_memory_handler = 0, use_smram = 0;
bx_bool is_bios = (a20addr >= (bx_phy_address)BX_MEM_THIS bios_rom_addr);
#if BX_PHY_ADDRESS_LONG
if (a20addr > BX_CONST64(0xffffffff)) is_bios = 0;
#endif
if ((a20addr >= 0x000a0000 && a20addr < 0x000c0000) && BX_MEM_THIS smram_available)
{
// SMRAM memory space
if (BX_MEM_THIS smram_enable || (cpu->smm_mode() && !BX_MEM_THIS smram_restricted))
use_smram = 1;
}
memory_handler = BX_MEM_THIS memory_handlers[a20addr >> 20];
while (memory_handler) {
if (memory_handler->begin <= a20addr && memory_handler->end >= a20addr)
{
if (!use_smram) {
use_memory_handler = 1;
break;
}
}
memory_handler = memory_handler->next;
}
for (; len>0; len--) {
// Reading standard PCI/ISA Video Mem / SMMRAM
if (addr >= 0x000a0000 && addr < 0x000c0000) {
if (BX_MEM_THIS smram_enable || cpu->smm_mode())
*buf = *(BX_MEM_THIS get_vector(addr));
else
*buf = DEV_vga_mem_read(addr);
if (use_memory_handler) {
memory_handler->read_handler(a20addr, 1, buf, memory_handler->param);
}
#if BX_SUPPORT_PCI
else if (BX_MEM_THIS pci_enabled && (addr >= 0x000c0000 && addr < 0x00100000)) {
unsigned area = (unsigned)(addr >> 14) & 0x0f;
else if (BX_MEM_THIS pci_enabled && (a20addr >= 0x000c0000 && a20addr < 0x00100000)) {
unsigned area = (unsigned)(a20addr >> 14) & 0x0f;
if (area > BX_MEM_AREA_F0000) area = BX_MEM_AREA_F0000;
if (BX_MEM_THIS memory_type[area][0] == 0) {
// Read from ROM
if ((addr & 0xfffe0000) == 0x000e0000) {
if ((a20addr & 0xfffe0000) == 0x000e0000) {
// last 128K of BIOS ROM mapped to 0xE0000-0xFFFFF
*buf = BX_MEM_THIS rom[BIOS_MAP_LAST128K(addr)];
if (BX_MEM_THIS flash_type > 0) {
*buf = BX_MEM_THIS flash_read(BIOS_MAP_LAST128K(a20addr));
} else {
*buf = BX_MEM_THIS rom[BIOS_MAP_LAST128K(a20addr)];
}
} else {
*buf = BX_MEM_THIS rom[(addr & EXROM_MASK) + BIOSROMSZ];
*buf = BX_MEM_THIS rom[(a20addr & EXROM_MASK) + BIOSROMSZ];
}
} else {
// Read from ShadowRAM
*buf = *(BX_MEM_THIS get_vector(addr));
*buf = *(BX_MEM_THIS get_vector(a20addr));
}
}
#endif // #if BX_SUPPORT_PCI
else if (addr < BX_MEM_THIS len)
else if ((a20addr < BX_MEM_THIS len) && !is_bios)
{
if (addr < 0x000c0000 || addr >= 0x00100000) {
*buf = *(BX_MEM_THIS get_vector(addr));
if (a20addr < 0x000c0000 || a20addr >= 0x00100000) {
*buf = *(BX_MEM_THIS get_vector(a20addr));
}
// must be in C0000 - FFFFF range
else if ((addr & 0xfffe0000) == 0x000e0000) {
else if ((a20addr & 0xfffe0000) == 0x000e0000) {
// last 128K of BIOS ROM mapped to 0xE0000-0xFFFFF
*buf = BX_MEM_THIS rom[BIOS_MAP_LAST128K(addr)];
}
else {
*buf = BX_MEM_THIS rom[(addr & EXROM_MASK) + BIOSROMSZ];
*buf = BX_MEM_THIS rom[BIOS_MAP_LAST128K(a20addr)];
} else {
*buf = BX_MEM_THIS rom[(a20addr & EXROM_MASK) + BIOSROMSZ];
}
}
#if BX_PHY_ADDRESS_LONG
else if (addr > BX_CONST64(0xffffffff)) {
else if (a20addr > BX_CONST64(0xffffffff)) {
*buf = 0xff;
ret = 0; // error, beyond limits of memory
}
#endif
else if (addr >= (bx_phy_address)BX_MEM_THIS bios_rom_addr)
else if (is_bios)
{
*buf = BX_MEM_THIS rom[addr & BIOS_MASK];
if (BX_MEM_THIS flash_type > 0) {
*buf = BX_MEM_THIS flash_read(a20addr & BIOS_MASK);
} else {
*buf = BX_MEM_THIS rom[a20addr & BIOS_MASK];
}
}
else
{
@ -636,44 +665,69 @@ bx_bool BX_MEM_C::dbg_fetch_mem(BX_CPU_C *cpu, bx_phy_address addr, unsigned len
ret = 0; // error, beyond limits of memory
}
buf++;
addr++;
a20addr++;
}
return ret;
}
#endif
#if BX_DEBUGGER || BX_GDBSTUB
bx_bool BX_MEM_C::dbg_set_mem(bx_phy_address addr, unsigned len, Bit8u *buf)
bx_bool BX_MEM_C::dbg_set_mem(BX_CPU_C *cpu, bx_phy_address addr, unsigned len, Bit8u *buf)
{
if ((addr + len - 1) > BX_MEM_THIS len) {
bx_phy_address a20addr = A20ADDR(addr);
struct memory_handler_struct *memory_handler = NULL;
bx_bool use_memory_handler = 0, use_smram = 0;
if ((a20addr + len - 1) > BX_MEM_THIS len) {
return(0); // error, beyond limits of memory
}
bx_bool is_bios = (a20addr >= (bx_phy_address)BX_MEM_THIS bios_rom_addr);
#if BX_PHY_ADDRESS_LONG
if (a20addr > BX_CONST64(0xffffffff)) is_bios = 0;
#endif
if ((a20addr >= 0x000a0000 && a20addr < 0x000c0000) && BX_MEM_THIS smram_available)
{
// SMRAM memory space
if (BX_MEM_THIS smram_enable || (cpu->smm_mode() && !BX_MEM_THIS smram_restricted))
use_smram = 1;
}
memory_handler = BX_MEM_THIS memory_handlers[a20addr >> 20];
while (memory_handler) {
if (memory_handler->begin <= a20addr && memory_handler->end >= a20addr)
{
if (!use_smram) {
use_memory_handler = 1;
break;
}
}
memory_handler = memory_handler->next;
}
for (; len>0; len--) {
// Write to standard PCI/ISA Video Mem / SMMRAM
if (addr >= 0x000a0000 && addr < 0x000c0000) {
if (BX_MEM_THIS smram_enable)
*(BX_MEM_THIS get_vector(addr)) = *buf;
else
DEV_vga_mem_write(addr, *buf);
if (use_memory_handler) {
memory_handler->write_handler(a20addr, 1, buf, memory_handler->param);
}
#if BX_SUPPORT_PCI
else if (BX_MEM_THIS pci_enabled && (addr >= 0x000c0000 && addr < 0x00100000)) {
unsigned area = (unsigned)(addr >> 14) & 0x0f;
else if (BX_MEM_THIS pci_enabled && (a20addr >= 0x000c0000 && a20addr < 0x00100000)) {
unsigned area = (unsigned)(a20addr >> 14) & 0x0f;
if (area > BX_MEM_AREA_F0000) area = BX_MEM_AREA_F0000;
if (BX_MEM_THIS memory_type[area][1] == 1) {
// Write to ShadowRAM
*(BX_MEM_THIS get_vector(addr)) = *buf;
*(BX_MEM_THIS get_vector(a20addr)) = *buf;
} else {
// Ignore write to ROM
}
}
#endif // #if BX_SUPPORT_PCI
else if ((addr < 0x000c0000 || addr >= 0x00100000) && (addr < (bx_phy_address)BX_MEM_THIS bios_rom_addr))
else if ((a20addr < 0x000c0000 || a20addr >= 0x00100000) && !is_bios)
{
*(BX_MEM_THIS get_vector(addr)) = *buf;
*(BX_MEM_THIS get_vector(a20addr)) = *buf;
}
buf++;
addr++;
a20addr++;
}
return(1);
}

View File

@ -226,8 +226,6 @@ extern "C" {
#define DEV_pic_iac() (bx_devices.pluginPicDevice->IAC())
///////// VGA macros
#define DEV_vga_mem_read(addr) (bx_devices.pluginVgaDevice->mem_read(addr))
#define DEV_vga_mem_write(addr, val) (bx_devices.pluginVgaDevice->mem_write(addr, val))
#define DEV_vga_redraw_area(left, top, right, bottom) \
(bx_devices.pluginVgaDevice->vga_redraw_area(left, top, right, bottom))
#define DEV_vga_get_text_snapshot(rawsnap, height, width) \