Some BIOS ROM related changes in the memory code.

- Store BIOS ROM start address and use it instead of hardcoded BIOS_MASK.
- Added stub for BIOS ROM access switches.
- Verify checksum of legacy Bochs BIOS, too.
This commit is contained in:
Volker Ruppert 2020-11-01 16:13:38 +00:00
parent 2293308afe
commit b91f907a1c
5 changed files with 39 additions and 16 deletions

View File

@ -385,6 +385,8 @@ void bx_piix3_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
if ((value8 & 0xc0) != (oldval & 0xc0)) {
BX_ERROR(("BIOS enable switches not supported (lower=%d / extended=%d)",
(value8 >> 6) & 1, (value8 >> 7) & 1));
DEV_mem_set_bios_rom_access(BIOS_ROM_LOWER, (value8 >> 6) & 1);
DEV_mem_set_bios_rom_access(BIOS_ROM_EXTENDED, (value8 >> 7) & 1);
}
BX_P2I_THIS pci_conf[address+i] = value8;
break;
@ -399,6 +401,7 @@ void bx_piix3_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
if ((value8 & 0x02) != (oldval & 0x02)) {
BX_ERROR(("1-meg extended BIOS enable switch not supported (value=%d)",
(value8 >> 1) & 1));
DEV_mem_set_bios_rom_access(BIOS_ROM_1MEG, (value8 >> 1) & 1);
}
}
break;

View File

