Ejemplo n.º 1
0
        public handler_entry_read_dispatch(int HighBits, int Width, int AddrShift, int Endian, address_space space, handler_entry.range init, handler_entry_read handler) : base(Width, AddrShift, Endian, space, handler_entry.F_DISPATCH)
        {
            this.HighBits = HighBits;


            LowBits  = (u32)handler_entry_dispatch_lowbits(HighBits, Width, AddrShift);
            BITCOUNT = (u32)HighBits > LowBits ? (u32)HighBits - LowBits : 0;
            COUNT    = 1U << (int)BITCOUNT;
            BITMASK  = make_bitmask32(BITCOUNT);
            LOWMASK  = make_bitmask32(LowBits);
            HIGHMASK = make_bitmask32((u32)HighBits) ^ LOWMASK;


            if (handler == null)
            {
                handler = space.get_unmap_r();
            }

            handler.ref_((s32)COUNT);

            m_dispatch = new handler_entry_read[COUNT];
            m_ranges   = new handler_entry.range[COUNT];
            for (UInt32 i = 0; i != COUNT; i++)
            {
                m_dispatch[i] = handler;
                m_ranges[i]   = init;
            }
        }
Ejemplo n.º 2
0
        Pointer <handler_entry.range> m_u_ranges;                              //handler_entry::range *m_u_ranges;


        public handler_entry_read_dispatch(address_space space, handler_entry.range init, handler_entry_read <int_Width, int_AddrShift> handler)
            : base(space, handler_entry.F_DISPATCH)
        {
            m_ranges_array.resize(1);
            m_ranges_array[0] = new range_array();
            m_dispatch_array.resize(1);
            m_dispatch_array[0] = new handler_array();
            m_a_ranges          = m_ranges_array[0].data();
            m_a_dispatch        = m_dispatch_array[0].data();
            m_u_ranges          = m_ranges_array[0].data();
            m_u_dispatch        = m_dispatch_array[0].data();


            if (handler == null)
            {
                handler = space.get_unmap_r <int_Width, int_AddrShift>();
            }

            handler.ref_((s32)COUNT);

            for (unsigned i = 0; i != COUNT; i++)
            {
                m_u_dispatch[i] = handler;
                m_u_ranges[i]   = new range(init);
            }
        }
Ejemplo n.º 3
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;
        }
Ejemplo n.º 4
0
        void populate_mirror_subdispatch(offs_t entry, offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_read handler)
        {
            var cur = m_dispatch[entry];

            if (cur.is_dispatch())
            {
                cur.populate_mirror(start, end, ostart, oend, mirror, handler);
            }
            else
            {
                var subdispatch = new handler_entry_read_dispatch((int)LowBits, Width, AddrShift, Endian, m_space, m_ranges[entry], cur);
                cur.unref();
                m_dispatch[entry] = subdispatch;
                subdispatch.populate_mirror(start, end, ostart, oend, mirror, handler);
            }
        }
Ejemplo n.º 5
0
        public override void populate_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_read handler)
        {
            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;
                start &= LOWMASK;
                end   &= LOWMASK;
                do
                {
                    if (offset != 0)
                    {
                        handler.ref_();
                    }

                    populate_mirror_subdispatch(base_entry | (offset >> (int)LowBits), start, end, ostart | offset, oend | offset, lmirror, handler);
                    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
                {
                    if (offset != 0)
                    {
                        handler.ref_();
                    }
                    populate_nomirror(start | offset, end | offset, ostart | offset, oend | offset, handler);
                    offset = (offset + add) & hmirror;
                } while (offset != 0);
            }
        }
Ejemplo n.º 6
0
        //void dump_map(std::vector<memory_entry> &map) const override;

        //std::string name() const override;

        public override void populate_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_read handler)
        {
            offs_t start_entry = start >> (int)LowBits;
            offs_t end_entry   = end >> (int)LowBits;

            range_cut_before(ostart - 1, (int)start_entry);
            range_cut_after(oend + 1, (int)end_entry);

            if (LowBits <= Width + AddrShift)
            {
                handler.ref_((int)(end_entry - start_entry));
                for (offs_t ent = start_entry; ent <= end_entry; ent++)
                {
                    m_dispatch[ent].unref();
                    m_dispatch[ent] = handler;
                    m_ranges[ent].set(ostart, oend);
                }
            }
            else if (start_entry == end_entry)
            {
                if ((start & LOWMASK) == 0 && (end & LOWMASK) == LOWMASK)
                {
                    m_dispatch[start_entry].unref();
                    m_dispatch[start_entry] = handler;
                    m_ranges[start_entry].set(ostart, oend);
                }
                else
                {
                    populate_nomirror_subdispatch(start_entry, start & LOWMASK, end & LOWMASK, ostart, oend, handler);
                }
            }
            else
            {
                if ((start & LOWMASK) != 0)
                {
                    populate_nomirror_subdispatch(start_entry, start & LOWMASK, LOWMASK, ostart, oend, handler);
                    start_entry++;
                    if (start_entry <= end_entry)
                    {
                        handler.ref_();
                    }
                }

                if ((end & LOWMASK) != LOWMASK)
                {
                    populate_nomirror_subdispatch(end_entry, 0, end & LOWMASK, ostart, oend, handler);
                    end_entry--;
                    if (start_entry <= end_entry)
                    {
                        handler.ref_();
                    }
                }

                if (start_entry <= end_entry)
                {
                    handler.ref_((int)(end_entry - start_entry));
                    for (offs_t ent = start_entry; ent <= end_entry; ent++)
                    {
                        m_dispatch[ent].unref();
                        m_dispatch[ent] = handler;
                        m_ranges[ent].set(ostart, oend);
                    }
                }
            }
        }
