Some changes related to the PCI ROM handling.

- Added support for setting memory write handler to NULL (ROM case).
- Added new PCI device method after_restore_pci_state(). It currently handles
  the PCI ROM case only (could be extended).
This commit is contained in:
Volker Ruppert 2017-10-08 15:54:21 +00:00
parent 610cec209d
commit 6dba96d10a
11 changed files with 28 additions and 78 deletions

View File

@ -1313,6 +1313,16 @@ void bx_pci_device_c::register_pci_state(bx_list_c *list)
new bx_shadow_data_c(list, "pci_conf", pci_conf, 256, 1);
}
void bx_pci_device_c::after_restore_pci_state(memory_handler_t mem_read_handler)
{
if (pci_rom_size > 0) {
if (DEV_pci_set_base_mem(this, mem_read_handler, NULL, &pci_rom_address,
&pci_conf[0x30], pci_rom_size)) {
BX_INFO(("new ROM address: 0x%08x", pci_rom_address));
}
}
}
void bx_pci_device_c::load_pci_rom(const char *path)
{
struct stat stat_buf;

View File

@ -408,6 +408,7 @@ void bx_svga_cirrus_c::after_restore_state(void)
{
#if BX_SUPPORT_PCI
if (BX_CIRRUS_THIS pci_enabled) {
bx_pci_device_c::after_restore_pci_state(cirrus_mem_read_handler);
if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
cirrus_mem_write_handler,
&BX_CIRRUS_THIS pci_base_address[0],
@ -422,13 +423,6 @@ void bx_svga_cirrus_c::after_restore_state(void)
CIRRUS_PNPMMIO_SIZE)) {
BX_INFO(("new pci_mmioaddr = 0x%08x", BX_CIRRUS_THIS pci_base_address[1]));
}
if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
cirrus_mem_write_handler,
&BX_CIRRUS_THIS pci_rom_address,
&BX_CIRRUS_THIS pci_conf[0x30],
BX_CIRRUS_THIS pci_rom_size)) {
BX_INFO(("new ROM address: 0x%08x", BX_CIRRUS_THIS pci_rom_address));
}
}
#endif
if ((BX_CIRRUS_THIS sequencer.reg[0x07] & 0x01) == CIRRUS_SR7_BPP_VGA) {
@ -2408,8 +2402,7 @@ void bx_svga_cirrus_c::pci_write_handler(Bit8u address, Bit32u value, unsigned i
}
}
if (romaddr_change) {
if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
cirrus_mem_write_handler,
if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler, NULL,
&BX_CIRRUS_THIS pci_rom_address,
&BX_CIRRUS_THIS pci_conf[0x30],
BX_CIRRUS_THIS pci_rom_size)) {

View File

@ -234,18 +234,13 @@ void bx_vga_c::after_restore_state(void)
bx_vgacore_c::after_restore_state();
#if BX_SUPPORT_PCI
if (BX_VGA_THIS pci_enabled) {
bx_pci_device_c::after_restore_pci_state(mem_read_handler);
if (BX_VGA_THIS vbe_present) {
if (BX_VGA_THIS vbe_set_base_addr(&BX_VGA_THIS pci_base_address[0],
&BX_VGA_THIS pci_conf[0x10])) {
BX_INFO(("new base address: 0x%08x", BX_VGA_THIS pci_base_address[0]));
}
}
if (DEV_pci_set_base_mem(this, mem_read_handler, mem_write_handler,
&BX_VGA_THIS pci_rom_address,
&BX_VGA_THIS pci_conf[0x30],
BX_VGA_THIS pci_rom_size)) {
BX_INFO(("new ROM address: 0x%08x", BX_VGA_THIS pci_rom_address));
}
}
#endif
if (BX_VGA_THIS vbe.enabled) {
@ -1360,7 +1355,7 @@ void bx_vga_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
}
}
if (romaddr_change) {
if (DEV_pci_set_base_mem(this, mem_read_handler, mem_write_handler,
if (DEV_pci_set_base_mem(this, mem_read_handler, NULL,
&BX_VGA_THIS pci_rom_address,
&BX_VGA_THIS pci_conf[0x30],
BX_VGA_THIS pci_rom_size)) {

View File

@ -99,6 +99,7 @@ public:
void init_pci_conf(Bit16u vid, Bit16u did, Bit8u rev, Bit32u classc, Bit8u headt);
void register_pci_state(bx_list_c *list);
void after_restore_pci_state(memory_handler_t mem_read_handler);
void load_pci_rom(const char *path);
protected:

View File

@ -595,6 +595,7 @@ void bx_e1000_c::register_state(void)
void bx_e1000_c::after_restore_state(void)
{
bx_pci_device_c::after_restore_pci_state(mem_read_handler);
if (DEV_pci_set_base_mem(BX_E1000_THIS_PTR, mem_read_handler, mem_write_handler,
&BX_E1000_THIS pci_base_address[0],
&BX_E1000_THIS pci_conf[0x10],
@ -607,15 +608,6 @@ void bx_e1000_c::after_restore_state(void)
64, &e1000_iomask[0], "e1000")) {
BX_INFO(("new i/o base address: 0x%04x", BX_E1000_THIS pci_base_address[1]));
}
if (BX_E1000_THIS pci_rom_size > 0) {
if (DEV_pci_set_base_mem(BX_E1000_THIS_PTR, mem_read_handler,
mem_write_handler,
&BX_E1000_THIS pci_rom_address,
&BX_E1000_THIS pci_conf[0x30],
BX_E1000_THIS pci_rom_size)) {
BX_INFO(("new ROM address: 0x%08x", BX_E1000_THIS pci_rom_address));
}
}
}
bx_bool bx_e1000_c::mem_read_handler(bx_phy_address addr, unsigned len,
@ -738,14 +730,6 @@ bx_bool bx_e1000_c::mem_write_handler(bx_phy_address addr, unsigned len,
Bit32u offset;
Bit16u index;
if (BX_E1000_THIS pci_rom_size > 0) {
Bit32u mask = (BX_E1000_THIS pci_rom_size - 1);
if ((addr & ~mask) == BX_E1000_THIS pci_rom_address) {
BX_INFO(("write to ROM ignored (addr=0x%08x len=%d)", (Bit32u)addr, len));
return 1;
}
}
offset = addr & 0x1ffff;
index = (offset >> 2);
if (len == 4) {
@ -1548,8 +1532,7 @@ void bx_e1000_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
}
}
if (romaddr_change) {
if (DEV_pci_set_base_mem(BX_E1000_THIS_PTR, mem_read_handler,
mem_write_handler,
if (DEV_pci_set_base_mem(BX_E1000_THIS_PTR, mem_read_handler, NULL,
&BX_E1000_THIS pci_rom_address,
&BX_E1000_THIS pci_conf[0x30],
BX_E1000_THIS pci_rom_size)) {

View File

@ -440,21 +440,13 @@ void bx_ne2k_c::register_state(void)
void bx_ne2k_c::after_restore_state(void)
{
if (BX_NE2K_THIS s.pci_enabled) {
bx_pci_device_c::after_restore_pci_state(mem_read_handler);
if (DEV_pci_set_base_io(BX_NE2K_THIS_PTR, read_handler, write_handler,
&BX_NE2K_THIS s.base_address,
&BX_NE2K_THIS pci_conf[0x10],
32, &ne2k_iomask[0], "NE2000 PCI NIC")) {
BX_INFO(("new base address: 0x%04x", BX_NE2K_THIS s.base_address));
}
if (BX_NE2K_THIS pci_rom_size > 0) {
if (DEV_pci_set_base_mem(BX_NE2K_THIS_PTR, mem_read_handler,
mem_write_handler,
&BX_NE2K_THIS pci_rom_address,
&BX_NE2K_THIS pci_conf[0x30],
BX_NE2K_THIS pci_rom_size)) {
BX_INFO(("new ROM address: 0x%08x", BX_NE2K_THIS pci_rom_address));
}
}
}
}
#endif
@ -1371,13 +1363,6 @@ bx_bool bx_ne2k_c::mem_read_handler(bx_phy_address addr, unsigned len,
}
return 1;
}
bx_bool bx_ne2k_c::mem_write_handler(bx_phy_address addr, unsigned len,
void *data, void *param)
{
BX_INFO(("write to ROM ignored (addr=0x%08x len=%d)", (Bit32u)addr, len));
return 1;
}
#endif
//
@ -1751,8 +1736,7 @@ void bx_ne2k_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
}
}
if (romaddr_change) {
if (DEV_pci_set_base_mem(BX_NE2K_THIS_PTR, mem_read_handler,
mem_write_handler,
if (DEV_pci_set_base_mem(BX_NE2K_THIS_PTR, mem_read_handler, NULL,
&BX_NE2K_THIS pci_rom_address,
&BX_NE2K_THIS pci_conf[0x30],
BX_NE2K_THIS pci_rom_size)) {

View File

@ -255,7 +255,6 @@ private:
#if BX_SUPPORT_PCI
BX_NE2K_SMF bx_bool mem_read_handler(bx_phy_address addr, unsigned len, void *data, void *param);
BX_NE2K_SMF bx_bool mem_write_handler(bx_phy_address addr, unsigned len, void *data, void *param);
#endif
static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);

View File

@ -234,21 +234,13 @@ void bx_pcipnic_c::register_state(void)
void bx_pcipnic_c::after_restore_state(void)
{
bx_pci_device_c::after_restore_pci_state(mem_read_handler);
if (DEV_pci_set_base_io(BX_PNIC_THIS_PTR, read_handler, write_handler,
&BX_PNIC_THIS pci_base_address[4],
&BX_PNIC_THIS pci_conf[0x20],
16, &pnic_iomask[0], "PNIC")) {
BX_INFO(("new base address: 0x%04x", BX_PNIC_THIS pci_base_address[4]));
}
if (BX_PNIC_THIS pci_rom_size > 0) {
if (DEV_pci_set_base_mem(BX_PNIC_THIS_PTR, mem_read_handler,
mem_write_handler,
&BX_PNIC_THIS pci_rom_address,
&BX_PNIC_THIS pci_conf[0x30],
BX_PNIC_THIS pci_rom_size)) {
BX_INFO(("new ROM address: 0x%08x", BX_PNIC_THIS pci_rom_address));
}
}
}
void bx_pcipnic_c::set_irq_level(bx_bool level)
@ -283,13 +275,6 @@ bx_bool bx_pcipnic_c::mem_read_handler(bx_phy_address addr, unsigned len,
return 1;
}
bx_bool bx_pcipnic_c::mem_write_handler(bx_phy_address addr, unsigned len,
void *data, void *param)
{
BX_INFO(("write to ROM ignored (addr=0x%08x len=%d)", (Bit32u)addr, len));
return 1;
}
// static IO port read callback handler
// redirects to non-static class handler to avoid virtual functions
@ -458,8 +443,7 @@ void bx_pcipnic_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_le
}
}
if (romaddr_change) {
if (DEV_pci_set_base_mem(BX_PNIC_THIS_PTR, mem_read_handler,
mem_write_handler,
if (DEV_pci_set_base_mem(BX_PNIC_THIS_PTR, mem_read_handler, NULL,
&BX_PNIC_THIS pci_rom_address,
&BX_PNIC_THIS pci_conf[0x30],
BX_PNIC_THIS pci_rom_size)) {

View File

@ -80,7 +80,6 @@ private:
void pnic_timer(void);
BX_PNIC_SMF bx_bool mem_read_handler(bx_phy_address addr, unsigned len, void *data, void *param);
BX_PNIC_SMF bx_bool mem_write_handler(bx_phy_address addr, unsigned len, void *data, void *param);
static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
static void write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2014 The Bochs Project
// Copyright (C) 2001-2017 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
@ -71,11 +71,13 @@ void BX_MEM_C::writePhysicalPage(BX_CPU_C *cpu, bx_phy_address addr, unsigned le
memory_handler = BX_MEM_THIS memory_handlers[a20addr >> 20];
while (memory_handler) {
if (memory_handler->begin <= a20addr &&
if (memory_handler->write_handler != NULL) {
if (memory_handler->begin <= a20addr &&
memory_handler->end >= a20addr &&
memory_handler->write_handler(a20addr, len, data, memory_handler->param))
{
return;
{
return;
}
}
memory_handler = memory_handler->next;
}

View File

@ -824,7 +824,7 @@ BX_MEM_C::registerMemoryHandlers(void *param, memory_handler_t read_handler,
{
if (end_addr < begin_addr)
return 0;
if (!read_handler || !write_handler) // allow NULL fetch handler
if (!read_handler) // allow NULL write and fetch handler
return 0;
BX_INFO(("Register memory access handlers: 0x" FMT_PHY_ADDRX " - 0x" FMT_PHY_ADDRX, begin_addr, end_addr));
for (Bit32u page_idx = (Bit32u)(begin_addr >> 20); page_idx <= (Bit32u)(end_addr >> 20); page_idx++) {