+/*
+ Virtual TLB interfaces(universal)
+
+ Origin : MAME 0.208
+ Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
+ Date : 2019.04.23-
+
+*/
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
***************************************************************************/
-#include "emu.h"
-#include "divtlb.h"
-
+#include "../../vm_template.h"
+#include "../../../emu.h"
+#include "./divtlb.h"
//**************************************************************************
// device_vtlb_interface - constructor
//-------------------------------------------------
-device_vtlb_interface::device_vtlb_interface(const machine_config &mconfig, device_t &device, int space)
- : device_interface(device, "vtlb"),
- m_space(space),
- m_dynamic(0),
- m_fixed(0),
- m_dynindex(0),
- m_pageshift(0),
- m_addrwidth(0),
- m_table_base(nullptr)
+device_vtlb_interface::device_vtlb_interface(VM_TEMPLATE* parent_vm, EMU* parent_emu, DEVICE* parent_device, int space, int fixed_entries, int dynamic_entries)
+ : DEVICE(parent_vm, parent_emu),
+ m_space(space),
+ m_dynamic(dynamic_entries),
+ m_fixed(fixed_entries),
+ m_dynindex(0),
+ m_pageshift(12),
+ m_addrwidth(32),
+ m_table_base(nullptr)
{
+ m_device = parent_device;
+ set_device_name(_T("VTLB DEVICE"));
}
// constructed
//-------------------------------------------------
+//
+// 2019-04-23 K.O: Temporally disable interface_varidity_check().
+//
+/*
void device_vtlb_interface::interface_validity_check(validity_checker &valid) const
{
const device_memory_interface *intf;
osd_printf_error("Invalid page shift %d for VTLB\n", spaceconfig->page_shift());
}
}
+*/
//-------------------------------------------------
// actually starting a device
//-------------------------------------------------
-void device_vtlb_interface::interface_pre_start()
+void device_vtlb_interface::initialize()
{
// fill in CPU information
- const address_space_config *spaceconfig = device().memory().space_config(m_space);
- m_pageshift = spaceconfig->page_shift();
- m_addrwidth = spaceconfig->logaddr_width();
-
+ //const address_space_config *spaceconfig = device().memory().space_config(m_space);
+ //m_pageshift = spaceconfig->page_shift();
+ //m_addrwidth = spaceconfig->logaddr_width();
+ // -> You must call set_page_shift() and set_addr_width() before initialize.
// allocate the entry array
m_live.resize(m_fixed + m_dynamic);
memset(&m_live[0], 0, m_live.size()*sizeof(m_live[0]));
}
}
-
-//-------------------------------------------------
-// interface_post_start - work to be done after
-// actually starting a device
-//-------------------------------------------------
-
-void device_vtlb_interface::interface_post_start()
+void device_vtlb_interface::release()
{
- device().save_item(NAME(m_live));
- device().save_item(NAME(m_table));
- device().save_item(NAME(m_refcnt));
- if (m_fixed > 0)
- device().save_item(NAME(m_fixedpages));
}
-
-//-------------------------------------------------
-// interface_pre_reset - work to be done prior to
-// actually resetting a device
-//-------------------------------------------------
-
-void device_vtlb_interface::interface_pre_reset()
+void device_vtlb_interface::reset()
{
vtlb_flush_dynamic();
}
{
offs_t tableindex = address >> m_pageshift;
vtlb_entry entry = m_table[tableindex];
- offs_t taddress;
+ uint64_t taddress;
#if PRINTF_TLB
- osd_printf_debug("vtlb_fill: %08X(%X) ... ", address, intention);
+ out_debug_log("vtlb_fill: %08X(%X) ... ", address, intention);
#endif
// should not be called here if the entry is in the table already
if (m_dynamic == 0)
{
#if PRINTF_TLB
- osd_printf_debug("failed: no dynamic entries\n");
+ out_debug_log("failed: no dynamic entries\n");
#endif
return false;
}
// ask the CPU core to translate for us
taddress = address;
- if (!device().memory().translate(m_space, intention, taddress))
+ if (!m_device->address_translate(m_space, intention, taddress))
{
#if PRINTF_TLB
- osd_printf_debug("failed: no translation\n");
+ out_debug_log("failed: no translation\n");
#endif
return false;
}
entry |= VTLB_FLAG_VALID;
#if PRINTF_TLB
- osd_printf_debug("success (%08X), new entry\n", taddress);
+ out_debug_log("success (%08X), new entry\n", taddress);
#endif
}
assert(entry & VTLB_FLAG_VALID);
#if PRINTF_TLB
- osd_printf_debug("success (%08X), existing entry\n", taddress);
+ out_debug_log("success (%08X), existing entry\n", taddress);
#endif
}
assert(entrynum >= 0 && entrynum < m_fixed);
#if PRINTF_TLB
- osd_printf_debug("vtlb_load %d for %d pages at %08X == %08X\n", entrynum, numpages, address, value);
+ out_debug_log("vtlb_load %d for %d pages at %08X == %08X\n", entrynum, numpages, address, value);
#endif
// if an entry already exists at this index, free it
if (m_dynamic == 0)
{
#if PRINTF_TLB
- osd_printf_debug("failed: no dynamic entries\n");
+ out_debug_log("failed: no dynamic entries\n");
#endif
return;
}
entry |= VTLB_FLAG_VALID | value;
#if PRINTF_TLB
- osd_printf_debug("success (%08X), new entry\n", address);
+ out_debug_log("success (%08X), new entry\n", address);
#endif
m_table[index] = entry;
}
void device_vtlb_interface::vtlb_flush_dynamic()
{
#if PRINTF_TLB
- osd_printf_debug("vtlb_flush_dynamic\n");
+ out_debug_log("vtlb_flush_dynamic\n");
#endif
// loop over live entries and release them from the table
offs_t tableindex = address >> m_pageshift;
#if PRINTF_TLB
- osd_printf_debug("vtlb_flush_address %08X\n", address);
+ out_debug_log("vtlb_flush_address %08X\n", address);
#endif
// free the entry in the table; for speed, we leave the entry in the live array
{
return m_table_base;
}
+
+#define STATE_VERSION 1
+
+bool device_vtlb_device::process_state(FILEIO* fio, bool loading)
+{
+ if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+ return false;
+ }
+ if(!state_fio->StateCheckInt32(this_device_id)) {
+ return false;
+ }
+ state_fio->StateValue(m_space);
+ state_fio->StateValue(m_dynamic);
+ state_fio->StateValue(m_fixed);
+ state_fio->StateValue(m_dynindex);
+ state_fio->StateValue(m_pageshift);
+ state_fio->StateValue(m_addrwidth);
+
+ state_fio->StateVector(m_live);
+ state_fio->StateVector(m_table);
+ state_fio->StateVector(m_refpages);
+ if(m_fixed > 0) {
+ state_fio->StateVector(m_fixedpages);
+ }
+ return true;
+}
#pragma once
-
+#include "device.h"
/***************************************************************************
CONSTANTS
***************************************************************************/
-constexpr u32 VTLB_FLAGS_MASK = 0xff;
+constexpr uint32_t VTLB_FLAGS_MASK = 0xff;
-constexpr u32 VTLB_READ_ALLOWED = 0x01; /* (1 << TRANSLATE_READ) */
-constexpr u32 VTLB_WRITE_ALLOWED = 0x02; /* (1 << TRANSLATE_WRITE) */
-constexpr u32 VTLB_FETCH_ALLOWED = 0x04; /* (1 << TRANSLATE_FETCH) */
-constexpr u32 VTLB_FLAG_VALID = 0x08;
-constexpr u32 VTLB_USER_READ_ALLOWED = 0x10; /* (1 << TRANSLATE_READ_USER) */
-constexpr u32 VTLB_USER_WRITE_ALLOWED = 0x20; /* (1 << TRANSLATE_WRITE_USER) */
-constexpr u32 VTLB_USER_FETCH_ALLOWED = 0x40; /* (1 << TRANSLATE_FETCH_USER) */
-constexpr u32 VTLB_FLAG_FIXED = 0x80;
+constexpr uint32_t VTLB_READ_ALLOWED = 0x01; /* (1 << TRANSLATE_READ) */
+constexpr uint32_t VTLB_WRITE_ALLOWED = 0x02; /* (1 << TRANSLATE_WRITE) */
+constexpr uint32_t VTLB_FETCH_ALLOWED = 0x04; /* (1 << TRANSLATE_FETCH) */
+constexpr uint32_t VTLB_FLAG_VALID = 0x08;
+constexpr uint32_t VTLB_USER_READ_ALLOWED = 0x10; /* (1 << TRANSLATE_READ_USER) */
+constexpr uint32_t VTLB_USER_WRITE_ALLOWED = 0x20; /* (1 << TRANSLATE_WRITE_USER) */
+constexpr uint32_t VTLB_USER_FETCH_ALLOWED = 0x40; /* (1 << TRANSLATE_FETCH_USER) */
+constexpr uint32_t VTLB_FLAG_FIXED = 0x80;
***************************************************************************/
/* represents an entry in the VTLB */
-typedef u32 vtlb_entry;
-
+typedef uint32_t vtlb_entry;
+typedef uint32_t offs_t;
// ======================> device_vtlb_interface
-class device_vtlb_interface : public device_interface
+class VM_TEMPLATE;
+class EMU;
+class device_vtlb_interface : public DEVICE
{
+protected:
+ DEVICE* m_device;
+ // private state
+ int m_space; // address space
+ int m_dynamic; // number of dynamic entries
+ int m_fixed; // number of fixed entries
+ int m_dynindex; // index of next dynamic entry
+ int m_pageshift; // bits to shift to get page index
+ int m_addrwidth; // logical address bus width
+ std::vector<offs_t> m_live; // array of live entries by table index
+ std::vector<int> m_fixedpages; // number of pages each fixed entry covers
+ std::vector<vtlb_entry> m_table; // table of entries by address
+ std::vector<offs_t> m_refcnt; // table of entry reference counts by address
+ vtlb_entry *m_table_base; // pointer to m_table[0]
public:
// construction/destruction
- device_vtlb_interface(const machine_config &mconfig, device_t &device, int space);
+ device_vtlb_interface(VM_TEMPLATE* parent_vm, EMU* parent_emu, DEVICE* parent_device, int space, int fixed_entries = 0, int dynamic_entries = 0);
virtual ~device_vtlb_interface();
+ void initialize();
+ void release();
+ void reset();
+ bool process_state(FILEIO* fio, bool loading);
+
// configuration helpers
void set_vtlb_dynamic_entries(int entries) { m_dynamic = entries; }
void set_vtlb_fixed_entries(int entries) { m_fixed = entries; }
// filling
bool vtlb_fill(offs_t address, int intention);
void vtlb_load(int entrynum, int numpages, offs_t address, vtlb_entry value);
- void vtlb_dynload(u32 index, offs_t address, vtlb_entry value);
+ void vtlb_dynload(uint32_t index, offs_t address, vtlb_entry value);
// flushing
void vtlb_flush_dynamic();
// accessors
const vtlb_entry *vtlb_table() const;
-
-protected:
- // interface-level overrides
- virtual void interface_validity_check(validity_checker &valid) const override;
- virtual void interface_pre_start() override;
- virtual void interface_post_start() override;
- virtual void interface_pre_reset() override;
-
-private:
- // private state
- int m_space; // address space
- int m_dynamic; // number of dynamic entries
- int m_fixed; // number of fixed entries
- int m_dynindex; // index of next dynamic entry
- int m_pageshift; // bits to shift to get page index
- int m_addrwidth; // logical address bus width
- std::vector<offs_t> m_live; // array of live entries by table index
- std::vector<int> m_fixedpages; // number of pages each fixed entry covers
- std::vector<vtlb_entry> m_table; // table of entries by address
- std::vector<offs_t> m_refcnt; // table of entry reference counts by address
- vtlb_entry *m_table_base; // pointer to m_table[0]
+ // Original APIs, must call before initialize().
+ void set_vtlb_page_shift(int m) { m_pageshift = m; }
+ void set_vtlb_addr_width(int m) { m_addrwidth = m; }
+ void set_parent_device(DEVICE* dev) { m_device = dev; }
};