ARM: Add checkpointing support
This commit is contained in:
parent
432fa0aad6
commit
a1e8225975
|
@ -178,10 +178,18 @@ namespace ArmISA
|
|||
}
|
||||
|
||||
void serialize(EventManager *em, std::ostream &os)
|
||||
{}
|
||||
{
|
||||
DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
|
||||
SERIALIZE_ARRAY(miscRegs, NumMiscRegs);
|
||||
}
|
||||
void unserialize(EventManager *em, Checkpoint *cp,
|
||||
const std::string §ion)
|
||||
{}
|
||||
{
|
||||
DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
|
||||
UNSERIALIZE_ARRAY(miscRegs, NumMiscRegs);
|
||||
CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
|
||||
updateRegMap(tmp_cpsr);
|
||||
}
|
||||
|
||||
ISA()
|
||||
{
|
||||
|
|
|
@ -99,9 +99,9 @@ LinuxArmSystem::LinuxArmSystem(Params *p)
|
|||
}
|
||||
|
||||
void
|
||||
LinuxArmSystem::startup()
|
||||
LinuxArmSystem::initState()
|
||||
{
|
||||
ArmSystem::startup();
|
||||
ArmSystem::initState();
|
||||
ThreadContext *tc = threadContexts[0];
|
||||
|
||||
// Set the initial PC to be at start of the kernel code
|
||||
|
@ -117,7 +117,6 @@ LinuxArmSystem::~LinuxArmSystem()
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
LinuxArmSystem *
|
||||
LinuxArmSystemParams::create()
|
||||
{
|
||||
|
|
|
@ -67,8 +67,8 @@ class LinuxArmSystem : public ArmSystem
|
|||
LinuxArmSystem(Params *p);
|
||||
~LinuxArmSystem();
|
||||
|
||||
/** Initialize the CPU for booting */
|
||||
void startup();
|
||||
void initState();
|
||||
|
||||
private:
|
||||
#ifndef NDEBUG
|
||||
/** Event to halt the simulator if the kernel calls panic() */
|
||||
|
|
|
@ -48,6 +48,8 @@
|
|||
#include "arch/arm/vtophys.hh"
|
||||
#include "config/full_system.hh"
|
||||
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
namespace ArmISA {
|
||||
|
||||
struct VAddr
|
||||
|
@ -71,39 +73,6 @@ struct PTE
|
|||
|
||||
};
|
||||
|
||||
struct TlbRange
|
||||
{
|
||||
Addr va;
|
||||
Addr size;
|
||||
int contextId;
|
||||
bool global;
|
||||
|
||||
inline bool
|
||||
operator<(const TlbRange &r2) const
|
||||
{
|
||||
if (!(global || r2.global)) {
|
||||
if (contextId < r2.contextId)
|
||||
return true;
|
||||
else if (contextId > r2.contextId)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (va < r2.va)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator==(const TlbRange &r2) const
|
||||
{
|
||||
return va == r2.va &&
|
||||
size == r2.size &&
|
||||
contextId == r2.contextId &&
|
||||
global == r2.global;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// ITB/DTB table entry
|
||||
struct TlbEntry
|
||||
{
|
||||
|
@ -143,10 +112,8 @@ struct TlbEntry
|
|||
|
||||
// Access permissions
|
||||
bool xn; // Execute Never
|
||||
uint8_t ap:3; // Access permissions bits
|
||||
uint8_t domain:4; // Access Domain
|
||||
|
||||
TlbRange range; // For fast TLB searching
|
||||
uint8_t ap; // Access permissions bits
|
||||
uint8_t domain; // Access Domain
|
||||
|
||||
//Construct an entry that maps to physical address addr for SE mode
|
||||
TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr)
|
||||
|
@ -196,9 +163,49 @@ struct TlbEntry
|
|||
return (pfn << N) | (va & size);
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os) { panic("Need to Implement\n"); }
|
||||
void unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{ panic("Need to Implement\n");}
|
||||
void
|
||||
serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_SCALAR(pfn);
|
||||
SERIALIZE_SCALAR(size);
|
||||
SERIALIZE_SCALAR(vpn);
|
||||
SERIALIZE_SCALAR(asid);
|
||||
SERIALIZE_SCALAR(N);
|
||||
SERIALIZE_SCALAR(global);
|
||||
SERIALIZE_SCALAR(valid);
|
||||
SERIALIZE_SCALAR(nonCacheable);
|
||||
SERIALIZE_SCALAR(sNp);
|
||||
SERIALIZE_ENUM(mtype);
|
||||
SERIALIZE_SCALAR(innerAttrs);
|
||||
SERIALIZE_SCALAR(outerAttrs);
|
||||
SERIALIZE_SCALAR(shareable);
|
||||
SERIALIZE_SCALAR(attributes);
|
||||
SERIALIZE_SCALAR(xn);
|
||||
SERIALIZE_SCALAR(ap);
|
||||
SERIALIZE_SCALAR(domain);
|
||||
}
|
||||
void
|
||||
unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_SCALAR(pfn);
|
||||
UNSERIALIZE_SCALAR(size);
|
||||
UNSERIALIZE_SCALAR(vpn);
|
||||
UNSERIALIZE_SCALAR(asid);
|
||||
UNSERIALIZE_SCALAR(N);
|
||||
UNSERIALIZE_SCALAR(global);
|
||||
UNSERIALIZE_SCALAR(valid);
|
||||
UNSERIALIZE_SCALAR(nonCacheable);
|
||||
UNSERIALIZE_SCALAR(sNp);
|
||||
UNSERIALIZE_ENUM(mtype);
|
||||
UNSERIALIZE_SCALAR(innerAttrs);
|
||||
UNSERIALIZE_SCALAR(outerAttrs);
|
||||
UNSERIALIZE_SCALAR(shareable);
|
||||
UNSERIALIZE_SCALAR(attributes);
|
||||
UNSERIALIZE_SCALAR(xn);
|
||||
UNSERIALIZE_SCALAR(ap);
|
||||
UNSERIALIZE_SCALAR(domain);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -59,10 +59,20 @@ TableWalker::~TableWalker()
|
|||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
drain(Event *de)
|
||||
unsigned int TableWalker::drain(Event *de)
|
||||
{
|
||||
panic("Not implemented\n");
|
||||
if (stateQueueL1.size() != 0 || stateQueueL2.size() != 0)
|
||||
{
|
||||
changeState(Draining);
|
||||
DPRINTF(Checkpoint, "TableWalker busy, wait to drain\n");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
changeState(Drained);
|
||||
DPRINTF(Checkpoint, "TableWalker free, no need to drain\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Port*
|
||||
|
|
|
@ -350,7 +350,7 @@ class TableWalker : public MemObject
|
|||
return dynamic_cast<const Params *>(_params);
|
||||
}
|
||||
|
||||
virtual unsigned int drain(Event *de) { panic("write me\n"); }
|
||||
virtual unsigned int drain(Event *de);
|
||||
virtual Port *getPort(const std::string &if_name, int idx = -1);
|
||||
|
||||
Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode,
|
||||
|
|
|
@ -245,14 +245,24 @@ TLB::flushMva(Addr mva)
|
|||
void
|
||||
TLB::serialize(ostream &os)
|
||||
{
|
||||
panic("Implement Serialize\n");
|
||||
DPRINTF(Checkpoint, "Serializing Arm TLB\n");
|
||||
|
||||
SERIALIZE_SCALAR(_attr);
|
||||
for(int i = 0; i < size; i++){
|
||||
nameOut(os, csprintf("%s.TlbEntry%d", name(), i));
|
||||
table[i].serialize(os);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TLB::unserialize(Checkpoint *cp, const string §ion)
|
||||
{
|
||||
DPRINTF(Checkpoint, "Unserializing Arm TLB\n");
|
||||
|
||||
panic("Need to properly unserialize TLB\n");
|
||||
UNSERIALIZE_SCALAR(_attr);
|
||||
for(int i = 0; i < size; i++){
|
||||
table[i].unserialize(cp, csprintf("%s.TlbEntry%d", section, i));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -83,8 +83,6 @@ class TLB : public BaseTLB
|
|||
MustBeOne = 0x80
|
||||
};
|
||||
protected:
|
||||
typedef std::multimap<Addr, int> PageTable;
|
||||
PageTable lookupTable; // Quick lookup into page table
|
||||
|
||||
TlbEntry *table; // the Page Table
|
||||
int size; // TLB Size
|
||||
|
|
|
@ -495,13 +495,53 @@ Gic::addressRanges(AddrRangeList &range_list)
|
|||
void
|
||||
Gic::serialize(std::ostream &os)
|
||||
{
|
||||
panic("Need to implement serialization\n");
|
||||
DPRINTF(Checkpoint, "Serializing Arm GIC\n");
|
||||
|
||||
SERIALIZE_SCALAR(distAddr);
|
||||
SERIALIZE_SCALAR(cpuAddr);
|
||||
SERIALIZE_SCALAR(distPioDelay);
|
||||
SERIALIZE_SCALAR(cpuPioDelay);
|
||||
SERIALIZE_SCALAR(enabled);
|
||||
SERIALIZE_SCALAR(itLines);
|
||||
SERIALIZE_SCALAR(itLinesLog2);
|
||||
SERIALIZE_ARRAY(intEnabled, 32);
|
||||
SERIALIZE_ARRAY(pendingInt, 32);
|
||||
SERIALIZE_ARRAY(activeInt, 32);
|
||||
SERIALIZE_ARRAY(iccrpr, 8);
|
||||
SERIALIZE_ARRAY(intPriority, 1020);
|
||||
SERIALIZE_ARRAY(cpuTarget, 1020);
|
||||
SERIALIZE_ARRAY(intConfig, 64);
|
||||
SERIALIZE_ARRAY(cpuEnabled, 8);
|
||||
SERIALIZE_ARRAY(cpuPriority, 8);
|
||||
SERIALIZE_ARRAY(cpuBpr, 8);
|
||||
SERIALIZE_ARRAY(cpuHighestInt, 8);
|
||||
SERIALIZE_SCALAR(irqEnable);
|
||||
}
|
||||
|
||||
void
|
||||
Gic::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
panic("Need to implement serialization\n");
|
||||
DPRINTF(Checkpoint, "Unserializing Arm GIC\n");
|
||||
|
||||
UNSERIALIZE_SCALAR(distAddr);
|
||||
UNSERIALIZE_SCALAR(cpuAddr);
|
||||
UNSERIALIZE_SCALAR(distPioDelay);
|
||||
UNSERIALIZE_SCALAR(cpuPioDelay);
|
||||
UNSERIALIZE_SCALAR(enabled);
|
||||
UNSERIALIZE_SCALAR(itLines);
|
||||
UNSERIALIZE_SCALAR(itLinesLog2);
|
||||
UNSERIALIZE_ARRAY(intEnabled, 32);
|
||||
UNSERIALIZE_ARRAY(pendingInt, 32);
|
||||
UNSERIALIZE_ARRAY(activeInt, 32);
|
||||
UNSERIALIZE_ARRAY(iccrpr, 8);
|
||||
UNSERIALIZE_ARRAY(intPriority, 1020);
|
||||
UNSERIALIZE_ARRAY(cpuTarget, 1020);
|
||||
UNSERIALIZE_ARRAY(intConfig, 64);
|
||||
UNSERIALIZE_ARRAY(cpuEnabled, 8);
|
||||
UNSERIALIZE_ARRAY(cpuPriority, 8);
|
||||
UNSERIALIZE_ARRAY(cpuBpr, 8);
|
||||
UNSERIALIZE_ARRAY(cpuHighestInt, 8);
|
||||
UNSERIALIZE_SCALAR(irqEnable);
|
||||
}
|
||||
|
||||
Gic *
|
||||
|
|
|
@ -274,13 +274,51 @@ Pl011::generateInterrupt()
|
|||
void
|
||||
Pl011::serialize(std::ostream &os)
|
||||
{
|
||||
panic("Need to implement serialization\n");
|
||||
DPRINTF(Checkpoint, "Serializing Arm PL011\n");
|
||||
SERIALIZE_SCALAR(control);
|
||||
SERIALIZE_SCALAR(fbrd);
|
||||
SERIALIZE_SCALAR(ibrd);
|
||||
SERIALIZE_SCALAR(lcrh);
|
||||
SERIALIZE_SCALAR(ifls);
|
||||
|
||||
uint16_t imsc_serial = imsc;
|
||||
SERIALIZE_SCALAR(imsc_serial);
|
||||
|
||||
uint16_t rawInt_serial = rawInt;
|
||||
SERIALIZE_SCALAR(rawInt_serial);
|
||||
|
||||
uint16_t maskInt_serial = maskInt;
|
||||
SERIALIZE_SCALAR(maskInt_serial);
|
||||
|
||||
SERIALIZE_SCALAR(endOnEOT);
|
||||
SERIALIZE_SCALAR(intDelay);
|
||||
}
|
||||
|
||||
void
|
||||
Pl011::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
panic("Need to implement serialization\n");
|
||||
DPRINTF(Checkpoint, "Unserializing Arm PL011\n");
|
||||
|
||||
UNSERIALIZE_SCALAR(control);
|
||||
UNSERIALIZE_SCALAR(fbrd);
|
||||
UNSERIALIZE_SCALAR(ibrd);
|
||||
UNSERIALIZE_SCALAR(lcrh);
|
||||
UNSERIALIZE_SCALAR(ifls);
|
||||
|
||||
uint16_t imsc_serial;
|
||||
UNSERIALIZE_SCALAR(imsc_serial);
|
||||
imsc = imsc_serial;
|
||||
|
||||
uint16_t rawInt_serial;
|
||||
UNSERIALIZE_SCALAR(rawInt_serial);
|
||||
rawInt = rawInt_serial;
|
||||
|
||||
uint16_t maskInt_serial;
|
||||
UNSERIALIZE_SCALAR(maskInt_serial);
|
||||
maskInt = maskInt_serial;
|
||||
|
||||
UNSERIALIZE_SCALAR(endOnEOT);
|
||||
UNSERIALIZE_SCALAR(intDelay);
|
||||
}
|
||||
|
||||
Pl011 *
|
||||
|
|
|
@ -97,13 +97,11 @@ RealViewCtrl::write(PacketPtr pkt)
|
|||
void
|
||||
RealViewCtrl::serialize(std::ostream &os)
|
||||
{
|
||||
panic("Need to implement serialization\n");
|
||||
}
|
||||
|
||||
void
|
||||
RealViewCtrl::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
panic("Need to implement serialization\n");
|
||||
}
|
||||
|
||||
RealViewCtrl *
|
||||
|
|
|
@ -219,17 +219,72 @@ Sp804::Timer::counterAtZero()
|
|||
restartCounter(loadValue);
|
||||
}
|
||||
|
||||
void
|
||||
Sp804::Timer::serialize(std::ostream &os)
|
||||
{
|
||||
DPRINTF(Checkpoint, "Serializing Arm Sp804\n");
|
||||
SERIALIZE_SCALAR(intNum);
|
||||
SERIALIZE_SCALAR(clock);
|
||||
|
||||
uint32_t control_serial = control;
|
||||
SERIALIZE_SCALAR(control_serial);
|
||||
|
||||
SERIALIZE_SCALAR(rawInt);
|
||||
SERIALIZE_SCALAR(pendingInt);
|
||||
SERIALIZE_SCALAR(loadValue);
|
||||
|
||||
bool is_in_event = zeroEvent.scheduled();
|
||||
SERIALIZE_SCALAR(is_in_event);
|
||||
|
||||
Tick event_time;
|
||||
if (is_in_event){
|
||||
event_time = zeroEvent.when();
|
||||
SERIALIZE_SCALAR(event_time);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Sp804::Timer::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
DPRINTF(Checkpoint, "Unserializing Arm Sp804\n");
|
||||
|
||||
UNSERIALIZE_SCALAR(intNum);
|
||||
UNSERIALIZE_SCALAR(clock);
|
||||
|
||||
uint32_t control_serial;
|
||||
UNSERIALIZE_SCALAR(control_serial);
|
||||
control = control_serial;
|
||||
|
||||
UNSERIALIZE_SCALAR(rawInt);
|
||||
UNSERIALIZE_SCALAR(pendingInt);
|
||||
UNSERIALIZE_SCALAR(loadValue);
|
||||
|
||||
bool is_in_event;
|
||||
UNSERIALIZE_SCALAR(is_in_event);
|
||||
|
||||
Tick event_time;
|
||||
if (is_in_event){
|
||||
UNSERIALIZE_SCALAR(event_time);
|
||||
parent->schedule(zeroEvent, event_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Sp804::serialize(std::ostream &os)
|
||||
{
|
||||
panic("Need to implement serialization\n");
|
||||
nameOut(os, csprintf("%s.timer0", name()));
|
||||
timer0.serialize(os);
|
||||
nameOut(os, csprintf("%s.timer1", name()));
|
||||
timer1.serialize(os);
|
||||
}
|
||||
|
||||
void
|
||||
Sp804::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
panic("Need to implement serialization\n");
|
||||
timer0.unserialize(cp, csprintf("%s.timer0", section));
|
||||
timer1.unserialize(cp, csprintf("%s.timer1", section));
|
||||
}
|
||||
|
||||
Sp804 *
|
||||
|
|
|
@ -121,6 +121,10 @@ class Sp804 : public AmbaDevice
|
|||
|
||||
/** Handle write for a single timer */
|
||||
void write(PacketPtr pkt, Addr daddr);
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
};
|
||||
|
||||
/** Pointer to the GIC for causing an interrupt */
|
||||
|
|
|
@ -1,4 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2010 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
* not be construed as granting a license to any other intellectual
|
||||
* property including but not limited to intellectual property relating
|
||||
* to a hardware implementation of the functionality of the software
|
||||
* licensed hereunder. You may use the software subject to the license
|
||||
* terms below provided that you ensure that this notice is replicated
|
||||
* unmodified and in its entirety in all distributions of the software,
|
||||
* modified or unmodified, in source code or in binary form.
|
||||
*
|
||||
* Copyright (c) 2001-2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@ -500,6 +512,18 @@ PhysicalMemory::serialize(ostream &os)
|
|||
if (gzclose(compressedMem))
|
||||
fatal("Close failed on physical memory checkpoint file '%s'\n",
|
||||
filename);
|
||||
|
||||
list<LockedAddr>::iterator i = lockedAddrList.begin();
|
||||
|
||||
vector<Addr> lal_addr;
|
||||
vector<int> lal_cid;
|
||||
while (i != lockedAddrList.end()) {
|
||||
lal_addr.push_back(i->addr);
|
||||
lal_cid.push_back(i->contextId);
|
||||
i++;
|
||||
}
|
||||
arrayParamOut(os, "lal_addr", lal_addr);
|
||||
arrayParamOut(os, "lal_cid", lal_cid);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -579,6 +603,12 @@ PhysicalMemory::unserialize(Checkpoint *cp, const string §ion)
|
|||
fatal("Close failed on physical memory checkpoint file '%s'\n",
|
||||
filename);
|
||||
|
||||
vector<Addr> lal_addr;
|
||||
vector<int> lal_cid;
|
||||
arrayParamIn(cp, section, "lal_addr", lal_addr);
|
||||
arrayParamIn(cp, section, "lal_cid", lal_cid);
|
||||
for(int i = 0; i < lal_addr.size(); i++)
|
||||
lockedAddrList.push_front(LockedAddr(lal_addr[i], lal_cid[i]));
|
||||
}
|
||||
|
||||
PhysicalMemory *
|
||||
|
|
|
@ -105,6 +105,11 @@ class PhysicalMemory : public MemObject
|
|||
contextId(req->contextId())
|
||||
{
|
||||
}
|
||||
// constructor for unserialization use
|
||||
LockedAddr(Addr _addr, int _cid)
|
||||
: addr(_addr), contextId(_cid)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
std::list<LockedAddr> lockedAddrList;
|
||||
|
|
|
@ -60,6 +60,7 @@ else:
|
|||
Source('process.cc')
|
||||
Source('syscall_emul.cc')
|
||||
|
||||
TraceFlag('Checkpoint')
|
||||
TraceFlag('Config')
|
||||
TraceFlag('Event')
|
||||
TraceFlag('Fault')
|
||||
|
|
|
@ -229,7 +229,7 @@ System::numRunningContexts()
|
|||
}
|
||||
|
||||
void
|
||||
System::startup()
|
||||
System::initState()
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
int i;
|
||||
|
|
|
@ -208,7 +208,7 @@ class System : public SimObject
|
|||
System(Params *p);
|
||||
~System();
|
||||
|
||||
void startup();
|
||||
void initState();
|
||||
|
||||
const Params *params() const { return (const Params *)_params; }
|
||||
|
||||
|
|
Loading…
Reference in a new issue