dev: Introduce a reset() method on RegisterBank and Register classes.

This will make it much easier to implement reset behaviors on devices
which have RegisterBanks in them.

Change-Id: I73fe9874fcb69feed33611a320dcca85c0de2d0e
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/66671
Tested-by: kokoro <noreply+kokoro@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Reviewed-by: Yu-hsin Wang <yuhsingw@google.com>
Reviewed-by: Jui-min Lee <fcrh@google.com>
This commit is contained in:
Gabe Black
2022-12-10 02:29:43 -08:00
committed by Gabe Black
parent f96513fd04
commit 8b1688da34
2 changed files with 46 additions and 2 deletions

View File

@@ -117,6 +117,11 @@
* RegisterBankLE and RegisterBankBE aliases to make it a little easier to
* refer to one or the other version.
*
* A RegisterBank also has a reset() method which will (by default) call the
* reset() method on each register within it. This method is virtual, and so
* can be overridden if something additional or different needs to be done to
* reset the hardware model.
*
*
* == Register interface ==
*
@@ -145,6 +150,12 @@
* it still has to implement these methods, but they don't have to actually do
* anything.
*
* Each register also has a "reset" method, which will reset the register as
* if its containing device is being reset. By default, this will just restore
* the initial value of the register, but can be overridden to implement
* additional behavior like resetting other aspects of the device which are
* controlled by the value of the register.
*
*
* == Basic Register types ==
*
@@ -360,6 +371,9 @@ class RegisterBank : public RegisterBankBase
// Methods for implementing serialization for checkpoints.
virtual void serialize(std::ostream &os) const = 0;
virtual bool unserialize(const std::string &s) = 0;
// Reset the register.
virtual void reset() = 0;
};
// Filler registers which return a fixed pattern.
@@ -388,6 +402,9 @@ class RegisterBank : public RegisterBankBase
void serialize(std::ostream &os) const override {}
bool unserialize(const std::string &s) override { return true; }
// Resetting a read only register doesn't need to do anything.
void reset() override {}
};
// Register which reads as all zeroes.
@@ -453,6 +470,10 @@ class RegisterBank : public RegisterBankBase
void serialize(std::ostream &os) const override {}
bool unserialize(const std::string &s) override { return true; }
// Assume since the buffer is managed externally, it will be reset
// externally.
void reset() override {}
protected:
/**
* This method exists so that derived classes that need to initialize
@@ -516,6 +537,8 @@ class RegisterBank : public RegisterBankBase
return true;
}
void reset() override { buffer = std::array<uint8_t, BufBytes>{}; }
};
template <typename Data, ByteOrder RegByteOrder=BankByteOrder>
@@ -534,6 +557,7 @@ class RegisterBank : public RegisterBankBase
private:
Data _data = {};
Data _resetData = {};
Data _writeMask = mask(sizeof(Data) * 8);
ReadFunc _reader = defaultReader;
@@ -602,11 +626,13 @@ class RegisterBank : public RegisterBankBase
// 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)
RegisterBase(new_name, sizeof(Data)), _data(new_data),
_resetData(new_data)
{}
constexpr Register(const std::string &new_name,
const Data &&new_data) :
RegisterBase(new_name, sizeof(Data)), _data(new_data)
RegisterBase(new_name, sizeof(Data)), _data(new_data),
_resetData(new_data)
{}
// Set which bits of the register are writeable.
@@ -789,6 +815,9 @@ class RegisterBank : public RegisterBankBase
{
return ParseParam<Data>::parse(s, get());
}
// Reset our data to its initial value.
void reset() override { get() = _resetData; }
};
private:
@@ -984,6 +1013,14 @@ class RegisterBank : public RegisterBankBase
}
}
}
// By default, reset all the registers in the bank.
virtual void
reset()
{
for (auto &[offset, reg]: _offsetMap)
reg.get().reset();
}
};
using RegisterBankLE = RegisterBank<ByteOrder::little>;

View File

@@ -113,6 +113,13 @@ class Uart8250 : public Uart
void serialize(std::ostream &os) const override {}
bool unserialize(const std::string &s) override { return true; }
void
reset() override
{
_reg1.reset();
_reg2.reset();
}
};
class BankedRegister : public PairedRegister