/*
 * Copyright 2020 Google, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __DEV_REG_BANK_HH__
#define __DEV_REG_BANK_HH__

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <functional>
#include <initializer_list>
#include <iostream>
#include <map>
#include <sstream>
#include <utility>

#include "base/bitfield.hh"
#include "base/logging.hh"
#include "base/types.hh"
#include "sim/byteswap.hh"
#include "sim/serialize_handlers.hh"

/*
 * Device models often have contiguous banks of registers which can each
 * have unique and arbitrary behavior when they are completely or partially
 * read or written. Historically it's been up to each model to map an access
 * which covers an arbitrary portion of that register bank down to individual
 * registers. It must handle cases where registers are only partially accessed,
 * or where multiple registers are accessed at the same time, or a combination
 * of both.
 *
 *
 * == RegisterBank ==
 *
 * The RegisterBank class(es), defined below, handle that mapping, and let the
 * device model focus on defining what each of the registers actually do when
 * read or written. Once it's set up, it has two primary interfaces which
 * access the registers it contains:
 *
 * void read(Addr addr, void *buf, Addr bytes);
 * void write(Addr addr, const void *buf, Addr bytes);
 *
 * These two methods will handle a read or write contained within the register
 * bank starting at address "addr". The data that will be written or has been
 * read is pointed to by "buf", and is "bytes" bytes long.
 *
 * These methods are virtual, so if you need to implement extra rules, like
 * for instance that registers can only be accessed one at a time, that
 * accesses have to be aligned, have to access complete registers, etc, that
 * can be added in a subclass.
 *
 * Additionally, each RegisterBank has a name and a base address which is
 * passed into the constructor. The meaning of the "base" value can be whatever
 * makes sense for your device, and is considered the lowest address contained
 * in the bank. The value could be the offset of this bank of registers within
 * the device itself, with the device's own offset subtracted out before read
 * or write are called. It could alternatively be the base address of the
 * entire device, with the address from accesses passed into read or write
 * unmodified.
 *
 * To add actual registers to the RegisterBank (discussed below), you can use
 * either the addRegister method which adds a single register, or addRegisters
 * which adds an initializer list of them all at once. The register will be
 * appended to the end of the bank as they're added, contiguous to the
 * existing registers. The size of the bank is automatically accumulated as
 * registers are added.
 *
 * The base(), size() and name() methods can be used to access each of those
 * read only properties of the RegisterBank instance.
 *
 * While the RegisterBank itself doesn't have any data in it directly and so
 * has no endianness, it's very likely all the registers within it will have
 * the same endinanness. The bank itself therefore has a default endianness
 * which, unless specified otherwise, will be passed on to the register types
 * within it. The RegisterBank class is templated on its endianness. There are
 * RegisterBankLE and RegisterBankBE aliases to make it a little easier to
 * refer to one or the other version.
 *
 *
 * == Register interface ==
 *
 * Every register in a RegisterBank needs to inherit, directly or indirectly,
 * from the RegisterBase class. Each register must have a name (for debugging),
 * and a well defined size. The following methods define the interface the
 * register bank uses to access the register, and where the register can
 * implement its special behaviors:
 *
 * void read(void *buf);
 * void read(void *buf, off_t offset, size_t bytes);
 *
 * void write(const void *buf);
 * void write(const void *buf, off_t offset, size_t bytes);
 *
 * The single argument versions of these methods completely overwrite the
 * register's contents with whatever is pointed to by buf.
 *
 * The version which also takes "offset" and "bytes" arguments reads or writes
 * only a portion of the register, starting "offset" bytes from the start of
 * the register, and writing or reading the next "bytes" bytes.
 *
 * Each register also needs to implement serialize or unserialize methods
 * which make it accessible to the checkpointing mechanism. If a register
 * doesn't need to be serialized (for instance if it has a fixed value) then
 * it still has to implement these methods, but they don't have to actually do
 * anything.
 *
 *
 * == Basic Register types ==
 *
 * Some simple register types have been defined which handle basic, common
 * behaviors found in many devices:
 *
 * = RegisterRaz and RegisterRao =
 *
 * RegisterRaz (read as zero) and RegisterRao (read as one) will ignore writes,
 * and will return all zeroes or ones, respectively, when read. These can have
 * arbitrary alignment and size, and can be used for, for instance,
 * unimplemented registers that still need to take up a certain amount of
 * space, or for gaps between registers which still need to handle accesses
 * even though they don't do anything or hold any data.
 *
 * For instance, a device might have several regions of registers which are
 * aligned on different boundaries, but which might not take up all of the
 * space in each region. The extra space can be filled with a RegisterRaz or
 * RegisterRao, making it possible to implement all the registers as a single
 * bank.
 *
 * If you need a register with a different fill pattern, you can subclass the
 * RegisterRoFill type and implement its "fill" method. This should behave
 * like the three argument form of the read() method, described above.
 *
 * = RegisterBuf and RegisterLBuf =
 *
 * These two types act like inert blobs of storage. They don't have any
 * special behavior and can have any arbitrary size like the RegisterRao and
 * RegisterRaz types above, but these registers actually store what's written
 * to them.
 *
 * The RegisterBuf type acts as an interface to a buffer stored elsewhere. That
 * makes it possible to, for instance, alias the same buffer to different parts
 * of the register space, or to expose some other object which needs to exist
 * outside of the register bank for some reason.
 *
 * The RegisterLBuf does the same thing, except it uses a local buffer it
 * manages. That makes it a little easier to work with if you don't need the
 * flexibility of the RegisterBuf type.
 *
 *
 * == Typed Registers ==
 *
 * The Register template class is for more complex registers with side effects,
 * and/or which hold structured data. The template arguments define what type
 * the register should hold, and also its endianness.
 *
 * = Access handlers =
 *
 * Instead of subclassing the Register<Data> type and redefining its read/write
 * methods, reads and writes are implemented using replaceable handlers with
 * these signatures:
 *
 * Data read(Register<Data> &reg);
 * Data partialRead(Register<Data> &reg, int first, int last);
 * void write(Register<Data> &reg, const Data &value);
 * void partialWrite(Register<Data> &reg, const Data &value,
 *                   int first, int last);
 *
 * The "partial" version of these handlers take "first" and "last" arguments
 * which specify what bits of the register to modify. They should be
 * interpreted like the same arguments in base/bitfield.hh. The endianness
 * of the register will have already been dealt with by the time the handler
 * is called.
 *
 * The read and partialRead handlers should generate whatever value reading the
 * register should return, based on (or not based on) the state of "reg". The
 * partial handler should keep the bits it returns in place. For example, if
 * bits 15-8 are read from a 16 bit register with the value 0x1234, it should
 * return 0x1200, not 0x0012.
 *
 * The write and partialWrite handlers work the same way, except in they write
 * instead of read. They are responsible for updating the value in reg in
 * whatever way and to whatever value is appropriate, based on
 * (or not based on) the value of "value" and the state of "reg".
 *
 * The default implementations of the read and write handlers simply return or
 * update the value stored in reg. The default partial read calls the read
 * handler (which may not be the default), and trims down the data as required.
 * The default partial write handler calls the read handler (which may not be
 * the default), updates the value as requested, and then calls the write
 * handler (which may not be the default).
 *
 * Overriding the partial read or write methods might be necessary if reads or
 * writes have side effects which should affect only the part of the register
 * read or written. For instance, there might be some status bits which will
 * be cleared when accessed. Only the bits which were actually accessed should
 * be affected, even if they're grouped together logically with the other bits
 * in a single register.
 *
 * To set your own handlers, you can use the "reader", "writer",
 * "partialReader", and "partialWriter" methods. Each of these takes a single
 * callable argument (lambda, functor, function pointer, etc.) which will
 * replace the current corresponding handler.
 *
 * These methods all return a reference to the current Register so that they
 * can be strung together without having to respecify what object you're
 * modifying over and over again.
 *
 * There are also versions of these which will set up methods on some object as
 * the handlers. These take a pointer to whatever object will handle the call,
 * and a member function pointer to the method that will actually implement
 * the handler. This can be used if, for instance, the registers are all
 * members of a RegisterBank subclass, and need to call methods on their
 * parent class to actually implement the behavior. These methods must have
 * the same signature as above, with the exception that they are methods and
 * not bare functions.
 *
 * When updating the register's value in custom write or partialWrite handlers,
 * be sure to use the "update" method which will honor read only bits. There
 * is an alternative form of update which also takes a custom bitmask, if you
 * need to update bits other than the normally writeable ones.
 *
 * = Read only bits =
 *
 * Often registers have bits which are fixed and not affected by writes. To
 * specify which bits are writeable, use the "writeable" method which takes a
 * single argument the same type as the type of the register. It should hold a
 * bitmask where a 1 bit can be written, and a 0 cannot. Calling writeable with
 * no arguments will return the current bitmask.
 *
 * A shorthand "readonly" method marks all bits as read only.
 *
 * Both methods return a reference to the current Register so they can be
 * strung together into a sequence when configuring it.
 *
 * = Underlying data and serialization =
 *
 * The "get" method returns a reference to the underlying storage inside the
 * register. That can be used to manually update the entire register, even bits
 * which are normally read only, or for structured data, to access members of
 * the underlying data type.
 *
 * For instance, if the register holds a BitUnion, you could use the get()
 * method to access the bitfields within it:
 *
 * reg.get().bitfieldA = reg.get().bitfieldB;
 *
 * The serialize and unserialize methods for these types will pass through the
 * underlying data within the register. For instance, when serializing a
 * Register<Foo>, the value in the checkpoint will be the same as if you had
 * serialized a Foo directly, with the value stored in the register.
 *
 * = Aliases =
 *
 * Some convenient aliases have been defined for frequently used versions of
 * the Register class. These are
 *
 * Register(8|16|32|64)(LE|BE|)
 *
 * Where the underlying type of the register is a uint8_t, uint16_t, etc, and
 * the endianness is little endian, big endian, or whatever the default is for
 * the RegisterBank.
 */

