From ed669adfd14d281587e24107aea71ea904d78d59 Mon Sep 17 00:00:00 2001 From: Volker Ruppert Date: Thu, 19 Jan 2012 18:32:11 +0000 Subject: [PATCH] - rewrite of the PCI memory management code for the expansion ROM and BIOS area - store memory type array in the memory object to avoid calling the pci plugin frequently. The pci code calls a memory method to change the memory type in case the PAM registers are modified. - removed now obsolete code and minor cleanups --- bochs/iodev/iodev.h | 3 -- bochs/iodev/pci.cc | 114 +++++++-------------------------------- bochs/iodev/pci.h | 2 - bochs/memory/memory.cc | 55 +++++++++---------- bochs/memory/memory.h | 19 +++++++ bochs/memory/misc_mem.cc | 107 ++++++++++++++++++++---------------- bochs/plugin.h | 4 +- 7 files changed, 125 insertions(+), 179 deletions(-) diff --git a/bochs/iodev/iodev.h b/bochs/iodev/iodev.h index 206d0a3e8..4d7dc1175 100644 --- a/bochs/iodev/iodev.h +++ b/bochs/iodev/iodev.h @@ -295,9 +295,6 @@ public: STUBFUNC(pci, pci_set_base_io); return 0; } - - virtual Bit8u rd_memType(Bit32u addr) { return 0; } - virtual Bit8u wr_memType(Bit32u addr) { return 0; } }; class BOCHSAPI bx_pci2isa_stub_c : public bx_devmodel_c, public bx_pci_device_stub_c { diff --git a/bochs/iodev/pci.cc b/bochs/iodev/pci.cc index 146abe603..4d03607ec 100644 --- a/bochs/iodev/pci.cc +++ b/bochs/iodev/pci.cc @@ -91,8 +91,6 @@ void bx_pci_bridge_c::init(void) for (i=0x0CFC; i<=0x0CFF; i++) { DEV_register_ioread_handler(this, read_handler, i, "i440FX", 7); - } - for (i=0x0CFC; i<=0x0CFF; i++) { DEV_register_iowrite_handler(this, write_handler, i, "i440FX", 7); } @@ -276,12 +274,14 @@ Bit32u bx_pci_bridge_c::pci_read_handler(Bit8u address, unsigned io_len) // pci configuration space write callback handler void bx_pci_bridge_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len) { - Bit8u value8; + Bit8u value8, oldval; + unsigned area; if ((address >= 0x10) && (address < 0x34)) return; for (unsigned i=0; i> (i*8)) & 0xFF; + oldval = BX_PCI_THIS pci_conf[address+i]; switch (address+i) { case 0x04: BX_PCI_THIS pci_conf[address+i] = (value8 & 0x40) | 0x06; @@ -296,9 +296,23 @@ void bx_pci_bridge_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io case 0x5D: case 0x5E: case 0x5F: - BX_INFO(("440FX PMC write to PAM register %x (TLB Flush)", address+i)); - BX_PCI_THIS pci_conf[address+i] = value8; - bx_pc_system.MemoryMappingChanged(); + if (value != oldval) { + BX_PCI_THIS pci_conf[address+i] = value8; + if ((address+i) == 0x59) { + area = BX_MEM_AREA_F0000; + DEV_mem_set_memory_type(area, 0, (value >> 4) & 0x1); + DEV_mem_set_memory_type(area, 1, (value >> 5) & 0x1); + } else { + area = ((address+i) - 0x5a) << 1; + DEV_mem_set_memory_type(area, 0, (value >> 0) & 0x1); + DEV_mem_set_memory_type(area, 1, (value >> 1) & 0x1); + area++; + DEV_mem_set_memory_type(area, 0, (value >> 4) & 0x1); + DEV_mem_set_memory_type(area, 1, (value >> 5) & 0x1); + } + BX_INFO(("440FX PMC write to PAM register %x (TLB Flush)", address+i)); + bx_pc_system.MemoryMappingChanged(); + } break; case 0x72: smram_control(value); // SMRAM conrol register @@ -366,94 +380,6 @@ void bx_pci_bridge_c::smram_control(Bit8u value8) BX_PCI_THIS pci_conf[0x72] = value8; } -Bit8u bx_pci_bridge_c::rd_memType(Bit32u addr) -{ - switch ((addr & 0xFC000) >> 12) { - case 0xC0: - return (BX_PCI_THIS pci_conf[0x5A] & 0x1); - case 0xC4: - return ((BX_PCI_THIS pci_conf[0x5A] >> 4) & 0x1); - case 0xC8: - return (BX_PCI_THIS pci_conf[0x5B] & 0x1); - case 0xCC: - return ((BX_PCI_THIS pci_conf[0x5B] >> 4) & 0x1); - - case 0xD0: - return (BX_PCI_THIS pci_conf[0x5C] & 0x1); - case 0xD4: - return ((BX_PCI_THIS pci_conf[0x5C] >> 4) & 0x1); - case 0xD8: - return (BX_PCI_THIS pci_conf[0x5D] & 0x1); - case 0xDC: - return ((BX_PCI_THIS pci_conf[0x5D] >> 4) & 0x1); - - case 0xE0: - return (BX_PCI_THIS pci_conf[0x5E] & 0x1); - case 0xE4: - return ((BX_PCI_THIS pci_conf[0x5E] >> 4) & 0x1); - case 0xE8: - return (BX_PCI_THIS pci_conf[0x5F] & 0x1); - case 0xEC: - return ((BX_PCI_THIS pci_conf[0x5F] >> 4) & 0x1); - - case 0xF0: - case 0xF4: - case 0xF8: - case 0xFC: - return ((BX_PCI_THIS pci_conf[0x59] >> 4) & 0x1); - - default: - BX_PANIC(("rd_memType () Error: Memory Type not known !")); - break; - } - - return(0); // keep compiler happy -} - -Bit8u bx_pci_bridge_c::wr_memType(Bit32u addr) -{ - switch ((addr & 0xFC000) >> 12) { - case 0xC0: - return ((BX_PCI_THIS pci_conf[0x5A] >> 1) & 0x1); - case 0xC4: - return ((BX_PCI_THIS pci_conf[0x5A] >> 5) & 0x1); - case 0xC8: - return ((BX_PCI_THIS pci_conf[0x5B] >> 1) & 0x1); - case 0xCC: - return ((BX_PCI_THIS pci_conf[0x5B] >> 5) & 0x1); - - case 0xD0: - return ((BX_PCI_THIS pci_conf[0x5C] >> 1) & 0x1); - case 0xD4: - return ((BX_PCI_THIS pci_conf[0x5C] >> 5) & 0x1); - case 0xD8: - return ((BX_PCI_THIS pci_conf[0x5D] >> 1) & 0x1); - case 0xDC: - return ((BX_PCI_THIS pci_conf[0x5D] >> 5) & 0x1); - - case 0xE0: - return ((BX_PCI_THIS pci_conf[0x5E] >> 1) & 0x1); - case 0xE4: - return ((BX_PCI_THIS pci_conf[0x5E] >> 5) & 0x1); - case 0xE8: - return ((BX_PCI_THIS pci_conf[0x5F] >> 1) & 0x1); - case 0xEC: - return ((BX_PCI_THIS pci_conf[0x5F] >> 5) & 0x1); - - case 0xF0: - case 0xF4: - case 0xF8: - case 0xFC: - return ((BX_PCI_THIS pci_conf[0x59] >> 5) & 0x1); - - default: - BX_PANIC(("wr_memType () Error: Memory Type not known !")); - break; - } - - return(0); // keep compiler happy -} - void bx_pci_bridge_c::debug_dump() { int i; diff --git a/bochs/iodev/pci.h b/bochs/iodev/pci.h index 8af0461e8..67edfd5c4 100644 --- a/bochs/iodev/pci.h +++ b/bochs/iodev/pci.h @@ -59,8 +59,6 @@ public: bx_write_handler_t f2, Bit32u *addr, Bit8u *pci_conf, unsigned size, const Bit8u *iomask, const char *name); - virtual Bit8u rd_memType(Bit32u addr); - virtual Bit8u wr_memType(Bit32u addr); virtual Bit32u pci_read_handler(Bit8u address, unsigned io_len); virtual void pci_write_handler(Bit8u address, Bit32u value, unsigned io_len); diff --git a/bochs/memory/memory.cc b/bochs/memory/memory.cc index 9a1abbce2..7f329f001 100644 --- a/bochs/memory/memory.cc +++ b/bochs/memory/memory.cc @@ -155,20 +155,16 @@ mem_write: // ignore write to ROM #else // Write Based on 440fx Programming - if (BX_MEM_THIS pci_enabled && ((a20addr & 0xfffc0000) == 0x000c0000)) - { - switch (DEV_pci_wr_memtype((Bit32u) a20addr)) { - case 0x1: // Writes to ShadowRAM - BX_DEBUG(("Writing to ShadowRAM: address 0x" FMT_PHY_ADDRX ", data %02x", a20addr, *data_ptr)); - *(BX_MEM_THIS get_vector(a20addr)) = *data_ptr; - break; - - case 0x0: // Writes to ROM, Inhibit - BX_DEBUG(("Write to ROM ignored: address 0x" FMT_PHY_ADDRX ", data %02x", a20addr, *data_ptr)); - break; - - default: - BX_PANIC(("writePhysicalPage: default case")); + if (BX_MEM_THIS pci_enabled && ((a20addr & 0xfffc0000) == 0x000c0000)) { + 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) { + // Writes to ShadowRAM + BX_DEBUG(("Writing to ShadowRAM: address 0x" FMT_PHY_ADDRX ", data %02x", a20addr, *data_ptr)); + *(BX_MEM_THIS get_vector(a20addr)) = *data_ptr; + } else { + // Writes to ROM, Inhibit + BX_DEBUG(("Write to ROM ignored: address 0x" FMT_PHY_ADDRX ", data %02x", a20addr, *data_ptr)); } } #endif @@ -290,23 +286,20 @@ mem_read: } #if BX_SUPPORT_PCI - if (BX_MEM_THIS pci_enabled && ((a20addr & 0xfffc0000) == 0x000c0000)) - { - switch (DEV_pci_rd_memtype((Bit32u) a20addr)) { - case 0x0: // Read from ROM - if ((a20addr & 0xfffe0000) == 0x000e0000) { - // last 128K of BIOS ROM mapped to 0xE0000-0xFFFFF - *data_ptr = BX_MEM_THIS rom[BIOS_MAP_LAST128K(a20addr)]; - } - else { - *data_ptr = BX_MEM_THIS rom[(a20addr & EXROM_MASK) + BIOSROMSZ]; - } - break; - case 0x1: // Read from ShadowRAM - *data_ptr = *(BX_MEM_THIS get_vector(a20addr)); - break; - default: - BX_PANIC(("readPhysicalPage: default case")); + if (BX_MEM_THIS pci_enabled && ((a20addr & 0xfffc0000) == 0x000c0000)) { + 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 ((a20addr & 0xfffe0000) == 0x000e0000) { + // last 128K of BIOS ROM mapped to 0xE0000-0xFFFFF + *data_ptr = BX_MEM_THIS rom[BIOS_MAP_LAST128K(a20addr)]; + } else { + *data_ptr = BX_MEM_THIS rom[(a20addr & EXROM_MASK) + BIOSROMSZ]; + } + } else { + // Read from ShadowRAM + *data_ptr = *(BX_MEM_THIS get_vector(a20addr)); } } else diff --git a/bochs/memory/memory.h b/bochs/memory/memory.h index 3c2c122f3..9680caa91 100644 --- a/bochs/memory/memory.h +++ b/bochs/memory/memory.h @@ -44,6 +44,22 @@ class BX_CPU_C; #define BIOS_MAP_LAST128K(addr) (((addr) | 0xfff00000) & BIOS_MASK) +enum memory_area_t { + BX_MEM_AREA_C0000 = 0, + BX_MEM_AREA_C4000, + BX_MEM_AREA_C8000, + BX_MEM_AREA_CC000, + BX_MEM_AREA_D0000, + BX_MEM_AREA_D4000, + BX_MEM_AREA_D8000, + BX_MEM_AREA_DC000, + BX_MEM_AREA_E0000, + BX_MEM_AREA_E4000, + BX_MEM_AREA_E8000, + BX_MEM_AREA_EC000, + BX_MEM_AREA_F0000 +}; + typedef bx_bool (*memory_handler_t)(bx_phy_address addr, unsigned len, void *data, void *param); // return a pointer to 4K region containing or NULL if direct access is not allowed // same format as getHostMemAddr method @@ -77,6 +93,7 @@ private: Bit8u *rom; // 512k BIOS rom space + 128k expansion rom space Bit8u *bogus; // 4k for unexisting memory bx_bool rom_present[65]; + bx_bool memory_type[13][2]; Bit32u used_blocks; #if BX_LARGE_RAMFILE @@ -99,6 +116,8 @@ public: BX_MEM_SMF void disable_smram(void); BX_MEM_SMF bx_bool is_smram_accessible(void); + 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); // Note: accesses should always be contained within a single page diff --git a/bochs/memory/misc_mem.cc b/bochs/memory/misc_mem.cc index ba2902dd8..055a6d483 100644 --- a/bochs/memory/misc_mem.cc +++ b/bochs/memory/misc_mem.cc @@ -38,15 +38,21 @@ Bit8u* const BX_MEM_C::swapped_out = ((Bit8u*)NULL - sizeof(Bit8u)); BX_MEM_C::BX_MEM_C() { - put("MEM0"); + int i; + + put("memory", "MEM0"); vector = NULL; actual_vector = NULL; blocks = NULL; len = 0; used_blocks = 0; - for (int i = 0; i < 65; i++) + for (i = 0; i < 65; i++) rom_present[i] = 0; + for (i = 0; i <= BX_MEM_AREA_F0000; i++) { + memory_type[i][0] = 0; + memory_type[i][1] = 0; + } memory_handlers = NULL; @@ -292,6 +298,8 @@ void memory_param_restore_handler(void *devptr, bx_param_c *param, Bit64s val) void BX_MEM_C::register_state() { + char param_name[15]; + bx_list_c *list = new bx_list_c(SIM->get_bochs_root(), "memory", "Memory State", 6); Bit32u num_blocks = BX_MEM_THIS len / BX_MEM_BLOCK_LEN; #if BX_LARGE_RAMFILE @@ -306,12 +314,18 @@ void BX_MEM_C::register_state() bx_list_c *mapping = new bx_list_c(list, "mapping", num_blocks); for (Bit32u blk=0; blk < num_blocks; blk++) { - char param_name[15]; sprintf(param_name, "blk%d", blk); bx_param_num_c *param = new bx_param_num_c(mapping, param_name, "", "", 0, BX_MAX_BIT32U, 0); param->set_base(BASE_DEC); param->set_sr_handlers(this, memory_param_save_handler, memory_param_restore_handler); } + bx_list_c *memtype = new bx_list_c(list, "memtype", 26); + for (int i = 0; i <= BX_MEM_AREA_F0000; i++) { + sprintf(param_name, "%d_r", i); + new bx_shadow_bool_c(memtype, param_name, &BX_MEM_THIS memory_type[i][0]); + sprintf(param_name, "%d_w", i); + new bx_shadow_bool_c(memtype, param_name, &BX_MEM_THIS memory_type[i][1]); + } } void BX_MEM_C::cleanup_memory() @@ -545,23 +559,20 @@ bx_bool BX_MEM_C::dbg_fetch_mem(BX_CPU_C *cpu, bx_phy_address addr, unsigned len *buf = DEV_vga_mem_read(addr); } #if BX_SUPPORT_PCI - else if (BX_MEM_THIS pci_enabled && (addr >= 0x000c0000 && addr < 0x00100000)) - { - switch (DEV_pci_rd_memtype ((Bit32u) addr)) { - case 0x0: // Read from ROM - if ((addr & 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]; - } - break; - case 0x1: // Read from ShadowRAM - *buf = *(BX_MEM_THIS get_vector(addr)); - break; - default: - BX_PANIC(("dbg_fetch_mem: default case")); + else if (BX_MEM_THIS pci_enabled && (addr >= 0x000c0000 && addr < 0x00100000)) { + unsigned area = (unsigned)(addr >> 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) { + // 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]; + } + } else { + // Read from ShadowRAM + *buf = *(BX_MEM_THIS get_vector(addr)); } } #endif // #if BX_SUPPORT_PCI @@ -616,16 +627,14 @@ bx_bool BX_MEM_C::dbg_set_mem(bx_phy_address addr, unsigned len, Bit8u *buf) DEV_vga_mem_write(addr, *buf); } #if BX_SUPPORT_PCI - else if (BX_MEM_THIS pci_enabled && (addr >= 0x000c0000 && addr < 0x00100000)) - { - switch (DEV_pci_wr_memtype (addr)) { - case 0x0: // Ignore write to ROM - break; - case 0x1: // Write to ShadowRAM - *(BX_MEM_THIS get_vector(addr)) = *buf; - break; - default: - BX_PANIC(("dbg_fetch_mem: default case")); + else if (BX_MEM_THIS pci_enabled && (addr >= 0x000c0000 && addr < 0x00100000)) { + unsigned area = (unsigned)(addr >> 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; + } else { + // Ignore write to ROM } } #endif // #if BX_SUPPORT_PCI @@ -729,23 +738,20 @@ Bit8u *BX_MEM_C::getHostMemAddr(BX_CPU_C *cpu, bx_phy_address addr, unsigned rw) if ((a20addr >= 0x000a0000 && a20addr < 0x000c0000)) return(NULL); // Vetoed! Mem mapped IO (VGA) #if BX_SUPPORT_PCI - else if (BX_MEM_THIS pci_enabled && (a20addr >= 0x000c0000 && a20addr < 0x00100000)) - { - switch (DEV_pci_rd_memtype ((Bit32u) a20addr)) { - case 0x0: // Read from ROM - if ((a20addr & 0xfffe0000) == 0x000e0000) { - // last 128K of BIOS ROM mapped to 0xE0000-0xFFFFF - return (Bit8u *) &BX_MEM_THIS rom[BIOS_MAP_LAST128K(a20addr)]; - } - else { - return (Bit8u *) &BX_MEM_THIS rom[(a20addr & EXROM_MASK) + BIOSROMSZ]; - } - break; - case 0x1: // Read from ShadowRAM - return BX_MEM_THIS get_vector(a20addr); - default: - BX_PANIC(("getHostMemAddr(): default case")); - return(NULL); + 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 ((a20addr & 0xfffe0000) == 0x000e0000) { + // last 128K of BIOS ROM mapped to 0xE0000-0xFFFFF + return (Bit8u *) &BX_MEM_THIS rom[BIOS_MAP_LAST128K(a20addr)]; + } else { + return (Bit8u *) &BX_MEM_THIS rom[(a20addr & EXROM_MASK) + BIOSROMSZ]; + } + } else { + // Read from ShadowRAM + return BX_MEM_THIS get_vector(a20addr); } } #endif @@ -884,6 +890,13 @@ bx_bool BX_MEM_C::is_smram_accessible(void) (BX_MEM_THIS smram_enable || !BX_MEM_THIS smram_restricted); } +void BX_MEM_C::set_memory_type(memory_area_t area, bx_bool rw, bx_bool dram) +{ + if (area <= BX_MEM_AREA_F0000) { + BX_MEM_THIS memory_type[area][rw] = dram; + } +} + #if BX_SUPPORT_MONITOR_MWAIT // diff --git a/bochs/plugin.h b/bochs/plugin.h index d7ffbfada..4e523103d 100644 --- a/bochs/plugin.h +++ b/bochs/plugin.h @@ -235,8 +235,6 @@ extern "C" { (bx_devices.pluginPciBridge->pci_set_base_mem(a,b,c,d,e,f)) #define DEV_pci_set_base_io(a,b,c,d,e,f,g,h) \ (bx_devices.pluginPciBridge->pci_set_base_io(a,b,c,d,e,f,g,h)) -#define DEV_pci_rd_memtype(addr) bx_devices.pluginPciBridge->rd_memType(addr) -#define DEV_pci_wr_memtype(addr) bx_devices.pluginPciBridge->wr_memType(addr) #define DEV_pci_debug_dump() bx_devices.pluginPciBridge->debug_dump() #define DEV_ide_bmdma_present() bx_devices.pluginPciIdeController->bmdma_present() #define DEV_ide_bmdma_set_irq(a) bx_devices.pluginPciIdeController->bmdma_set_irq(a) @@ -255,6 +253,8 @@ extern "C" { bx_devices.mem->registerMemoryHandlers(param,rh,wh,b,e) #define DEV_unregister_memory_handlers(param,b,e) \ bx_devices.mem->unregisterMemoryHandlers(param,b,e) +#define DEV_mem_set_memory_type(a,b,c) \ + bx_devices.mem->set_memory_type((memory_area_t)a,b,c) ///////// USB device macros #define DEV_usb_init_device(a,b,c,d) (usbdev_type)bx_devices.pluginUsbDevCtl->init_device(a,b,(void**)c,d)