From 4d6a88ec94253e976f63320041c7e76de7e9d346 Mon Sep 17 00:00:00 2001 From: Volker Ruppert Date: Tue, 8 Dec 2020 19:52:39 +0000 Subject: [PATCH] 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. --- bochs/bx_debug/dbg_main.cc | 4 +- bochs/gdbstub.cc | 4 +- bochs/gui/enh_dbg.cc | 4 +- bochs/memory/memory-bochs.h | 2 +- bochs/memory/misc_mem.cc | 132 +++++++++++++++++++++++++----------- bochs/plugin.h | 2 - 6 files changed, 100 insertions(+), 48 deletions(-) diff --git a/bochs/bx_debug/dbg_main.cc b/bochs/bx_debug/dbg_main.cc index 532b0b4a5..3361e0ce7 100644 --- a/bochs/bx_debug/dbg_main.cc +++ b/bochs/bx_debug/dbg_main.cc @@ -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"); } } diff --git a/bochs/gdbstub.cc b/bochs/gdbstub.cc index 29dbe1fe4..fd311e5e0 100644 --- a/bochs/gdbstub.cc +++ b/bochs/gdbstub.cc @@ -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); } diff --git a/bochs/gui/enh_dbg.cc b/bochs/gui/enh_dbg.cc index df4f9a165..da7c5829b 100644 --- a/bochs/gui/enh_dbg.cc +++ b/bochs/gui/enh_dbg.cc @@ -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 diff --git a/bochs/memory/memory-bochs.h b/bochs/memory/memory-bochs.h index 3ac1c9a73..c19eeb689 100644 --- a/bochs/memory/memory-bochs.h +++ b/bochs/memory/memory-bochs.h @@ -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 diff --git a/bochs/memory/misc_mem.cc b/bochs/memory/misc_mem.cc index eb58af7db..f2fe0f98e 100644 --- a/bochs/memory/misc_mem.cc +++ b/bochs/memory/misc_mem.cc @@ -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); } diff --git a/bochs/plugin.h b/bochs/plugin.h index a18794db0..308bd5c47 100644 --- a/bochs/plugin.h +++ b/bochs/plugin.h @@ -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) \