From a1e82259759ce7290269aeca6742098f1adbf2fd Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 8 Nov 2010 13:58:25 -0600 Subject: [PATCH] ARM: Add checkpointing support --- src/arch/arm/isa.hh | 12 ++++- src/arch/arm/linux/system.cc | 5 +-- src/arch/arm/linux/system.hh | 4 +- src/arch/arm/pagetable.hh | 87 +++++++++++++++++++----------------- src/arch/arm/table_walker.cc | 16 +++++-- src/arch/arm/table_walker.hh | 2 +- src/arch/arm/tlb.cc | 14 +++++- src/arch/arm/tlb.hh | 2 - src/dev/arm/gic.cc | 44 +++++++++++++++++- src/dev/arm/pl011.cc | 42 ++++++++++++++++- src/dev/arm/rv_ctrl.cc | 2 - src/dev/arm/timer_sp804.cc | 59 +++++++++++++++++++++++- src/dev/arm/timer_sp804.hh | 4 ++ src/mem/physical.cc | 30 +++++++++++++ src/mem/physical.hh | 5 +++ src/sim/SConscript | 1 + src/sim/system.cc | 2 +- src/sim/system.hh | 2 +- 18 files changed, 268 insertions(+), 65 deletions(-) diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 8318417f5..88d08e971 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -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() { diff --git a/src/arch/arm/linux/system.cc b/src/arch/arm/linux/system.cc index ddf7f19f3..38024c058 100644 --- a/src/arch/arm/linux/system.cc +++ b/src/arch/arm/linux/system.cc @@ -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() { diff --git a/src/arch/arm/linux/system.hh b/src/arch/arm/linux/system.hh index 12c86db25..4e5ebcd73 100644 --- a/src/arch/arm/linux/system.hh +++ b/src/arch/arm/linux/system.hh @@ -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() */ diff --git a/src/arch/arm/pagetable.hh b/src/arch/arm/pagetable.hh index 76b0e3bb8..46322046f 100644 --- a/src/arch/arm/pagetable.hh +++ b/src/arch/arm/pagetable.hh @@ -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); + } + }; diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc index ddf9fe5d3..c7c00924d 100644 --- a/src/arch/arm/table_walker.cc +++ b/src/arch/arm/table_walker.cc @@ -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* diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh index fde553ff4..0804997c3 100644 --- a/src/arch/arm/table_walker.hh +++ b/src/arch/arm/table_walker.hh @@ -350,7 +350,7 @@ class TableWalker : public MemObject return dynamic_cast(_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, diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index 239d5d8a2..4f1279404 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -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 diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh index 2d3661f7d..bd723e8d1 100644 --- a/src/arch/arm/tlb.hh +++ b/src/arch/arm/tlb.hh @@ -83,8 +83,6 @@ class TLB : public BaseTLB MustBeOne = 0x80 }; protected: - typedef std::multimap PageTable; - PageTable lookupTable; // Quick lookup into page table TlbEntry *table; // the Page Table int size; // TLB Size diff --git a/src/dev/arm/gic.cc b/src/dev/arm/gic.cc index eff7d94bb..ee8008144 100644 --- a/src/dev/arm/gic.cc +++ b/src/dev/arm/gic.cc @@ -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 * diff --git a/src/dev/arm/pl011.cc b/src/dev/arm/pl011.cc index 555636f04..d8ea9409b 100644 --- a/src/dev/arm/pl011.cc +++ b/src/dev/arm/pl011.cc @@ -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 * diff --git a/src/dev/arm/rv_ctrl.cc b/src/dev/arm/rv_ctrl.cc index e2543426b..08ac07233 100644 --- a/src/dev/arm/rv_ctrl.cc +++ b/src/dev/arm/rv_ctrl.cc @@ -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 * diff --git a/src/dev/arm/timer_sp804.cc b/src/dev/arm/timer_sp804.cc index c662d35bb..f6bbfb515 100644 --- a/src/dev/arm/timer_sp804.cc +++ b/src/dev/arm/timer_sp804.cc @@ -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 * diff --git a/src/dev/arm/timer_sp804.hh b/src/dev/arm/timer_sp804.hh index 1039456ab..afb6e29ed 100644 --- a/src/dev/arm/timer_sp804.hh +++ b/src/dev/arm/timer_sp804.hh @@ -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 */ diff --git a/src/mem/physical.cc b/src/mem/physical.cc index 889794db6..c24300cad 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -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::iterator i = lockedAddrList.begin(); + + vector lal_addr; + vector 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 lal_addr; + vector 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 * diff --git a/src/mem/physical.hh b/src/mem/physical.hh index 290e2bbae..a19db4d9d 100644 --- a/src/mem/physical.hh +++ b/src/mem/physical.hh @@ -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 lockedAddrList; diff --git a/src/sim/SConscript b/src/sim/SConscript index c91d08c44..b1e3a4b02 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -60,6 +60,7 @@ else: Source('process.cc') Source('syscall_emul.cc') +TraceFlag('Checkpoint') TraceFlag('Config') TraceFlag('Event') TraceFlag('Fault') diff --git a/src/sim/system.cc b/src/sim/system.cc index 6ed6b8e42..58e765b89 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -229,7 +229,7 @@ System::numRunningContexts() } void -System::startup() +System::initState() { #if FULL_SYSTEM int i; diff --git a/src/sim/system.hh b/src/sim/system.hh index 11a4b007a..452446623 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -208,7 +208,7 @@ class System : public SimObject System(Params *p); ~System(); - void startup(); + void initState(); const Params *params() const { return (const Params *)_params; } -- 2.30.2