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:
parent
911ccef6c0
commit
62e05ed78a
15 changed files with 269 additions and 2 deletions
|
@ -247,7 +247,9 @@ Intel8254Timer::Counter::unserialize(const string &base, Checkpoint *cp,
|
||||||
paramIn(cp, section, base + ".read_byte", read_byte);
|
paramIn(cp, section, base + ".read_byte", read_byte);
|
||||||
paramIn(cp, section, base + ".write_byte", write_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);
|
paramIn(cp, section, base + ".event_tick", event_tick);
|
||||||
if (event_tick)
|
if (event_tick)
|
||||||
parent->schedule(event, event_tick);
|
parent->schedule(event, event_tick);
|
||||||
|
|
|
@ -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 *
|
X86ISA::Cmos *
|
||||||
CmosParams::create()
|
CmosParams::create()
|
||||||
{
|
{
|
||||||
|
|
|
@ -82,6 +82,10 @@ class Cmos : public BasicPioDevice
|
||||||
Tick read(PacketPtr pkt);
|
Tick read(PacketPtr pkt);
|
||||||
|
|
||||||
Tick write(PacketPtr pkt);
|
Tick write(PacketPtr pkt);
|
||||||
|
|
||||||
|
virtual void serialize(std::ostream &os);
|
||||||
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace X86ISA
|
} // namespace X86ISA
|
||||||
|
|
|
@ -439,6 +439,115 @@ X86ISA::I8042::write(PacketPtr pkt)
|
||||||
return latency;
|
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 *
|
X86ISA::I8042 *
|
||||||
I8042Params::create()
|
I8042Params::create()
|
||||||
{
|
{
|
||||||
|
|
|
@ -116,6 +116,10 @@ class PS2Mouse : public PS2Device
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool processData(uint8_t data);
|
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
|
class PS2Keyboard : public PS2Device
|
||||||
|
@ -146,6 +150,10 @@ class PS2Keyboard : public PS2Device
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool processData(uint8_t data);
|
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
|
class I8042 : public BasicPioDevice
|
||||||
|
@ -252,6 +260,9 @@ class I8042 : public BasicPioDevice
|
||||||
Tick read(PacketPtr pkt);
|
Tick read(PacketPtr pkt);
|
||||||
|
|
||||||
Tick write(PacketPtr pkt);
|
Tick write(PacketPtr pkt);
|
||||||
|
|
||||||
|
virtual void serialize(std::ostream &os);
|
||||||
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace X86ISA
|
} // namespace X86ISA
|
||||||
|
|
|
@ -236,6 +236,35 @@ X86ISA::I82094AA::registerLocalApic(int initialId, Interrupts *localApic)
|
||||||
localApics[initialId] = 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 *
|
X86ISA::I82094AA *
|
||||||
I82094AAParams::create()
|
I82094AAParams::create()
|
||||||
{
|
{
|
||||||
|
|
|
@ -130,6 +130,9 @@ class I82094AA : public PioDevice, public IntDev
|
||||||
void raiseInterruptPin(int number);
|
void raiseInterruptPin(int number);
|
||||||
void lowerInterruptPin(int number);
|
void lowerInterruptPin(int number);
|
||||||
void registerLocalApic(int id, Interrupts *localApic);
|
void registerLocalApic(int id, Interrupts *localApic);
|
||||||
|
|
||||||
|
virtual void serialize(std::ostream &os);
|
||||||
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace X86ISA
|
} // namespace X86ISA
|
||||||
|
|
|
@ -119,12 +119,24 @@ X86ISA::I8237::write(PacketPtr pkt)
|
||||||
case 0xf:
|
case 0xf:
|
||||||
panic("Write to i8237 write all mask register bits unimplemented.\n");
|
panic("Write to i8237 write all mask register bits unimplemented.\n");
|
||||||
default:
|
default:
|
||||||
panic("Write to undefined i8254 register.\n");
|
panic("Write to undefined i8237 register.\n");
|
||||||
}
|
}
|
||||||
pkt->makeAtomicResponse();
|
pkt->makeAtomicResponse();
|
||||||
return latency;
|
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 *
|
X86ISA::I8237 *
|
||||||
I8237Params::create()
|
I8237Params::create()
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,6 +59,9 @@ class I8237 : public BasicPioDevice
|
||||||
Tick read(PacketPtr pkt);
|
Tick read(PacketPtr pkt);
|
||||||
|
|
||||||
Tick write(PacketPtr pkt);
|
Tick write(PacketPtr pkt);
|
||||||
|
|
||||||
|
virtual void serialize(std::ostream &os);
|
||||||
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace X86ISA
|
} // namespace X86ISA
|
||||||
|
|
|
@ -76,6 +76,18 @@ X86ISA::I8254::write(PacketPtr pkt)
|
||||||
return latency;
|
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 *
|
X86ISA::I8254 *
|
||||||
I8254Params::create()
|
I8254Params::create()
|
||||||
{
|
{
|
||||||
|
|
|
@ -109,6 +109,10 @@ class I8254 : public BasicPioDevice
|
||||||
{
|
{
|
||||||
pit.writeControl(val);
|
pit.writeControl(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void serialize(std::ostream &os);
|
||||||
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace X86ISA
|
} // namespace X86ISA
|
||||||
|
|
|
@ -303,6 +303,42 @@ X86ISA::I8259::getVector()
|
||||||
return line | vectorOffset;
|
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 *
|
X86ISA::I8259 *
|
||||||
I8259Params::create()
|
I8259Params::create()
|
||||||
{
|
{
|
||||||
|
|
|
@ -108,6 +108,9 @@ class I8259 : public BasicPioDevice, public IntDev
|
||||||
void raiseInterruptPin(int number);
|
void raiseInterruptPin(int number);
|
||||||
void lowerInterruptPin(int number);
|
void lowerInterruptPin(int number);
|
||||||
int getVector();
|
int getVector();
|
||||||
|
|
||||||
|
virtual void serialize(std::ostream &os);
|
||||||
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace X86ISA
|
} // namespace X86ISA
|
||||||
|
|
|
@ -72,6 +72,21 @@ X86ISA::Speaker::write(PacketPtr pkt)
|
||||||
return latency;
|
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 *
|
X86ISA::Speaker *
|
||||||
PcSpeakerParams::create()
|
PcSpeakerParams::create()
|
||||||
{
|
{
|
||||||
|
|
|
@ -72,6 +72,10 @@ class Speaker : public BasicPioDevice
|
||||||
Tick read(PacketPtr pkt);
|
Tick read(PacketPtr pkt);
|
||||||
|
|
||||||
Tick write(PacketPtr pkt);
|
Tick write(PacketPtr pkt);
|
||||||
|
|
||||||
|
virtual void serialize(std::ostream &os);
|
||||||
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace X86ISA
|
} // namespace X86ISA
|
||||||
|
|
Loading…
Reference in a new issue