public handler_entry_read_units(memory_units_descriptor <int_Width, int_AddrShift> descriptor, u8 ukey, handler_entry_read_units <int_Width, int_AddrShift> src) : base(src.m_space, F_UNITS) { m_subunits = 0; uX fullmask = new uX(Width, 0); var entries = descriptor.get_entries_for_key(ukey); foreach (var e in entries) { fullmask |= e.m_dmask; } for (u32 i = 0; i != src.m_subunits; i++) { if ((src.m_subunit_infos[i].m_dmask & fullmask) == 0) { m_subunit_infos[m_subunits] = src.m_subunit_infos[i]; m_subunit_infos[m_subunits].m_handler.ref_(); m_subunits++; } } fill(descriptor, entries); Array.Sort(m_subunit_infos, 0, m_subunits, Comparer <subunit_info> .Create((a, b) => { return(a.m_offset < b.m_offset ? -1 : 1); })); //std::sort(m_subunit_infos, m_subunit_infos + m_subunits, [](const subunit_info &a, const subunit_info &b) { return a.m_offset < b.m_offset; }); }
void fill(memory_units_descriptor <int_Width, int_AddrShift> descriptor, std.vector <memory_units_descriptor <int_Width, int_AddrShift> .entry> entries) { handler_entry handler = descriptor.get_subunit_handler(); handler.ref_((int)entries.size()); foreach (var e in entries) { m_subunit_infos[m_subunits++] = new subunit_info(handler, e.m_amask, e.m_dmask, e.m_ashift, e.m_offset, e.m_dshift, descriptor.get_subunit_width()); } }
u8 m_subunits; // number of subunits public handler_entry_read_units(memory_units_descriptor <int_Width, int_AddrShift> descriptor, u8 ukey, address_space space) : base(space, F_UNITS) { m_subunits = 0; var entries = descriptor.get_entries_for_key(ukey); fill(descriptor, entries); Array.Sort(m_subunit_infos, 0, m_subunits, Comparer <subunit_info> .Create((a, b) => { return(a.m_offset < b.m_offset ? -1 : 1); })); //std::sort(m_subunit_infos, m_subunit_infos + m_subunits, [](const subunit_info &a, const subunit_info &b) { return a.m_offset < b.m_offset; }); }
void mismatched_patch(memory_units_descriptor <int_Width, int_AddrShift> descriptor, u8 rkey, std.vector <mapping> mappings, ref handler_entry_read <int_Width, int_AddrShift> target) { u8 ukey = descriptor.rkey_to_ukey(rkey); handler_entry_read <int_Width, int_AddrShift> original = target.is_units() ? target : null; handler_entry_read <int_Width, int_AddrShift> replacement = null; foreach (var p in mappings) { if (p.ukey == ukey && p.original == original) { replacement = p.patched; break; } } if (replacement == null) { if (original != null) { replacement = new handler_entry_read_units <int_Width, int_AddrShift>(descriptor, ukey, (handler_entry_read_units <int_Width, int_AddrShift>)original); } else { replacement = new handler_entry_read_units <int_Width, int_AddrShift>(descriptor, ukey, m_space); } mappings.emplace_back(new mapping() { original = original, patched = replacement, ukey = ukey }); } else { replacement.ref_(); } target.unref(); target = replacement; }
void populate_mismatched_mirror_subdispatch(offs_t entry, offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, memory_units_descriptor <int_Width, int_AddrShift> descriptor, std.vector <mapping> mappings) { var cur = m_u_dispatch[entry]; if (cur.is_dispatch()) { cur.populate_mismatched_mirror(start, end, ostart, oend, mirror, descriptor, mappings); } else { var subdispatch = new handler_entry_read_dispatch <int_const_LowBits, int_Width, int_AddrShift>(m_space, m_u_ranges[entry], cur); //auto subdispatch = new handler_entry_read_dispatch<LowBits, Width, AddrShift>(handler_entry::m_space, m_u_ranges[entry], cur); cur.unref(); m_u_dispatch[entry] = subdispatch; subdispatch.populate_mismatched_mirror(start, end, ostart, oend, mirror, descriptor, mappings); } }
public override void populate_mismatched_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, memory_units_descriptor <int_Width, int_AddrShift> descriptor, std.vector <mapping> mappings) { offs_t hmirror = mirror & HIGHMASK; offs_t lmirror = mirror & LOWMASK; if (lmirror != 0) { // If lmirror is non-zero, then each mirror instance is a single entry offs_t add = 1 + ~hmirror; offs_t offset = 0; offs_t base_entry = start >> (int)LowBits; do { populate_mismatched_mirror_subdispatch(base_entry | (offset >> (int)LowBits), start, end, ostart | offset, oend | offset, lmirror, descriptor, mappings); offset = (offset + add) & hmirror; } while(offset != 0); } else { // If lmirror is zero, call the nomirror version as needed offs_t add = 1 + ~hmirror; offs_t offset = 0; do { populate_mismatched_nomirror(start | offset, end | offset, ostart | offset, oend | offset, descriptor, handler_entry.START | handler_entry.END, mappings); offset = (offset + add) & hmirror; } while(offset != 0); } }
public override void populate_mismatched_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, memory_units_descriptor <int_Width, int_AddrShift> descriptor, u8 rkey, std.vector <mapping> mappings) { offs_t start_entry = (start & HIGHMASK) >> (int)LowBits; offs_t end_entry = (end & HIGHMASK) >> (int)LowBits; range_cut_before(ostart - 1, (int)start_entry); range_cut_after(oend + 1, (int)end_entry); if (LowBits <= Width + AddrShift) { for (offs_t ent = start_entry; ent <= end_entry; ent++) { u8 rkey1 = rkey; if (ent != start_entry) { rkey1 &= unchecked ((u8) ~handler_entry.START); } if (ent != end_entry) { rkey1 &= unchecked ((u8) ~handler_entry.END); } var temp = m_u_dispatch[ent]; mismatched_patch(descriptor, rkey1, mappings, ref temp); m_u_dispatch[ent] = temp; //mismatched_patch(descriptor, rkey1, mappings, m_u_dispatch[ent]); m_u_ranges[ent].set(ostart, oend); } } else if (start_entry == end_entry) { if ((start & LOWMASK) == 0 && (end & LOWMASK) == LOWMASK) { if (m_u_dispatch[start_entry].is_dispatch()) { m_u_dispatch[start_entry].populate_mismatched_nomirror(start, end, ostart, oend, descriptor, rkey, mappings); } else { var temp = m_u_dispatch[start_entry]; mismatched_patch(descriptor, rkey, mappings, ref temp); temp = m_u_dispatch[start_entry]; //mismatched_patch(descriptor, rkey, mappings, m_u_dispatch[start_entry]); m_u_ranges[start_entry].set(ostart, oend); } } else { populate_mismatched_nomirror_subdispatch(start_entry, start, end, ostart, oend, descriptor, rkey, mappings); } } else { if ((start & LOWMASK) != 0) { populate_mismatched_nomirror_subdispatch(start_entry, start, start | LOWMASK, ostart, oend, descriptor, (u8)(rkey & ~handler_entry.END), mappings); start_entry++; rkey &= unchecked ((u8) ~handler_entry.START); } if ((end & LOWMASK) != LOWMASK) { populate_mismatched_nomirror_subdispatch(end_entry, end & ~LOWMASK, end, ostart, oend, descriptor, (u8)(rkey & ~handler_entry.START), mappings); end_entry--; rkey &= unchecked ((u8) ~handler_entry.END); } offs_t base_ = start & ~LOWMASK; for (offs_t ent = start_entry; ent <= end_entry; ent++) { u8 rkey1 = rkey; if (ent != start_entry) { rkey1 &= unchecked ((u8) ~handler_entry.START); } if (ent != end_entry) { rkey1 &= unchecked ((u8) ~handler_entry.END); } if (m_u_dispatch[ent].is_dispatch()) { m_u_dispatch[ent].populate_mismatched_nomirror(base_ | (ent << (int)LowBits), base_ | (ent << (int)LowBits) | LOWMASK, ostart, oend, descriptor, rkey1, mappings); } else { var temp = m_u_dispatch[ent]; mismatched_patch(descriptor, rkey1, mappings, ref temp); temp = m_u_dispatch[ent]; //mismatched_patch(descriptor, rkey1, mappings, m_u_dispatch[ent]); m_u_ranges[ent].set(ostart, oend); } } } }