changeset 179bc8ca2d8c in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=179bc8ca2d8c
description:
        dev, x86: Fix serialization bug in the i8042 device

        The i8042 device drops the contents of a PS2 device's buffer when
        serializing, which results in corrupted PS2 state when continuing
        simulation after a checkpoint. This changeset fixes this bug and
        transitions the i8042 model to use the new serialization API that
        requires the serialize() method to be const.

diffstat:

 src/dev/x86/i8042.cc |  91 +++++++++++++++++----------------------------------
 src/dev/x86/i8042.hh |  20 ++++++-----
 2 files changed, 42 insertions(+), 69 deletions(-)

diffs (205 lines):

diff -r 703f42dbca21 -r 179bc8ca2d8c src/dev/x86/i8042.cc
--- a/src/dev/x86/i8042.cc      Fri Aug 07 09:59:14 2015 +0100
+++ b/src/dev/x86/i8042.cc      Fri Aug 07 09:59:15 2015 +0100
@@ -92,6 +92,29 @@
 }
 
 void
+X86ISA::PS2Device::serialize(const std::string &base, CheckpointOut &cp) const
+{
+    paramOut(cp, base + ".lastCommand", lastCommand);
+
+    std::vector<uint8_t> buffer(outBuffer.size());
+    std::copy(outBuffer.begin(), outBuffer.end(), buffer.begin());
+    arrayParamOut(cp, base + ".outBuffer.elts", buffer);
+}
+
+void
+X86ISA::PS2Device::unserialize(const std::string &base, CheckpointIn &cp)
+{
+    paramIn(cp, base + ".lastCommand", lastCommand);
+
+    std::vector<uint8_t> buffer;
+    arrayParamIn(cp, base + ".outBuffer.elts", buffer);
+    assert(outBuffer.empty());
+    for (auto c : buffer)
+        outBuffer.push_back(c);
+}
+
+
+void
 X86ISA::PS2Device::ack()
 {
     bufferData(&CommandAck, sizeof(CommandAck));
@@ -108,7 +131,7 @@
 {
     assert(data || size == 0);
     while (size) {
-        outBuffer.push(*(data++));
+        outBuffer.push_back(*(data++));
         size--;
     }
 }
@@ -463,7 +486,7 @@
 }
 
 void
-X86ISA::I8042::serializeOld(CheckpointOut &cp)
+X86ISA::I8042::serialize(CheckpointOut &cp) const
 {
     uint8_t statusRegData = statusReg.__data;
     uint8_t commandByteData = commandByte.__data;
@@ -498,52 +521,11 @@
 }
 
 void
-X86ISA::PS2Keyboard::serialize(const std::string &base, CheckpointOut &cp)
+X86ISA::PS2Mouse::serialize(const std::string &base, CheckpointOut &cp) const
 {
-    paramOut(cp, base + ".lastCommand", lastCommand);
-    int bufferSize = outBuffer.size();
-    paramOut(cp, base + ".outBuffer.size", bufferSize);
-    uint8_t *buffer = new uint8_t[bufferSize];
-    for (int i = 0; i < bufferSize; ++i) {
-        buffer[i] = outBuffer.front();
-        outBuffer.pop();
-    }
-    arrayParamOut(cp, base + ".outBuffer.elts", buffer,
-            bufferSize*sizeof(uint8_t));
-    delete[] buffer;
-}
+    PS2Device::serialize(base, cp);
 
-void
-X86ISA::PS2Keyboard::unserialize(const std::string &base, CheckpointIn &cp)
-{
-    paramIn(cp, base + ".lastCommand", lastCommand);
-    int bufferSize;
-    paramIn(cp, base + ".outBuffer.size", bufferSize);
-    uint8_t *buffer = new uint8_t[bufferSize];
-    arrayParamIn(cp, base + ".outBuffer.elts", buffer,
-            bufferSize*sizeof(uint8_t));
-    for (int i = 0; i < bufferSize; ++i) {
-        outBuffer.push(buffer[i]);
-    }
-    delete[] buffer;
-}
-
-void
-X86ISA::PS2Mouse::serialize(const std::string &base, CheckpointOut &cp)
-{
-    uint8_t statusData = status.__data;
-    paramOut(cp, base + ".lastCommand", lastCommand);
-    int bufferSize = outBuffer.size();
-    paramOut(cp, base + ".outBuffer.size", bufferSize);
-    uint8_t *buffer = new uint8_t[bufferSize];
-    for (int i = 0; i < bufferSize; ++i) {
-        buffer[i] = outBuffer.front();
-        outBuffer.pop();
-    }
-    arrayParamOut(cp, base + ".outBuffer.elts", buffer,
-            bufferSize*sizeof(uint8_t));
-    delete[] buffer;
-    paramOut(cp, base + ".status", statusData);
+    paramOut(cp, base + ".status", status);
     paramOut(cp, base + ".resolution", resolution);
     paramOut(cp, base + ".sampleRate", sampleRate);
 }