namespace gem5
{

// Common bases to make it easier to identify both endiannesses at once.
class RegisterBankBase
{
  public:
    class RegisterBaseBase {};
};

template <ByteOrder BankByteOrder>
class RegisterBank : public RegisterBankBase
{
  public:
    // Static helper methods for implementing register types.
    template <typename Data>
    static constexpr Data
    readWithMask(const Data &value, const Data &bitmask)
    {
        return value & bitmask;
    }

    template <typename Data>
    static constexpr Data
    writeWithMask(const Data &old, const Data &value, const Data &bitmask)
    {
        return readWithMask(
                old, (Data)~bitmask) | readWithMask(value, bitmask);
    }

    class RegisterBase : public RegisterBankBase::RegisterBaseBase
    {
      protected:
        const std::string _name;
        size_t _size = 0;

      public:
        constexpr RegisterBase(const std::string &new_name, size_t new_size) :
            _name(new_name), _size(new_size)
        {}
        virtual ~RegisterBase() {}

        // Read the register's name.
        virtual const std::string &name() const { return _name; }

        // Read the register's size in bytes.
        size_t size() const { return _size; }

        // Perform a read on the register.
        virtual void read(void *buf) = 0;
        virtual void read(void *buf, off_t offset, size_t bytes) = 0;

