ARM: Add checkpointing support

This commit is contained in:
Ali Saidi 2010-11-08 13:58:25 -06:00
parent 432fa0aad6
commit a1e8225975
18 changed files with 268 additions and 65 deletions

View file

@ -178,10 +178,18 @@ namespace ArmISA
} }
void serialize(EventManager *em, std::ostream &os) void serialize(EventManager *em, std::ostream &os)
{} {
DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
SERIALIZE_ARRAY(miscRegs, NumMiscRegs);
}
void unserialize(EventManager *em, Checkpoint *cp, void unserialize(EventManager *em, Checkpoint *cp,
const std::string &section) const std::string &section)
{} {
DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
UNSERIALIZE_ARRAY(miscRegs, NumMiscRegs);
CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
updateRegMap(tmp_cpsr);
}
ISA() ISA()
{ {

View file

@ -99,9 +99,9 @@ LinuxArmSystem::LinuxArmSystem(Params *p)
} }
void void
LinuxArmSystem::startup() LinuxArmSystem::initState()
{ {
ArmSystem::startup(); ArmSystem::initState();
ThreadContext *tc = threadContexts[0]; ThreadContext *tc = threadContexts[0];
// Set the initial PC to be at start of the kernel code // Set the initial PC to be at start of the kernel code
@ -117,7 +117,6 @@ LinuxArmSystem::~LinuxArmSystem()
{ {
} }
LinuxArmSystem * LinuxArmSystem *
LinuxArmSystemParams::create() LinuxArmSystemParams::create()
{ {

View file

@ -67,8 +67,8 @@ class LinuxArmSystem : public ArmSystem
LinuxArmSystem(Params *p); LinuxArmSystem(Params *p);
~LinuxArmSystem(); ~LinuxArmSystem();
/** Initialize the CPU for booting */ void initState();
void startup();
private: private:
#ifndef NDEBUG #ifndef NDEBUG
/** Event to halt the simulator if the kernel calls panic() */ /** Event to halt the simulator if the kernel calls panic() */

View file

@ -48,6 +48,8 @@
#include "arch/arm/vtophys.hh" #include "arch/arm/vtophys.hh"
#include "config/full_system.hh" #include "config/full_system.hh"
#include "sim/serialize.hh"
namespace ArmISA { namespace ArmISA {
struct VAddr 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 // ITB/DTB table entry
struct TlbEntry struct TlbEntry
{ {
@ -143,10 +112,8 @@ struct TlbEntry
// Access permissions // Access permissions
bool xn; // Execute Never bool xn; // Execute Never
uint8_t ap:3; // Access permissions bits uint8_t ap; // Access permissions bits
uint8_t domain:4; // Access Domain uint8_t domain; // Access Domain
TlbRange range; // For fast TLB searching
//Construct an entry that maps to physical address addr for SE mode //Construct an entry that maps to physical address addr for SE mode
TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr) TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr)
@ -196,9 +163,49 @@ struct TlbEntry
return (pfn << N) | (va & size); return (pfn << N) | (va & size);
} }
void serialize(std::ostream &os) { panic("Need to Implement\n"); } void
void unserialize(Checkpoint *cp, const std::string &section) serialize(std::ostream &os)
{ panic("Need to Implement\n");} {
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 &section)
{
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);
}
}; };

View file

@ -59,10 +59,20 @@ TableWalker::~TableWalker()
} }
unsigned int unsigned int TableWalker::drain(Event *de)
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* Port*

View file

@ -350,7 +350,7 @@ class TableWalker : public MemObject
return dynamic_cast<const Params *>(_params); 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); virtual Port *getPort(const std::string &if_name, int idx = -1);
Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode, Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode,

View file

@ -245,14 +245,24 @@ TLB::flushMva(Addr mva)
void void
TLB::serialize(ostream &os) 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 void
TLB::unserialize(Checkpoint *cp, const string &section) TLB::unserialize(Checkpoint *cp, const string &section)
{ {
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 void

View file

@ -83,8 +83,6 @@ class TLB : public BaseTLB
MustBeOne = 0x80 MustBeOne = 0x80
}; };
protected: protected:
typedef std::multimap<Addr, int> PageTable;
PageTable lookupTable; // Quick lookup into page table
TlbEntry *table; // the Page Table TlbEntry *table; // the Page Table
int size; // TLB Size int size; // TLB Size

