示例#1
0
        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; });
        }
示例#2
0
        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());
            }
        }
示例#3
0
        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; });
        }
示例#4
0
        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;
        }
示例#5
0
        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);
            }
        }
示例#6
0
        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);
            }
        }
示例#7
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);
                    }
                }
            }
        }