        // Perform a write on the register.
        virtual void write(const void *buf) = 0;
        virtual void write(const void *buf, off_t offset, size_t bytes) = 0;

        // Methods for implementing serialization for checkpoints.
        virtual void serialize(std::ostream &os) const = 0;
        virtual bool unserialize(const std::string &s) = 0;
    };

    // Filler registers which return a fixed pattern.
    class RegisterRoFill : public RegisterBase
    {
      protected:
        constexpr RegisterRoFill(
                const std::string &new_name, size_t new_size) :
            RegisterBase(new_name, new_size)
        {}

        virtual void fill(void *buf, off_t offset, size_t bytes) = 0;

      public:
        // Ignore writes.
        void write(const void *buf) override {}
        void write(const void *buf, off_t offset, size_t bytes) override {}

        // Use fill() to handle reads.
        void read(void *buf) override { fill(buf, 0, this->size()); }
        void
        read(void *buf, off_t offset, size_t bytes) override
        {
            fill(buf, offset, bytes);
        }

        void serialize(std::ostream &os) const override {}
        bool unserialize(const std::string &s) override { return true; }
    };

    // Register which reads as all zeroes.
    class RegisterRaz : public RegisterRoFill
    {
      protected:
        void
        fill(void *buf, off_t offset, size_t bytes) override
        {
            bzero(buf, bytes);
        }

