[gem5-dev] [M] Change in gem5/gem5[develop]: dev: Introduce a reset() method on RegisterBank and Register classes.

2022-12-15 Thread Gabe Black (Gerrit) via gem5-dev
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.

2022-12-14 Thread Gabe Black (Gerrit) via gem5-dev
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