i386.cpp: add new mame debugger function cacheflush(x) to writeback cache (nw)

cacheflush() or cacheflush(0) writes back dirty cachelines to ram
cacheflush(1) also marks dirty cachelines as clean
cacheflush(2) or cacheflush(3) also invalidates the whole cache
This commit is contained in:
yz70s 2019-04-05 10:40:21 +02:00
parent 12210fec7b
commit 551eb4328c
2 changed files with 56 additions and 22 deletions

View File

@ -3316,6 +3316,26 @@ uint64_t i386_device::debug_virttophys(symbol_table &table, int params, const ui
return result;
}
uint64_t i386_device::debug_cacheflush(symbol_table &table, int params, const uint64_t *param)
{
uint32_t option;
bool invalidate;
bool clean;
if (params > 0)
option = param[0];
else
option = 0;
invalidate = (option & 1) != 0;
clean = (option & 2) != 0;
cache_writeback();
if (invalidate)
cache_invalidate();
if (clean)
cache_clean();
return 0;
}
void i386_device::device_debug_setup()
{
using namespace std::placeholders;
@ -3323,6 +3343,7 @@ void i386_device::device_debug_setup()
debug()->symtable().add("seglimit", 1, 1, std::bind(&i386_device::debug_seglimit, this, _1, _2, _3));
debug()->symtable().add("segofftovirt", 2, 2, std::bind(&i386_device::debug_segofftovirt, this, _1, _2, _3));
debug()->symtable().add("virttophys", 1, 1, std::bind(&i386_device::debug_virttophys, this, _1, _2, _3));
debug()->symtable().add("cacheflush", 0, 1, std::bind(&i386_device::debug_cacheflush, this, _1, _2, _3));
}
/*************************************************************************/
@ -4929,30 +4950,36 @@ void athlonxp_device::program_write_cache(offs_t address, dt data)
}
}
void athlonxp_device::invalidate_cache(bool writeback)
void athlonxp_device::cache_writeback()
{
// dirty cachelines are written back to memory
u32 base;
u8 *data;
data = cache.first_dirty(base, false);
while (data != nullptr)
{
for (int w = 0; w < 64; w += 4)
m_program->write_dword(base + w, *(u32 *)(data + w));
data = cache.next_dirty(base, false);
}
}
void athlonxp_device::cache_invalidate()
{
// dirty cachelines are not written back to memory
cache.reset();
}
void athlonxp_device::cache_clean()
{
// dirty cachelines are marked as clean but not written back to memory
u32 base;
u8 *data;
data = cache.first_dirty(base, true);
while (data != nullptr)
{
if (writeback)
for (int w = 0; w < 64; w += 4)
m_program->write_dword(base + w, *(u32 *)(data + w));
data = cache.next_dirty(base, true);
}
cache.reset();
}
void athlonxp_device::opcode_invd()
{
invalidate_cache(false);
}
void athlonxp_device::opcode_wbinvd()
{
invalidate_cache(true);
}

View File

@ -41,6 +41,7 @@ public:
uint64_t debug_seglimit(symbol_table &table, int params, const uint64_t *param);
uint64_t debug_segofftovirt(symbol_table &table, int params, const uint64_t *param);
uint64_t debug_virttophys(symbol_table &table, int params, const uint64_t *param);
uint64_t debug_cacheflush(symbol_table &table, int params, const uint64_t *param);
protected:
i386_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_data_width, int program_addr_width, int io_data_width);
@ -76,8 +77,14 @@ protected:
virtual void opcode_cpuid();
virtual uint64_t opcode_rdmsr(bool &valid_msr);
virtual void opcode_wrmsr(uint64_t data, bool &valid_msr);
virtual void opcode_invd() {}
virtual void opcode_wbinvd() {}
virtual void opcode_invd() { cache_invalidate(); }
virtual void opcode_wbinvd() { cache_writeback(); cache_invalidate(); }
// routines for the cache
// default implementation assumes there is no cache
virtual void cache_writeback() {}
virtual void cache_invalidate() {}
virtual void cache_clean() {}
// routine to access memory
virtual u8 mem_pr8(offs_t address) { return macache32->read_byte(address); }
@ -1632,8 +1639,9 @@ protected:
virtual void opcode_cpuid() override;
virtual uint64_t opcode_rdmsr(bool &valid_msr) override;
virtual void opcode_wrmsr(uint64_t data, bool &valid_msr) override;
virtual void opcode_invd() override;
virtual void opcode_wbinvd() override;
virtual void cache_writeback() override;
virtual void cache_invalidate() override;
virtual void cache_clean() override;
virtual void device_start() override;
virtual void device_reset() override;
@ -1650,7 +1658,6 @@ protected:
private:
void parse_mtrrfix(u64 mtrr, offs_t base, int kblock);
int check_cacheable(offs_t address);
void invalidate_cache(bool writeback);
template <class dt, offs_t xorle> dt opcode_read_cache(offs_t address);
template <class dt, offs_t xorle> dt program_read_cache(offs_t address);