Go to the documentation of this file.
28 #ifndef __DEV_REG_BANK_HH__
29 #define __DEV_REG_BANK_HH__
37 #include <initializer_list>
299 template <ByteOrder BankByteOrder>
304 template <
typename Data>
305 static constexpr Data
308 return value & bitmask;
311 template <
typename Data>
312 static constexpr Data
332 virtual const std::string &
name()
const {
return _name; }
338 virtual void read(
void *buf) = 0;
339 virtual void read(
void *buf, off_t
offset,
size_t bytes) = 0;
342 virtual void write(
const void *buf) = 0;
343 virtual void write(
const void *buf, off_t
offset,
size_t bytes) = 0;
346 virtual void serialize(std::ostream &
os)
const = 0;
355 const std::string &new_name,
size_t new_size) :
359 virtual void fill(
void *buf, off_t
offset,
size_t bytes) = 0;
363 void write(
const void *buf)
override {}
364 void write(
const void *buf, off_t
offset,
size_t bytes)
override {}
401 memset(buf, 0xff, bytes);
417 RegisterBuf(
const std::string &new_name,
void *ptr,
size_t bytes) :
451 assert(
_ptr ==
nullptr);
452 assert(buf !=
nullptr);
458 template <
int BufBytes>
475 for (
int i = 1;
i < BufBytes;
i++) {
485 std::istringstream
is(
s);
489 tokens.push_back(
token);
491 if (tokens.size() != BufBytes) {
492 warn(
"Size mismatch unserialing %s, expected %d, got %d",
493 this->
name(), BufBytes, tokens.size());
497 for (
int i = 0;
i < BufBytes;
i++) {
506 template <
typename Data, ByteOrder RegByteOrder=BankByteOrder>
518 void (
This &
reg,
const Data &value,
int first,
int last)>;
547 reg._writer(
reg, writeWithMask<Data>(
reg._reader(
reg), value,
554 switch (RegByteOrder) {
557 case ByteOrder::little:
560 panic(
"Unrecognized byte order %d.", (
unsigned)RegByteOrder);
567 switch (RegByteOrder) {
570 case ByteOrder::little:
573 panic(
"Unrecognized byte order %d.", (
unsigned)RegByteOrder);
589 constexpr
Register(
const std::string &new_name,
const Data &new_data) :
593 const Data &&new_data) :
617 template <
class Parent,
class... Args>
619 reader(Parent *parent, Data (Parent::*nr)(Args... args))
621 auto wrapper = [parent, nr](Args&&... args) -> Data {
622 return (parent->*nr)(std::forward<Args>(args)...);
632 template <
class Parent,
class... Args>
634 writer(Parent *parent,
void (Parent::*
nw)(Args... args))
636 auto wrapper = [parent,
nw](Args&&... args) {
637 (parent->*
nw)(std::forward<Args>(args)...);
658 template <
class Parent,
class... Args>
662 auto wrapper = [parent, nr](Args&&... args) -> Data {
663 return (parent->*nr)(std::forward<Args>(args)...);
673 template <
class Parent,
class... Args>
677 auto wrapper = [parent,
nw](Args&&... args) {
678 return (parent->*
nw)(std::forward<Args>(args)...);
697 update(
const Data &new_data,
const Data &bitmask)
719 memcpy(buf, (uint8_t *)&
data,
sizeof(
data));
727 const off_t host_off = (RegByteOrder != ByteOrder::little) ?
730 const int first = (host_off + bytes) * 8 - 1;
731 const int last = host_off * 8;
734 memcpy(buf, (uint8_t *)&
data +
offset, bytes);
742 memcpy((uint8_t *)&
data, buf,
sizeof(
data));
751 memcpy((uint8_t *)&
data +
offset, buf, bytes);
757 const off_t host_off = (RegByteOrder != ByteOrder::little) ?
760 const int first = (host_off + bytes) * 8 - 1;
761 const int last = host_off * 8;
780 std::map<Addr, std::reference_wrapper<RegisterBase>>
_offsetMap;
810 std::initializer_list<std::reference_wrapper<RegisterBase>> regs)
812 panic_if(regs.size() == 0,
"Adding an empty list of registers to %s?",
814 for (
auto &
reg: regs) {
829 uint8_t *ptr = (uint8_t *)buf;
834 "Out of bounds read in register bank %s, address %#x, size %d.",
841 if (it->first <
addr) {
842 RegisterBase &
reg = it->second.get();
846 const off_t reg_off =
addr - it->first;
847 const size_t reg_bytes = std::min(
reg.size() - reg_off,
851 reg.read(ptr, reg_off, reg_bytes);
861 RegisterBase &
reg = it->second.get();
863 const size_t reg_size =
reg.size();
864 const size_t remaining = bytes - done;
866 if (remaining == reg_size) {
868 reg.read(ptr + done);
870 }
else if (remaining > reg_size) {
872 reg.read(ptr + done);
877 reg.read(ptr + done, 0, remaining);
886 const uint8_t *ptr = (
const uint8_t *)buf;
891 "Out of bounds write in register bank %s, address %#x, size %d.",
898 if (it->first <
addr) {
899 RegisterBase &
reg = it->second.get();
903 const off_t reg_off =
addr - it->first;
904 const size_t reg_bytes = std::min(
reg.size() - reg_off,
908 reg.write(ptr, reg_off, reg_bytes);
918 RegisterBase &
reg = it->second.get();
920 const size_t reg_size =
reg.size();
921 const size_t remaining = bytes - done;
923 if (remaining == reg_size) {
925 reg.write(ptr + done);
927 }
else if (remaining > reg_size) {
929 reg.write(ptr + done);
934 reg.write(ptr + done, 0, remaining);
947 typename RegisterBankBase::RegisterBaseBase, T>::value>>
952 return value.unserialize(
s);
958 typename RegisterBankBase::RegisterBaseBase, T>::value>>
969 #endif // __DEV_REG_BANK_HH__
static void defaultWriter(This ®, const Data &value)
Register< uint8_t > Register8
static void show(std::ostream &os, const T &value)
Register< uint64_t, ByteOrder::little > Register64LE
void read(void *buf, off_t offset, size_t bytes) override
void read(void *buf, off_t offset, size_t bytes) override
void serialize(std::ostream &os) const override
void write(const void *buf) override
constexpr RegisterRoFill(const std::string &new_name, size_t new_size)
virtual bool unserialize(const std::string &s)=0
constexpr This & partialReader(const PartialReadFunc &new_reader)
void read(void *buf) override
static void show(std::ostream &os, const T &value)
RegisterRao(const std::string &new_name, size_t new_size)
virtual void write(Addr addr, const void *buf, Addr bytes)
RegisterRaz(const std::string &new_name, size_t new_size)
void setBuffer(void *buf)
This method exists so that derived classes that need to initialize their buffers before they can be s...
constexpr This & partialReader(Parent *parent, Data(Parent::*nr)(Args... args))
static Data defaultPartialReader(This ®, int first, int last)
bool unserialize(const std::string &s) override
static constexpr Data readWithMask(const Data &value, const Data &bitmask)
std::map< Addr, std::reference_wrapper< RegisterBase > > _offsetMap
constexpr T mbits(T val, unsigned first, unsigned last)
Mask off the given bits in place like bits() but without shifting.
constexpr Register(const std::string &new_name, const Data &new_data)
RegisterLBuf(const std::string &new_name)
void addRegisters(std::initializer_list< std::reference_wrapper< RegisterBase >> regs)
void serialize(std::ostream &os) const override
const Data & writeable() const
void write(const void *buf, off_t offset, size_t bytes) override
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
virtual void read(void *buf)=0
constexpr This & writer(Parent *parent, void(Parent::*nw)(Args... args))
constexpr This & partialWriter(const PartialWriteFunc &new_writer)
virtual const std::string & name() const
void serialize(std::ostream &os) const override
constexpr Register(const std::string &new_name, const Data &&new_data)
std::array< uint8_t, BufBytes > buffer
void read(void *buf, off_t offset, size_t bytes) override
std::function< void(This ®, const BackingType &value, int first, int last)> PartialWriteFunc
Register< uint8_t, ByteOrder::little > Register8LE
Register< Data, RegByteOrder > This
void read(void *buf) override
Register< uint8_t, ByteOrder::big > Register8BE
bool unserialize(const std::string &s) override
PartialWriteFunc _partialWriter
bool unserialize(const std::string &s) override
virtual void fill(void *buf, off_t offset, size_t bytes)=0
PartialReadFunc _partialReader
constexpr This & writeable(const Data &new_mask)
void fill(void *buf, off_t offset, size_t bytes) override
void read(void *buf) override
constexpr Register(const std::string &new_name)
void write(const void *buf) override
void update(const Data &new_data)
RegisterBuf(const std::string &new_name, void *ptr, size_t bytes)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
constexpr RegisterBank(const std::string &new_name, Addr new_base)
std::function< void(This ®, const BackingType &value)> WriteFunc
static bool parse(const std::string &s, T &value)
virtual void write(const void *buf)=0
void addRegister(RegisterBase ®)
constexpr RegisterBase(const std::string &new_name, size_t new_size)
constexpr This & reader(Parent *parent, Data(Parent::*nr)(Args... args))
static constexpr Data writeWithMask(const Data &old, const Data &value, const Data &bitmask)
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
virtual void read(Addr addr, void *buf, Addr bytes)
constexpr This & readonly()
Overload hash function for BasicBlockRange type.
void write(const void *buf) override
const std::string & name() const
void fill(void *buf, off_t offset, size_t bytes) override
Register< uint32_t, ByteOrder::big > Register32BE
constexpr This & reader(const ReadFunc &new_reader)
void write(const void *buf, off_t offset, size_t bytes) override
std::function< BackingType(This ®, int first, int last)> PartialReadFunc
void write(const void *buf, off_t offset, size_t bytes) override
Register< uint64_t, ByteOrder::big > Register64BE
constexpr This & partialWriter(Parent *parent, void(Parent::*nw)(Args... args))
static void defaultPartialWriter(This ®, const Data &value, int first, int last)
std::function< BackingType(This ®)> ReadFunc
virtual void serialize(std::ostream &os) const =0
Register< uint16_t, ByteOrder::little > Register16LE
void update(const Data &new_data, const Data &bitmask)
Register< uint16_t > Register16
Register< uint32_t > Register32
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
constexpr Data htoreg(Data data)
bool unserialize(const std::string &s) override
Register< uint64_t > Register64
void serialize(std::ostream &os) const override
Register< uint16_t, ByteOrder::big > Register16BE
constexpr Data regtoh(Data data)
constexpr This & writer(const WriteFunc &new_writer)
static Data defaultReader(This ®)
#define panic(...)
This implements a cprintf based panic() function.
Register< uint32_t, ByteOrder::little > Register32LE
Generated on Wed Jul 28 2021 12:10:26 for gem5 by doxygen 1.8.17