      public:
        RegisterRaz(const std::string &new_name, size_t new_size) :
            RegisterRoFill(new_name, new_size)
        {}
    };

    // Register which reads as all ones.
    class RegisterRao : public RegisterRoFill
    {
      protected:
        void
        fill(void *buf, off_t offset, size_t bytes) override
        {
            memset(buf, 0xff, bytes);
        }

      public:
        RegisterRao(const std::string &new_name, size_t new_size) :
            RegisterRoFill(new_name, new_size)
        {}
    };

    // Register which acts as a simple buffer.
    class RegisterBuf : public RegisterBase
    {
      private:
        void *_ptr = nullptr;

      public:
        RegisterBuf(const std::string &new_name, void *ptr, size_t bytes) :
            RegisterBase(new_name, bytes), _ptr(ptr)
        {}

        void write(const void *buf) override { write(buf, 0, this->size()); }
        void
        write(const void *buf, off_t offset, size_t bytes) override
        {
            assert(offset + bytes <= this->size());
            memcpy((uint8_t *)_ptr + offset, buf, bytes);
        }

        void read(void *buf) override { read(buf, 0, this->size()); }
        void
        read(void *buf, off_t offset, size_t bytes) override
        {
            assert(offset + bytes <= this->size());
            memcpy(buf, (uint8_t *)_ptr + offset, bytes);
        }

        // The buffer's owner is responsible for serializing it.
        void serialize(std::ostream &os) const override {}
        bool unserialize(const std::string &s) override { return true; }

      protected:
        /**
         * This method exists so that derived classes that need to initialize
         * their buffers before they can be set can do so.
         *
         * @param buf The pointer to the backing buffer.
         */
        void
        setBuffer(void *buf)
        {
            assert(_ptr == nullptr);
            assert(buf != nullptr);
            _ptr = buf;
        }
    };

    // Same as above, but which keeps its storage locally.
    template <int BufBytes>
    class RegisterLBuf : public RegisterBuf
    {
      public:
        std::array<uint8_t, BufBytes> buffer;

        RegisterLBuf(const std::string &new_name) :
            RegisterBuf(new_name, nullptr, BufBytes)
        {
            this->setBuffer(buffer.data());
        }

        void
        serialize(std::ostream &os) const override
        {
            if (BufBytes)
                ShowParam<uint8_t>::show(os, buffer[0]);
            for (int i = 1; i < BufBytes; i++) {
                os << " ";
                ShowParam<uint8_t>::show(os, buffer[i]);
            }
        }

        bool
        unserialize(const std::string &s) override
        {
            std::vector<std::string> tokens;
            std::istringstream is(s);

            std::string token;
            while (is >> token)
                tokens.push_back(token);

            if (tokens.size() != BufBytes) {
                warn("Size mismatch unserialing %s, expected %d, got %d",
                        this->name(), BufBytes, tokens.size());
                return false;
            }

            for (int i = 0; i < BufBytes; i++) {
                if (!ParseParam<uint8_t>::parse(tokens[i], buffer[i]))
                    return false;
            }

            return true;
        }
    };

    template <typename Data, ByteOrder RegByteOrder=BankByteOrder>
    class Register : public RegisterBase
    {
      protected:
        using This = Register<Data, RegByteOrder>;

      public:
        using ReadFunc = std::function<Data (This &reg)>;
        using PartialReadFunc = std::function<
            Data (This &reg, int first, int last)>;
        using WriteFunc = std::function<void (This &reg, const Data &value)>;
        using PartialWriteFunc = std::function<
            void (This &reg, const Data &value, int first, int last)>;

      private:
        Data _data = {};
        Data _writeMask = mask(sizeof(Data) * 8);

