ARM: Add checkpointing support
authorAli Saidi <Ali.Saidi@ARM.com>
Mon, 8 Nov 2010 19:58:25 +0000 (13:58 -0600)
committerAli Saidi <Ali.Saidi@ARM.com>
Mon, 8 Nov 2010 19:58:25 +0000 (13:58 -0600)
18 files changed:
src/arch/arm/isa.hh
src/arch/arm/linux/system.cc
src/arch/arm/linux/system.hh
src/arch/arm/pagetable.hh
src/arch/arm/table_walker.cc
src/arch/arm/table_walker.hh
src/arch/arm/tlb.cc
src/arch/arm/tlb.hh
src/dev/arm/gic.cc
src/dev/arm/pl011.cc
src/dev/arm/rv_ctrl.cc
src/dev/arm/timer_sp804.cc
src/dev/arm/timer_sp804.hh
src/mem/physical.cc
src/mem/physical.hh
src/sim/SConscript
src/sim/system.cc
src/sim/system.hh

index 8318417f59c3ea59add17099036f29ff41a0b4cf..88d08e97161c30a08cf6e66ca59d188b190b713a 100644 (file)
@@ -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 &section)
-        {}
+        {
+            DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
+            UNSERIALIZE_ARRAY(miscRegs, NumMiscRegs);
+            CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
+            updateRegMap(tmp_cpsr);
+        }
 
         ISA()
         {
index ddf7f19f35b3bea8cd1cd0266c507b99b9185312..38024c0588d644702cac6672ed135138156bc8c9 100644 (file)
@@ -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()
 {
index 12c86db25c6a5ef582a13468157bf0ac784b5b15..4e5ebcd7353292c292fc8b462e915e0d9296f8b1 100644 (file)
@@ -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()  */
index 76b0e3bb838f25b62b5e55fc334058338d1eb60d..46322046f6ce2e467c866ce53655171234c02dcc 100644 (file)
@@ -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 &section)
-                   { 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 &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);
+    }
+
 };
 
 
index ddf9fe5d36d4267dfd15f84a714d8306109a5507..c7c00924d9f62d5322a773a898b08c619f69f7ed 100644 (file)
@@ -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*
index fde553ff421244d366d5bf24be8f42a7da0ec23f..0804997c309706a898309b1531318d4d62366df5 100644 (file)
@@ -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,
index 239d5d8a2e56c373fa42c65328d1634b303c5f2e..4f1279404b87f63c5243f635d40340e2bf692851 100644 (file)
@@ -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 &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
index 2d3661f7dce5799391fa91119557c62d4eb733fe..bd723e8d1851bca4739e89249c2148a779b56639 100644 (file)
@@ -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
index eff7d94bb32b3cf3ba284bad14412b9b3b043c6a..ee80081442254a0742eda81c040b57bdca95ad6e 100644 (file)
@@ -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 &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 *
index 555636f04625465c34d3986e3c99187a102b7612..d8ea9409bc4069e08f1d11be6ca8fe7820a8bcce 100644 (file)
@@ -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 &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 *
index e2543426b27c7838b84c0e3bf7ad484485e5d9f3..08ac0723350c1afb1eaee82371bc92350aafddc4 100644 (file)
@@ -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 &section)
 {
-    panic("Need to implement serialization\n");
 }
 
 RealViewCtrl *
index c662d35bb008216c429a9be4a61e213eb65fea80..f6bbfb515b736044257769376115e3a633b618a3 100644 (file)
@@ -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 &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
 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 &section)
 {
-    panic("Need to implement serialization\n");
+    timer0.unserialize(cp, csprintf("%s.timer0", section));
+    timer1.unserialize(cp, csprintf("%s.timer1", section));
 }
 
 Sp804 *
index 1039456ab8f081c724985a7a6eee859f16e9fad1..afb6e29ed2499ccf10aed869d0d4e304e99797d7 100644 (file)
@@ -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 &section);
+
     };
 
     /** Pointer to the GIC for causing an interrupt */
index 889794db61569c05cb00decabf09cef9370cd882..c24300cad44e5c261161871e4d06038104a73a37 100644 (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
  * 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 &section)
         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 *
index 290e2bbae825e8145b1b2ab806d3216ae29cefa3..a19db4d9d5c4d73d52af20322fbca3418e0bf954 100644 (file)
@@ -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;
index c91d08c44ddee4dcbcb90474e286981375d3ca6a..b1e3a4b022743691b969b40208b13882ce6f3888 100644 (file)
@@ -60,6 +60,7 @@ else:
     Source('process.cc')
     Source('syscall_emul.cc')
 
+TraceFlag('Checkpoint')
 TraceFlag('Config')
 TraceFlag('Event')
 TraceFlag('Fault')
index 6ed6b8e4222898c59099f7249880114618c19429..58e765b89ba55bdcbb3e9f405738eda3b82773aa 100644 (file)
@@ -229,7 +229,7 @@ System::numRunningContexts()
 }
 
 void
-System::startup()
+System::initState()
 {
 #if FULL_SYSTEM
     int i;
index 11a4b007a4b93412acc356b2914cb81bed7a43ef..45244662392df75df1a89d2c8886519ae72cbb1f 100644 (file)
@@ -208,7 +208,7 @@ class System : public SimObject
     System(Params *p);
     ~System();
 
-    void startup();
+    void initState();
 
     const Params *params() const { return (const Params *)_params; }