diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index bd1a44342..dafdc96f6 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -468,12 +468,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 @@ -893,9 +893,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 +949,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 +975,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 { 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..e3ac26612 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; @@ -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 @@ -610,7 +613,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,34 +634,32 @@ 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) { @@ -668,6 +669,10 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) panic("Block ASIs not supported\n"); if (AsiIsNoFault(asi)) panic("No Fault ASIs not supported\n"); + + // These twin ASIs are OK + if (asi == ASI_P || asi == ASI_LDTX_P) + goto continueDtbFlow; if (!write && (asi == ASI_QUAD_LDD || asi == ASI_LDTX_REAL)) goto continueDtbFlow; @@ -687,7 +692,7 @@ 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)) panic("Accessing ASI %#X. Should we?\n", asi); } @@ -707,7 +712,7 @@ continueDtbFlow: } - if ((!lsu_dm && !hpriv) || AsiIsReal(asi)) { + if ((!lsu_dm && !hpriv && !red) || AsiIsReal(asi)) { real = true; context = 0; }; @@ -720,8 +725,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; @@ -893,7 +897,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 +967,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 +997,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 +1116,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 +1191,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/base/loader/elf_object.cc b/src/base/loader/elf_object.cc index 7339507f6..89a5d4512 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(".dynamic", 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::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::max()) = 0; + virtual bool isDynamic(); + Arch getArch() const { return arch; } OpSys getOpSys() const { return opSys; } 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 + +#include +#include +#include + +#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 pio_addr; + Param pio_latency; + SimObjectParam platform; + SimObjectParam system; + Param 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/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).");