        ReadFunc _reader = defaultReader;
        WriteFunc _writer = defaultWriter;
        PartialWriteFunc _partialWriter = defaultPartialWriter;
        PartialReadFunc _partialReader = defaultPartialReader;

      protected:
        static Data defaultReader(This &reg) { return reg.get(); }

        static Data
        defaultPartialReader(This &reg, int first, int last)
        {
            return mbits(reg._reader(reg), first, last);
        }

        static void
        defaultWriter(This &reg, const Data &value)
        {
            reg.update(value);
        }

        static void
        defaultPartialWriter(This &reg, const Data &value, int first, int last)
        {
            reg._writer(reg, writeWithMask<Data>(reg._reader(reg), value,
                                                 mask(first, last)));
        }

        constexpr Data
        htoreg(Data data)
        {
            switch (RegByteOrder) {
              case ByteOrder::big:
                return htobe(data);
              case ByteOrder::little:
                return htole(data);
              default:
                panic("Unrecognized byte order %d.", (unsigned)RegByteOrder);
            }
        }

        constexpr Data
        regtoh(Data data)
        {
            switch (RegByteOrder) {
              case ByteOrder::big:
                return betoh(data);
              case ByteOrder::little:
                return letoh(data);
              default:
                panic("Unrecognized byte order %d.", (unsigned)RegByteOrder);
            }
        }

      public:

        /*
         * Interface for setting up the register.
         */

        // Constructor which lets data default initialize itself.
        constexpr Register(const std::string &new_name) :
            RegisterBase(new_name, sizeof(Data))
        {}

        // Constructor and move constructor with an initial data value.
        constexpr Register(const std::string &new_name, const Data &new_data) :
            RegisterBase(new_name, sizeof(Data)), _data(new_data)
        {}
        constexpr Register(const std::string &new_name,
                           const Data &&new_data) :
            RegisterBase(new_name, sizeof(Data)), _data(new_data)
        {}

        // Set which bits of the register are writeable.
        constexpr This &
        writeable(const Data &new_mask)
        {
            _writeMask = new_mask;
            return *this;
        }

        // Set the register as read only.
        constexpr This &readonly() { return writeable(0); }

        // Set the callables which handles reads or writes.
        // The default reader just returns the register value.
        // The default writer uses the write mask to update the register value.
        constexpr This &
        reader(const ReadFunc &new_reader)
        {
            _reader = new_reader;
            return *this;
        }
        template <class Parent, class... Args>
        constexpr This &
        reader(Parent *parent, Data (Parent::*nr)(Args... args))
        {
            auto wrapper = [parent, nr](Args&&... args) -> Data {
                return (parent->*nr)(std::forward<Args>(args)...);
            };
            return reader(wrapper);
        }
        constexpr This &
        writer(const WriteFunc &new_writer)
        {
            _writer = new_writer;
            return *this;
        }
        template <class Parent, class... Args>
        constexpr This &
        writer(Parent *parent, void (Parent::*nw)(Args... args))
        {
            auto wrapper = [parent, nw](Args&&... args) {
                (parent->*nw)(std::forward<Args>(args)...);
            };
            return writer(wrapper);
        }

        // Set the callables which handle reads or writes. These may need to
        // be handled specially if, for instance, accessing bits outside of
        // the enables would have side effects that shouldn't happen.
        //
        // The default partial reader just uses the byte enables to mask off
        // bits that are not being read.
        //
        // The default partial writer reads the current value of the register,
        // uses the byte enables to update only the bytes that are changing,
        // and then writes the result back to the register.
        constexpr This &
        partialReader(const PartialReadFunc &new_reader)
        {
            _partialReader = new_reader;
            return *this;
        }
        template <class Parent, class... Args>
        constexpr This &
        partialReader(Parent *parent, Data (Parent::*nr)(Args... args))
        {
            auto wrapper = [parent, nr](Args&&... args) -> Data {
                return (parent->*nr)(std::forward<Args>(args)...);
            };
            return partialReader(wrapper);
        }
        constexpr This &
        partialWriter(const PartialWriteFunc &new_writer)
        {
            _partialWriter = new_writer;
            return *this;
        }
        template <class Parent, class... Args>
        constexpr This &
        partialWriter(Parent *parent, void (Parent::*nw)(Args... args))
        {
            auto wrapper = [parent, nw](Args&&... args) {
                return (parent->*nw)(std::forward<Args>(args)...);
            };
            return partialWriter(wrapper);
        }


