From 62e05ed78a0f24982e4066adb45dc220c9e200ea Mon Sep 17 00:00:00 2001 From: Joel Hestness Date: Sun, 6 Feb 2011 22:14:18 -0800 Subject: x86: Add checkpointing capability to devices Add checkpointing capability to the Intel 8254 timer, CMOS, I8042, PS2 Keyboard and Mouse, I82094AA, I8237, I8254, I8259, and speaker devices --- src/dev/intel_8254_timer.cc | 4 +- src/dev/x86/cmos.cc | 20 ++++++++ src/dev/x86/cmos.hh | 4 ++ src/dev/x86/i8042.cc | 109 ++++++++++++++++++++++++++++++++++++++++++++ src/dev/x86/i8042.hh | 11 +++++ src/dev/x86/i82094aa.cc | 29 ++++++++++++ src/dev/x86/i82094aa.hh | 3 ++ src/dev/x86/i8237.cc | 14 +++++- src/dev/x86/i8237.hh | 3 ++ src/dev/x86/i8254.cc | 12 +++++ src/dev/x86/i8254.hh | 4 ++ src/dev/x86/i8259.cc | 36 +++++++++++++++ src/dev/x86/i8259.hh | 3 ++ src/dev/x86/speaker.cc | 15 ++++++ src/dev/x86/speaker.hh | 4 ++ 15 files changed, 269 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/dev/intel_8254_timer.cc b/src/dev/intel_8254_timer.cc index aee716c01..cad59bbdb 100644 --- a/src/dev/intel_8254_timer.cc +++ b/src/dev/intel_8254_timer.cc @@ -247,7 +247,9 @@ Intel8254Timer::Counter::unserialize(const string &base, Checkpoint *cp, paramIn(cp, section, base + ".read_byte", read_byte); paramIn(cp, section, base + ".write_byte", write_byte); - Tick event_tick; + Tick event_tick = 0; + if (event.scheduled()) + parent->deschedule(event); paramIn(cp, section, base + ".event_tick", event_tick); if (event_tick) parent->schedule(event, event_tick); diff --git a/src/dev/x86/cmos.cc b/src/dev/x86/cmos.cc index 122b531ca..aa92521dc 100644 --- a/src/dev/x86/cmos.cc +++ b/src/dev/x86/cmos.cc @@ -111,6 +111,26 @@ X86ISA::Cmos::writeRegister(uint8_t reg, uint8_t val) } } +void +X86ISA::Cmos::serialize(std::ostream &os) +{ + SERIALIZE_SCALAR(address); + SERIALIZE_ARRAY(regs, numRegs); + + // Serialize the timer + rtc.serialize("rtc", os); +} + +void +X86ISA::Cmos::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(address); + UNSERIALIZE_ARRAY(regs, numRegs); + + // Serialize the timer + rtc.unserialize("rtc", cp, section); +} + X86ISA::Cmos * CmosParams::create() { diff --git a/src/dev/x86/cmos.hh b/src/dev/x86/cmos.hh index 22cd9e3af..83d92e721 100644 --- a/src/dev/x86/cmos.hh +++ b/src/dev/x86/cmos.hh @@ -82,6 +82,10 @@ class Cmos : public BasicPioDevice Tick read(PacketPtr pkt); Tick write(PacketPtr pkt); + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); + }; } // namespace X86ISA diff --git a/src/dev/x86/i8042.cc b/src/dev/x86/i8042.cc index afcbfdfb4..fb1412615 100644 --- a/src/dev/x86/i8042.cc +++ b/src/dev/x86/i8042.cc @@ -439,6 +439,115 @@ X86ISA::I8042::write(PacketPtr pkt) return latency; } +void +X86ISA::I8042::serialize(std::ostream &os) +{ + uint8_t statusRegData = statusReg.__data; + uint8_t commandByteData = commandByte.__data; + + SERIALIZE_SCALAR(dataPort); + SERIALIZE_SCALAR(commandPort); + SERIALIZE_SCALAR(statusRegData); + SERIALIZE_SCALAR(commandByteData); + SERIALIZE_SCALAR(dataReg); + SERIALIZE_SCALAR(lastCommand); + mouse.serialize("mouse", os); + keyboard.serialize("keyboard", os); +} + +void +X86ISA::I8042::unserialize(Checkpoint *cp, const std::string §ion) +{ + uint8_t statusRegData; + uint8_t commandByteData; + + UNSERIALIZE_SCALAR(dataPort); + UNSERIALIZE_SCALAR(commandPort); + UNSERIALIZE_SCALAR(statusRegData); + UNSERIALIZE_SCALAR(commandByteData); + UNSERIALIZE_SCALAR(dataReg); + UNSERIALIZE_SCALAR(lastCommand); + mouse.unserialize("mouse", cp, section); + keyboard.unserialize("keyboard", cp, section); + + statusReg.__data = statusRegData; + commandByte.__data = commandByteData; +} + +void +X86ISA::PS2Keyboard::serialize(const std::string &base, std::ostream &os) +{ + paramOut(os, base + ".lastCommand", lastCommand); + int bufferSize = outBuffer.size(); + paramOut(os, 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(os, base + ".outBuffer.elts", buffer, + bufferSize*sizeof(uint8_t)); + delete buffer; +} + +void +X86ISA::PS2Keyboard::unserialize(const std::string &base, Checkpoint *cp, + const std::string §ion) +{ + paramIn(cp, section, base + ".lastCommand", lastCommand); + int bufferSize; + paramIn(cp, section, base + ".outBuffer.size", bufferSize); + uint8_t *buffer = new uint8_t[bufferSize]; + arrayParamIn(cp, section, 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, std::ostream &os) +{ + uint8_t statusData = status.__data; + paramOut(os, base + ".lastCommand", lastCommand); + int bufferSize = outBuffer.size(); + paramOut(os, 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(os, base + ".outBuffer.elts", buffer, + bufferSize*sizeof(uint8_t)); + delete buffer; + paramOut(os, base + ".status", statusData); + paramOut(os, base + ".resolution", resolution); + paramOut(os, base + ".sampleRate", sampleRate); +} + +void +X86ISA::PS2Mouse::unserialize(const std::string &base, Checkpoint *cp, + const std::string §ion) +{ + uint8_t statusData; + paramIn(cp, section, base + ".lastCommand", lastCommand); + int bufferSize; + paramIn(cp, section, base + ".outBuffer.size", bufferSize); + uint8_t *buffer = new uint8_t[bufferSize]; + arrayParamIn(cp, section, base + ".outBuffer.elts", buffer, + bufferSize*sizeof(uint8_t)); + for (int i = 0; i < bufferSize; ++i) { + outBuffer.push(buffer[i]); + } + delete buffer; + paramIn(cp, section, base + ".status", statusData); + paramIn(cp, section, base + ".resolution", resolution); + paramIn(cp, section, base + ".sampleRate", sampleRate); + + status.__data = statusData; +} + X86ISA::I8042 * I8042Params::create() { diff --git a/src/dev/x86/i8042.hh b/src/dev/x86/i8042.hh index 7aa59e9a7..b14d254ca 100644 --- a/src/dev/x86/i8042.hh +++ b/src/dev/x86/i8042.hh @@ -116,6 +116,10 @@ class PS2Mouse : public PS2Device {} bool processData(uint8_t data); + + void serialize(const std::string &base, std::ostream &os); + void unserialize(const std::string &base, Checkpoint *cp, + const std::string §ion); }; class PS2Keyboard : public PS2Device @@ -146,6 +150,10 @@ class PS2Keyboard : public PS2Device public: bool processData(uint8_t data); + + void serialize(const std::string &base, std::ostream &os); + void unserialize(const std::string &base, Checkpoint *cp, + const std::string §ion); }; class I8042 : public BasicPioDevice @@ -252,6 +260,9 @@ class I8042 : public BasicPioDevice Tick read(PacketPtr pkt); Tick write(PacketPtr pkt); + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); }; } // namespace X86ISA diff --git a/src/dev/x86/i82094aa.cc b/src/dev/x86/i82094aa.cc index 65b3ee732..cb9b51d58 100644 --- a/src/dev/x86/i82094aa.cc +++ b/src/dev/x86/i82094aa.cc @@ -236,6 +236,35 @@ X86ISA::I82094AA::registerLocalApic(int initialId, Interrupts *localApic) localApics[initialId] = localApic; } +void +X86ISA::I82094AA::serialize(std::ostream &os) +{ + uint64_t* redirTableArray = (uint64_t*)redirTable; + SERIALIZE_SCALAR(regSel); + SERIALIZE_SCALAR(initialApicId); + SERIALIZE_SCALAR(id); + SERIALIZE_SCALAR(arbId); + SERIALIZE_SCALAR(lowestPriorityOffset); + SERIALIZE_ARRAY(redirTableArray, TableSize); + SERIALIZE_ARRAY(pinStates, TableSize); +} + +void +X86ISA::I82094AA::unserialize(Checkpoint *cp, const std::string §ion) +{ + uint64_t redirTableArray[TableSize]; + UNSERIALIZE_SCALAR(regSel); + UNSERIALIZE_SCALAR(initialApicId); + UNSERIALIZE_SCALAR(id); + UNSERIALIZE_SCALAR(arbId); + UNSERIALIZE_SCALAR(lowestPriorityOffset); + UNSERIALIZE_ARRAY(redirTableArray, TableSize); + UNSERIALIZE_ARRAY(pinStates, TableSize); + for (int i = 0; i < TableSize; i++) { + redirTable[i] = (RedirTableEntry)redirTableArray[i]; + } +} + X86ISA::I82094AA * I82094AAParams::create() { diff --git a/src/dev/x86/i82094aa.hh b/src/dev/x86/i82094aa.hh index 70717f6ba..442163bbf 100644 --- a/src/dev/x86/i82094aa.hh +++ b/src/dev/x86/i82094aa.hh @@ -130,6 +130,9 @@ class I82094AA : public PioDevice, public IntDev void raiseInterruptPin(int number); void lowerInterruptPin(int number); void registerLocalApic(int id, Interrupts *localApic); + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); }; } // namespace X86ISA diff --git a/src/dev/x86/i8237.cc b/src/dev/x86/i8237.cc index f6ea9d75f..a43c1ec91 100644 --- a/src/dev/x86/i8237.cc +++ b/src/dev/x86/i8237.cc @@ -119,12 +119,24 @@ X86ISA::I8237::write(PacketPtr pkt) case 0xf: panic("Write to i8237 write all mask register bits unimplemented.\n"); default: - panic("Write to undefined i8254 register.\n"); + panic("Write to undefined i8237 register.\n"); } pkt->makeAtomicResponse(); return latency; } +void +X86ISA::I8237::serialize(std::ostream &os) +{ + SERIALIZE_SCALAR(maskReg); +} + +void +X86ISA::I8237::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(maskReg); +} + X86ISA::I8237 * I8237Params::create() { diff --git a/src/dev/x86/i8237.hh b/src/dev/x86/i8237.hh index 1db91236a..28d9e85a3 100644 --- a/src/dev/x86/i8237.hh +++ b/src/dev/x86/i8237.hh @@ -59,6 +59,9 @@ class I8237 : public BasicPioDevice Tick read(PacketPtr pkt); Tick write(PacketPtr pkt); + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); }; } // namespace X86ISA diff --git a/src/dev/x86/i8254.cc b/src/dev/x86/i8254.cc index 5eb28844a..dd1ff7c5e 100644 --- a/src/dev/x86/i8254.cc +++ b/src/dev/x86/i8254.cc @@ -76,6 +76,18 @@ X86ISA::I8254::write(PacketPtr pkt) return latency; } +void +X86ISA::I8254::serialize(std::ostream &os) +{ + pit.serialize("pit", os); +} + +void +X86ISA::I8254::unserialize(Checkpoint *cp, const std::string §ion) +{ + pit.unserialize("pit", cp, section); +} + X86ISA::I8254 * I8254Params::create() { diff --git a/src/dev/x86/i8254.hh b/src/dev/x86/i8254.hh index e295f5105..e6d500f42 100644 --- a/src/dev/x86/i8254.hh +++ b/src/dev/x86/i8254.hh @@ -109,6 +109,10 @@ class I8254 : public BasicPioDevice { pit.writeControl(val); } + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); + }; } // namespace X86ISA diff --git a/src/dev/x86/i8259.cc b/src/dev/x86/i8259.cc index b868295eb..651196b47 100644 --- a/src/dev/x86/i8259.cc +++ b/src/dev/x86/i8259.cc @@ -303,6 +303,42 @@ X86ISA::I8259::getVector() return line | vectorOffset; } +void +X86ISA::I8259::serialize(std::ostream &os) +{ + SERIALIZE_ARRAY(pinStates, NumLines); + SERIALIZE_ENUM(mode); + SERIALIZE_SCALAR(IRR); + SERIALIZE_SCALAR(ISR); + SERIALIZE_SCALAR(IMR); + SERIALIZE_SCALAR(vectorOffset); + SERIALIZE_SCALAR(cascadeMode); + SERIALIZE_SCALAR(cascadeBits); + SERIALIZE_SCALAR(edgeTriggered); + SERIALIZE_SCALAR(readIRR); + SERIALIZE_SCALAR(expectICW4); + SERIALIZE_SCALAR(initControlWord); + SERIALIZE_SCALAR(autoEOI); +} + +void +X86ISA::I8259::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_ARRAY(pinStates, NumLines); + UNSERIALIZE_ENUM(mode); + UNSERIALIZE_SCALAR(IRR); + UNSERIALIZE_SCALAR(ISR); + UNSERIALIZE_SCALAR(IMR); + UNSERIALIZE_SCALAR(vectorOffset); + UNSERIALIZE_SCALAR(cascadeMode); + UNSERIALIZE_SCALAR(cascadeBits); + UNSERIALIZE_SCALAR(edgeTriggered); + UNSERIALIZE_SCALAR(readIRR); + UNSERIALIZE_SCALAR(expectICW4); + UNSERIALIZE_SCALAR(initControlWord); + UNSERIALIZE_SCALAR(autoEOI); +} + X86ISA::I8259 * I8259Params::create() { diff --git a/src/dev/x86/i8259.hh b/src/dev/x86/i8259.hh index a9362d403..2a5d5f6aa 100644 --- a/src/dev/x86/i8259.hh +++ b/src/dev/x86/i8259.hh @@ -108,6 +108,9 @@ class I8259 : public BasicPioDevice, public IntDev void raiseInterruptPin(int number); void lowerInterruptPin(int number); int getVector(); + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); }; } // namespace X86ISA diff --git a/src/dev/x86/speaker.cc b/src/dev/x86/speaker.cc index c6eb9db9e..b0f4dcd8b 100644 --- a/src/dev/x86/speaker.cc +++ b/src/dev/x86/speaker.cc @@ -72,6 +72,21 @@ X86ISA::Speaker::write(PacketPtr pkt) return latency; } +void +X86ISA::Speaker::serialize(std::ostream &os) +{ + uint8_t controlValData = controlVal.__data; + SERIALIZE_SCALAR(controlValData); +} + +void +X86ISA::Speaker::unserialize(Checkpoint *cp, const std::string §ion) +{ + uint8_t controlValData; + UNSERIALIZE_SCALAR(controlValData); + controlVal.__data = controlValData; +} + X86ISA::Speaker * PcSpeakerParams::create() { diff --git a/src/dev/x86/speaker.hh b/src/dev/x86/speaker.hh index fb7476ca0..5aa1ccf0a 100644 --- a/src/dev/x86/speaker.hh +++ b/src/dev/x86/speaker.hh @@ -72,6 +72,10 @@ class Speaker : public BasicPioDevice Tick read(PacketPtr pkt); Tick write(PacketPtr pkt); + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); + }; } // namespace X86ISA -- cgit v1.2.3