[gem5-dev] [M] Change in gem5/gem5[develop]: dev: Introduce a reset() method on RegisterBank and Register classes.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/66671?usp=email ) ( 1 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: dev: Introduce a reset() method on RegisterBank and Register classes. .. 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 Maintainer: Gabe Black Reviewed-by: Yu-hsin Wang Reviewed-by: Jui-min Lee --- M src/dev/reg_bank.hh M src/dev/serial/uart8250.hh 2 files changed, 63 insertions(+), 2 deletions(-) Approvals: Gabe Black: Looks good to me, approved Jui-min Lee: Looks good to me, but someone else must approve kokoro: Regressions pass Yu-hsin Wang: Looks good to me, approved diff --git a/src/dev/reg_bank.hh b/src/dev/reg_bank.hh index 31c0ce5..66d668b 100644 --- a/src/dev/reg_bank.hh +++ b/src/dev/reg_bank.hh @@ -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 @@ // 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 @@ 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 @@ 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 @@ return true; } + +void reset() override { buffer = std::array{}; } }; template @@ -534,6 +557,7 @@ private: Data _data = {}; +Data _resetData = {}; Data _writeMask = mask(sizeof(Data) * 8); ReadFunc _reader = defaultReader; @@ -602,11 +626,13 @@ // 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 @@ { return ParseParam::parse(s, get()); } + +// Reset our data to its initial value. +void reset() override { get() = _resetData; } }; private: @@ -984,6 +1013,14 @@ } } } + +// By default, reset all the registers in the bank. +virtual void +reset() +{ +for (auto &[offset, reg]: _offsetMap) +reg.get().reset(); +} }; using RegisterBankLE = RegisterBank; diff --git a/src/dev/serial/uart8250.hh b/src/dev/serial/uart8250.hh index c55d889..5774f78 100644 --- a/src/dev/serial/uart8250.hh +++ b/src/dev/serial/uart8250.hh @@ -113,6 +113,13 @@
[gem5-dev] [M] Change in gem5/gem5[develop]: dev: Introduce a reset() method on RegisterBank and Register classes.
Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/66671?usp=email ) Change subject: dev: Introduce a reset() method on RegisterBank and Register classes. .. 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 --- M src/dev/reg_bank.hh M src/dev/serial/uart8250.hh 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/dev/reg_bank.hh b/src/dev/reg_bank.hh index 31c0ce5..66d668b 100644 --- a/src/dev/reg_bank.hh +++ b/src/dev/reg_bank.hh @@ -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 @@ // 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 @@ 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 @@ 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 @@ return true; } + +void reset() override { buffer = std::array{}; } }; template @@ -534,6 +557,7 @@ private: Data _data = {}; +Data _resetData = {}; Data _writeMask = mask(sizeof(Data) * 8); ReadFunc _reader = defaultReader; @@ -602,11 +626,13 @@ // 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 @@ { return ParseParam::parse(s, get()); } + +// Reset our data to its initial value. +void reset() override { get() = _resetData; } }; private: @@ -984,6 +1013,14 @@ } } } + +// By default, reset all the registers in the bank. +virtual void +reset() +{ +for (auto &[offset, reg]: _offsetMap) +reg.get().reset(); +} }; using RegisterBankLE = RegisterBank; diff --git a/src/dev/serial/uart8250.hh b/src/dev/serial/uart8250.hh index c55d889..5774f78 100644 --- a/src/dev/serial/uart8250.hh +++ b/src/dev/serial/uart8250.hh @@ -113,6 +113,13 @@ 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 -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/66671?usp=email To unsubscribe, or for