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
This commit is contained in:
Joel Hestness 2011-02-06 22:14:18 -08:00
parent 911ccef6c0
commit 62e05ed78a
15 changed files with 269 additions and 2 deletions

View file

@ -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);

View file

@ -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 &section)
{
UNSERIALIZE_SCALAR(address);
UNSERIALIZE_ARRAY(regs, numRegs);
// Serialize the timer
rtc.unserialize("rtc", cp, section);
}
X86ISA::Cmos *
CmosParams::create()
{

View file

@ -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 &section);
};
} // namespace X86ISA

View file

@ -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 &section)
{
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 &section)
{
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 &section)
{
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()
{

View file

@ -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 &section);
};
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 &section);
};
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 &section);
};
} // namespace X86ISA

View file

@ -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 &section)
{
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()
{

View file

@ -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 &section);
};
} // namespace X86ISA

View file

@ -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 &section)
{
UNSERIALIZE_SCALAR(maskReg);
}
X86ISA::I8237 *
I8237Params::create()
{

View file

@ -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 &section);
};
} // namespace X86ISA

View file

@ -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 &section)
{
pit.unserialize("pit", cp, section);
}
X86ISA::I8254 *
I8254Params::create()
{

View file

@ -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 &section);
};
} // namespace X86ISA

View file

@ -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 &section)
{
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()
{

View file

@ -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 &section);
};
} // namespace X86ISA

View file

@ -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 &section)
{
uint8_t controlValData;
UNSERIALIZE_SCALAR(controlValData);
controlVal.__data = controlValData;
}
X86ISA::Speaker *
PcSpeakerParams::create()
{

View file

@ -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 &section);
};
} // namespace X86ISA