@ -44,6 +44,10 @@ class BX_CPU_C;
#define BIOS_MAP_LAST128K(addr) (((addr) | 0xfff00000) & BIOS_MASK)
#define BIOS_ROM_LOWER 0x01
#define BIOS_ROM_EXTENDED 0x02
#define BIOS_ROM_1MEG 0x04
enum memory_area_t {
BX_MEM_AREA_C0000 = 0,
BX_MEM_AREA_C4000,
@ -96,6 +100,8 @@ private:
Bit8u *bogus; // 4k for unexisting memory
bx_bool rom_present[65];
bx_bool memory_type[13][2];
Bit32u bios_rom_addr;
Bit8u bios_rom_access;
Bit32u used_blocks;
#if BX_LARGE_RAMFILE
@ -121,6 +127,7 @@ public:
BX_MEM_SMF bx_bool is_smram_accessible(void);
BX_MEM_SMF void set_bios_write(bx_bool enabled);
BX_MEM_SMF void set_bios_rom_access(Bit8u region, bx_bool enabled);
BX_MEM_SMF void set_memory_type(memory_area_t area, bx_bool rw, bx_bool dram);
BX_MEM_SMF Bit8u* getHostMemAddr(BX_CPU_C *cpu, bx_phy_address addr, unsigned rw);

View File

@ -51,7 +51,7 @@ void BX_MEM_C::writePhysicalPage(BX_CPU_C *cpu, bx_phy_address addr, unsigned le
BX_MEM_THIS check_monitor(a20addr, len);
#endif
bx_bool is_bios = (a20addr >= (bx_phy_address)~BIOS_MASK);
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
@ -85,7 +85,7 @@ void BX_MEM_C::writePhysicalPage(BX_CPU_C *cpu, bx_phy_address addr, unsigned le
mem_write:
// all memory access fits in single 4K page
if (a20addr < BX_MEM_THIS len && ! is_bios) {
if ((a20addr < BX_MEM_THIS len) && !is_bios) {
// all of data is within limits of physical memory
if (a20addr < 0x000a0000 || a20addr >= 0x00100000)
{
@ -210,7 +210,7 @@ inc_one:
#endif
}
} else if (BX_MEM_THIS bios_write_enabled && (a20addr >= (bx_phy_address)~BIOS_MASK)) {
} else if (BX_MEM_THIS bios_write_enabled && is_bios) {
// volatile BIOS write support
#ifdef BX_LITTLE_ENDIAN
data_ptr = (Bit8u *) data;
@ -247,7 +247,7 @@ void BX_MEM_C::readPhysicalPage(BX_CPU_C *cpu, bx_phy_address addr, unsigned len
BX_PANIC(("readPhysicalPage: cross page access at address 0x" FMT_PHY_ADDRX ", len=%d", addr, len));
}
bx_bool is_bios = (a20addr >= (bx_phy_address)~BIOS_MASK);
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
@ -278,7 +278,7 @@ void BX_MEM_C::readPhysicalPage(BX_CPU_C *cpu, bx_phy_address addr, unsigned len
mem_read:
if (a20addr < BX_MEM_THIS len && ! is_bios) {
if ((a20addr < BX_MEM_THIS len) && !is_bios) {
// all of data is within limits of physical memory
if (a20addr < 0x000a0000 || a20addr >= 0x00100000)
{
@ -405,7 +405,7 @@ inc_one:
data_ptr = (Bit8u *) data + (len - 1);
#endif
if (a20addr >= (bx_phy_address)~BIOS_MASK) {
if (is_bios) {
for (unsigned i = 0; i < len; i++) {
if (BX_MEM_THIS pci_enabled) {
*data_ptr = BX_MEM_THIS flash_read(a20addr & BIOS_MASK);
@ -419,8 +419,8 @@ inc_one:
data_ptr--;
#endif
}
}
else {
} else {
// bogus memory
memset(data, 0xFF, len);
}
}

View File

@ -148,6 +148,7 @@ void BX_MEM_C::init_memory(Bit64u guest, Bit64u host)
BX_MEM_THIS memory_type[i][0] = 0;
BX_MEM_THIS memory_type[i][1] = 0;
}
BX_MEM_THIS bios_rom_addr = 0xffff0000;
BX_MEM_THIS register_state();
}
@ -435,7 +436,9 @@ void BX_MEM_C::load_ROM(const char *path, bx_phy_address romaddress, Bit8u type)
if ((romaddress & 0xf0000) < 0xf0000) {
BX_MEM_THIS rom_present[64] = 1;
}
is_bochs_bios = (strstr(path, "BIOS-bochs-latest") != NULL);
BX_MEM_THIS bios_rom_addr = romaddress;
is_bochs_bios = ((strstr(path, "BIOS-bochs-latest") != NULL) ||
(strstr(path, "BIOS-bochs-legacy") != NULL));
} else {
if ((size % 512) != 0) {
close(fd);
@ -598,7 +601,7 @@ 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
}
#endif
else if (addr >= (bx_phy_address)~BIOS_MASK)
else if (addr >= (bx_phy_address)BX_MEM_THIS bios_rom_addr)
{
*buf = BX_MEM_THIS rom[addr & BIOS_MASK];
}
@ -640,7 +643,7 @@ bx_bool BX_MEM_C::dbg_set_mem(bx_phy_address addr, unsigned len, Bit8u *buf)
}
}
#endif // #if BX_SUPPORT_PCI
else if ((addr < 0x000c0000 || addr >= 0x00100000) && (addr < (bx_phy_address)(~BIOS_MASK)))
else if ((addr < 0x000c0000 || addr >= 0x00100000) && (addr < (bx_phy_address)BX_MEM_THIS bios_rom_addr))
{
*(BX_MEM_THIS get_vector(addr)) = *buf;
}
@ -700,7 +703,7 @@ Bit8u *BX_MEM_C::getHostMemAddr(BX_CPU_C *cpu, bx_phy_address addr, unsigned rw)
{
bx_phy_address a20addr = A20ADDR(addr);
bx_bool is_bios = (a20addr >= (bx_phy_address)~BIOS_MASK);
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
@ -757,7 +760,7 @@ Bit8u *BX_MEM_C::getHostMemAddr(BX_CPU_C *cpu, bx_phy_address addr, unsigned rw)
}
}
#endif
else if(a20addr < BX_MEM_THIS len && ! is_bios)
else if ((a20addr < BX_MEM_THIS len) && !is_bios)
{
if (a20addr < 0x000c0000 || a20addr >= 0x00100000) {
return BX_MEM_THIS get_vector(a20addr);
@ -777,7 +780,7 @@ Bit8u *BX_MEM_C::getHostMemAddr(BX_CPU_C *cpu, bx_phy_address addr, unsigned rw)
return (Bit8u *) &BX_MEM_THIS bogus[a20addr & 0xfff];
}
#endif
else if (a20addr >= (bx_phy_address)~BIOS_MASK)
else if (is_bios)
{
return (Bit8u *) &BX_MEM_THIS rom[a20addr & BIOS_MASK];
}
@ -789,7 +792,7 @@ Bit8u *BX_MEM_C::getHostMemAddr(BX_CPU_C *cpu, bx_phy_address addr, unsigned rw)
}
else
{ // op == {BX_WRITE, BX_RW}
if (a20addr >= BX_MEM_THIS len || is_bios)
if ((a20addr >= BX_MEM_THIS len) || is_bios)
return(NULL); // Error, requested addr is out of bounds.
else if (a20addr >= 0x000a0000 && a20addr < 0x000c0000)
return(NULL); // Vetoed! Mem mapped IO (VGA)
@ -927,6 +930,15 @@ void BX_MEM_C::set_bios_write(bx_bool enabled)
BX_MEM_THIS bios_write_enabled = enabled;
}
void BX_MEM_C::set_bios_rom_access(Bit8u region, bx_bool enabled)
{
if (enabled) {
BX_MEM_THIS bios_rom_access |= region;
} else {
BX_MEM_THIS bios_rom_access &= ~region;
}
}
Bit8u BX_MEM_C::flash_read(Bit32u addr)
{
// TODO

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2018 The Bochs Project
// Copyright (C) 2002-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
@ -266,6 +266,7 @@ extern "C" {
#define DEV_mem_set_memory_type(a,b,c) \
bx_devices.mem->set_memory_type((memory_area_t)a,b,c)
#define DEV_mem_set_bios_write(a) bx_devices.mem->set_bios_write(a)
#define DEV_mem_set_bios_rom_access(a,b) bx_devices.mem->set_bios_rom_access(a,b)
///////// USB device macro
#define DEV_usb_init_device(a,b,c,d) (usbdev_type)bx_usbdev_ctl.init_device(a,b,(void**)c,d)