        /*
         * Interface for accessing the register's state, for use by the
         * register's helper functions and the register bank.
         */

        const Data &writeable() const { return _writeMask; }

        // Directly access the underlying data value.
        const Data &get() const { return _data; }
        Data &get() { return _data; }

        // Update data while applying a mask.
        void
        update(const Data &new_data, const Data &bitmask)
        {
            _data = writeWithMask(_data, new_data, bitmask);
        }
        // This version uses the default write mask.
        void
        update(const Data &new_data)
        {
            _data = writeWithMask(_data, new_data, _writeMask);
        }


        /*
         * Interface for reading/writing the register, for use by the
         * register bank.
         */

        // Perform a read on the register.
        void
        read(void *buf) override
        {
            Data data = htoreg(_reader(*this));
            memcpy(buf, (uint8_t *)&data, sizeof(data));
        }

        void
        read(void *buf, off_t offset, size_t bytes) override
        {
            // Move the region we're reading to be little endian, since that's
            // what gem5 uses internally in BitUnions, masks, etc.
            const off_t host_off = (RegByteOrder != ByteOrder::little) ?
                sizeof(Data) - (offset + bytes) : offset;

            const int first = (host_off + bytes) * 8 - 1;
            const int last = host_off * 8;
            Data data = htoreg(_partialReader(*this, first, last));

            memcpy(buf, (uint8_t *)&data + offset, bytes);
        }

        // Perform a write on the register.
        void
        write(const void *buf) override
        {
            Data data;
            memcpy((uint8_t *)&data, buf, sizeof(data));
            data = regtoh(data);
            _writer(*this, data);
        }

        void
        write(const void *buf, off_t offset, size_t bytes) override
        {
            Data data = {};
            memcpy((uint8_t *)&data + offset, buf, bytes);

            data = regtoh(data);

            // Move the region we're reading to be little endian, since that's
            // what gem5 uses internally in BitUnions, masks, etc.
            const off_t host_off = (RegByteOrder != ByteOrder::little) ?
                sizeof(Data) - (offset + bytes) : offset;

            const int first = (host_off + bytes) * 8 - 1;
            const int last = host_off * 8;
            _partialWriter(*this, data, first, last);
        }

        // Serialize our data using existing mechanisms.
        void
        serialize(std::ostream &os) const override
        {
            ShowParam<Data>::show(os, get());
        }

        bool
        unserialize(const std::string &s) override
        {
            return ParseParam<Data>::parse(s, get());
        }
    };

  private:
    std::map<Addr, std::reference_wrapper<RegisterBase>> _offsetMap;

    Addr _base = 0;
    Addr _size = 0;
    const std::string _name;

  public:

    using Register8 = Register<uint8_t>;
    using Register8LE = Register<uint8_t, ByteOrder::little>;
    using Register8BE = Register<uint8_t, ByteOrder::big>;
    using Register16 = Register<uint16_t>;
    using Register16LE = Register<uint16_t, ByteOrder::little>;
    using Register16BE = Register<uint16_t, ByteOrder::big>;
    using Register32 = Register<uint32_t>;
    using Register32LE = Register<uint32_t, ByteOrder::little>;
    using Register32BE = Register<uint32_t, ByteOrder::big>;
    using Register64 = Register<uint64_t>;
    using Register64LE = Register<uint64_t, ByteOrder::little>;
    using Register64BE = Register<uint64_t, ByteOrder::big>;


    constexpr RegisterBank(const std::string &new_name, Addr new_base) :
        _base(new_base), _name(new_name)
    {}

    virtual ~RegisterBank() {}

    void
    addRegisters(
            std::initializer_list<std::reference_wrapper<RegisterBase>> regs)
    {
        panic_if(regs.size() == 0, "Adding an empty list of registers to %s?",
                 name());
        for (auto &reg: regs) {
            _offsetMap.emplace(_base + _size, reg);
            _size += reg.get().size();
        }
    }