Ejemplo n.º 7
0
        //void *get_ptr(offs_t offset) const override;


        public override void lookup(offs_t address, ref offs_t start, ref offs_t end, ref handler_entry_read handler)
        {
            offs_t slot = (address >> (int)LowBits) & BITMASK;
            var    h    = m_dispatch[slot];

            if (h.is_dispatch())
            {
                h.lookup(address, ref start, ref end, ref handler);
            }
            else
            {
                start   = m_ranges[slot].start;
                end     = m_ranges[slot].end;
                handler = h;
            }
        }
Ejemplo n.º 8
0
        void populate_mirror_subdispatch(offs_t entry, offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_read <int_Width, int_AddrShift> handler)
        {
            var cur = m_u_dispatch[entry];

            if (cur.is_dispatch())
            {
                cur.populate_mirror(start, end, ostart, oend, mirror, handler);
            }
            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_mirror(start, end, ostart, oend, mirror, handler);
            }
        }
Ejemplo n.º 9
0
        public override void populate_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_read <int_Width, int_AddrShift> handler)
        {
            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)
            {
                if (handler.is_view())
                {
                    int delta = (int)(dispatch_entry(ostart) - handler.dispatch_entry(ostart));
                    handler.init_handlers(start >> (int)LowBits, end >> (int)LowBits, LowBits, ostart, oend, m_u_dispatch + delta, m_u_ranges + delta);
                }
                handler.ref_((int)(end_entry - start_entry));
                for (offs_t ent = start_entry; ent <= end_entry; ent++)
                {
                    m_u_dispatch[ent].unref();
                    m_u_dispatch[ent] = handler;
                    m_u_ranges[ent].set(ostart, oend);
                }
            }
            else if (start_entry == end_entry)
            {
                if ((start & LOWMASK) == 0 && (end & LOWMASK) == LOWMASK)
                {
                    if (handler.is_view())
                    {
                        int delta = (int)(dispatch_entry(ostart) - handler.dispatch_entry(ostart));
                        handler.init_handlers(start >> (int)LowBits, end >> (int)LowBits, LowBits, ostart, oend, m_u_dispatch + delta, m_u_ranges + delta);
                    }
                    m_u_dispatch[start_entry].unref();
                    m_u_dispatch[start_entry] = handler;
                    m_u_ranges[start_entry].set(ostart, oend);
                }
                else
                {
                    populate_nomirror_subdispatch(start_entry, start, end, ostart, oend, handler);
                }
            }
            else
            {
                if ((start & LOWMASK) != 0)
                {
                    populate_nomirror_subdispatch(start_entry, start, start | LOWMASK, ostart, oend, handler);
                    start_entry++;
                    start = (start | LOWMASK) + 1;
                    if (start_entry <= end_entry)
                    {
                        handler.ref_();
                    }
                }

                if ((end & LOWMASK) != LOWMASK)
                {
                    populate_nomirror_subdispatch(end_entry, end & ~LOWMASK, end, ostart, oend, handler);
                    end_entry--;
                    end = (end & ~LOWMASK) - 1;
                    if (start_entry <= end_entry)
                    {
                        handler.ref_();
                    }
                }

                if (start_entry <= end_entry)
                {
                    if (handler.is_view())
                    {
                        int delta = (int)(dispatch_entry(ostart) - handler.dispatch_entry(ostart));
                        handler.init_handlers(start >> (int)LowBits, end >> (int)LowBits, LowBits, ostart, oend, m_u_dispatch + delta, m_u_ranges + delta);
                    }
                    handler.ref_((int)(end_entry - start_entry));
                    for (offs_t ent = start_entry; ent <= end_entry; ent++)
                    {
                        m_u_dispatch[ent].unref();
                        m_u_dispatch[ent] = handler;
                        m_u_ranges[ent].set(ostart, oend);
                    }
                }
            }
        }
Ejemplo n.º 10
0
 protected abstract handler_entry_read_passthrough <int_Width, int_AddrShift> instantiate(handler_entry_read <int_Width, int_AddrShift> next);
Ejemplo n.º 11
0
 handler_entry_read_passthrough(address_space space, memory_passthrough_handler mph, handler_entry_read <int_Width, int_AddrShift> next) : base(space, handler_entry.F_PASSTHROUGH)
 {
     m_mph = mph; m_next = next;  next.ref_(); mph.add_handler(this);
 }
Ejemplo n.º 12
0
        handler_entry_read <int_Width, int_AddrShift> m_next;  //handler_entry_read<Width, AddrShift, Endian> *m_next;


        handler_entry_read_passthrough(address_space space, memory_passthrough_handler mph) : base(space, handler_entry.F_PASSTHROUGH)
        {
            m_mph = mph; m_next = null;
        }