View file

@ -495,13 +495,53 @@ Gic::addressRanges(AddrRangeList &range_list)
void void
Gic::serialize(std::ostream &os) 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 void
Gic::unserialize(Checkpoint *cp, const std::string &section) Gic::unserialize(Checkpoint *cp, const std::string &section)
{ {
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 * Gic *

View file

@ -274,13 +274,51 @@ Pl011::generateInterrupt()
void void
Pl011::serialize(std::ostream &os) 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 void
Pl011::unserialize(Checkpoint *cp, const std::string &section) Pl011::unserialize(Checkpoint *cp, const std::string &section)
{ {
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 * Pl011 *

View file

@ -97,13 +97,11 @@ RealViewCtrl::write(PacketPtr pkt)
void void
RealViewCtrl::serialize(std::ostream &os) RealViewCtrl::serialize(std::ostream &os)
{ {
panic("Need to implement serialization\n");
} }
void void
RealViewCtrl::unserialize(Checkpoint *cp, const std::string &section) RealViewCtrl::unserialize(Checkpoint *cp, const std::string &section)
{ {
panic("Need to implement serialization\n");
} }
RealViewCtrl * RealViewCtrl *

View file

@ -219,17 +219,72 @@ Sp804::Timer::counterAtZero()
restartCounter(loadValue); 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 &section)
{
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 void
Sp804::serialize(std::ostream &os) 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 void
Sp804::unserialize(Checkpoint *cp, const std::string &section) Sp804::unserialize(Checkpoint *cp, const std::string &section)
{ {
panic("Need to implement serialization\n"); timer0.unserialize(cp, csprintf("%s.timer0", section));
timer1.unserialize(cp, csprintf("%s.timer1", section));
} }
Sp804 * Sp804 *

View file

@ -121,6 +121,10 @@ class Sp804 : public AmbaDevice
/** Handle write for a single timer */ /** Handle write for a single timer */
void write(PacketPtr pkt, Addr daddr); void write(PacketPtr pkt, Addr daddr);
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
}; };
/** Pointer to the GIC for causing an interrupt */ /** Pointer to the GIC for causing an interrupt */

View file

@ -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 * Copyright (c) 2001-2005 The Regents of The University of Michigan
* All rights reserved. * All rights reserved.
* *
@ -500,6 +512,18 @@ PhysicalMemory::serialize(ostream &os)
if (gzclose(compressedMem)) if (gzclose(compressedMem))
fatal("Close failed on physical memory checkpoint file '%s'\n", fatal("Close failed on physical memory checkpoint file '%s'\n",
filename); 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 void
@ -579,6 +603,12 @@ PhysicalMemory::unserialize(Checkpoint *cp, const string &section)
fatal("Close failed on physical memory checkpoint file '%s'\n", fatal("Close failed on physical memory checkpoint file '%s'\n",
filename); 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 * PhysicalMemory *

View file

@ -105,6 +105,11 @@ class PhysicalMemory : public MemObject
contextId(req->contextId()) contextId(req->contextId())
{ {
} }
// constructor for unserialization use
LockedAddr(Addr _addr, int _cid)
: addr(_addr), contextId(_cid)
{
}
}; };
std::list<LockedAddr> lockedAddrList; std::list<LockedAddr> lockedAddrList;

View file

@ -60,6 +60,7 @@ else:
Source('process.cc') Source('process.cc')
Source('syscall_emul.cc') Source('syscall_emul.cc')
TraceFlag('Checkpoint')
TraceFlag('Config') TraceFlag('Config')
TraceFlag('Event') TraceFlag('Event')
TraceFlag('Fault') TraceFlag('Fault')

View file

@ -229,7 +229,7 @@ System::numRunningContexts()
} }
void void
System::startup() System::initState()
{ {
#if FULL_SYSTEM #if FULL_SYSTEM
int i; int i;

View file

@ -208,7 +208,7 @@ class System : public SimObject
System(Params *p); System(Params *p);
~System(); ~System();
void startup(); void initState();
const Params *params() const { return (const Params *)_params; } const Params *params() const { return (const Params *)_params; }