    void addRegister(RegisterBase &reg) { addRegisters({reg}); }

    Addr base() const { return _base; }
    Addr size() const { return _size; }
    const std::string &name() const { return _name; }

    virtual void
    read(Addr addr, void *buf, Addr bytes)
    {
        uint8_t *ptr = (uint8_t *)buf;
        // Number of bytes we've transferred.
        Addr done = 0;

        panic_if(addr - base() + bytes > size(),
            "Out of bounds read in register bank %s, address %#x, size %d.",
            name(), addr, bytes);

        auto it = _offsetMap.lower_bound(addr);
        if (it == _offsetMap.end() || it->first > addr)
            it--;

        if (it->first < addr) {
            RegisterBase &reg = it->second.get();
            // Skip at least the beginning of the first register.

            // Figure out what parts of it we're accessing.
            const off_t reg_off = addr - it->first;
            const size_t reg_bytes = std::min(reg.size() - reg_off,
                                              bytes - done);

            // Actually do the access.
            reg.read(ptr, reg_off, reg_bytes);
            done += reg_bytes;
            it++;

            // Was that everything?
            if (done == bytes)
                return;
        }

        while (true) {
            RegisterBase &reg = it->second.get();

            const size_t reg_size = reg.size();
            const size_t remaining = bytes - done;

            if (remaining == reg_size) {
                // A complete register read, and then we're done.
                reg.read(ptr + done);
                return;
            } else if (remaining > reg_size) {
                // A complete register read, with more to go.
                reg.read(ptr + done);
                done += reg_size;
                it++;
            } else {
                // Skip the end of the register, and then we're done.
                reg.read(ptr + done, 0, remaining);
                return;
            }
        }
    }

    virtual void
    write(Addr addr, const void *buf, Addr bytes)
    {
        const uint8_t *ptr = (const uint8_t *)buf;
        // Number of bytes we've transferred.
        Addr done = 0;

        panic_if(addr - base() + bytes > size(),
            "Out of bounds write in register bank %s, address %#x, size %d.",
            name(), addr, bytes);

        auto it = _offsetMap.lower_bound(addr);
        if (it == _offsetMap.end() || it->first > addr)
            it--;

        if (it->first < addr) {
            RegisterBase &reg = it->second.get();
            // Skip at least the beginning of the first register.

            // Figure out what parts of it we're accessing.
            const off_t reg_off = addr - it->first;
            const size_t reg_bytes = std::min(reg.size() - reg_off,
                                              bytes - done);

            // Actually do the access.
            reg.write(ptr, reg_off, reg_bytes);
            done += reg_bytes;
            it++;

            // Was that everything?
            if (done == bytes)
                return;
        }

        while (true) {
            RegisterBase &reg = it->second.get();

            const size_t reg_size = reg.size();
            const size_t remaining = bytes - done;

            if (remaining == reg_size) {
                // A complete register write, and then we're done.
                reg.write(ptr + done);
                return;
            } else if (remaining > reg_size) {
                // A complete register write, with more to go.
                reg.write(ptr + done);
                done += reg_size;
                it++;
            } else {
                // Skip the end of the register, and then we're done.
                reg.write(ptr + done, 0, remaining);
                return;
            }
        }
    }
};

using RegisterBankLE = RegisterBank<ByteOrder::little>;
using RegisterBankBE = RegisterBank<ByteOrder::big>;

// Delegate serialization to the individual RegisterBase subclasses.
template <class T>
struct ParseParam<T, std::enable_if_t<std::is_base_of_v<
    typename RegisterBankBase::RegisterBaseBase, T>>>
{
    static bool
    parse(const std::string &s, T &value)
    {
        return value.unserialize(s);
    }
};

template <class T>
struct ShowParam<T, std::enable_if_t<std::is_base_of_v<
    typename RegisterBankBase::RegisterBaseBase, T>>>
{
    static void
    show(std::ostream &os, const T &value)
    {
        value.serialize(os);
    }
};

} // namespace gem5

#endif // __DEV_REG_BANK_HH__
