diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/sparc/asi.cc | 27 | ||||
-rw-r--r-- | src/arch/sparc/faults.cc | 73 | ||||
-rw-r--r-- | src/arch/sparc/isa/decoder.isa | 96 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/blockmem.isa | 6 | ||||
-rw-r--r-- | src/arch/sparc/isa/includes.isa | 3 | ||||
-rw-r--r-- | src/arch/sparc/regfile.cc | 6 | ||||
-rw-r--r-- | src/arch/sparc/tlb.cc | 102 | ||||
-rw-r--r-- | src/arch/sparc/tlb_map.hh | 13 | ||||
-rw-r--r-- | src/arch/sparc/ua2005.cc | 2 | ||||
-rw-r--r-- | src/base/loader/elf_object.cc | 38 | ||||
-rw-r--r-- | src/base/loader/elf_object.hh | 2 | ||||
-rw-r--r-- | src/base/loader/object_file.cc | 6 | ||||
-rw-r--r-- | src/base/loader/object_file.hh | 2 | ||||
-rw-r--r-- | src/cpu/exetrace.cc | 3 | ||||
-rw-r--r-- | src/cpu/simple/base.cc | 2 | ||||
-rw-r--r-- | src/dev/alpha/tsunami_io.cc | 82 | ||||
-rw-r--r-- | src/dev/alpha/tsunami_io.hh | 13 | ||||
-rw-r--r-- | src/dev/sparc/SConscript | 1 | ||||
-rw-r--r-- | src/dev/sparc/dtod.cc | 115 | ||||
-rw-r--r-- | src/dev/sparc/dtod.hh | 67 | ||||
-rw-r--r-- | src/python/m5/objects/T1000.py | 9 | ||||
-rw-r--r-- | src/python/m5/objects/Tsunami.py | 2 | ||||
-rw-r--r-- | src/python/m5/params.py | 70 | ||||
-rw-r--r-- | src/sim/byteswap.hh | 2 | ||||
-rw-r--r-- | src/sim/process.cc | 5 |
25 files changed, 544 insertions, 203 deletions
diff --git a/src/arch/sparc/asi.cc b/src/arch/sparc/asi.cc index a9a778ff6..3d553955f 100644 --- a/src/arch/sparc/asi.cc +++ b/src/arch/sparc/asi.cc @@ -179,26 +179,23 @@ namespace SparcISA (asi == ASI_LDTX_PL) || (asi == ASI_LDTX_SL) || (asi == ASI_BLK_PL) || - (asi == ASI_BLK_SL); + (asi == ASI_BLK_SL) || + (asi == ASI_LTX_L); } bool AsiIsTwin(ASI asi) { return - (asi == ASI_QUAD_LDD) || - (asi == ASI_LDTX_AIUP) || - (asi == ASI_LDTX_AIUS) || - (asi == ASI_LDTX_REAL) || - (asi == ASI_LDTX_N) || - (asi == ASI_LDTX_AIUP_L) || - (asi == ASI_LDTX_AIUS_L) || - (asi == ASI_LDTX_REAL_L) || - (asi == ASI_LDTX_NL) || - (asi == ASI_LDTX_P) || - (asi == ASI_LDTX_S) || - (asi == ASI_LDTX_PL) || - (asi == ASI_LDTX_SL) || - (asi == ASI_LTX_L); + (asi >= ASI_LDTX_AIUP && + asi <= ASI_LDTX_N && + asi != ASI_QUEUE) || + (asi >= ASI_LDTX_AIUP_L && + asi <= ASI_LDTX_NL && + asi != 0x2D) || + asi == ASI_LDTX_P || + asi == ASI_LDTX_S || + asi == ASI_LDTX_PL || + asi == ASI_LDTX_SL; } bool AsiIsPartialStore(ASI asi) diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index a74eebafa..825ff40f6 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -312,6 +312,11 @@ void doREDFault(ThreadContext *tc, TrapType tt) TL++; + if (bits(PSTATE, 3,3)) { + PC &= mask(32); + NPC &= mask(32); + } + //set TSTATE.gl to gl replaceBits(TSTATE, 42, 40, GL); //set TSTATE.ccr to ccr @@ -340,22 +345,8 @@ void doREDFault(ThreadContext *tc, TrapType tt) //Update GL tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL)); - //set PSTATE.mm to 00 - //set PSTATE.pef to 1 - PSTATE |= (1 << 4); - //set PSTATE.am to 0 - PSTATE &= ~(1 << 3); -/* //set PSTATE.priv to 0 - PSTATE &= ~(1 << 2);*/ - //set PSTATE.ie to 0 - //PSTATE.priv is set to 1 here. The manual says it should be 0, but - //Legion sets it to 1. - PSTATE |= (1 << 2); - //set PSTATE.cle to 0 - PSTATE &= ~(1 << 9); - //PSTATE.tle is unchanged - //XXX Where is the tct bit? - //set PSTATE.tct to 0 + PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit + PSTATE |= (1 << 4); //set PSTATE.pef to 1 tc->setMiscReg(MISCREG_PSTATE, PSTATE); //set HPSTATE.red to 1 @@ -404,6 +395,11 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) MiscReg PC = tc->readPC(); MiscReg NPC = tc->readNextPC(); + if (bits(PSTATE, 3,3)) { + PC &= mask(32); + NPC &= mask(32); + } + //Increment the trap level TL++; tc->setMiscReg(MISCREG_TL, TL); @@ -442,46 +438,27 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL)); //PSTATE.mm is unchanged - //PSTATE.pef = whether or not an fpu is present - //XXX We'll say there's one present, even though there aren't - //implementations for a decent number of the instructions - PSTATE |= (1 << 4); - //PSTATE.am = 0 - PSTATE &= ~(1 << 3); - if (!gotoHpriv) - { - //PSTATE.priv = 1 - PSTATE |= (1 << 2); - //PSTATE.cle = PSTATE.tle - replaceBits(PSTATE, 9, 9, PSTATE >> 8); - } - else - { - //PSTATE.priv = 0 - //PSTATE.priv is set to 1 here. The manual says it should be 0, but - //Legion sets it to 1. - PSTATE |= (1 << 2); - //PSTATE.cle = 0 - PSTATE &= ~(1 << 9); - } - //PSTATE.ie = 0 - PSTATE &= ~(1 << 1); + PSTATE |= (1 << 4); //PSTATE.pef = whether or not an fpu is present + PSTATE &= ~(1 << 3); //PSTATE.am = 0 + PSTATE &= ~(1 << 1); //PSTATE.ie = 0 //PSTATE.tle is unchanged //PSTATE.tct = 0 - //XXX Where exactly is this field? - tc->setMiscReg(MISCREG_PSTATE, PSTATE); if (gotoHpriv) { - //HPSTATE.red = 0 - HPSTATE &= ~(1 << 5); - //HPSTATE.hpriv = 1 - HPSTATE |= (1 << 2); - //HPSTATE.ibe = 0 - HPSTATE &= ~(1 << 10); + PSTATE &= ~(1 << 9); // PSTATE.cle = 0 + //The manual says PSTATE.priv should be 0, but Legion leaves it alone + HPSTATE &= ~(1 << 5); //HPSTATE.red = 0 + HPSTATE |= (1 << 2); //HPSTATE.hpriv = 1 + HPSTATE &= ~(1 << 10); //HPSTATE.ibe = 0 //HPSTATE.tlz is unchanged tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); + } else { // we are going to priv + PSTATE |= (1 << 2); //PSTATE.priv = 1 + replaceBits(PSTATE, 9, 9, PSTATE >> 8); //PSTATE.cle = PSTATE.tle } + tc->setMiscReg(MISCREG_PSTATE, PSTATE); + bool changedCWP = true; if (tt == 0x24) diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index bd1a44342..425ebc9d0 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -163,7 +163,10 @@ decode OP default Unknown::unknown() 0x6: Trap::fbfcc({{fault = new FpDisabled;}}); } 0x1: BranchN::call(30, {{ - R15 = xc->readPC(); + if (Pstate<3:>) + R15 = (xc->readPC())<31:0>; + else + R15 = xc->readPC(); NNPC = R15 + disp; }}); 0x2: decode OP3 { @@ -183,7 +186,7 @@ decode OP default Unknown::unknown() Y = Rd<63:32>; }}); 0x0B: smul({{ - Rd.sdw = Rs1.sdw<31:0> * Rs2_or_imm13<31:0>; + Rd.sdw = sext<32>(Rs1.sdw) * sext<32>(Rs2_or_imm13); Y = Rd.sdw<63:32>; }}); 0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm13) + 1 - Ccr<0:0>}}); @@ -206,10 +209,10 @@ decode OP default Unknown::unknown() else { Rd.udw = ((int64_t)((Y << 32) | Rs1.sdw<31:0>)) / Rs2_or_imm13.sdw; - if(Rd.udw<63:31> != 0) + if((int64_t)Rd.udw >= std::numeric_limits<int32_t>::max()) Rd.udw = 0x7FFFFFFF; - else if(Rd.udw<63:> && Rd.udw<62:31> != 0xFFFFFFFF) - Rd.udw = 0xFFFFFFFF80000000ULL; + else if((int64_t)Rd.udw <= std::numeric_limits<int32_t>::min()) + Rd.udw = ULL(0xFFFFFFFF80000000); } }}); } @@ -254,7 +257,7 @@ decode OP default Unknown::unknown() {{0}},{{0}},{{0}},{{0}}); 0x1B: smulcc({{ int64_t resTemp; - Rd = resTemp = Rs1.sdw<31:0> * Rs2_or_imm13.sdw<31:0>; + Rd = resTemp = sext<32>(Rs1.sdw) * sext<32>(Rs2_or_imm13); Y = resTemp<63:32>;}}, {{0}},{{0}},{{0}},{{0}}); 0x1C: subccc({{ @@ -293,10 +296,10 @@ decode OP default Unknown::unknown() else { Rd = (int64_t)((Y << 32) | Rs1.sdw<31:0>) / val2; - overflow = (Rd<63:31> != 0); - underflow = (Rd<63:> && Rd<62:31> != 0xFFFFFFFF); + overflow = ((int64_t)Rd >= std::numeric_limits<int32_t>::max()); + underflow = ((int64_t)Rd <= std::numeric_limits<int32_t>::min()); if(overflow) Rd = 0x7FFFFFFF; - else if(underflow) Rd = 0xFFFFFFFF80000000ULL; + else if(underflow) Rd = ULL(0xFFFFFFFF80000000); } }}, {{0}}, {{overflow || underflow}}, @@ -373,7 +376,7 @@ decode OP default Unknown::unknown() 0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}}); } 0x28: decode RS1 { - 0x00: NoPriv::rdy({{Rd = Y;}}); + 0x00: NoPriv::rdy({{Rd = Y<31:0>;}}); //1 should cause an illegal instruction exception 0x02: NoPriv::rdccr({{Rd = Ccr;}}); 0x03: NoPriv::rdasi({{Rd = Asi;}}); @@ -468,12 +471,12 @@ decode OP default Unknown::unknown() //0x11-0x1F should cause an illegal instruction exception } 0x2B: BasicOperate::flushw({{ - if(NWindows - 2 - Cansave == 0) + if(NWindows - 2 - Cansave != 0) { if(Otherwin) - fault = new SpillNOther(Wstate<5:3>); + fault = new SpillNOther(4*Wstate<5:3>); else - fault = new SpillNNormal(Wstate<2:0>); + fault = new SpillNNormal(4*Wstate<2:0>); } }}); 0x2C: decode MOVCC3 @@ -523,7 +526,7 @@ decode OP default Unknown::unknown() 0x7: movrge({{Rd = (Rs1.sdw >= 0) ? Rs2_or_imm10 : Rd;}}); } 0x30: decode RD { - 0x00: NoPriv::wry({{Y = Rs1 ^ Rs2_or_imm13;}}); + 0x00: NoPriv::wry({{Y = (Rs1 ^ Rs2_or_imm13)<31:0>;}}); //0x01 should cause an illegal instruction exception 0x02: NoPriv::wrccr({{Ccr = Rs1 ^ Rs2_or_imm13;}}); 0x03: NoPriv::wrasi({{Asi = Rs1 ^ Rs2_or_imm13;}}); @@ -578,6 +581,9 @@ decode OP default Unknown::unknown() Cansave = Cansave - 1; else Otherwin = Otherwin - 1; + + if(Cleanwin < NWindows - 1) + Cleanwin = Cleanwin + 1; }}); } 0x32: decode RD { @@ -875,7 +881,10 @@ decode OP default Unknown::unknown() fault = new MemAddressNotAligned; else { - Rd = xc->readPC(); + if (Pstate<3:>) + Rd = (xc->readPC())<31:0>; + else + Rd = xc->readPC(); NNPC = target; } }}); @@ -893,9 +902,9 @@ decode OP default Unknown::unknown() if(Canrestore == 0) { if(Otherwin) - fault = new FillNOther(Wstate<5:3>); + fault = new FillNOther(4*Wstate<5:3>); else - fault = new FillNNormal(Wstate<2:0>); + fault = new FillNNormal(4*Wstate<2:0>); } else { @@ -949,9 +958,9 @@ decode OP default Unknown::unknown() if(Cansave == 0) { if(Otherwin) - fault = new SpillNOther(Wstate<5:3>); + fault = new SpillNOther(4*Wstate<5:3>); else - fault = new SpillNNormal(Wstate<2:0>); + fault = new SpillNNormal(4*Wstate<2:0>); //Cwp = (Cwp + 2) % NWindows; } else if(Cleanwin - Canrestore == 0) @@ -975,9 +984,9 @@ decode OP default Unknown::unknown() if(Canrestore == 0) { if(Otherwin) - fault = new FillNOther(Wstate<5:3>); + fault = new FillNOther(4*Wstate<5:3>); else - fault = new FillNNormal(Wstate<2:0>); + fault = new FillNNormal(4*Wstate<2:0>); } else { @@ -1049,39 +1058,49 @@ decode OP default Unknown::unknown() 0x0B: ldx({{Rd = (int64_t)Mem.sdw;}}); } 0x0D: LoadStore::ldstub( - {{Rd = Mem.ub;}}, - {{Mem.ub = 0xFF;}}); + {{uReg0 = Mem.ub;}}, + {{Rd.ub = uReg0; + Mem.ub = 0xFF;}}); 0x0E: Store::stx({{Mem.udw = Rd}}); 0x0F: LoadStore::swap( - {{uReg0 = Rd.uw; - Rd.uw = Mem.uw;}}, - {{Mem.uw = uReg0;}}); + {{ uReg0 = Mem.uw}}, + {{ Mem.uw = Rd.uw; + Rd.uw = uReg0;}}); format LoadAlt { 0x10: lduwa({{Rd = Mem.uw;}}, {{EXT_ASI}}); 0x11: lduba({{Rd = Mem.ub;}}, {{EXT_ASI}}); 0x12: lduha({{Rd = Mem.uhw;}}, {{EXT_ASI}}); 0x13: decode EXT_ASI { + //ASI_LDTD_AIUP + 0x22: TwinLoad::ldtx_aiup( + {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + //ASI_LDTD_AIUS + 0x23: TwinLoad::ldtx_aius( + {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); //ASI_QUAD_LDD 0x24: TwinLoad::ldtx_quad_ldd( - {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}}); + {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); //ASI_LDTX_REAL 0x26: TwinLoad::ldtx_real( - {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}}); + {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); //ASI_LDTX_N 0x27: TwinLoad::ldtx_n( - {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}}); + {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); //ASI_LDTX_L 0x2C: TwinLoad::ldtx_l( - {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}}); + {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); //ASI_LDTX_REAL_L 0x2E: TwinLoad::ldtx_real_l( - {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}}); + {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); //ASI_LDTX_N_L 0x2F: TwinLoad::ldtx_n_l( - {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}}); + {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); //ASI_LDTX_P 0xE2: TwinLoad::ldtx_p( - {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}}); + {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); + //ASI_LDTX_S + 0xE3: TwinLoad::ldtx_s( + {{RdTwin.udw = Mem.udw;}}, {{EXT_ASI}}); default: ldtwa({{ uint64_t val = Mem.udw; RdLow = val<31:0>; @@ -1102,13 +1121,14 @@ decode OP default Unknown::unknown() 0x1B: ldxa({{Rd = (int64_t)Mem.sdw;}}, {{EXT_ASI}}); } 0x1D: LoadStoreAlt::ldstuba( - {{Rd = Mem.ub;}}, - {{Mem.ub = 0xFF}}, {{EXT_ASI}}); + {{uReg0 = Mem.ub;}}, + {{Rd.ub = uReg0; + Mem.ub = 0xFF;}}, {{EXT_ASI}}); 0x1E: StoreAlt::stxa({{Mem.udw = Rd}}, {{EXT_ASI}}); 0x1F: LoadStoreAlt::swapa( - {{uReg0 = Rd.uw; - Rd.uw = Mem.uw;}}, - {{Mem.uw = uReg0;}}, {{EXT_ASI}}); + {{ uReg0 = Mem.uw}}, + {{ Mem.uw = Rd.uw; + Rd.uw = uReg0;}}, {{EXT_ASI}}); format Trap { 0x20: Load::ldf({{Frd.uw = Mem.uw;}}); 0x21: decode X { diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa index 32421a75f..c36fede2e 100644 --- a/src/arch/sparc/isa/formats/mem/blockmem.isa +++ b/src/arch/sparc/isa/formats/mem/blockmem.isa @@ -476,7 +476,6 @@ let {{ faultCode = '' return (header_output, decoder_output, exec_output, decode_block) - def doTwinLoadFormat(code, faultCode, name, Name, asi, opt_flags): addrCalcReg = 'EA = Rs1 + Rs2 + offset;' addrCalcImm = 'EA = Rs1 + imm + offset;' @@ -492,10 +491,11 @@ let {{ pcedCode = '' if (microPc == 1): flag_code = "flags[IsLastMicroOp] = true;" - pcedCode = matcher.sub("RdHigh", code) + pcedCode = "RdLow = uReg0;\n" + pcedCode += matcher.sub("RdHigh", code) else: flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroOp] = true;" - pcedCode = matcher.sub("RdLow", code) + pcedCode = matcher.sub("uReg0", code) iop = InstObjParams(name, Name, 'TwinMem', pcedCode, opt_flags, {"ea_code": addrCalcReg, "fault_check": faultCode, "micro_pc": microPc, diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa index 624afb693..0c112d481 100644 --- a/src/arch/sparc/isa/includes.isa +++ b/src/arch/sparc/isa/includes.isa @@ -1,4 +1,4 @@ -// Copyright (c) 2006 The Regents of The University of Michigan +// Copyright (c) 2006-2007 The Regents of The University of Michigan // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -63,6 +63,7 @@ output exec {{ #if defined(linux) #include <fenv.h> #endif +#include <limits> #include "arch/sparc/asi.hh" #include "cpu/base.hh" diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc index 5d8ac6a17..b36133544 100644 --- a/src/arch/sparc/regfile.cc +++ b/src/arch/sparc/regfile.cc @@ -189,10 +189,10 @@ int SparcISA::InterruptLevel(uint64_t softint) if (softint & 0x10000 || softint & 0x1) return 14; - int level = 14; - while (level >= 0 && !(1 << (level + 1) & softint)) + int level = 15; + while (level > 0 && !(1 << level & softint)) level--; - if (1 << (level + 1) & softint) + if (1 << level & softint) return level; return 0; } diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 612345300..bf57c894f 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -85,6 +85,7 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real, int x; cacheValid = false; + va &= ~(PTE.size()-1); /* tr.va = va; tr.size = PTE.size() - 1; tr.contextId = context_id; @@ -169,8 +170,8 @@ insertAllLocked: freeList.remove(new_entry); if (new_entry->valid && new_entry->used) usedEntries--; - - lookupTable.erase(new_entry->range); + if (new_entry->valid) + lookupTable.erase(new_entry->range); DPRINTF(TLB, "Using entry: %#X\n", new_entry); @@ -414,6 +415,9 @@ TLB::writeSfsr(ThreadContext *tc, int reg, bool write, ContextType ct, void TLB::writeTagAccess(ThreadContext *tc, int reg, Addr va, int context) { + DPRINTF(TLB, "TLB: Writing Tag Access: va: %#X ctx: %#X value: %#X\n", + va, context, mbits(va, 63,13) | mbits(context,12,0)); + tc->setMiscRegWithEffect(reg, mbits(va, 63,13) | mbits(context,12,0)); } @@ -536,8 +540,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) } if (e == NULL || !e->valid) { - tc->setMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS, - vaddr & ~BytesInPageMask | context); + writeTagAccess(tc, vaddr, context); if (real) return new InstructionRealTranslationMiss; else @@ -546,6 +549,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) // were not priviledged accesing priv page if (!priv && e->pte.priv()) { + writeTagAccess(tc, vaddr, context); writeSfsr(tc, false, ct, false, PrivViolation, asi); return new InstructionAccessException; } @@ -578,6 +582,9 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) DPRINTF(TLB, "TLB: DTB Request to translate va=%#x size=%d asi=%#x\n", vaddr, size, asi); + if (lookupTable.size() != 64 - freeList.size()) + panic("Lookup table size: %d tlb size: %d\n", lookupTable.size(), + freeList.size()); if (asi == ASI_IMPLICIT) implicit = true; @@ -589,13 +596,15 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) // Be fast if we can! if (cacheValid && cacheState == tlbdata) { if (cacheEntry[0] && cacheAsi[0] == asi && cacheEntry[0]->range.va < vaddr + size && - cacheEntry[0]->range.va + cacheEntry[0]->range.size > vaddr) { + cacheEntry[0]->range.va + cacheEntry[0]->range.size > vaddr && + (!write || cacheEntry[0]->pte.writable())) { req->setPaddr(cacheEntry[0]->pte.paddr() & ~(cacheEntry[0]->pte.size()-1) | vaddr & cacheEntry[0]->pte.size()-1 ); return NoFault; } if (cacheEntry[1] && cacheAsi[1] == asi && cacheEntry[1]->range.va < vaddr + size && - cacheEntry[1]->range.va + cacheEntry[1]->range.size > vaddr) { + cacheEntry[1]->range.va + cacheEntry[1]->range.size > vaddr && + (!write || cacheEntry[1]->pte.writable())) { req->setPaddr(cacheEntry[1]->pte.paddr() & ~(cacheEntry[1]->pte.size()-1) | vaddr & cacheEntry[1]->pte.size()-1 ); return NoFault; @@ -610,7 +619,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) int part_id = bits(tlbdata,15,8); int tl = bits(tlbdata,18,16); int pri_context = bits(tlbdata,47,32); - int sec_context = bits(tlbdata,47,32); + int sec_context = bits(tlbdata,63,48); bool real = false; ContextType ct = Primary; @@ -631,48 +640,42 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) ct = Primary; context = pri_context; } - } else if (!hpriv && !red) { - if (tl > 0 || AsiIsNucleus(asi)) { - ct = Nucleus; - context = 0; - } else if (AsiIsSecondary(asi)) { - ct = Secondary; - context = sec_context; - } else { - context = pri_context; - ct = Primary; //??? - } - + } else { // We need to check for priv level/asi priv - if (!priv && !AsiIsUnPriv(asi)) { + if (!priv && !hpriv && !AsiIsUnPriv(asi)) { // It appears that context should be Nucleus in these cases? writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi); return new PrivilegedAction; } - if (priv && AsiIsHPriv(asi)) { + + if (!hpriv && AsiIsHPriv(asi)) { writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi); return new DataAccessException; } - } - if (asi == ASI_P || asi == ASI_LDTX_P) { - ct = Primary; - context = pri_context; - goto continueDtbFlow; + if (AsiIsPrimary(asi)) { + context = pri_context; + ct = Primary; + } else if (AsiIsSecondary(asi)) { + context = sec_context; + ct = Secondary; + } else if (AsiIsNucleus(asi)) { + ct = Nucleus; + context = 0; + } else { // ???? + ct = Primary; + context = pri_context; + } } - if (!implicit) { + if (!implicit && asi != ASI_P && asi != ASI_S) { if (AsiIsLittle(asi)) panic("Little Endian ASIs not supported\n"); if (AsiIsBlock(asi)) panic("Block ASIs not supported\n"); if (AsiIsNoFault(asi)) panic("No Fault ASIs not supported\n"); - if (!write && (asi == ASI_QUAD_LDD || asi == ASI_LDTX_REAL)) - goto continueDtbFlow; - if (AsiIsTwin(asi)) - panic("Twin ASIs not supported\n"); if (AsiIsPartialStore(asi)) panic("Partial Store ASIs not supported\n"); if (AsiIsInterrupt(asi)) @@ -687,11 +690,11 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) if (AsiIsSparcError(asi)) goto handleSparcErrorRegAccess; - if (!AsiIsReal(asi) && !AsiIsNucleus(asi)) + if (!AsiIsReal(asi) && !AsiIsNucleus(asi) && !AsiIsAsIfUser(asi) && + !AsiIsTwin(asi)) panic("Accessing ASI %#X. Should we?\n", asi); } -continueDtbFlow: // If the asi is unaligned trap if (vaddr & size-1) { writeSfr(tc, vaddr, false, ct, false, OtherFault, asi); @@ -707,7 +710,7 @@ continueDtbFlow: } - if ((!lsu_dm && !hpriv) || AsiIsReal(asi)) { + if ((!lsu_dm && !hpriv && !red) || AsiIsReal(asi)) { real = true; context = 0; }; @@ -720,8 +723,7 @@ continueDtbFlow: e = lookup(vaddr, part_id, real, context); if (e == NULL || !e->valid) { - tc->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS, - vaddr & ~BytesInPageMask | context); + writeTagAccess(tc, vaddr, context); DPRINTF(TLB, "TLB: DTB Failed to find matching TLB entry\n"); if (real) return new DataRealTranslationMiss; @@ -730,26 +732,34 @@ continueDtbFlow: } + if (!priv && e->pte.priv()) { + writeTagAccess(tc, vaddr, context); + writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), PrivViolation, asi); + return new DataAccessException; + } if (write && !e->pte.writable()) { + writeTagAccess(tc, vaddr, context); writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), OtherFault, asi); return new FastDataAccessProtection; } if (e->pte.nofault() && !AsiIsNoFault(asi)) { + writeTagAccess(tc, vaddr, context); writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), LoadFromNfo, asi); return new DataAccessException; } - if (e->pte.sideffect()) - req->setFlags(req->getFlags() | UNCACHEABLE); - - - if (!priv && e->pte.priv()) { - writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), PrivViolation, asi); + if (e->pte.sideffect() && AsiIsNoFault(asi)) { + writeTagAccess(tc, vaddr, context); + writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), SideEffect, asi); return new DataAccessException; } + + if (e->pte.sideffect()) + req->setFlags(req->getFlags() | UNCACHEABLE); + // cache translation date for next translation cacheState = tlbdata; if (!cacheValid) { @@ -893,7 +903,7 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) break; case ASI_SPARC_ERROR_STATUS_REG: warn("returning 0 for SPARC ERROR regsiter read\n"); - pkt->set(0); + pkt->set((uint64_t)0); break; case ASI_HYP_SCRATCHPAD: case ASI_SCRATCHPAD: @@ -963,7 +973,7 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) data = mbits(tsbtemp,63,13); if (bits(tsbtemp,12,12)) data |= ULL(1) << (13+bits(tsbtemp,3,0)); - data |= temp >> (9 + bits(cnftemp,2,0) * 3) & + data |= temp >> (9 + bits(cnftemp,10,8) * 3) & mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4); pkt->set(data); break; @@ -993,7 +1003,7 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) data = mbits(tsbtemp,63,13); if (bits(tsbtemp,12,12)) data |= ULL(1) << (13+bits(tsbtemp,3,0)); - data |= temp >> (9 + bits(cnftemp,2,0) * 3) & + data |= temp >> (9 + bits(cnftemp,10,8) * 3) & mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4); pkt->set(data); break; @@ -1112,6 +1122,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_SFSR, data); break; case 0x30: + sext<59>(bits(data, 59,0)); tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS, data); break; default: @@ -1186,6 +1197,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_SFSR, data); break; case 0x30: + sext<59>(bits(data, 59,0)); tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS, data); break; case 0x80: diff --git a/src/arch/sparc/tlb_map.hh b/src/arch/sparc/tlb_map.hh index 688daf5b9..8285db939 100644 --- a/src/arch/sparc/tlb_map.hh +++ b/src/arch/sparc/tlb_map.hh @@ -135,6 +135,19 @@ class TlbMap { return tree.empty(); } + + void print() + { + iterator i; + i = tree.begin(); + while (i != tree.end()) { + std::cout << std::hex << i->first.va << " " << i->first.size << " " << + i->first.contextId << " " << i->first.partitionId << " " << + i->first.real << " " << i->second << std::endl; + i++; + } + } + }; }; diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index b583da8b0..ecb63bb9a 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -43,8 +43,6 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, /* Full system only ASRs */ case MISCREG_SOFTINT: setReg(miscReg, val);; - if (val != 0x10000 && val != 0) - warn("Writing to softint not really supported, writing: %#x\n", val); break; case MISCREG_SOFTINT_CLR: diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc index 7339507f6..d59affe85 100644 --- a/src/base/loader/elf_object.cc +++ b/src/base/loader/elf_object.cc @@ -340,3 +340,41 @@ ElfObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask) { return loadSomeSymbols(symtab, STB_LOCAL); } + +bool +ElfObject::isDynamic() +{ + Elf *elf; + int sec_idx = 1; // there is a 0 but it is nothing, go figure + Elf_Scn *section; + GElf_Shdr shdr; + + GElf_Ehdr ehdr; + + // check that header matches library version + if (elf_version(EV_CURRENT) == EV_NONE) + panic("wrong elf version number!"); + + // get a pointer to elf structure + elf = elf_memory((char*)fileData,len); + assert(elf != NULL); + + // Check that we actually have a elf file + if (gelf_getehdr(elf, &ehdr) ==0) { + panic("Not ELF, shouldn't be here"); + } + + // Get the first section + section = elf_getscn(elf, sec_idx); + + // While there are no more sections + while (section != NULL) { + gelf_getshdr(section, &shdr); + if (!strcmp(".interp", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name))) + return true; + section = elf_getscn(elf, ++sec_idx); + } // while sections + return false; +} + + diff --git a/src/base/loader/elf_object.hh b/src/base/loader/elf_object.hh index fb728b3c5..d909140f3 100644 --- a/src/base/loader/elf_object.hh +++ b/src/base/loader/elf_object.hh @@ -58,6 +58,8 @@ class ElfObject : public ObjectFile virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask = std::numeric_limits<Addr>::max()); + virtual bool isDynamic(); + static ObjectFile *tryFile(const std::string &fname, int fd, size_t len, uint8_t *data); Addr programHeaderTable() {return _programHeaderTable;} diff --git a/src/base/loader/object_file.cc b/src/base/loader/object_file.cc index ad2cd34ba..da5aa9552 100644 --- a/src/base/loader/object_file.cc +++ b/src/base/loader/object_file.cc @@ -150,3 +150,9 @@ createObjectFile(const string &fname, bool raw) munmap(fileData, len); return NULL; } + +bool +ObjectFile::isDynamic() +{ + return false; +} diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh index 6e98332c5..18e6482be 100644 --- a/src/base/loader/object_file.hh +++ b/src/base/loader/object_file.hh @@ -83,6 +83,8 @@ class ObjectFile virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask = std::numeric_limits<Addr>::max()) = 0; + virtual bool isDynamic(); + Arch getArch() const { return arch; } OpSys getOpSys() const { return opSys; } diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 87075c1ec..26e8b6b44 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -340,6 +340,9 @@ Trace::InstRecord::dump(ostream &outs) while (!compared) { if (shared_data->flags == OWN_M5) { m5Pc = PC & TheISA::PAddrImplMask; + if (bits(shared_data->pstate,3,3)) { + m5Pc &= mask(32); + } lgnPc = shared_data->pc & TheISA::PAddrImplMask; if (lgnPc != m5Pc) diffPC = true; diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 9e5dfe2a6..b8d1f3bed 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -438,6 +438,8 @@ BaseSimpleCPU::advancePC(Fault fault) if (fault != NoFault) { curMacroStaticInst = StaticInst::nullStaticInstPtr; fault->invoke(tc); + thread->setMicroPC(0); + thread->setNextMicroPC(1); } else { //If we're at the last micro op for this instruction if (curStaticInst->isLastMicroOp()) { diff --git a/src/dev/alpha/tsunami_io.cc b/src/dev/alpha/tsunami_io.cc index 38986b77e..d701dc98f 100644 --- a/src/dev/alpha/tsunami_io.cc +++ b/src/dev/alpha/tsunami_io.cc @@ -57,25 +57,77 @@ using namespace std; //Should this be AlphaISA? using namespace TheISA; -TsunamiIO::RTC::RTC(const string &n, Tsunami* tsunami, time_t t, Tick i) - : _name(n), event(tsunami, i), addr(0) +TsunamiIO::RTC::RTC(const string &n, Tsunami* tsunami, const vector<int> &t, + bool bcd, Tick i) + : _name(n), event(tsunami, i), addr(0), year_is_bcd(bcd) { memset(clock_data, 0, sizeof(clock_data)); stat_regA = RTCA_32768HZ | RTCA_1024HZ; stat_regB = RTCB_PRDC_IE |RTCB_BIN | RTCB_24HR; + if (year_is_bcd) { + // The RTC uses BCD for the last two digits in the year. + // They python year is a full year. + int _year = t[0] % 100; + int tens = _year / 10; + int ones = _year % 10; + + year = (tens << 4) + ones; + } else { + // Even though the datasheet says that the year field should be + // interpreted as BCD, we just enter the number of years since + // 1900 since linux seems to be happy with that (and I believe + // that Tru64 was as well) + year = t[0] - 1900; + } + + mon = t[1]; + mday = t[2]; + hour = t[3]; + min = t[4]; + sec = t[5]; + + // wday is defined to be in the range from 1 - 7 with 1 being Sunday. + // the value coming from python is in the range from 0 - 6 with 0 being + // Monday. Fix that here. + wday = t[6] + 2; + if (wday > 7) + wday -= 7; + + DPRINTFN("Real-time clock set to %s", getDateString()); +} + +std::string +TsunamiIO::RTC::getDateString() +{ struct tm tm; - gmtime_r(&t, &tm); - sec = tm.tm_sec; - min = tm.tm_min; - hour = tm.tm_hour; - wday = tm.tm_wday + 1; - mday = tm.tm_mday; - mon = tm.tm_mon + 1; - year = tm.tm_year; + memset(&tm, 0, sizeof(tm)); + + if (year_is_bcd) { + // undo the BCD and conver to years since 1900 guessing that + // anything before 1970 is actually after 2000 + int _year = (year >> 4) * 10 + (year & 0xf); + if (_year < 70) + _year += 100; + + tm.tm_year = _year; + } else { + // number of years since 1900 + tm.tm_year = year; + } + + // unix is 0-11 for month + tm.tm_mon = mon - 1; + tm.tm_mday = mday; + tm.tm_hour = hour; + tm.tm_min = min; + tm.tm_sec = sec; + + // to add more annoyance unix is 0 - 6 with 0 as sunday + tm.tm_wday = wday - 1; - DPRINTFN("Real-time clock set to %s", asctime(&tm)); + return asctime(&tm); } void @@ -424,7 +476,8 @@ TsunamiIO::PITimer::Counter::CounterEvent::description() TsunamiIO::TsunamiIO(Params *p) : BasicPioDevice(p), tsunami(p->tsunami), pitimer(p->name + "pitimer"), - rtc(p->name + ".rtc", p->tsunami, p->init_time, p->frequency) + rtc(p->name + ".rtc", p->tsunami, p->init_time, p->year_is_bcd, + p->frequency) { pioSize = 0x100; @@ -649,7 +702,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) Param<Tick> frequency; SimObjectParam<Platform *> platform; SimObjectParam<System *> system; - Param<time_t> time; + VectorParam<int> time; + Param<bool> year_is_bcd; SimObjectParam<Tsunami *> tsunami; END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) @@ -662,6 +716,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO) INIT_PARAM(platform, "platform"), INIT_PARAM(system, "system object"), INIT_PARAM(time, "System time to use (0 for actual time"), + INIT_PARAM(year_is_bcd, ""), INIT_PARAM(tsunami, "Tsunami") END_INIT_SIM_OBJECT_PARAMS(TsunamiIO) @@ -676,6 +731,7 @@ CREATE_SIM_OBJECT(TsunamiIO) p->platform = platform; p->system = system; p->init_time = time; + p->year_is_bcd = year_is_bcd; p->tsunami = tsunami; return new TsunamiIO(p); } diff --git a/src/dev/alpha/tsunami_io.hh b/src/dev/alpha/tsunami_io.hh index b0c368eb8..f42af4197 100644 --- a/src/dev/alpha/tsunami_io.hh +++ b/src/dev/alpha/tsunami_io.hh @@ -85,6 +85,9 @@ class TsunamiIO : public BasicPioDevice /** Current RTC register address/index */ int addr; + /** should the year be interpreted as BCD? */ + bool year_is_bcd; + /** Data for real-time clock function */ union { uint8_t clock_data[10]; @@ -110,7 +113,8 @@ class TsunamiIO : public BasicPioDevice uint8_t stat_regB; public: - RTC(const std::string &name, Tsunami* tsunami, time_t t, Tick i); + RTC(const std::string &name, Tsunami* tsunami, + const std::vector<int> &t, bool bcd, Tick i); /** RTC address port: write address of RTC RAM data to access */ void writeAddr(const uint8_t data); @@ -121,6 +125,9 @@ class TsunamiIO : public BasicPioDevice /** RTC read data */ uint8_t readData(); + /** RTC get the date */ + std::string getDateString(); + /** * Serialize this object to the given output stream. * @param base The base name of the counter object. @@ -313,8 +320,10 @@ class TsunamiIO : public BasicPioDevice { Tick frequency; Tsunami *tsunami; - time_t init_time; + std::vector<int> init_time; + bool year_is_bcd; }; + protected: const Params *params() const { return (const Params*)_params; } diff --git a/src/dev/sparc/SConscript b/src/dev/sparc/SConscript index 63f29846a..44b082b68 100644 --- a/src/dev/sparc/SConscript +++ b/src/dev/sparc/SConscript @@ -37,6 +37,7 @@ Import('env') sources = [] sources += Split(''' + dtod.cc t1000.cc mm_disk.cc ''') diff --git a/src/dev/sparc/dtod.cc b/src/dev/sparc/dtod.cc new file mode 100644 index 000000000..30c7baaf5 --- /dev/null +++ b/src/dev/sparc/dtod.cc @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2004-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +/** @file + * Time of date device implementation + */ +#include <sys/time.h> + +#include <deque> +#include <string> +#include <vector> + +#include "base/trace.hh" +#include "dev/sparc/dtod.hh" +#include "dev/platform.hh" +#include "mem/packet_access.hh" +#include "mem/port.hh" +#include "sim/builder.hh" +#include "sim/system.hh" + +using namespace std; +using namespace TheISA; + +DumbTOD::DumbTOD(Params *p) + : BasicPioDevice(p), todTime(p->init_time) +{ + pioSize = 0x08; + + struct tm tm; + gmtime_r((time_t*)&todTime, &tm); + DPRINTFN("Real-time clock set to %s\n", asctime(&tm)); + DPRINTFN("Real-time clock set to %d\n", todTime); +} + +Tick +DumbTOD::read(PacketPtr pkt) +{ + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + assert(pkt->getSize() == 8); + + pkt->allocate(); + pkt->set(todTime); + todTime += 1000; + + pkt->result = Packet::Success; + return pioDelay; +} + +Tick +DumbTOD::write(PacketPtr pkt) +{ + panic("Dumb tod device doesn't support writes\n"); +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(DumbTOD) + + Param<Addr> pio_addr; + Param<Tick> pio_latency; + SimObjectParam<Platform *> platform; + SimObjectParam<System *> system; + Param<time_t> time; + +END_DECLARE_SIM_OBJECT_PARAMS(DumbTOD) + +BEGIN_INIT_SIM_OBJECT_PARAMS(DumbTOD) + + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object"), + INIT_PARAM(time, "System time to use (0 for actual time") + +END_INIT_SIM_OBJECT_PARAMS(DumbTOD) + +CREATE_SIM_OBJECT(DumbTOD) +{ + DumbTOD::Params *p = new DumbTOD::Params; + p->name =getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->system = system; + p->init_time = time; + return new DumbTOD(p); +} + +REGISTER_SIM_OBJECT("DumbTOD", DumbTOD) diff --git a/src/dev/sparc/dtod.hh b/src/dev/sparc/dtod.hh new file mode 100644 index 000000000..7d3a9f628 --- /dev/null +++ b/src/dev/sparc/dtod.hh @@ -0,0 +1,67 @@ +/* + * Copyright (c) 206, 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +/** @file + * This device acts as a simple time of date device. It's implemented as a + * simple device register read. + */ + +#ifndef __DEV_SPARC_DTOD_HH__ +#define __DEV_SPARC_DTOD_HH__ + +#include "base/range.hh" +#include "dev/io_device.hh" + + +/** + * DumbTOD simply returns some idea of time when read. Until we finish with + * legion it starts with the start time and increments itself by 1000 each time. + */ +class DumbTOD : public BasicPioDevice +{ + private: + uint64_t todTime; + + public: + struct Params : public BasicPioDevice::Params + { + time_t init_time; + }; + protected: + const Params *params() const { return (const Params *)_params; } + + public: + DumbTOD(Params *p); + + virtual Tick read(PacketPtr pkt); + virtual Tick write(PacketPtr pkt); +}; + +#endif // __DEV_BADDEV_HH__ diff --git a/src/python/m5/objects/T1000.py b/src/python/m5/objects/T1000.py index 030f4abd8..7b93268ac 100644 --- a/src/python/m5/objects/T1000.py +++ b/src/python/m5/objects/T1000.py @@ -11,6 +11,12 @@ class MmDisk(BasicPioDevice): image = Param.DiskImage("Disk Image") pio_addr = 0x1F40000000 +class DumbTOD(BasicPioDevice): + type = 'DumbTOD' + time = Param.Time('01/01/2009', "System time to use ('Now' for real time)") + pio_addr = 0xfff0c1fff8 + + class T1000(Platform): type = 'T1000' system = Param.System(Parent.any, "system") @@ -64,6 +70,8 @@ class T1000(Platform): warn_access="Accessing SSI -- Unimplemented!") hvuart = Uart8250(pio_addr=0xfff0c2c000) + htod = DumbTOD() + puart0 = Uart8250(pio_addr=0x1f10000000) console = SimConsole(listener = ConsoleListener()) @@ -86,3 +94,4 @@ class T1000(Platform): self.fake_ssi.pio = bus.port self.puart0.pio = bus.port self.hvuart.pio = bus.port + self.htod.pio = bus.port diff --git a/src/python/m5/objects/Tsunami.py b/src/python/m5/objects/Tsunami.py index 18a776a7f..85105ff20 100644 --- a/src/python/m5/objects/Tsunami.py +++ b/src/python/m5/objects/Tsunami.py @@ -15,6 +15,8 @@ class TsunamiIO(BasicPioDevice): type = 'TsunamiIO' time = Param.Time('01/01/2009', "System time to use ('Now' for actual time)") + year_is_bcd = Param.Bool(False, + "The RTC should interpret the year as a BCD value") tsunami = Param.Tsunami(Parent.any, "Tsunami") frequency = Param.Frequency('1024Hz', "frequency of interrupts") diff --git a/src/python/m5/params.py b/src/python/m5/params.py index d570804d8..f8a9f9ddd 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -518,49 +518,55 @@ class EthernetAddr(ParamValue): else: return self.value +time_formats = [ "%a %b %d %H:%M:%S %Z %Y", + "%a %b %d %H:%M:%S %Z %Y", + "%Y/%m/%d %H:%M:%S", + "%Y/%m/%d %H:%M", + "%Y/%m/%d", + "%m/%d/%Y %H:%M:%S", + "%m/%d/%Y %H:%M", + "%m/%d/%Y", + "%m/%d/%y %H:%M:%S", + "%m/%d/%y %H:%M", + "%m/%d/%y"] + + def parse_time(value): - strings = [ "%a %b %d %H:%M:%S %Z %Y", - "%a %b %d %H:%M:%S %Z %Y", - "%Y/%m/%d %H:%M:%S", - "%Y/%m/%d %H:%M", - "%Y/%m/%d", - "%m/%d/%Y %H:%M:%S", - "%m/%d/%Y %H:%M", - "%m/%d/%Y", - "%m/%d/%y %H:%M:%S", - "%m/%d/%y %H:%M", - "%m/%d/%y"] - - for string in strings: - try: - return time.strptime(value, string) - except ValueError: - pass + from time import gmtime, strptime, struct_time, time + from datetime import datetime, date + + if isinstance(value, struct_time): + return value + + if isinstance(value, (int, long)): + return gmtime(value) + + if isinstance(value, (datetime, date)): + return value.timetuple() + + if isinstance(value, str): + if value in ('Now', 'Today'): + return time.gmtime(time.time()) + + for format in time_formats: + try: + return strptime(value, format) + except ValueError: + pass raise ValueError, "Could not parse '%s' as a time" % value class Time(ParamValue): cxx_type = 'time_t' def __init__(self, value): - if isinstance(value, time.struct_time): - self.value = time.mktime(value) - elif isinstance(value, int): - self.value = value - elif isinstance(value, str): - if value in ('Now', 'Today'): - self.value = time.time() - else: - self.value = time.mktime(parse_time(value)) - elif isinstance(value, (datetime.datetime, datetime.date)): - self.value = time.mktime(value.timetuple()) - else: - raise ValueError, "Could not parse '%s' as a time" % value + self.value = parse_time(value) def __str__(self): - return str(int(self.value)) + tm = self.value + return ' '.join([ str(tm[i]) for i in xrange(8)]) def ini_str(self): - return str(int(self.value)) + return str(self) # Enumerated types are a little more complex. The user specifies the # type as Enum(foo) where foo is either a list or dictionary of diff --git a/src/sim/byteswap.hh b/src/sim/byteswap.hh index 7b1ae701e..4ac1ee711 100644 --- a/src/sim/byteswap.hh +++ b/src/sim/byteswap.hh @@ -130,7 +130,7 @@ template <typename T> static inline T letobe(T value) {return swap_byte(value);} //For conversions not involving the guest system, we can define the functions //conditionally based on the BYTE_ORDER macro and outside of the namespaces -#if defined(_BIG_ENDIAN) || BYTE_ORDER == BIG_ENDIAN +#if defined(_BIG_ENDIAN) || !defined(_LITTLE_ENDIAN) && BYTE_ORDER == BIG_ENDIAN template <typename T> static inline T htole(T value) {return swap_byte(value);} template <typename T> static inline T letoh(T value) {return swap_byte(value);} template <typename T> static inline T htobe(T value) {return value;} diff --git a/src/sim/process.cc b/src/sim/process.cc index b43fa7d00..63ff33969 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -440,6 +440,11 @@ LiveProcess::create(const std::string &nm, System *system, int stdin_fd, fatal("Can't load object file %s", executable); } + if (objFile->isDynamic()) + fatal("Object file is a dynamic executable however only static " + "executables are supported!\n Please recompile your " + "executable as a static binary and try again.\n"); + #if THE_ISA == ALPHA_ISA if (objFile->getArch() != ObjectFile::Alpha) fatal("Object file architecture does not match compiled ISA (Alpha)."); |