@@ -551,22 +533,11 @@
 void
 X86ISA::PS2Mouse::unserialize(const std::string &base, CheckpointIn &cp)
 {
-    uint8_t statusData;
-    paramIn(cp, base + ".lastCommand", lastCommand);
-    int bufferSize;
-    paramIn(cp, base + ".outBuffer.size", bufferSize);
-    uint8_t *buffer = new uint8_t[bufferSize];
-    arrayParamIn(cp, base + ".outBuffer.elts", buffer,
-            bufferSize*sizeof(uint8_t));
-    for (int i = 0; i < bufferSize; ++i) {
-        outBuffer.push(buffer[i]);
-    }
-    delete[] buffer;
-    paramIn(cp, base + ".status", statusData);
+    PS2Device::unserialize(base, cp);
+
+    paramIn(cp, base + ".status", status);
     paramIn(cp, base + ".resolution", resolution);
     paramIn(cp, base + ".sampleRate", sampleRate);
-
-    status.__data = statusData;
 }
 
 X86ISA::I8042 *
diff -r 703f42dbca21 -r 179bc8ca2d8c src/dev/x86/i8042.hh
--- a/src/dev/x86/i8042.hh      Fri Aug 07 09:59:14 2015 +0100
+++ b/src/dev/x86/i8042.hh      Fri Aug 07 09:59:15 2015 +0100
@@ -31,7 +31,7 @@
 #ifndef __DEV_X86_I8042_HH__
 #define __DEV_X86_I8042_HH__
 
-#include <queue>
+#include <deque>
 
 #include "dev/x86/intdev.hh"
 #include "dev/io_device.hh"
@@ -45,7 +45,7 @@
 class PS2Device
 {
   protected:
-    std::queue<uint8_t> outBuffer;
+    std::deque<uint8_t> outBuffer;
 
     static const uint16_t NoCommand = (uint16_t)(-1);
 
@@ -61,6 +61,9 @@
     PS2Device() : lastCommand(NoCommand)
     {}
 
+    virtual void serialize(const std::string &base, CheckpointOut &cp) const;
+    virtual void unserialize(const std::string &base, CheckpointIn &cp);
+
     bool hasData()
     {
         return !outBuffer.empty();
@@ -69,7 +72,7 @@
     uint8_t getData()
     {
         uint8_t data = outBuffer.front();
-        outBuffer.pop();
+        outBuffer.pop_front();
         return data;
     }
 
@@ -117,8 +120,10 @@
 
     bool processData(uint8_t data);
 
-    void serialize(const std::string &base, CheckpointOut &cp);
-    void unserialize(const std::string &base, CheckpointIn &cp);
+    void serialize(const std::string &base,
+                   CheckpointOut &cp) const M5_ATTR_OVERRIDE;
+    void unserialize(const std::string &base,
+                     CheckpointIn &cp) M5_ATTR_OVERRIDE;
 };
 
 class PS2Keyboard : public PS2Device
@@ -149,9 +154,6 @@
 
   public:
     bool processData(uint8_t data);
-
-    void serialize(const std::string &base, CheckpointOut &cp);
-    void unserialize(const std::string &base, CheckpointIn &cp);
 };
 
 class I8042 : public BasicPioDevice
@@ -247,7 +249,7 @@
 
     Tick write(PacketPtr pkt);
 
-    void serializeOld(CheckpointOut &cp) M5_ATTR_OVERRIDE;
+    void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
     void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
 };
 
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to