diff options
Diffstat (limited to 'src/arch')
50 files changed, 1419 insertions, 829 deletions
diff --git a/src/arch/alpha/SConscript b/src/arch/alpha/SConscript index 4f293e22f..04bac3996 100644 --- a/src/arch/alpha/SConscript +++ b/src/arch/alpha/SConscript @@ -32,27 +32,28 @@ Import('*') if env['TARGET_ISA'] == 'alpha': + Source('ev5.cc') Source('faults.cc') Source('floatregfile.cc') Source('intregfile.cc') + Source('ipr.cc') Source('miscregfile.cc') + Source('pagetable.cc') Source('regfile.cc') Source('remote_gdb.cc') + Source('tlb.cc') Source('utility.cc') + SimObject('AlphaTLB.py') + if env['FULL_SYSTEM']: SimObject('AlphaSystem.py') - SimObject('AlphaTLB.py') - Source('ev5.cc') Source('idle_event.cc') - Source('ipr.cc') Source('kernel_stats.cc') Source('osfpal.cc') - Source('pagetable.cc') Source('stacktrace.cc') Source('system.cc') - Source('tlb.cc') Source('vtophys.cc') Source('freebsd/system.cc') diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 86b8fd2d0..5dc49623e 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -68,22 +68,6 @@ AlphaISA::initCPU(ThreadContext *tc, int cpuId) delete reset; } -//////////////////////////////////////////////////////////////////////// -// -// -// -void -AlphaISA::initIPRs(ThreadContext *tc, int cpuId) -{ - for (int i = 0; i < NumInternalProcRegs; ++i) { - tc->setMiscRegNoEffect(i, 0); - } - - tc->setMiscRegNoEffect(IPR_PAL_BASE, PalBase); - tc->setMiscRegNoEffect(IPR_MCSR, 0x6); - tc->setMiscRegNoEffect(IPR_PALtemp16, cpuId); -} - template <class CPU> void @@ -171,6 +155,24 @@ AlphaISA::MiscRegFile::getDataAsid() return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); } +#endif + +//////////////////////////////////////////////////////////////////////// +// +// +// +void +AlphaISA::initIPRs(ThreadContext *tc, int cpuId) +{ + for (int i = 0; i < NumInternalProcRegs; ++i) { + tc->setMiscRegNoEffect(i, 0); + } + + tc->setMiscRegNoEffect(IPR_PAL_BASE, EV5::PalBase); + tc->setMiscRegNoEffect(IPR_MCSR, 0x6); + tc->setMiscRegNoEffect(IPR_PALtemp16, cpuId); +} + AlphaISA::MiscReg AlphaISA::MiscRegFile::readIpr(int idx, ThreadContext *tc) { @@ -243,15 +245,16 @@ AlphaISA::MiscRegFile::readIpr(int idx, ThreadContext *tc) case AlphaISA::IPR_DTB_PTE: { - AlphaISA::PTE &pte = tc->getDTBPtr()->index(!tc->misspeculating()); - - retval |= ((uint64_t)pte.ppn & ULL(0x7ffffff)) << 32; - retval |= ((uint64_t)pte.xre & ULL(0xf)) << 8; - retval |= ((uint64_t)pte.xwe & ULL(0xf)) << 12; - retval |= ((uint64_t)pte.fonr & ULL(0x1)) << 1; - retval |= ((uint64_t)pte.fonw & ULL(0x1))<< 2; - retval |= ((uint64_t)pte.asma & ULL(0x1)) << 4; - retval |= ((uint64_t)pte.asn & ULL(0x7f)) << 57; + AlphaISA::TlbEntry &entry + = tc->getDTBPtr()->index(!tc->misspeculating()); + + retval |= ((uint64_t)entry.ppn & ULL(0x7ffffff)) << 32; + retval |= ((uint64_t)entry.xre & ULL(0xf)) << 8; + retval |= ((uint64_t)entry.xwe & ULL(0xf)) << 12; + retval |= ((uint64_t)entry.fonr & ULL(0x1)) << 1; + retval |= ((uint64_t)entry.fonw & ULL(0x1))<< 2; + retval |= ((uint64_t)entry.asma & ULL(0x1)) << 4; + retval |= ((uint64_t)entry.asn & ULL(0x7f)) << 57; } break; @@ -340,8 +343,10 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) // write entire quad w/ no side-effect old = ipr[idx]; ipr[idx] = val; +#if FULL_SYSTEM if (tc->getKernelStats()) tc->getKernelStats()->context(old, val, tc); +#endif break; case AlphaISA::IPR_DTB_PTE: @@ -368,11 +373,14 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) // only write least significant five bits - interrupt level ipr[idx] = val & 0x1f; +#if FULL_SYSTEM if (tc->getKernelStats()) tc->getKernelStats()->swpipl(ipr[idx]); +#endif break; case AlphaISA::IPR_DTB_CM: +#if FULL_SYSTEM if (val & 0x18) { if (tc->getKernelStats()) tc->getKernelStats()->mode(TheISA::Kernel::user, tc); @@ -380,6 +388,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) if (tc->getKernelStats()) tc->getKernelStats()->mode(TheISA::Kernel::kernel, tc); } +#endif case AlphaISA::IPR_ICM: // only write two mode bits - processor mode @@ -468,54 +477,54 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) ipr[idx] = val; tc->getDTBPtr()->flushAddr(val, - DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); + EV5::DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); break; case AlphaISA::IPR_DTB_TAG: { - struct AlphaISA::PTE pte; + struct AlphaISA::TlbEntry entry; // FIXME: granularity hints NYI... - if (DTB_PTE_GH(ipr[AlphaISA::IPR_DTB_PTE]) != 0) + if (EV5::DTB_PTE_GH(ipr[AlphaISA::IPR_DTB_PTE]) != 0) panic("PTE GH field != 0"); // write entire quad ipr[idx] = val; // construct PTE for new entry - pte.ppn = DTB_PTE_PPN(ipr[AlphaISA::IPR_DTB_PTE]); - pte.xre = DTB_PTE_XRE(ipr[AlphaISA::IPR_DTB_PTE]); - pte.xwe = DTB_PTE_XWE(ipr[AlphaISA::IPR_DTB_PTE]); - pte.fonr = DTB_PTE_FONR(ipr[AlphaISA::IPR_DTB_PTE]); - pte.fonw = DTB_PTE_FONW(ipr[AlphaISA::IPR_DTB_PTE]); - pte.asma = DTB_PTE_ASMA(ipr[AlphaISA::IPR_DTB_PTE]); - pte.asn = DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]); + entry.ppn = EV5::DTB_PTE_PPN(ipr[AlphaISA::IPR_DTB_PTE]); + entry.xre = EV5::DTB_PTE_XRE(ipr[AlphaISA::IPR_DTB_PTE]); + entry.xwe = EV5::DTB_PTE_XWE(ipr[AlphaISA::IPR_DTB_PTE]); + entry.fonr = EV5::DTB_PTE_FONR(ipr[AlphaISA::IPR_DTB_PTE]); + entry.fonw = EV5::DTB_PTE_FONW(ipr[AlphaISA::IPR_DTB_PTE]); + entry.asma = EV5::DTB_PTE_ASMA(ipr[AlphaISA::IPR_DTB_PTE]); + entry.asn = EV5::DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]); // insert new TAG/PTE value into data TLB - tc->getDTBPtr()->insert(val, pte); + tc->getDTBPtr()->insert(val, entry); } break; case AlphaISA::IPR_ITB_PTE: { - struct AlphaISA::PTE pte; + struct AlphaISA::TlbEntry entry; // FIXME: granularity hints NYI... - if (ITB_PTE_GH(val) != 0) + if (EV5::ITB_PTE_GH(val) != 0) panic("PTE GH field != 0"); // write entire quad ipr[idx] = val; // construct PTE for new entry - pte.ppn = ITB_PTE_PPN(val); - pte.xre = ITB_PTE_XRE(val); - pte.xwe = 0; - pte.fonr = ITB_PTE_FONR(val); - pte.fonw = ITB_PTE_FONW(val); - pte.asma = ITB_PTE_ASMA(val); - pte.asn = ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]); + entry.ppn = EV5::ITB_PTE_PPN(val); + entry.xre = EV5::ITB_PTE_XRE(val); + entry.xwe = 0; + entry.fonr = EV5::ITB_PTE_FONR(val); + entry.fonw = EV5::ITB_PTE_FONW(val); + entry.asma = EV5::ITB_PTE_ASMA(val); + entry.asn = EV5::ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]); // insert new TAG/PTE value into data TLB - tc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], pte); + tc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], entry); } break; @@ -538,7 +547,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) ipr[idx] = val; tc->getITBPtr()->flushAddr(val, - ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); + EV5::ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); break; default: @@ -558,6 +567,7 @@ AlphaISA::copyIprs(ThreadContext *src, ThreadContext *dest) } } +#if FULL_SYSTEM /** * Check for special simulator handling of specific PAL calls. diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index 149729351..7d4de902a 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -29,13 +29,13 @@ * Kevin Lim */ +#include "arch/alpha/ev5.hh" #include "arch/alpha/faults.hh" +#include "arch/alpha/tlb.hh" #include "cpu/thread_context.hh" #include "cpu/base.hh" #include "base/trace.hh" -#if FULL_SYSTEM -#include "arch/alpha/ev5.hh" -#else +#if !FULL_SYSTEM #include "sim/process.hh" #include "mem/page_table.hh" #endif @@ -83,10 +83,6 @@ FaultName DtbAlignmentFault::_name = "unalign"; FaultVect DtbAlignmentFault::_vect = 0x0301; FaultStat DtbAlignmentFault::_count; -FaultName ItbMissFault::_name = "itbmiss"; -FaultVect ItbMissFault::_vect = 0x0181; -FaultStat ItbMissFault::_count; - FaultName ItbPageFault::_name = "itbmiss"; FaultVect ItbPageFault::_vect = 0x0181; FaultStat ItbPageFault::_count; @@ -176,6 +172,63 @@ void ItbFault::invoke(ThreadContext * tc) AlphaFault::invoke(tc); } +#else + +void ItbPageFault::invoke(ThreadContext * tc) +{ + Process *p = tc->getProcessPtr(); + Addr physaddr; + bool success = p->pTable->translate(pc, physaddr); + if(!success) { + panic("Tried to execute unmapped address %#x.\n", pc); + } else { + VAddr vaddr(pc); + VAddr paddr(physaddr); + + TlbEntry entry; + entry.tag = vaddr.vpn(); + entry.ppn = paddr.vpn(); + entry.xre = 15; //This can be read in all modes. + entry.xwe = 1; //This can be written only in kernel mode. + entry.asn = p->M5_pid; //Address space number. + entry.asma = false; //Only match on this ASN. + entry.fonr = false; //Don't fault on read. + entry.fonw = false; //Don't fault on write. + entry.valid = true; //This entry is valid. + + tc->getITBPtr()->insert(vaddr.page(), entry); + } +} + +void NDtbMissFault::invoke(ThreadContext * tc) +{ + Process *p = tc->getProcessPtr(); + Addr physaddr; + bool success = p->pTable->translate(vaddr, physaddr); + if(!success) { + p->checkAndAllocNextPage(vaddr); + success = p->pTable->translate(vaddr, physaddr); + } + if(!success) { + panic("Tried to access unmapped address %#x.\n", (Addr)vaddr); + } else { + VAddr paddr(physaddr); + + TlbEntry entry; + entry.tag = vaddr.vpn(); + entry.ppn = paddr.vpn(); + entry.xre = 15; //This can be read in all modes. + entry.xwe = 15; //This can be written in all modes. + entry.asn = p->M5_pid; //Address space number. + entry.asma = false; //Only match on this ASN. + entry.fonr = false; //Don't fault on read. + entry.fonw = false; //Don't fault on write. + entry.valid = true; //This entry is valid. + + tc->getDTBPtr()->insert(vaddr.page(), entry); + } +} + #endif } // namespace AlphaISA diff --git a/src/arch/alpha/faults.hh b/src/arch/alpha/faults.hh index ed0c3a6b1..74699b2b5 100644 --- a/src/arch/alpha/faults.hh +++ b/src/arch/alpha/faults.hh @@ -35,9 +35,7 @@ #include "config/full_system.hh" #include "sim/faults.hh" -#if FULL_SYSTEM #include "arch/alpha/pagetable.hh" -#endif // The design of the "name" and "vect" functions is in sim/faults.hh @@ -90,11 +88,6 @@ static inline Fault genMachineCheckFault() return new MachineCheckFault; } -static inline Fault genAlignmentFault() -{ - return new AlignmentFault; -} - class ResetFault : public AlphaFault { private: @@ -140,8 +133,7 @@ class InterruptFault : public AlphaFault class DtbFault : public AlphaFault { -#if FULL_SYSTEM - private: + protected: AlphaISA::VAddr vaddr; uint32_t reqFlags; uint64_t flags; @@ -149,7 +141,6 @@ class DtbFault : public AlphaFault DtbFault(AlphaISA::VAddr _vaddr, uint32_t _reqFlags, uint64_t _flags) : vaddr(_vaddr), reqFlags(_reqFlags), flags(_flags) { } -#endif FaultName name() const = 0; FaultVect vect() = 0; FaultStat & countStat() = 0; @@ -165,14 +156,15 @@ class NDtbMissFault : public DtbFault static FaultVect _vect; static FaultStat _count; public: -#if FULL_SYSTEM NDtbMissFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } -#endif FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} +#if !FULL_SYSTEM + void invoke(ThreadContext * tc); +#endif }; class PDtbMissFault : public DtbFault @@ -182,11 +174,9 @@ class PDtbMissFault : public DtbFault static FaultVect _vect; static FaultStat _count; public: -#if FULL_SYSTEM PDtbMissFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } -#endif FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} @@ -199,11 +189,9 @@ class DtbPageFault : public DtbFault static FaultVect _vect; static FaultStat _count; public: -#if FULL_SYSTEM DtbPageFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } -#endif FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} @@ -216,11 +204,9 @@ class DtbAcvFault : public DtbFault static FaultVect _vect; static FaultStat _count; public: -#if FULL_SYSTEM DtbAcvFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } -#endif FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} @@ -233,11 +219,9 @@ class DtbAlignmentFault : public DtbFault static FaultVect _vect; static FaultStat _count; public: -#if FULL_SYSTEM DtbAlignmentFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } -#endif FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} @@ -245,7 +229,7 @@ class DtbAlignmentFault : public DtbFault class ItbFault : public AlphaFault { - private: + protected: Addr pc; public: ItbFault(Addr _pc) @@ -259,21 +243,6 @@ class ItbFault : public AlphaFault #endif }; -class ItbMissFault : public ItbFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - ItbMissFault(Addr pc) - : ItbFault(pc) - { } - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - class ItbPageFault : public ItbFault { private: @@ -287,6 +256,9 @@ class ItbPageFault : public ItbFault FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} +#if !FULL_SYSTEM + void invoke(ThreadContext * tc); +#endif }; class ItbAcvFault : public ItbFault diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh index 7dc7e5151..53eea5f69 100644 --- a/src/arch/alpha/isa_traits.hh +++ b/src/arch/alpha/isa_traits.hh @@ -63,14 +63,13 @@ namespace AlphaISA const Addr PageMask = ~(PageBytes - 1); const Addr PageOffset = PageBytes - 1; -#if FULL_SYSTEM //////////////////////////////////////////////////////////////////////// // // Translation stuff // - const Addr PteShift = 3; + const Addr PteShift = 3; const Addr NPtePageShift = PageShift - PteShift; const Addr NPtePage = ULL(1) << NPtePageShift; const Addr PteMask = NPtePage - 1; @@ -90,6 +89,8 @@ namespace AlphaISA // For loading... XXX This maybe could be USegEnd?? --ali const Addr LoadAddrMask = ULL(0xffffffffff); +#if FULL_SYSTEM + //////////////////////////////////////////////////////////////////////// // // Interrupt levels @@ -114,6 +115,8 @@ namespace AlphaISA NumInterruptLevels = INTLEVEL_EXTERNAL_MAX }; +#endif + // EV5 modes enum mode_type { @@ -124,8 +127,6 @@ namespace AlphaISA mode_number // number of modes }; -#endif - // Constants Related to the number of registers const int NumIntArchRegs = 32; diff --git a/src/arch/alpha/miscregfile.cc b/src/arch/alpha/miscregfile.cc index 1af97adcf..cb5875349 100644 --- a/src/arch/alpha/miscregfile.cc +++ b/src/arch/alpha/miscregfile.cc @@ -43,9 +43,7 @@ namespace AlphaISA SERIALIZE_SCALAR(uniq); SERIALIZE_SCALAR(lock_flag); SERIALIZE_SCALAR(lock_addr); -#if FULL_SYSTEM SERIALIZE_ARRAY(ipr, NumInternalProcRegs); -#endif } void @@ -55,9 +53,7 @@ namespace AlphaISA UNSERIALIZE_SCALAR(uniq); UNSERIALIZE_SCALAR(lock_flag); UNSERIALIZE_SCALAR(lock_addr); -#if FULL_SYSTEM UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs); -#endif } MiscReg @@ -74,15 +70,9 @@ namespace AlphaISA return lock_addr; case MISCREG_INTR: return intr_flag; -#if FULL_SYSTEM default: assert(misc_reg < NumInternalProcRegs); return ipr[misc_reg]; -#else - default: - panic("Attempt to read an invalid misc register!"); - return 0; -#endif } } @@ -100,14 +90,8 @@ namespace AlphaISA return lock_addr; case MISCREG_INTR: return intr_flag; -#if FULL_SYSTEM default: return readIpr(misc_reg, tc); -#else - default: - panic("No faulting misc regs in SE mode!"); - return 0; -#endif } } @@ -130,15 +114,10 @@ namespace AlphaISA case MISCREG_INTR: intr_flag = val; return; -#if FULL_SYSTEM default: assert(misc_reg < NumInternalProcRegs); ipr[misc_reg] = val; return; -#else - default: - panic("Attempt to write to an invalid misc register!"); -#endif } } @@ -163,11 +142,7 @@ namespace AlphaISA intr_flag = val; return; default: -#if FULL_SYSTEM setIpr(misc_reg, val, tc); -#else - panic("No registers with side effects in SE mode!"); -#endif return; } } diff --git a/src/arch/alpha/miscregfile.hh b/src/arch/alpha/miscregfile.hh index aea702849..022b6404a 100644 --- a/src/arch/alpha/miscregfile.hh +++ b/src/arch/alpha/miscregfile.hh @@ -34,7 +34,6 @@ #include "arch/alpha/ipr.hh" #include "arch/alpha/types.hh" -#include "config/full_system.hh" #include "sim/host.hh" #include "sim/serialize.hh" @@ -70,9 +69,7 @@ namespace AlphaISA public: MiscRegFile() { -#if FULL_SYSTEM initializeIprTable(); -#endif } MiscReg readRegNoEffect(int misc_reg); @@ -100,7 +97,6 @@ namespace AlphaISA void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); -#if FULL_SYSTEM protected: typedef uint64_t InternalProcReg; @@ -110,13 +106,10 @@ namespace AlphaISA InternalProcReg readIpr(int idx, ThreadContext *tc); void setIpr(int idx, InternalProcReg val, ThreadContext *tc); -#endif friend class RegFile; }; -#if FULL_SYSTEM void copyIprs(ThreadContext *src, ThreadContext *dest); -#endif } diff --git a/src/arch/alpha/pagetable.cc b/src/arch/alpha/pagetable.cc index 0c26ccbe3..3f9537834 100644 --- a/src/arch/alpha/pagetable.cc +++ b/src/arch/alpha/pagetable.cc @@ -1,5 +1,5 @@ /* - * 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 @@ -34,7 +34,7 @@ namespace AlphaISA { void - PTE::serialize(std::ostream &os) + TlbEntry::serialize(std::ostream &os) { SERIALIZE_SCALAR(tag); SERIALIZE_SCALAR(ppn); @@ -48,7 +48,7 @@ namespace AlphaISA } void - PTE::unserialize(Checkpoint *cp, const std::string §ion) + TlbEntry::unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_SCALAR(tag); UNSERIALIZE_SCALAR(ppn); diff --git a/src/arch/alpha/pagetable.hh b/src/arch/alpha/pagetable.hh index c7e1c8923..4375f24f1 100644 --- a/src/arch/alpha/pagetable.hh +++ b/src/arch/alpha/pagetable.hh @@ -89,9 +89,16 @@ namespace AlphaISA { Addr paddr() const { return _pfn() << PageShift; } }; - // ITB/DTB page table entry - struct PTE + // ITB/DTB table entry + struct TlbEntry { + Addr pageStart; + //Construct an entry that maps to physical address addr. + TlbEntry(Addr addr) : pageStart(addr) + {} + TlbEntry() + {} + Addr tag; // virtual page number tag Addr ppn; // physical page number uint8_t xre; // read permissions - VMEM_PERM_* mask diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index 85619e493..a9848ebb5 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -71,6 +71,12 @@ AlphaLiveProcess::startup() argsInit(MachineBytes, VMPageSize); threadContexts[0]->setIntReg(GlobalPointerReg, objFile->globalPointer()); + //Opperate in user mode + threadContexts[0]->setMiscRegNoEffect(IPR_ICM, 0x18); + //No super page mapping + threadContexts[0]->setMiscRegNoEffect(IPR_MCSR, 0); + //Set this to 0 for now, but it should be unique for each process + threadContexts[0]->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57); } diff --git a/src/arch/alpha/regfile.cc b/src/arch/alpha/regfile.cc index 3b42ca9bc..2653310d7 100644 --- a/src/arch/alpha/regfile.cc +++ b/src/arch/alpha/regfile.cc @@ -94,8 +94,6 @@ namespace AlphaISA dest->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKADDR, src->readMiscRegNoEffect(AlphaISA::MISCREG_LOCKADDR)); -#if FULL_SYSTEM copyIprs(src, dest); -#endif } } diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index f701c423d..628d7ad6b 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -62,8 +62,8 @@ bool uncacheBit40 = false; TLB::TLB(const string &name, int s) : SimObject(name), size(s), nlu(0) { - table = new PTE[size]; - memset(table, 0, sizeof(PTE[size])); + table = new TlbEntry[size]; + memset(table, 0, sizeof(TlbEntry[size])); flushCache(); } @@ -74,23 +74,23 @@ TLB::~TLB() } // look up an entry in the TLB -PTE * +TlbEntry * TLB::lookup(Addr vpn, uint8_t asn) { // assume not found... - PTE *retval = NULL; - - if (PTECache[0]) { - if (vpn == PTECache[0]->tag && - (PTECache[0]->asma || PTECache[0]->asn == asn)) - retval = PTECache[0]; - else if (PTECache[1]) { - if (vpn == PTECache[1]->tag && - (PTECache[1]->asma || PTECache[1]->asn == asn)) - retval = PTECache[1]; - else if (PTECache[2] && vpn == PTECache[2]->tag && - (PTECache[2]->asma || PTECache[2]->asn == asn)) - retval = PTECache[2]; + TlbEntry *retval = NULL; + + if (EntryCache[0]) { + if (vpn == EntryCache[0]->tag && + (EntryCache[0]->asma || EntryCache[0]->asn == asn)) + retval = EntryCache[0]; + else if (EntryCache[1]) { + if (vpn == EntryCache[1]->tag && + (EntryCache[1]->asma || EntryCache[1]->asn == asn)) + retval = EntryCache[1]; + else if (EntryCache[2] && vpn == EntryCache[2]->tag && + (EntryCache[2]->asma || EntryCache[2]->asn == asn)) + retval = EntryCache[2]; } } @@ -99,10 +99,10 @@ TLB::lookup(Addr vpn, uint8_t asn) if (i != lookupTable.end()) { while (i->first == vpn) { int index = i->second; - PTE *pte = &table[index]; - assert(pte->valid); - if (vpn == pte->tag && (pte->asma || pte->asn == asn)) { - retval = updateCache(pte); + TlbEntry *entry = &table[index]; + assert(entry->valid); + if (vpn == entry->tag && (entry->asma || entry->asn == asn)) { + retval = updateCache(entry); break; } @@ -157,7 +157,7 @@ TLB::checkCacheability(RequestPtr &req) // insert a new TLB entry void -TLB::insert(Addr addr, PTE &pte) +TLB::insert(Addr addr, TlbEntry &entry) { flushCache(); VAddr vaddr = addr; @@ -181,9 +181,9 @@ TLB::insert(Addr addr, PTE &pte) lookupTable.erase(i); } - DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn); + DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), entry.ppn); - table[nlu] = pte; + table[nlu] = entry; table[nlu].tag = vaddr.vpn(); table[nlu].valid = true; @@ -195,7 +195,7 @@ void TLB::flushAll() { DPRINTF(TLB, "flushAll\n"); - memset(table, 0, sizeof(PTE[size])); + memset(table, 0, sizeof(TlbEntry[size])); flushCache(); lookupTable.clear(); nlu = 0; @@ -209,17 +209,17 @@ TLB::flushProcesses() PageTable::iterator end = lookupTable.end(); while (i != end) { int index = i->second; - PTE *pte = &table[index]; - assert(pte->valid); + TlbEntry *entry = &table[index]; + assert(entry->valid); // we can't increment i after we erase it, so save a copy and // increment it to get the next entry now PageTable::iterator cur = i; ++i; - if (!pte->asma) { - DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn); - pte->valid = false; + if (!entry->asma) { + DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, entry->tag, entry->ppn); + entry->valid = false; lookupTable.erase(cur); } } @@ -237,15 +237,15 @@ TLB::flushAddr(Addr addr, uint8_t asn) while (i != lookupTable.end() && i->first == vaddr.vpn()) { int index = i->second; - PTE *pte = &table[index]; - assert(pte->valid); + TlbEntry *entry = &table[index]; + assert(entry->valid); - if (vaddr.vpn() == pte->tag && (pte->asma || pte->asn == asn)) { + if (vaddr.vpn() == entry->tag && (entry->asma || entry->asn == asn)) { DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(), - pte->ppn); + entry->ppn); // invalidate this entry - pte->valid = false; + entry->valid = false; lookupTable.erase(i++); } else { @@ -262,7 +262,7 @@ TLB::serialize(ostream &os) SERIALIZE_SCALAR(nlu); for (int i = 0; i < size; i++) { - nameOut(os, csprintf("%s.PTE%d", name(), i)); + nameOut(os, csprintf("%s.Entry%d", name(), i)); table[i].serialize(os); } } @@ -274,7 +274,7 @@ TLB::unserialize(Checkpoint *cp, const string §ion) UNSERIALIZE_SCALAR(nlu); for (int i = 0; i < size; i++) { - table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); + table[i].unserialize(cp, csprintf("%s.Entry%d", section, i)); if (table[i].valid) { lookupTable.insert(make_pair(table[i].tag, i)); } @@ -364,20 +364,20 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) } else { // not a physical address: need to look up pte int asn = DTB_ASN_ASN(tc->readMiscRegNoEffect(IPR_DTB_ASN)); - PTE *pte = lookup(VAddr(req->getVaddr()).vpn(), + TlbEntry *entry = lookup(VAddr(req->getVaddr()).vpn(), asn); - if (!pte) { + if (!entry) { misses++; return new ItbPageFault(req->getVaddr()); } - req->setPaddr((pte->ppn << PageShift) + + req->setPaddr((entry->ppn << PageShift) + (VAddr(req->getVaddr()).offset() & ~3)); // check permissions for this access - if (!(pte->xre & + if (!(entry->xre & (1 << ICM_CM(tc->readMiscRegNoEffect(IPR_ICM))))) { // instruction access fault acv++; @@ -548,10 +548,9 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) int asn = DTB_ASN_ASN(tc->readMiscRegNoEffect(IPR_DTB_ASN)); // not a physical address: need to look up pte - PTE *pte = lookup(VAddr(req->getVaddr()).vpn(), - asn); + TlbEntry *entry = lookup(VAddr(req->getVaddr()).vpn(), asn); - if (!pte) { + if (!entry) { // page fault if (write) { write_misses++; } else { read_misses++; } uint64_t flags = (write ? MM_STAT_WR_MASK : 0) | @@ -563,32 +562,32 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) flags)); } - req->setPaddr((pte->ppn << PageShift) + + req->setPaddr((entry->ppn << PageShift) + VAddr(req->getVaddr()).offset()); if (write) { - if (!(pte->xwe & MODE2MASK(mode))) { + if (!(entry->xwe & MODE2MASK(mode))) { // declare the instruction access fault write_acv++; uint64_t flags = MM_STAT_WR_MASK | MM_STAT_ACV_MASK | - (pte->fonw ? MM_STAT_FONW_MASK : 0); + (entry->fonw ? MM_STAT_FONW_MASK : 0); return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); } - if (pte->fonw) { + if (entry->fonw) { write_acv++; uint64_t flags = MM_STAT_WR_MASK | MM_STAT_FONW_MASK; return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); } } else { - if (!(pte->xre & MODE2MASK(mode))) { + if (!(entry->xre & MODE2MASK(mode))) { read_acv++; uint64_t flags = MM_STAT_ACV_MASK | - (pte->fonr ? MM_STAT_FONR_MASK : 0); + (entry->fonr ? MM_STAT_FONR_MASK : 0); return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags); } - if (pte->fonr) { + if (entry->fonr) { read_acv++; uint64_t flags = MM_STAT_FONR_MASK; return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); @@ -609,15 +608,15 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) return checkCacheability(req); } -PTE & +TlbEntry & TLB::index(bool advance) { - PTE *pte = &table[nlu]; + TlbEntry *entry = &table[nlu]; if (advance) nextnlu(); - return *pte; + return *entry; } /* end namespace AlphaISA */ } diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index a4255f3c5..8df47dbec 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -48,20 +48,20 @@ class ThreadContext; namespace AlphaISA { - class PTE; + class TlbEntry; class TLB : public SimObject { protected: typedef std::multimap<Addr, int> PageTable; - PageTable lookupTable; // Quick lookup into page table + PageTable lookupTable; // Quick lookup into page table - PTE *table; // the Page Table - int size; // TLB Size - int nlu; // not last used entry (for replacement) + TlbEntry *table; // the Page Table + int size; // TLB Size + int nlu; // not last used entry (for replacement) void nextnlu() { if (++nlu >= size) nlu = 0; } - PTE *lookup(Addr vpn, uint8_t asn); + TlbEntry *lookup(Addr vpn, uint8_t asn); public: TLB(const std::string &name, int size); @@ -69,8 +69,8 @@ namespace AlphaISA int getsize() const { return size; } - PTE &index(bool advance = true); - void insert(Addr vaddr, PTE &pte); + TlbEntry &index(bool advance = true); + void insert(Addr vaddr, TlbEntry &entry); void flushAll(); void flushProcesses(); @@ -90,13 +90,17 @@ namespace AlphaISA virtual void unserialize(Checkpoint *cp, const std::string §ion); // Most recently used page table entries - PTE *PTECache[3]; - inline void flushCache() { memset(PTECache, 0, 3 * sizeof(PTE*)); } - inline PTE* updateCache(PTE *pte) { - PTECache[2] = PTECache[1]; - PTECache[1] = PTECache[0]; - PTECache[0] = pte; - return pte; + TlbEntry *EntryCache[3]; + inline void flushCache() + { + memset(EntryCache, 0, 3 * sizeof(TlbEntry*)); + } + + inline TlbEntry* updateCache(TlbEntry *entry) { + EntryCache[2] = EntryCache[1]; + EntryCache[1] = EntryCache[0]; + EntryCache[0] = entry; + return entry; } }; diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh index 5d461a0f9..11357bc44 100644 --- a/src/arch/alpha/utility.hh +++ b/src/arch/alpha/utility.hh @@ -115,7 +115,6 @@ namespace AlphaISA inline void startupCPU(ThreadContext *tc, int cpuId) { tc->activate(0); } -#if FULL_SYSTEM //////////////////////////////////////////////////////////////////////// // @@ -142,8 +141,9 @@ namespace AlphaISA RoundPage(Addr addr) { return (addr + PageBytes - 1) & ~(PageBytes - 1); } - void initCPU(ThreadContext *tc, int cpuId); void initIPRs(ThreadContext *tc, int cpuId); +#if FULL_SYSTEM + void initCPU(ThreadContext *tc, int cpuId); /** * Function to check for and process any interrupts. diff --git a/src/arch/micro_asm.py b/src/arch/micro_asm.py index 32dd79fdf..925e6b585 100644 --- a/src/arch/micro_asm.py +++ b/src/arch/micro_asm.py @@ -140,9 +140,9 @@ def handle_statement(parser, container, statement): raise try: for label in statement.labels: - container.labels[label.name] = microop + container.labels[label.text] = microop if label.extern: - container.externs[label.name] = microop + container.externs[label.text] = microop container.add_microop(microop) except: print_error("Error adding microop.") @@ -439,6 +439,11 @@ def p_labels_1(t): t[1].append(t[2]) t[0] = t[1] +# labels on lines by themselves are attached to the following instruction. +def p_labels_2(t): + 'labels : labels NEWLINE' + t[0] = t[1] + def p_label_0(t): 'label : ID COLON' label = Label() diff --git a/src/arch/mips/MipsTLB.py b/src/arch/mips/MipsTLB.py new file mode 100644 index 000000000..8c1a00abe --- /dev/null +++ b/src/arch/mips/MipsTLB.py @@ -0,0 +1,20 @@ +from m5.SimObject import SimObject +from m5.params import * +class MipsTLB(SimObject): + type = 'MipsTLB' + abstract = True + #size = Param.Int("TLB size") + +class MipsDTB(MipsTLB): + type = 'MipsDTB' + cxx_namespace = 'MipsISA' + cxx_class = 'DTB' + + #size = 64 + +class MipsITB(MipsTLB): + type = 'MipsITB' + cxx_namespace = 'MipsISA' + cxx_class = 'ITB' + + #size = 64 diff --git a/src/arch/mips/SConscript b/src/arch/mips/SConscript index 658710389..e1d2146eb 100644 --- a/src/arch/mips/SConscript +++ b/src/arch/mips/SConscript @@ -33,12 +33,15 @@ Import('*') if env['TARGET_ISA'] == 'mips': + Source('dsp.cc') Source('faults.cc') Source('regfile/int_regfile.cc') Source('regfile/misc_regfile.cc') Source('regfile/regfile.cc') + Source('tlb.cc') Source('utility.cc') - Source('dsp.cc') + + SimObject('MipsTLB.py') if env['FULL_SYSTEM']: #Insert Full-System Files Here diff --git a/src/arch/mips/faults.cc b/src/arch/mips/faults.cc index 39a2fa997..3d83a21aa 100644 --- a/src/arch/mips/faults.cc +++ b/src/arch/mips/faults.cc @@ -75,12 +75,6 @@ FaultName UnimplementedOpcodeFault::_name = "opdec"; FaultVect UnimplementedOpcodeFault::_vect = 0x0481; FaultStat UnimplementedOpcodeFault::_count; -#if !FULL_SYSTEM -//FaultName PageTableFault::_name = "page_table_fault"; -//FaultVect PageTableFault::_vect = 0x0000; -//FaultStat PageTableFault::_count; -#endif - FaultName InterruptFault::_name = "interrupt"; FaultVect InterruptFault::_vect = 0x0101; FaultStat InterruptFault::_count; @@ -125,40 +119,6 @@ FaultName DspStateDisabledFault::_name = "intover"; FaultVect DspStateDisabledFault::_vect = 0x001a; FaultStat DspStateDisabledFault::_count; - -/*void PageTableFault::invoke(ThreadContext *tc) -{ - Process *p = tc->getProcessPtr(); - - Addr page_addr = p->pTable->pageAlign(vaddr); - - warn("%i: [tid:%i]: %s encountered @ addr %x. Allocating new page for address range %x - %x.\n", - curTick, tc->getThreadNum(), name(), vaddr, page_addr, page_addr+VMPageSize); - - p->pTable->allocate(page_addr, VMPageSize); - - return; -} -*/ - /* address is higher than the stack region or in the current stack region - if (vaddr > p->stack_base || vaddr > p->stack_min) - FaultBase::invoke(tc); - - // We've accessed the next page - if (vaddr > p->stack_min - PageBytes) { - p->stack_min -= PageBytes; - if (p->stack_base - p->stack_min > 8*1024*1024) { - warn("Already allocated Over max stack size for one thread\n"); - } - warn("%i: Allocating page for range %x - %x", - curTick, p->stack_min, p->stack_min-PageBytes); - - p->pTable->allocate(p->stack_min, PageBytes); - warn("Increasing stack size by one page."); - } else { - FaultBase::invoke(tc); - }*/ - void ResetFault::invoke(ThreadContext *tc) { warn("[tid:%i]: %s encountered.\n", tc->getThreadNum(), name()); diff --git a/src/arch/mips/faults.hh b/src/arch/mips/faults.hh index 2e5aa81d6..441e7c27f 100644 --- a/src/arch/mips/faults.hh +++ b/src/arch/mips/faults.hh @@ -92,40 +92,11 @@ class UnimplementedOpcodeFault : public MipsFault FaultStat & countStat() {return _count;} }; -#if !FULL_SYSTEM -//class PageTableFault : public MipsFault -//{ -//private: -// Addr vaddr; -// static FaultName _name; -// static FaultVect _vect; -// static FaultStat _count; -//public: -// PageTableFault(Addr va) -// : vaddr(va) {} -// FaultName name() {return _name;} -// FaultVect vect() {return _vect;} -// FaultStat & countStat() {return _count;} -// void invoke(ThreadContext * tc); -//}; - -static inline Fault genPageTableFault(Addr va) -{ - return new PageTableFault(va); -} -#endif - - static inline Fault genMachineCheckFault() { return new MachineCheckFault; } -static inline Fault genAlignmentFault() -{ - return new AlignmentFault; -} - class ResetFault : public MipsFault { private: diff --git a/src/arch/mips/tlb.cc b/src/arch/mips/tlb.cc new file mode 100644 index 000000000..71111b843 --- /dev/null +++ b/src/arch/mips/tlb.cc @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2001-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: Gabe Black + */ + +#include <cstring> + +#include "arch/mips/tlb.hh" +#include "params/MipsDTB.hh" +#include "params/MipsITB.hh" + +namespace MipsISA { + void + TlbEntry::serialize(std::ostream &os) + { + SERIALIZE_SCALAR(pageStart); + } + + void + TlbEntry::unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_SCALAR(pageStart); + } +}; + +MipsISA::ITB * +MipsITBParams::create() +{ + return new MipsISA::ITB(name); +} + +MipsISA::DTB * +MipsDTBParams::create() +{ + return new MipsISA::DTB(name); +} diff --git a/src/arch/mips/tlb.hh b/src/arch/mips/tlb.hh new file mode 100644 index 000000000..6025de4c0 --- /dev/null +++ b/src/arch/mips/tlb.hh @@ -0,0 +1,63 @@ +/* + * Copyright (c) 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: Gabe Black + */ + +#ifndef __ARCH_MIPS_TLB_HH__ +#define __ARCH_MIPS_TLB_HH__ + +#include "sim/tlb.hh" + +namespace MipsISA +{ + struct TlbEntry + { + Addr pageStart; + TlbEntry() {} + TlbEntry(Addr paddr) : pageStart(paddr) {} + + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + }; + + class ITB : public GenericITB<> + { + public: + ITB(const std::string &name) : GenericITB<>(name) + {} + }; + + class DTB : public GenericDTB<> + { + public: + DTB(const std::string &name) : GenericDTB<>(name) + {} + }; +}; + +#endif // __ARCH_MIPS_TLB_HH__ diff --git a/src/arch/mips/types.hh b/src/arch/mips/types.hh index fc45ea253..9d2c6285d 100644 --- a/src/arch/mips/types.hh +++ b/src/arch/mips/types.hh @@ -93,7 +93,7 @@ namespace MipsISA RND_DOWN, RND_UP, RND_NEAREST - }; + }; } // namespace MipsISA diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript index 0552c282b..81e96a8d6 100644 --- a/src/arch/sparc/SConscript +++ b/src/arch/sparc/SConscript @@ -37,18 +37,19 @@ if env['TARGET_ISA'] == 'sparc': Source('floatregfile.cc') Source('intregfile.cc') Source('miscregfile.cc') + Source('pagetable.cc') Source('regfile.cc') Source('remote_gdb.cc') + Source('tlb.cc') Source('utility.cc') + SimObject('SparcTLB.py') + if env['FULL_SYSTEM']: SimObject('SparcSystem.py') - SimObject('SparcTLB.py') - Source('pagetable.cc') Source('stacktrace.cc') Source('system.cc') - Source('tlb.cc') Source('ua2005.cc') Source('vtophys.cc') else: diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 88c086090..07d332b58 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -620,6 +620,70 @@ void PowerOnReset::invoke(ThreadContext * tc) #else // !FULL_SYSTEM +void FastInstructionAccessMMUMiss::invoke(ThreadContext *tc) +{ + Process *p = tc->getProcessPtr(); + Addr paddr; + bool success = p->pTable->translate(vaddr, paddr); + if(!success) { + panic("Tried to execute unmapped address %#x.\n", vaddr); + } else { + + uint64_t entry = 0; + entry |= 0ULL << 1; // Not writable + entry |= 0ULL << 2; // Available in nonpriveleged mode + entry |= 0ULL << 3; // No side effects + entry |= 1ULL << 4; // Virtually cachable + entry |= 1ULL << 5; // Physically cachable + entry |= 0ULL << 6; // Not locked + entry |= mbits(paddr, 39, 13); // Physical address + entry |= 0ULL << 48; // size = 8k + entry |= 0uLL << 59; // Endianness not inverted + entry |= 0ULL << 60; // Not no fault only + entry |= 0ULL << 61; // size = 8k + entry |= 1ULL << 63; // valid + PageTableEntry PTE(entry); + + Addr alignedVaddr = p->pTable->pageAlign(vaddr); + tc->getITBPtr()->insert(alignedVaddr, 0 /*partition id*/, + p->M5_pid /*context id*/, false, PTE); + } +} + +void FastDataAccessMMUMiss::invoke(ThreadContext *tc) +{ + Process *p = tc->getProcessPtr(); + Addr paddr; + bool success = p->pTable->translate(vaddr, paddr); + if(!success) { + p->checkAndAllocNextPage(vaddr); + success = p->pTable->translate(vaddr, paddr); + } + if(!success) { + panic("Tried to access unmapped address %#x.\n", vaddr); + } else { + + uint64_t entry = 0; + entry |= 1ULL << 1; // Writable + entry |= 0ULL << 2; // Available in nonpriveleged mode + entry |= 0ULL << 3; // No side effects + entry |= 1ULL << 4; // Virtually cachable + entry |= 1ULL << 5; // Physically cachable + entry |= 0ULL << 6; // Not locked + entry |= mbits(paddr, 39, 13); // Physical address + entry |= 0ULL << 48; // size = 8k + entry |= 0uLL << 59; // Endianness not inverted + entry |= 0ULL << 60; // Not no fault only + entry |= 0ULL << 61; // size = 8k + entry |= 1ULL << 63; // valid + PageTableEntry PTE(entry); + + Addr alignedVaddr = p->pTable->pageAlign(vaddr); + tc->getDTBPtr()->insert(alignedVaddr, 0 /*partition id*/, + p->M5_pid /*context id*/, false, PTE); + } +} + void SpillNNormal::invoke(ThreadContext *tc) { doNormalFault(tc, trapType(), false); diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh index 2456ad28a..20dd113c6 100644 --- a/src/arch/sparc/faults.hh +++ b/src/arch/sparc/faults.hh @@ -32,6 +32,7 @@ #ifndef __SPARC_FAULTS_HH__ #define __SPARC_FAULTS_HH__ +#include "config/full_system.hh" #include "sim/faults.hh" // The design of the "name" and "vect" functions is in sim/faults.hh @@ -42,6 +43,8 @@ namespace SparcISA typedef uint32_t TrapType; typedef uint32_t FaultPriority; +class ITB; + class SparcFaultBase : public FaultBase { public: @@ -199,9 +202,29 @@ class PAWatchpoint : public SparcFault<PAWatchpoint> {}; class VAWatchpoint : public SparcFault<VAWatchpoint> {}; class FastInstructionAccessMMUMiss : - public SparcFault<FastInstructionAccessMMUMiss> {}; + public SparcFault<FastInstructionAccessMMUMiss> +{ +#if !FULL_SYSTEM + protected: + Addr vaddr; + public: + FastInstructionAccessMMUMiss(Addr addr) : vaddr(addr) + {} + void invoke(ThreadContext * tc); +#endif +}; -class FastDataAccessMMUMiss : public SparcFault<FastDataAccessMMUMiss> {}; +class FastDataAccessMMUMiss : public SparcFault<FastDataAccessMMUMiss> +{ +#if !FULL_SYSTEM + protected: + Addr vaddr; + public: + FastDataAccessMMUMiss(Addr addr) : vaddr(addr) + {} + void invoke(ThreadContext * tc); +#endif +}; class FastDataAccessProtection : public SparcFault<FastDataAccessProtection> {}; @@ -260,11 +283,6 @@ static inline Fault genMachineCheckFault() return new InternalProcessorError; } -static inline Fault genAlignmentFault() -{ - return new MemAddressNotAligned; -} - } // SparcISA namespace diff --git a/src/arch/sparc/handlers.hh b/src/arch/sparc/handlers.hh index ce5b69427..6a866c859 100644 --- a/src/arch/sparc/handlers.hh +++ b/src/arch/sparc/handlers.hh @@ -44,7 +44,7 @@ const int numSpillInsts = 32; const MachInst fillHandler64[numFillInsts] = { - htog(0x87802018), //wr %g0, ASI_AIUP, %asi + htog(0x87802016), //wr %g0, ASI_AIUP, %asi htog(0xe0dba7ff), //ldxa [%sp + BIAS + (0*8)] %asi, %l0 htog(0xe2dba807), //ldxa [%sp + BIAS + (1*8)] %asi, %l1 htog(0xe4dba80f), //ldxa [%sp + BIAS + (2*8)] %asi, %l2 @@ -80,7 +80,7 @@ const MachInst fillHandler64[numFillInsts] = const MachInst fillHandler32[numFillInsts] = { - htog(0x87802018), //wr %g0, ASI_AIUP, %asi + htog(0x87802016), //wr %g0, ASI_AIUP, %asi htog(0xe083a000), //lduwa [%sp + (0*4)] %asi, %l0 htog(0xe283a004), //lduwa [%sp + (1*4)] %asi, %l1 htog(0xe483a008), //lduwa [%sp + (2*4)] %asi, %l2 @@ -116,7 +116,7 @@ const MachInst fillHandler32[numFillInsts] = const MachInst spillHandler64[numSpillInsts] = { - htog(0x87802018), //wr %g0, ASI_AIUP, %asi + htog(0x87802016), //wr %g0, ASI_AIUP, %asi htog(0xe0f3a7ff), //stxa %l0, [%sp + BIAS + (0*8)] %asi htog(0xe2f3a807), //stxa %l1, [%sp + BIAS + (1*8)] %asi htog(0xe4f3a80f), //stxa %l2, [%sp + BIAS + (2*8)] %asi @@ -152,7 +152,7 @@ const MachInst spillHandler64[numSpillInsts] = const MachInst spillHandler32[numSpillInsts] = { - htog(0x87802018), //wr %g0, ASI_AIUP, %asi + htog(0x87802016), //wr %g0, ASI_AIUP, %asi htog(0xe0a3a000), //stwa %l0, [%sp + (0*4)] %asi htog(0xe2a3a004), //stwa %l1, [%sp + (1*4)] %asi htog(0xe4a3a008), //stwa %l2, [%sp + (2*4)] %asi diff --git a/src/arch/sparc/isa/formats/nop.isa b/src/arch/sparc/isa/formats/nop.isa index de2ba2f54..63c541288 100644 --- a/src/arch/sparc/isa/formats/nop.isa +++ b/src/arch/sparc/isa/formats/nop.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 @@ -53,6 +53,7 @@ output header {{ Nop(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) { + flags[IsNop] = true; } // All Nop instructions do the same thing, so this can be diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index 0edbdec4b..4f3d20606 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -98,12 +98,6 @@ namespace SparcISA StaticInstPtr decodeInst(ExtMachInst); -#if FULL_SYSTEM - // I don't know what it's for, so I don't - // know what SPARC's value should be - // For loading... XXX This maybe could be USegEnd?? --ali - const Addr LoadAddrMask = ULL(0xffffffffff); - /////////// TLB Stuff //////////// const Addr StartVAddrHole = ULL(0x0000800000000000); const Addr EndVAddrHole = ULL(0xFFFF7FFFFFFFFFFF); @@ -111,6 +105,12 @@ namespace SparcISA const Addr PAddrImplMask = ULL(0x000000FFFFFFFFFF); const Addr BytesInPageMask = ULL(0x1FFF); +#if FULL_SYSTEM + // I don't know what it's for, so I don't + // know what SPARC's value should be + // For loading... XXX This maybe could be USegEnd?? --ali + const Addr LoadAddrMask = ULL(0xffffffffff); + enum InterruptTypes { IT_TRAP_LEVEL_ZERO, diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 0300694cc..7b9c73433 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -54,11 +54,7 @@ string SparcISA::getMiscRegName(RegIndex index) "wstate",*/ "gl", "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg", "hstick_cmpr", - "fsr", "prictx", "secctx", "partId", "lsuCtrlReg", "itbTsbC0Ps0", - "itbTsbC0Ps1", "iTlbC0Cnfg", "itbTsbCXPs0", "itbTsbCXPs1", - "iTlbCXCnfg","iTlbSfsr", "iTlbTagAcs", "dtbTsbC0Ps0", - "dtbTsbC0Ps1", "dTlbC0Cnfg", "dtbTsbCXPs0", "dtbTsbCXPs1", - "dTlbCXCnfg","dTlbSfsr", "dTlbSfar", "dTlbTagAcs", + "fsr", "prictx", "secctx", "partId", "lsuCtrlReg", "scratch0", "scratch1", "scratch2", "scratch3", "scratch4", "scratch5", "scratch6", "scratch7", "cpuMondoHead", "cpuMondoTail", "devMondoHead", "devMondoTail", "resErrorHead", "resErrorTail", @@ -113,25 +109,6 @@ void MiscRegFile::clear() partId = 0; lsuCtrlReg = 0; - iTlbC0TsbPs0 = 0; - iTlbC0TsbPs1 = 0; - iTlbC0Config = 0; - iTlbCXTsbPs0 = 0; - iTlbCXTsbPs1 = 0; - iTlbCXConfig = 0; - iTlbSfsr = 0; - iTlbTagAccess = 0; - - dTlbC0TsbPs0 = 0; - dTlbC0TsbPs1 = 0; - dTlbC0Config = 0; - dTlbCXTsbPs0 = 0; - dTlbCXTsbPs1 = 0; - dTlbCXConfig = 0; - dTlbSfsr = 0; - dTlbSfar = 0; - dTlbTagAccess = 0; - memset(scratchPad, 0, sizeof(scratchPad)); #if FULL_SYSTEM tickCompare = NULL; @@ -262,42 +239,6 @@ MiscReg MiscRegFile::readRegNoEffect(int miscReg) case MISCREG_MMU_LSU_CTRL: return lsuCtrlReg; - case MISCREG_MMU_ITLB_C0_TSB_PS0: - return iTlbC0TsbPs0; - case MISCREG_MMU_ITLB_C0_TSB_PS1: - return iTlbC0TsbPs1; - case MISCREG_MMU_ITLB_C0_CONFIG: - return iTlbC0Config; - case MISCREG_MMU_ITLB_CX_TSB_PS0: - return iTlbCXTsbPs0; - case MISCREG_MMU_ITLB_CX_TSB_PS1: - return iTlbCXTsbPs1; - case MISCREG_MMU_ITLB_CX_CONFIG: - return iTlbCXConfig; - case MISCREG_MMU_ITLB_SFSR: - return iTlbSfsr; - case MISCREG_MMU_ITLB_TAG_ACCESS: - return iTlbTagAccess; - - case MISCREG_MMU_DTLB_C0_TSB_PS0: - return dTlbC0TsbPs0; - case MISCREG_MMU_DTLB_C0_TSB_PS1: - return dTlbC0TsbPs1; - case MISCREG_MMU_DTLB_C0_CONFIG: - return dTlbC0Config; - case MISCREG_MMU_DTLB_CX_TSB_PS0: - return dTlbCXTsbPs0; - case MISCREG_MMU_DTLB_CX_TSB_PS1: - return dTlbCXTsbPs1; - case MISCREG_MMU_DTLB_CX_CONFIG: - return dTlbCXConfig; - case MISCREG_MMU_DTLB_SFSR: - return dTlbSfsr; - case MISCREG_MMU_DTLB_SFAR: - return dTlbSfar; - case MISCREG_MMU_DTLB_TAG_ACCESS: - return dTlbTagAccess; - case MISCREG_SCRATCHPAD_R0: return scratchPad[0]; case MISCREG_SCRATCHPAD_R1: @@ -519,59 +460,6 @@ void MiscRegFile::setRegNoEffect(int miscReg, const MiscReg &val) lsuCtrlReg = val; break; - case MISCREG_MMU_ITLB_C0_TSB_PS0: - iTlbC0TsbPs0 = val; - break; - case MISCREG_MMU_ITLB_C0_TSB_PS1: - iTlbC0TsbPs1 = val; - break; - case MISCREG_MMU_ITLB_C0_CONFIG: - iTlbC0Config = val; - break; - case MISCREG_MMU_ITLB_CX_TSB_PS0: - iTlbCXTsbPs0 = val; - break; - case MISCREG_MMU_ITLB_CX_TSB_PS1: - iTlbCXTsbPs1 = val; - break; - case MISCREG_MMU_ITLB_CX_CONFIG: - iTlbCXConfig = val; - break; - case MISCREG_MMU_ITLB_SFSR: - iTlbSfsr = val; - break; - case MISCREG_MMU_ITLB_TAG_ACCESS: - iTlbTagAccess = val; - break; - - case MISCREG_MMU_DTLB_C0_TSB_PS0: - dTlbC0TsbPs0 = val; - break; - case MISCREG_MMU_DTLB_C0_TSB_PS1: - dTlbC0TsbPs1 = val; - break; - case MISCREG_MMU_DTLB_C0_CONFIG: - dTlbC0Config = val; - break; - case MISCREG_MMU_DTLB_CX_TSB_PS0: - dTlbCXTsbPs0 = val; - break; - case MISCREG_MMU_DTLB_CX_TSB_PS1: - dTlbCXTsbPs1 = val; - break; - case MISCREG_MMU_DTLB_CX_CONFIG: - dTlbCXConfig = val; - break; - case MISCREG_MMU_DTLB_SFSR: - dTlbSfsr = val; - break; - case MISCREG_MMU_DTLB_SFAR: - dTlbSfar = val; - break; - case MISCREG_MMU_DTLB_TAG_ACCESS: - dTlbTagAccess = val; - break; - case MISCREG_SCRATCHPAD_R0: scratchPad[0] = val; break; @@ -733,23 +621,6 @@ void MiscRegFile::serialize(std::ostream & os) SERIALIZE_SCALAR(secContext); SERIALIZE_SCALAR(partId); SERIALIZE_SCALAR(lsuCtrlReg); - SERIALIZE_SCALAR(iTlbC0TsbPs0); - SERIALIZE_SCALAR(iTlbC0TsbPs1); - SERIALIZE_SCALAR(iTlbC0Config); - SERIALIZE_SCALAR(iTlbCXTsbPs0); - SERIALIZE_SCALAR(iTlbCXTsbPs1); - SERIALIZE_SCALAR(iTlbCXConfig); - SERIALIZE_SCALAR(iTlbSfsr); - SERIALIZE_SCALAR(iTlbTagAccess); - SERIALIZE_SCALAR(dTlbC0TsbPs0); - SERIALIZE_SCALAR(dTlbC0TsbPs1); - SERIALIZE_SCALAR(dTlbC0Config); - SERIALIZE_SCALAR(dTlbCXTsbPs0); - SERIALIZE_SCALAR(dTlbCXTsbPs1); - SERIALIZE_SCALAR(dTlbCXConfig); - SERIALIZE_SCALAR(dTlbSfsr); - SERIALIZE_SCALAR(dTlbSfar); - SERIALIZE_SCALAR(dTlbTagAccess); SERIALIZE_ARRAY(scratchPad,8); SERIALIZE_SCALAR(cpu_mondo_head); SERIALIZE_SCALAR(cpu_mondo_tail); @@ -827,23 +698,6 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) UNSERIALIZE_SCALAR(secContext); UNSERIALIZE_SCALAR(partId); UNSERIALIZE_SCALAR(lsuCtrlReg); - UNSERIALIZE_SCALAR(iTlbC0TsbPs0); - UNSERIALIZE_SCALAR(iTlbC0TsbPs1); - UNSERIALIZE_SCALAR(iTlbC0Config); - UNSERIALIZE_SCALAR(iTlbCXTsbPs0); - UNSERIALIZE_SCALAR(iTlbCXTsbPs1); - UNSERIALIZE_SCALAR(iTlbCXConfig); - UNSERIALIZE_SCALAR(iTlbSfsr); - UNSERIALIZE_SCALAR(iTlbTagAccess); - UNSERIALIZE_SCALAR(dTlbC0TsbPs0); - UNSERIALIZE_SCALAR(dTlbC0TsbPs1); - UNSERIALIZE_SCALAR(dTlbC0Config); - UNSERIALIZE_SCALAR(dTlbCXTsbPs0); - UNSERIALIZE_SCALAR(dTlbCXTsbPs1); - UNSERIALIZE_SCALAR(dTlbCXConfig); - UNSERIALIZE_SCALAR(dTlbSfsr); - UNSERIALIZE_SCALAR(dTlbSfar); - UNSERIALIZE_SCALAR(dTlbTagAccess); UNSERIALIZE_ARRAY(scratchPad,8); UNSERIALIZE_SCALAR(cpu_mondo_head); UNSERIALIZE_SCALAR(cpu_mondo_tail); diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index 867f959e1..3e17779a9 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -100,25 +100,6 @@ namespace SparcISA MISCREG_MMU_PART_ID, MISCREG_MMU_LSU_CTRL, - MISCREG_MMU_ITLB_C0_TSB_PS0, - MISCREG_MMU_ITLB_C0_TSB_PS1, - MISCREG_MMU_ITLB_C0_CONFIG, - MISCREG_MMU_ITLB_CX_TSB_PS0, - MISCREG_MMU_ITLB_CX_TSB_PS1, - MISCREG_MMU_ITLB_CX_CONFIG, - MISCREG_MMU_ITLB_SFSR, - MISCREG_MMU_ITLB_TAG_ACCESS, /* 50 */ - - MISCREG_MMU_DTLB_C0_TSB_PS0, - MISCREG_MMU_DTLB_C0_TSB_PS1, - MISCREG_MMU_DTLB_C0_CONFIG, - MISCREG_MMU_DTLB_CX_TSB_PS0, - MISCREG_MMU_DTLB_CX_TSB_PS1, - MISCREG_MMU_DTLB_CX_CONFIG, - MISCREG_MMU_DTLB_SFSR, - MISCREG_MMU_DTLB_SFAR, - MISCREG_MMU_DTLB_TAG_ACCESS, - /** Scratchpad regiscers **/ MISCREG_SCRATCHPAD_R0, /* 60 */ MISCREG_SCRATCHPAD_R1, @@ -241,25 +222,6 @@ namespace SparcISA uint16_t partId; uint64_t lsuCtrlReg; - uint64_t iTlbC0TsbPs0; - uint64_t iTlbC0TsbPs1; - uint64_t iTlbC0Config; - uint64_t iTlbCXTsbPs0; - uint64_t iTlbCXTsbPs1; - uint64_t iTlbCXConfig; - uint64_t iTlbSfsr; - uint64_t iTlbTagAccess; - - uint64_t dTlbC0TsbPs0; - uint64_t dTlbC0TsbPs1; - uint64_t dTlbC0Config; - uint64_t dTlbCXTsbPs0; - uint64_t dTlbCXTsbPs1; - uint64_t dTlbCXConfig; - uint64_t dTlbSfsr; - uint64_t dTlbSfar; - uint64_t dTlbTagAccess; - uint64_t scratchPad[8]; uint64_t cpu_mondo_head; diff --git a/src/arch/sparc/pagetable.hh b/src/arch/sparc/pagetable.hh index 980225052..961870579 100644 --- a/src/arch/sparc/pagetable.hh +++ b/src/arch/sparc/pagetable.hh @@ -190,6 +190,11 @@ struct TlbRange { struct TlbEntry { + Addr pageStart; + TlbEntry() + {} + TlbEntry(Addr addr) : pageStart(addr) + {} TlbRange range; PageTableEntry pte; bool used; diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 41a1c2136..29b1a244b 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -121,6 +121,12 @@ Sparc32LiveProcess::startup() threadContexts[0]->setMiscRegNoEffect(MISCREG_TL, 0); //Set the ASI register to something fixed threadContexts[0]->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY); + + /* + * T1 specific registers + */ + //Turn on the icache, dcache, dtb translation, and itb translation. + threadContexts[0]->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, 15); } void @@ -137,7 +143,7 @@ Sparc64LiveProcess::startup() threadContexts[0]->setMiscRegNoEffect(MISCREG_FSR, 0); threadContexts[0]->setMiscRegNoEffect(MISCREG_TICK, 0); - // + /* * Register window management registers */ @@ -163,6 +169,12 @@ Sparc64LiveProcess::startup() threadContexts[0]->setMiscRegNoEffect(MISCREG_TL, 0); //Set the ASI register to something fixed threadContexts[0]->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY); + + /* + * T1 specific registers + */ + //Turn on the icache, dcache, dtb translation, and itb translation. + threadContexts[0]->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, 15); } M5_32_auxv_t::M5_32_auxv_t(int32_t type, int32_t val) diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc index 667b1f002..d6be52424 100644 --- a/src/arch/sparc/regfile.cc +++ b/src/arch/sparc/regfile.cc @@ -326,42 +326,6 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest) dest->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, src->readMiscRegNoEffect(MISCREG_MMU_LSU_CTRL)); - dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_C0_TSB_PS0, - src->readMiscRegNoEffect(MISCREG_MMU_ITLB_C0_TSB_PS0)); - dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_C0_TSB_PS1, - src->readMiscRegNoEffect(MISCREG_MMU_ITLB_C0_TSB_PS1)); - dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_C0_CONFIG, - src->readMiscRegNoEffect(MISCREG_MMU_ITLB_C0_CONFIG)); - dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_CX_TSB_PS0, - src->readMiscRegNoEffect(MISCREG_MMU_ITLB_CX_TSB_PS0)); - dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_CX_TSB_PS1, - src->readMiscRegNoEffect(MISCREG_MMU_ITLB_CX_TSB_PS1)); - dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_CX_CONFIG, - src->readMiscRegNoEffect(MISCREG_MMU_ITLB_CX_CONFIG)); - dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_SFSR, - src->readMiscRegNoEffect(MISCREG_MMU_ITLB_SFSR)); - dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_TAG_ACCESS, - src->readMiscRegNoEffect(MISCREG_MMU_ITLB_TAG_ACCESS)); - - dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_C0_TSB_PS0, - src->readMiscRegNoEffect(MISCREG_MMU_DTLB_C0_TSB_PS0)); - dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_C0_TSB_PS1, - src->readMiscRegNoEffect(MISCREG_MMU_DTLB_C0_TSB_PS1)); - dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_C0_CONFIG, - src->readMiscRegNoEffect(MISCREG_MMU_DTLB_C0_CONFIG)); - dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_CX_TSB_PS0, - src->readMiscRegNoEffect(MISCREG_MMU_DTLB_CX_TSB_PS0)); - dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_CX_TSB_PS1, - src->readMiscRegNoEffect(MISCREG_MMU_DTLB_CX_TSB_PS1)); - dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_CX_CONFIG, - src->readMiscRegNoEffect(MISCREG_MMU_DTLB_CX_CONFIG)); - dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_SFSR, - src->readMiscRegNoEffect(MISCREG_MMU_DTLB_SFSR)); - dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_SFAR, - src->readMiscRegNoEffect(MISCREG_MMU_DTLB_SFAR)); - dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_TAG_ACCESS, - src->readMiscRegNoEffect(MISCREG_MMU_DTLB_TAG_ACCESS)); - // Scratchpad Registers dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R0, src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R0)); diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 21d56b8c6..edc9d37a9 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -60,6 +60,15 @@ TLB::TLB(const std::string &name, int s) for (int x = 0; x < size; x++) freeList.push_back(&tlb[x]); + + c0_tsb_ps0 = 0; + c0_tsb_ps1 = 0; + c0_config = 0; + cx_tsb_ps0 = 0; + cx_tsb_ps1 = 0; + cx_config = 0; + sfsr = 0; + tag_access = 0; } void @@ -393,12 +402,8 @@ TLB::validVirtualAddress(Addr va, bool am) } void -TLB::writeSfsr(ThreadContext *tc, int reg, bool write, ContextType ct, - bool se, FaultTypes ft, int asi) +TLB::writeSfsr(bool write, ContextType ct, bool se, FaultTypes ft, int asi) { - uint64_t sfsr; - sfsr = tc->readMiscRegNoEffect(reg); - if (sfsr & 0x1) sfsr = 0x3; else @@ -411,51 +416,35 @@ TLB::writeSfsr(ThreadContext *tc, int reg, bool write, ContextType ct, sfsr |= 1 << 6; sfsr |= ft << 7; sfsr |= asi << 16; - tc->setMiscReg(reg, sfsr); } void -TLB::writeTagAccess(ThreadContext *tc, int reg, Addr va, int context) +TLB::writeTagAccess(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->setMiscReg(reg, mbits(va, 63,13) | mbits(context,12,0)); + tag_access = mbits(va, 63,13) | mbits(context,12,0); } void -ITB::writeSfsr(ThreadContext *tc, bool write, ContextType ct, - bool se, FaultTypes ft, int asi) +ITB::writeSfsr(bool write, ContextType ct, bool se, FaultTypes ft, int asi) { DPRINTF(TLB, "TLB: ITB Fault: w=%d ct=%d ft=%d asi=%d\n", (int)write, ct, ft, asi); - TLB::writeSfsr(tc, MISCREG_MMU_ITLB_SFSR, write, ct, se, ft, asi); + TLB::writeSfsr(write, ct, se, ft, asi); } void -ITB::writeTagAccess(ThreadContext *tc, Addr va, int context) -{ - TLB::writeTagAccess(tc, MISCREG_MMU_ITLB_TAG_ACCESS, va, context); -} - -void -DTB::writeSfr(ThreadContext *tc, Addr a, bool write, ContextType ct, +DTB::writeSfsr(Addr a, bool write, ContextType ct, bool se, FaultTypes ft, int asi) { DPRINTF(TLB, "TLB: DTB Fault: A=%#x w=%d ct=%d ft=%d asi=%d\n", a, (int)write, ct, ft, asi); - TLB::writeSfsr(tc, MISCREG_MMU_DTLB_SFSR, write, ct, se, ft, asi); - tc->setMiscReg(MISCREG_MMU_DTLB_SFAR, a); -} - -void -DTB::writeTagAccess(ThreadContext *tc, Addr va, int context) -{ - TLB::writeTagAccess(tc, MISCREG_MMU_DTLB_TAG_ACCESS, va, context); + TLB::writeSfsr(write, ct, se, ft, asi); + sfar = a; } - - Fault ITB::translate(RequestPtr &req, ThreadContext *tc) { @@ -521,7 +510,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) // If the access is unaligned trap if (vaddr & 0x3) { - writeSfsr(tc, false, ct, false, OtherFault, asi); + writeSfsr(false, ct, false, OtherFault, asi); return new MemAddressNotAligned; } @@ -529,7 +518,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) vaddr = vaddr & VAddrAMask; if (!validVirtualAddress(vaddr, addr_mask)) { - writeSfsr(tc, false, ct, false, VaOutOfRange, asi); + writeSfsr(false, ct, false, VaOutOfRange, asi); return new InstructionAccessException; } @@ -542,17 +531,21 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) } if (e == NULL || !e->valid) { - writeTagAccess(tc, vaddr, context); + writeTagAccess(vaddr, context); if (real) return new InstructionRealTranslationMiss; else +#if FULL_SYSTEM return new FastInstructionAccessMMUMiss; +#else + return new FastInstructionAccessMMUMiss(req->getVaddr()); +#endif } // were not priviledged accesing priv page if (!priv && e->pte.priv()) { - writeTagAccess(tc, vaddr, context); - writeSfsr(tc, false, ct, false, PrivViolation, asi); + writeTagAccess(vaddr, context); + writeSfsr(false, ct, false, PrivViolation, asi); return new InstructionAccessException; } @@ -580,6 +573,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) asi = (ASI)req->getAsi(); bool implicit = false; bool hpriv = bits(tlbdata,0,0); + bool unaligned = (vaddr & size-1); DPRINTF(TLB, "TLB: DTB Request to translate va=%#x size=%d asi=%#x\n", vaddr, size, asi); @@ -590,43 +584,47 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) if (asi == ASI_IMPLICIT) implicit = true; - if (hpriv && implicit) { - req->setPaddr(vaddr & PAddrImplMask); - return NoFault; - } - - // Be fast if we can! - if (cacheValid && cacheState == tlbdata) { - - + // Only use the fast path here if there doesn't need to be an unaligned + // trap later + if (!unaligned) { + if (hpriv && implicit) { + req->setPaddr(vaddr & PAddrImplMask); + return NoFault; + } - if (cacheEntry[0]) { - TlbEntry *ce = cacheEntry[0]; - Addr ce_va = ce->range.va; - if (cacheAsi[0] == asi && - ce_va < vaddr + size && ce_va + ce->range.size > vaddr && - (!write || ce->pte.writable())) { - req->setPaddr(ce->pte.paddrMask() | vaddr & ce->pte.sizeMask()); - if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) - req->setFlags(req->getFlags() | UNCACHEABLE); - DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); - return NoFault; - } // if matched - } // if cache entry valid - if (cacheEntry[1]) { - TlbEntry *ce = cacheEntry[1]; - Addr ce_va = ce->range.va; - if (cacheAsi[1] == asi && - ce_va < vaddr + size && ce_va + ce->range.size > vaddr && - (!write || ce->pte.writable())) { - req->setPaddr(ce->pte.paddrMask() | vaddr & ce->pte.sizeMask()); - if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) - req->setFlags(req->getFlags() | UNCACHEABLE); - DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); - return NoFault; - } // if matched - } // if cache entry valid - } + // Be fast if we can! + if (cacheValid && cacheState == tlbdata) { + + + + if (cacheEntry[0]) { + TlbEntry *ce = cacheEntry[0]; + Addr ce_va = ce->range.va; + if (cacheAsi[0] == asi && + ce_va < vaddr + size && ce_va + ce->range.size > vaddr && + (!write || ce->pte.writable())) { + req->setPaddr(ce->pte.paddrMask() | vaddr & ce->pte.sizeMask()); + if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) + req->setFlags(req->getFlags() | UNCACHEABLE); + DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); + return NoFault; + } // if matched + } // if cache entry valid + if (cacheEntry[1]) { + TlbEntry *ce = cacheEntry[1]; + Addr ce_va = ce->range.va; + if (cacheAsi[1] == asi && + ce_va < vaddr + size && ce_va + ce->range.size > vaddr && + (!write || ce->pte.writable())) { + req->setPaddr(ce->pte.paddrMask() | vaddr & ce->pte.sizeMask()); + if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) + req->setFlags(req->getFlags() | UNCACHEABLE); + DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); + return NoFault; + } // if matched + } // if cache entry valid + } + } bool red = bits(tlbdata,1,1); bool priv = bits(tlbdata,2,2); @@ -661,12 +659,12 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) // We need to check for priv level/asi priv if (!priv && !hpriv && !AsiIsUnPriv(asi)) { // It appears that context should be Nucleus in these cases? - writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi); + writeSfsr(vaddr, write, Nucleus, false, IllegalAsi, asi); return new PrivilegedAction; } if (!hpriv && AsiIsHPriv(asi)) { - writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi); + writeSfsr(vaddr, write, Nucleus, false, IllegalAsi, asi); return new DataAccessException; } @@ -688,8 +686,12 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) if (!implicit && asi != ASI_P && asi != ASI_S) { if (AsiIsLittle(asi)) panic("Little Endian ASIs not supported\n"); - if (AsiIsNoFault(asi)) - panic("No Fault ASIs not supported\n"); + + //XXX It's unclear from looking at the documentation how a no fault + //load differs from a regular one, other than what happens concerning + //nfo and e bits in the TTE +// if (AsiIsNoFault(asi)) +// panic("No Fault ASIs not supported\n"); if (AsiIsPartialStore(asi)) panic("Partial Store ASIs not supported\n"); @@ -709,13 +711,13 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) goto handleSparcErrorRegAccess; if (!AsiIsReal(asi) && !AsiIsNucleus(asi) && !AsiIsAsIfUser(asi) && - !AsiIsTwin(asi) && !AsiIsBlock(asi)) + !AsiIsTwin(asi) && !AsiIsBlock(asi) && !AsiIsNoFault(asi)) panic("Accessing ASI %#X. Should we?\n", asi); } // If the asi is unaligned trap - if (vaddr & size-1) { - writeSfr(tc, vaddr, false, ct, false, OtherFault, asi); + if (unaligned) { + writeSfsr(vaddr, false, ct, false, OtherFault, asi); return new MemAddressNotAligned; } @@ -723,7 +725,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) vaddr = vaddr & VAddrAMask; if (!validVirtualAddress(vaddr, addr_mask)) { - writeSfr(tc, vaddr, false, ct, true, VaOutOfRange, asi); + writeSfsr(vaddr, false, ct, true, VaOutOfRange, asi); return new DataAccessException; } @@ -741,36 +743,40 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) e = lookup(vaddr, part_id, real, context); if (e == NULL || !e->valid) { - writeTagAccess(tc, vaddr, context); + writeTagAccess(vaddr, context); DPRINTF(TLB, "TLB: DTB Failed to find matching TLB entry\n"); if (real) return new DataRealTranslationMiss; else +#if FULL_SYSTEM return new FastDataAccessMMUMiss; +#else + return new FastDataAccessMMUMiss(req->getVaddr()); +#endif } if (!priv && e->pte.priv()) { - writeTagAccess(tc, vaddr, context); - writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), PrivViolation, asi); + writeTagAccess(vaddr, context); + writeSfsr(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); + writeTagAccess(vaddr, context); + writeSfsr(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); + writeTagAccess(vaddr, context); + writeSfsr(vaddr, write, ct, e->pte.sideffect(), LoadFromNfo, asi); return new DataAccessException; } if (e->pte.sideffect() && AsiIsNoFault(asi)) { - writeTagAccess(tc, vaddr, context); - writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), SideEffect, asi); + writeTagAccess(vaddr, context); + writeSfsr(vaddr, write, ct, e->pte.sideffect(), SideEffect, asi); return new DataAccessException; } @@ -802,7 +808,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) /** Normal flow ends here. */ handleIntRegAccess: if (!hpriv) { - writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi); + writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi); if (priv) return new DataAccessException; else @@ -811,7 +817,7 @@ handleIntRegAccess: if (asi == ASI_SWVR_UDB_INTR_W && !write || asi == ASI_SWVR_UDB_INTR_R && write) { - writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi); + writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi); return new DataAccessException; } @@ -820,25 +826,25 @@ handleIntRegAccess: handleScratchRegAccess: if (vaddr > 0x38 || (vaddr >= 0x20 && vaddr < 0x30 && !hpriv)) { - writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi); + writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi); return new DataAccessException; } goto regAccessOk; handleQueueRegAccess: if (!priv && !hpriv) { - writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi); + writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi); return new PrivilegedAction; } if (!hpriv && vaddr & 0xF || vaddr > 0x3f8 || vaddr < 0x3c0) { - writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi); + writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi); return new DataAccessException; } goto regAccessOk; handleSparcErrorRegAccess: if (!hpriv) { - writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi); + writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi); if (priv) return new DataAccessException; else @@ -855,6 +861,8 @@ handleMmuRegAccess: return NoFault; }; +#if FULL_SYSTEM + Tick DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) { @@ -865,6 +873,8 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) DPRINTF(IPR, "Memory Mapped IPR Read: asi=%#X a=%#x\n", (uint32_t)pkt->req->getAsi(), pkt->getAddr()); + ITB * itb = tc->getITBPtr(); + switch (asi) { case ASI_LSU_CONTROL_REG: assert(va == 0); @@ -888,51 +898,51 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) break; case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0: assert(va == 0); - pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0)); + pkt->set(c0_tsb_ps0); break; case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS1: assert(va == 0); - pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1)); + pkt->set(c0_tsb_ps1); break; case ASI_DMMU_CTXT_ZERO_CONFIG: assert(va == 0); - pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG)); + pkt->set(c0_config); break; case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0: assert(va == 0); - pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0)); + pkt->set(itb->c0_tsb_ps0); break; case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS1: assert(va == 0); - pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1)); + pkt->set(itb->c0_tsb_ps1); break; case ASI_IMMU_CTXT_ZERO_CONFIG: assert(va == 0); - pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG)); + pkt->set(itb->c0_config); break; case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0: assert(va == 0); - pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0)); + pkt->set(cx_tsb_ps0); break; case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS1: assert(va == 0); - pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1)); + pkt->set(cx_tsb_ps1); break; case ASI_DMMU_CTXT_NONZERO_CONFIG: assert(va == 0); - pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG)); + pkt->set(cx_config); break; case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0: assert(va == 0); - pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0)); + pkt->set(itb->cx_tsb_ps0); break; case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1: assert(va == 0); - pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1)); + pkt->set(itb->cx_tsb_ps1); break; case ASI_IMMU_CTXT_NONZERO_CONFIG: assert(va == 0); - pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG)); + pkt->set(itb->cx_config); break; case ASI_SPARC_ERROR_STATUS_REG: pkt->set((uint64_t)0); @@ -944,14 +954,14 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) case ASI_IMMU: switch (va) { case 0x0: - temp = tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS); + temp = itb->tag_access; pkt->set(bits(temp,63,22) | bits(temp,12,0) << 48); break; case 0x18: - pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_SFSR)); + pkt->set(itb->sfsr); break; case 0x30: - pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS)); + pkt->set(itb->tag_access); break; default: goto doMmuReadError; @@ -960,17 +970,17 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) case ASI_DMMU: switch (va) { case 0x0: - temp = tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS); + temp = tag_access; pkt->set(bits(temp,63,22) | bits(temp,12,0) << 48); break; case 0x18: - pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_SFSR)); + pkt->set(sfsr); break; case 0x20: - pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_SFAR)); + pkt->set(sfar); break; case 0x30: - pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS)); + pkt->set(tag_access); break; case 0x80: pkt->set(tc->readMiscReg(MISCREG_MMU_PART_ID)); @@ -981,35 +991,35 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) break; case ASI_DMMU_TSB_PS0_PTR_REG: pkt->set(MakeTsbPtr(Ps0, - tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS), - tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0), - tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG), - tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0), - tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG))); + tag_access, + c0_tsb_ps0, + c0_config, + cx_tsb_ps0, + cx_config)); break; case ASI_DMMU_TSB_PS1_PTR_REG: pkt->set(MakeTsbPtr(Ps1, - tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS), - tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1), - tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG), - tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1), - tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG))); + tag_access, + c0_tsb_ps1, + c0_config, + cx_tsb_ps1, + cx_config)); break; case ASI_IMMU_TSB_PS0_PTR_REG: pkt->set(MakeTsbPtr(Ps0, - tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS), - tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0), - tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG), - tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0), - tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG))); + itb->tag_access, + itb->c0_tsb_ps0, + itb->c0_config, + itb->cx_tsb_ps0, + itb->cx_config)); break; case ASI_IMMU_TSB_PS1_PTR_REG: pkt->set(MakeTsbPtr(Ps1, - tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS), - tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1), - tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG), - tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1), - tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG))); + itb->tag_access, + itb->c0_tsb_ps1, + itb->c0_config, + itb->cx_tsb_ps1, + itb->cx_config)); break; case ASI_SWVR_INTR_RECEIVE: pkt->set(tc->getCpuPtr()->get_interrupts(IT_INT_VEC)); @@ -1049,6 +1059,8 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) DPRINTF(IPR, "Memory Mapped IPR Write: asi=%#X a=%#x d=%#X\n", (uint32_t)asi, va, data); + ITB * itb = tc->getITBPtr(); + switch (asi) { case ASI_LSU_CONTROL_REG: assert(va == 0); @@ -1073,51 +1085,51 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) break; case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0: assert(va == 0); - tc->setMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0, data); + c0_tsb_ps0 = data; break; case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS1: assert(va == 0); - tc->setMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1, data); + c0_tsb_ps1 = data; break; case ASI_DMMU_CTXT_ZERO_CONFIG: assert(va == 0); - tc->setMiscReg(MISCREG_MMU_DTLB_C0_CONFIG, data); + c0_config = data; break; case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0: assert(va == 0); - tc->setMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0, data); + itb->c0_tsb_ps0 = data; break; case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS1: assert(va == 0); - tc->setMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1, data); + itb->c0_tsb_ps1 = data; break; case ASI_IMMU_CTXT_ZERO_CONFIG: assert(va == 0); - tc->setMiscReg(MISCREG_MMU_ITLB_C0_CONFIG, data); + itb->c0_config = data; break; case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0: assert(va == 0); - tc->setMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0, data); + cx_tsb_ps0 = data; break; case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS1: assert(va == 0); - tc->setMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1, data); + cx_tsb_ps1 = data; break; case ASI_DMMU_CTXT_NONZERO_CONFIG: assert(va == 0); - tc->setMiscReg(MISCREG_MMU_DTLB_CX_CONFIG, data); + cx_config = data; break; case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0: assert(va == 0); - tc->setMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0, data); + itb->cx_tsb_ps0 = data; break; case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1: assert(va == 0); - tc->setMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1, data); + itb->cx_tsb_ps1 = data; break; case ASI_IMMU_CTXT_NONZERO_CONFIG: assert(va == 0); - tc->setMiscReg(MISCREG_MMU_ITLB_CX_CONFIG, data); + itb->cx_config = data; break; case ASI_SPARC_ERROR_EN_REG: case ASI_SPARC_ERROR_STATUS_REG: @@ -1130,11 +1142,11 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) case ASI_IMMU: switch (va) { case 0x18: - tc->setMiscReg(MISCREG_MMU_ITLB_SFSR, data); + itb->sfsr = data; break; case 0x30: sext<59>(bits(data, 59,0)); - tc->setMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS, data); + itb->tag_access = data; break; default: goto doMmuWriteError; @@ -1144,7 +1156,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) entry_insert = bits(va, 8,3); case ASI_ITLB_DATA_IN_REG: assert(entry_insert != -1 || mbits(va,10,9) == va); - ta_insert = tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS); + ta_insert = itb->tag_access; va_insert = mbits(ta_insert, 63,13); ct_insert = mbits(ta_insert, 12,0); part_insert = tc->readMiscReg(MISCREG_MMU_PART_ID); @@ -1158,7 +1170,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) entry_insert = bits(va, 8,3); case ASI_DTLB_DATA_IN_REG: assert(entry_insert != -1 || mbits(va,10,9) == va); - ta_insert = tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS); + ta_insert = tag_access; va_insert = mbits(ta_insert, 63,13); ct_insert = mbits(ta_insert, 12,0); part_insert = tc->readMiscReg(MISCREG_MMU_PART_ID); @@ -1205,11 +1217,11 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) case ASI_DMMU: switch (va) { case 0x18: - tc->setMiscReg(MISCREG_MMU_DTLB_SFSR, data); + sfsr = data; break; case 0x30: sext<59>(bits(data, 59,0)); - tc->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS, data); + tag_access = data; break; case 0x80: tc->setMiscReg(MISCREG_MMU_PART_ID, data); @@ -1273,30 +1285,33 @@ doMmuWriteError: return tc->getCpuPtr()->cycles(1); } +#endif + void DTB::GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs) { uint64_t tag_access = mbits(addr,63,13) | mbits(ctx,12,0); + ITB * itb = tc->getITBPtr(); ptrs[0] = MakeTsbPtr(Ps0, tag_access, - tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0), - tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG), - tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0), - tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG)); + c0_tsb_ps0, + c0_config, + cx_tsb_ps0, + cx_config); ptrs[1] = MakeTsbPtr(Ps1, tag_access, - tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1), - tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG), - tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1), - tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG)); + c0_tsb_ps1, + c0_config, + cx_tsb_ps1, + cx_config); ptrs[2] = MakeTsbPtr(Ps0, tag_access, - tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0), - tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG), - tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0), - tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG)); + itb->c0_tsb_ps0, + itb->c0_config, + itb->cx_tsb_ps0, + itb->cx_config); ptrs[3] = MakeTsbPtr(Ps1, tag_access, - tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1), - tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG), - tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1), - tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG)); + itb->c0_tsb_ps1, + itb->c0_config, + itb->cx_tsb_ps1, + itb->cx_config); } @@ -1354,6 +1369,15 @@ TLB::serialize(std::ostream &os) nameOut(os, csprintf("%s.PTE%d", name(), x)); tlb[x].serialize(os); } + + SERIALIZE_SCALAR(c0_tsb_ps0); + SERIALIZE_SCALAR(c0_tsb_ps1); + SERIALIZE_SCALAR(c0_config); + SERIALIZE_SCALAR(cx_tsb_ps0); + SERIALIZE_SCALAR(cx_tsb_ps1); + SERIALIZE_SCALAR(cx_config); + SERIALIZE_SCALAR(sfsr); + SERIALIZE_SCALAR(tag_access); } void @@ -1383,6 +1407,29 @@ TLB::unserialize(Checkpoint *cp, const std::string §ion) lookupTable.insert(tlb[x].range, &tlb[x]); } + + UNSERIALIZE_SCALAR(c0_tsb_ps0); + UNSERIALIZE_SCALAR(c0_tsb_ps1); + UNSERIALIZE_SCALAR(c0_config); + UNSERIALIZE_SCALAR(cx_tsb_ps0); + UNSERIALIZE_SCALAR(cx_tsb_ps1); + UNSERIALIZE_SCALAR(cx_config); + UNSERIALIZE_SCALAR(sfsr); + UNSERIALIZE_SCALAR(tag_access); +} + +void +DTB::serialize(std::ostream &os) +{ + TLB::serialize(os); + SERIALIZE_SCALAR(sfar); +} + +void +DTB::unserialize(Checkpoint *cp, const std::string §ion) +{ + TLB::unserialize(cp, section); + UNSERIALIZE_SCALAR(sfar); } /* end namespace SparcISA */ } diff --git a/src/arch/sparc/tlb.hh b/src/arch/sparc/tlb.hh index b5f02c62e..d35a6e096 100644 --- a/src/arch/sparc/tlb.hh +++ b/src/arch/sparc/tlb.hh @@ -34,6 +34,7 @@ #include "arch/sparc/asi.hh" #include "arch/sparc/tlb_map.hh" #include "base/misc.hh" +#include "config/full_system.hh" #include "mem/request.hh" #include "sim/faults.hh" #include "sim/sim_object.hh" @@ -46,6 +47,23 @@ namespace SparcISA class TLB : public SimObject { +#if !FULL_SYSTEM + //These faults need to be able to populate the tlb in SE mode. + friend class FastInstructionAccessMMUMiss; + friend class FastDataAccessMMUMiss; +#endif + + //TLB state + protected: + uint64_t c0_tsb_ps0; + uint64_t c0_tsb_ps1; + uint64_t c0_config; + uint64_t cx_tsb_ps0; + uint64_t cx_tsb_ps1; + uint64_t cx_config; + uint64_t sfsr; + uint64_t tag_access; + protected: TlbMap lookupTable;; typedef TlbMap::iterator MapIter; @@ -120,13 +138,13 @@ class TLB : public SimObject /** Checks if the virtual address provided is a valid one. */ bool validVirtualAddress(Addr va, bool am); - void writeSfsr(ThreadContext *tc, int reg, bool write, ContextType ct, + void writeSfsr(bool write, ContextType ct, bool se, FaultTypes ft, int asi); void clearUsedBits(); - void writeTagAccess(ThreadContext *tc, int reg, Addr va, int context); + void writeTagAccess(Addr va, int context); public: TLB(const std::string &name, int size); @@ -152,31 +170,39 @@ class ITB : public TLB Fault translate(RequestPtr &req, ThreadContext *tc); private: - void writeSfsr(ThreadContext *tc, bool write, ContextType ct, + void writeSfsr(bool write, ContextType ct, bool se, FaultTypes ft, int asi); - void writeTagAccess(ThreadContext *tc, Addr va, int context); TlbEntry *cacheEntry; friend class DTB; }; class DTB : public TLB { + //DTLB specific state + protected: + uint64_t sfar; public: DTB(const std::string &name, int size) : TLB(name, size) { + sfar = 0; cacheEntry[0] = NULL; cacheEntry[1] = NULL; } Fault translate(RequestPtr &req, ThreadContext *tc, bool write); +#if FULL_SYSTEM Tick doMmuRegRead(ThreadContext *tc, Packet *pkt); Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt); +#endif void GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs); + // Checkpointing + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); + private: - void writeSfr(ThreadContext *tc, Addr a, bool write, ContextType ct, + void writeSfsr(Addr a, bool write, ContextType ct, bool se, FaultTypes ft, int asi); - void writeTagAccess(ThreadContext *tc, Addr va, int context); uint64_t MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb, uint64_t c0_config, uint64_t cX_tsb, uint64_t cX_config); diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index e8f8059ce..b791a0624 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -96,6 +96,9 @@ if env['TARGET_ISA'] == 'x86': Source('predecoder_tables.cc') Source('regfile.cc') Source('remote_gdb.cc') + Source('tlb.cc') + + SimObject('X86TLB.py') if env['FULL_SYSTEM']: # Full-system sources diff --git a/src/arch/x86/X86TLB.py b/src/arch/x86/X86TLB.py new file mode 100644 index 000000000..f16408e63 --- /dev/null +++ b/src/arch/x86/X86TLB.py @@ -0,0 +1,75 @@ +# Copyright (c) 2007 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use of this software in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# +# The software must be used only for Non-Commercial Use which means any +# use which is NOT directed to receiving any direct monetary +# compensation for, or commercial advantage from such use. Illustrative +# examples of non-commercial use are academic research, personal study, +# teaching, education and corporate research & development. +# Illustrative examples of commercial use are distributing products for +# commercial advantage and providing services using the software for +# commercial advantage. +# +# If you wish to use this software or functionality therein that may be +# covered by patents for commercial use, please contact: +# Director of Intellectual Property Licensing +# Office of Strategy and Technology +# Hewlett-Packard Company +# 1501 Page Mill Road +# Palo Alto, California 94304 +# +# 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. No right of +# sublicense is granted herewith. Derivatives of the software and +# output created using the software may be prepared, but only for +# Non-Commercial Uses. Derivatives of the software may be shared with +# others provided: (i) the others agree to abide by the list of +# conditions herein which includes the Non-Commercial Use restrictions; +# and (ii) such Derivatives of the software include the above copyright +# notice to acknowledge the contribution from this software where +# applicable, this list of conditions and the disclaimer below. +# +# 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: Gabe Black + +from m5.SimObject import SimObject +from m5.params import * +class X86TLB(SimObject): + type = 'X86TLB' + abstract = True + #size = Param.Int("TLB size") + +class X86DTB(X86TLB): + type = 'X86DTB' + cxx_namespace = 'X86ISA' + cxx_class = 'DTB' + + #size = 64 + +class X86ITB(X86TLB): + type = 'X86ITB' + cxx_namespace = 'X86ISA' + cxx_class = 'ITB' + + #size = 64 diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index 51c34cebd..936d0357c 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -91,20 +91,10 @@ namespace X86ISA } }; - static inline Fault genPageTableFault(Addr va) - { - panic("Page table fault not implemented in x86!\n"); - } - static inline Fault genMachineCheckFault() { panic("Machine check fault not implemented in x86!\n"); } - - static inline Fault genAlignmentFault() - { - panic("Alignment fault not implemented (or for the most part existant) in x86!\n"); - } }; #endif // __ARCH_X86_FAULTS_HH__ diff --git a/src/arch/x86/insts/microldstop.hh b/src/arch/x86/insts/microldstop.hh index fac1fa3aa..5b1210d69 100644 --- a/src/arch/x86/insts/microldstop.hh +++ b/src/arch/x86/insts/microldstop.hh @@ -106,29 +106,22 @@ namespace X86ISA Fault read(Context *xc, Addr EA, MemType & Mem, unsigned flags) const { Fault fault = NoFault; - int size = dataSize; - Addr alignedEA = EA & ~(dataSize - 1); - if (EA != alignedEA) - size *= 2; - switch(size) + switch(dataSize) { case 1: - fault = xc->read(alignedEA, (uint8_t&)(Mem.a), flags); + fault = xc->read(EA, (uint8_t&)Mem, flags); break; case 2: - fault = xc->read(alignedEA, (uint16_t&)(Mem.a), flags); + fault = xc->read(EA, (uint16_t&)Mem, flags); break; case 4: - fault = xc->read(alignedEA, (uint32_t&)(Mem.a), flags); + fault = xc->read(EA, (uint32_t&)Mem, flags); break; case 8: - fault = xc->read(alignedEA, (uint64_t&)(Mem.a), flags); - break; - case 16: - fault = xc->read(alignedEA, Mem, flags); + fault = xc->read(EA, (uint64_t&)Mem, flags); break; default: - panic("Bad operand size %d for read at %#x.\n", size, EA); + panic("Bad operand size %d for read at %#x.\n", dataSize, EA); } return fault; } @@ -137,29 +130,22 @@ namespace X86ISA Fault write(Context *xc, MemType & Mem, Addr EA, unsigned flags) const { Fault fault = NoFault; - int size = dataSize; - Addr alignedEA = EA & ~(dataSize - 1); - if (EA != alignedEA) - size *= 2; - switch(size) + switch(dataSize) { case 1: - fault = xc->write((uint8_t&)(Mem.a), alignedEA, flags, 0); + fault = xc->write((uint8_t&)Mem, EA, flags, 0); break; case 2: - fault = xc->write((uint16_t&)(Mem.a), alignedEA, flags, 0); + fault = xc->write((uint16_t&)Mem, EA, flags, 0); break; case 4: - fault = xc->write((uint32_t&)(Mem.a), alignedEA, flags, 0); + fault = xc->write((uint32_t&)Mem, EA, flags, 0); break; case 8: - fault = xc->write((uint64_t&)(Mem.a), alignedEA, flags, 0); - break; - case 16: - fault = xc->write(Mem, alignedEA, flags, 0); + fault = xc->write((uint64_t&)Mem, EA, flags, 0); break; default: - panic("Bad operand size %d for write at %#x.\n", size, EA); + panic("Bad operand size %d for write at %#x.\n", dataSize, EA); } return fault; } diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index ee7fbc683..d8db47063 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -332,8 +332,8 @@ 0x3: mov_Ov_rAX(); 0x4: movs_Yb_Xb(); 0x5: movs_Yv_Xv(); - 0x6: cmps_Yb_Xb(); - 0x7: cmps_Yv_Xv(); + 0x6: StringInst::CMPS(Yb,Xb); + 0x7: StringInst::CMPS(Yv,Xv); } 0x15: decode OPCODE_OP_BOTTOM3 { 0x0: Inst::TEST(rAb,Ib); diff --git a/src/arch/x86/isa/insts/processor_information.py b/src/arch/x86/isa/insts/processor_information.py index 48891cd84..9cad8181c 100644 --- a/src/arch/x86/isa/insts/processor_information.py +++ b/src/arch/x86/isa/insts/processor_information.py @@ -55,15 +55,351 @@ microcode = ''' def macroop CPUID_R { - # - # For now, the CPUID function number will be hard wired to 0x8000_0000. - # Getting it to work more robustly will likely require microcode branching - # which probably doesn't work at the moment. - # +# +# Find which type of cpuid function it is by checking bit 31. Also clear that +# bit to form an offset into the functions of that type. +# + limm t1, 0x80000000, dataSize=4 + and t2, t1, rax, flags=(EZF,) + # clear the bit + xor t1, t2, rax + +# +# Do range checking on the offset +# + # If EZF is set, the function is standard and the max is 0x1. + movi t2, t2, 0x1, flags=(CEZF,) + # If EZF is cleared, the function is extended and the max is 0x18. + movi t2, t2, 0x18, flags=(nCEZF,) + subi t0, t1, t2, flags=(ECF,) + # ECF will be set if the offset is too large. + bri t0, label("end"), flags=(CECF,) + + +# +# Jump to the right portion +# + movi t2, t2, label("standardStart"), flags=(CEZF,) + movi t2, t2, label("extendedStart"), flags=(nCEZF,) + # This gives each function 8 microops to use. It's wasteful because only + # 5 will be needed, but a multiply would be expensive. In the system + # described in the RISC86 patent, the fifth instruction would really be + # the sequencing field on an op quad, so each function would be implemented + # by -exactly- one op quad. Since we're approximating, this should be ok. + slli t1, t1, 3 + br t2, t1 + +############################################################################# +############################################################################# + +# +# Standard functions. +# + +standardStart: + +# 0x00000000 -- Processor Vendor and Largest Standard Function Number + limm rax, 0x00000001, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x00000001 -- Family, Model, Stepping Identifiers + limm rax, 0x00020f51, dataSize=4 + limm rbx, 0x00000405, dataSize=4 + limm rdx, 0xe3d3fbff, dataSize=4 + limm rcx, 0x00000001, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# +# Extended functions. +# + +extendedStart: + +# 0x80000000 -- Processor Vendor and Largest Extended Function Number + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000001 -- EAX: AMD Family, Model, Stepping +# EBX: BrandId Identifier +# ECX: Feature Identifiers +# EDX: Feature Identifiers + limm rax, 0x00020f51, dataSize=4 + limm rbx, 0x00000405, dataSize=4 + limm rdx, 0xe3d3fbff, dataSize=4 + limm rcx, 0x00000001, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000002 -- Processor Name String Identifier + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000003 -- Processor Name String Identifier + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000004 -- Processor Name String Identifier + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000005 -- L1 Cache and TLB Identifiers + limm rax, 0xff08ff08, dataSize=4 + limm rbx, 0xff20ff20, dataSize=4 + limm rdx, 0x40020140, dataSize=4 + limm rcx, 0x40020140, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000006 -- L2/L3 Cache and L2 TLB Identifiers + limm rax, 0x00000000, dataSize=4 + limm rbx, 0x42004200, dataSize=4 + limm rdx, 0x00000000, dataSize=4 + limm rcx, 0x04008140, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000007 -- Advanced Power Management Information + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000008 -- Long Mode Address Size Identification + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000009 -- Reserved + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x8000000A -- SVM Revision and Feature Identification + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x8000000B -- Reserved + # JUNK VALUES limm rax, 0x80000018, dataSize=4 limm rbx, 0x68747541, dataSize=4 limm rdx, 0x69746e65, dataSize=4 limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x8000000C -- Reserved + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x8000000D -- Reserved + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x8000000E -- Reserved + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x8000000F -- Reserved + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000010 -- Reserved + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000011 -- Reserved + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000012 -- Reserved + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000013 -- Reserved + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000014 -- Reserved + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000015 -- Reserved + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000016 -- Reserved + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000017 -- Reserved + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +# 0x80000018 -- Reserved + # JUNK VALUES + limm rax, 0x80000018, dataSize=4 + limm rbx, 0x68747541, dataSize=4 + limm rdx, 0x69746e65, dataSize=4 + limm rcx, 0x444d4163, dataSize=4 + bri t0, label("end") + fault "NoFault" + fault "NoFault" + fault "NoFault" + +end: + fault "NoFault" }; ''' diff --git a/src/arch/x86/isa/insts/rotate_and_shift/shift.py b/src/arch/x86/isa/insts/rotate_and_shift/shift.py index 45758b489..6c688cca3 100644 --- a/src/arch/x86/isa/insts/rotate_and_shift/shift.py +++ b/src/arch/x86/isa/insts/rotate_and_shift/shift.py @@ -56,13 +56,13 @@ microcode = ''' def macroop SAL_R_I { - slli reg, reg, imm + slli reg, reg, imm, flags=(SF,ZF,PF) }; def macroop SAL_M_I { ld t1, seg, sib, disp - slli t1, t1, imm + slli t1, t1, imm, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -70,19 +70,19 @@ def macroop SAL_P_I { rdip t7 ld t1, seg, riprel, disp - slli t1, t1, imm + slli t1, t1, imm, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; def macroop SAL_1_R { - slli reg, reg, 1 + slli reg, reg, 1, flags=(SF,ZF,PF) }; def macroop SAL_1_M { ld t1, seg, sib, disp - slli t1, t1, 1 + slli t1, t1, 1, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -90,19 +90,19 @@ def macroop SAL_1_P { rdip t7 ld t1, seg, riprel, disp - slli t1, t1, 1 + slli t1, t1, 1, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; def macroop SAL_R_R { - sll reg, reg, regm + sll reg, reg, regm, flags=(SF,ZF,PF) }; def macroop SAL_M_R { ld t1, seg, sib, disp - sll t1, t1, reg + sll t1, t1, reg, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -110,19 +110,19 @@ def macroop SAL_P_R { rdip t7 ld t1, seg, riprel, disp - sll t1, t1, reg + sll t1, t1, reg, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; def macroop SHR_R_I { - srli reg, reg, imm + srli reg, reg, imm, flags=(SF,ZF,PF) }; def macroop SHR_M_I { ld t1, seg, sib, disp - srli t1, t1, imm + srli t1, t1, imm, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -130,19 +130,19 @@ def macroop SHR_P_I { rdip t7 ld t1, seg, riprel, disp - srli t1, t1, imm + srli t1, t1, imm, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; def macroop SHR_1_R { - srli reg, reg, 1 + srli reg, reg, 1, flags=(SF,ZF,PF) }; def macroop SHR_1_M { ld t1, seg, sib, disp - srli t1, t1, 1 + srli t1, t1, 1, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -150,19 +150,19 @@ def macroop SHR_1_P { rdip t7 ld t1, seg, riprel, disp - srli t1, t1, 1 + srli t1, t1, 1, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; def macroop SHR_R_R { - srl reg, reg, regm + srl reg, reg, regm, flags=(SF,ZF,PF) }; def macroop SHR_M_R { ld t1, seg, sib, disp - srl t1, t1, reg + srl t1, t1, reg, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -170,19 +170,19 @@ def macroop SHR_P_R { rdip t7 ld t1, seg, riprel, disp - srl t1, t1, reg + srl t1, t1, reg, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; def macroop SAR_R_I { - srai reg, reg, imm + srai reg, reg, imm, flags=(SF,ZF,PF) }; def macroop SAR_M_I { ld t1, seg, sib, disp - srai t1, t1, imm + srai t1, t1, imm, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -190,19 +190,19 @@ def macroop SAR_P_I { rdip t7 ld t1, seg, riprel, disp - srai t1, t1, imm + srai t1, t1, imm, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; def macroop SAR_1_R { - srai reg, reg, 1 + srai reg, reg, 1, flags=(SF,ZF,PF) }; def macroop SAR_1_M { ld t1, seg, sib, disp - srai t1, t1, 1 + srai t1, t1, 1, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -210,19 +210,19 @@ def macroop SAR_1_P { rdip t7 ld t1, seg, riprel, disp - srai t1, t1, 1 + srai t1, t1, 1, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; def macroop SAR_R_R { - sra reg, reg, regm + sra reg, reg, regm, flags=(SF,ZF,PF) }; def macroop SAR_M_R { ld t1, seg, sib, disp - sra t1, t1, reg + sra t1, t1, reg, flags=(SF,ZF,PF) st t1, seg, sib, disp }; @@ -230,7 +230,7 @@ def macroop SAR_P_R { rdip t7 ld t1, seg, riprel, disp - sra t1, t1, reg + sra t1, t1, reg, flags=(SF,ZF,PF) st t1, seg, riprel, disp }; ''' diff --git a/src/arch/x86/isa/insts/string/compare_strings.py b/src/arch/x86/isa/insts/string/compare_strings.py index 1484c4706..71b8511b4 100644 --- a/src/arch/x86/isa/insts/string/compare_strings.py +++ b/src/arch/x86/isa/insts/string/compare_strings.py @@ -53,16 +53,60 @@ # # Authors: Gabe Black -microcode = "" -#let {{ -# class CMPS(Inst): -# "GenFault ${new UnimpInstFault}" -# class CMPSB(Inst): -# "GenFault ${new UnimpInstFault}" -# class CMPSW(Inst): -# "GenFault ${new UnimpInstFault}" -# class CMPSD(Inst): -# "GenFault ${new UnimpInstFault}" -# class CMPSQ(Inst): -# "GenFault ${new UnimpInstFault}" -#}}; +microcode = ''' +def macroop CMPS_M_M { + # Find the constant we need to either add or subtract from rdi + ruflag t0, 10 + movi t3, t3, dsz, flags=(CEZF,), dataSize=asz + subi t4, t0, dsz, dataSize=asz + mov t3, t3, t4, flags=(nCEZF,), dataSize=asz + + ld t1, seg, [1, t0, rsi] + ld t2, es, [1, t0, rdi] + sub t0, t1, t2, flags=(OF, SF, ZF, AF, PF, CF) + + add rdi, rdi, t3, dataSize=asz + add rsi, rsi, t3, dataSize=asz +}; + +# +# Versions which have the rep prefix. These could benefit from some loop +# unrolling. +# + +def macroop CMPS_E_M_M { + # Find the constant we need to either add or subtract from rdi + ruflag t0, 10 + movi t3, t3, dsz, flags=(CEZF,), dataSize=asz + subi t4, t0, dsz, dataSize=asz + mov t3, t3, t4, flags=(nCEZF,), dataSize=asz + + ld t1, seg, [1, t0, rsi] + ld t2, es, [1, t0, rdi] + sub t0, t1, t2, flags=(OF, SF, ZF, AF, PF, CF) + + subi rcx, rcx, 1, flags=(EZF,), dataSize=asz + add rdi, rdi, t3, dataSize=asz + add rsi, rsi, t3, dataSize=asz + bri t0, 4, flags=(CSTRZnEZF,) + fault "NoFault" +}; + +def macroop CMPS_N_M_M { + # Find the constant we need to either add or subtract from rdi + ruflag t0, 10 + movi t3, t3, dsz, flags=(CEZF,), dataSize=asz + subi t4, t0, dsz, dataSize=asz + mov t3, t3, t4, flags=(nCEZF,), dataSize=asz + + ld t1, seg, [1, t0, rsi] + ld t2, es, [1, t0, rdi] + sub t0, t1, t2, flags=(OF, SF, ZF, AF, PF, CF) + + subi rcx, rcx, 1, flags=(EZF,), dataSize=asz + add rdi, rdi, t3, dataSize=asz + add rsi, rsi, t3, dataSize=asz + bri t0, 4, flags=(CSTRnZnEZF,) + fault "NoFault" +}; +''' diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa index 4675b9d56..fdfea6136 100644 --- a/src/arch/x86/isa/macroop.isa +++ b/src/arch/x86/isa/macroop.isa @@ -126,6 +126,8 @@ def template MacroDeclare {{ */ class %(class_name)s : public %(base_class)s { + private: + %(declareLabels)s public: // Constructor. %(class_name)s(ExtMachInst machInst, X86ISA::EmulEnv env); @@ -151,6 +153,9 @@ def template MacroConstructor {{ let {{ from micro_asm import Combinational_Macroop, Rom_Macroop class X86Macroop(Combinational_Macroop): + def add_microop(self, microop): + microop.micropc = len(self.microops) + self.microops.append(microop) def setAdjustEnv(self, val): self.adjust_env = val def __init__(self, name): @@ -166,7 +171,14 @@ let {{ def getDeclaration(self): #FIXME This first parameter should be the mnemonic. I need to #write some code which pulls that out - iop = InstObjParams(self.name, self.name, "Macroop", {"code" : ""}) + declareLabels = "" + for (label, microop) in self.labels.items(): + declareLabels += "const static uint64_t label_%s = %d;\n" \ + % (label, microop.micropc) + iop = InstObjParams(self.name, self.name, "Macroop", + {"code" : "", + "declareLabels" : declareLabels + }) return MacroDeclare.subst(iop); def getDefinition(self): #FIXME This first parameter should be the mnemonic. I need to diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index af3148631..929fd0075 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -125,5 +125,10 @@ let {{ env.dataSize = 8; ''' + def labeler(labelStr): + return "label_%s" % labelStr + + assembler.symbols["label"] = labeler + macroopDict = assembler.assemble(microcode) }}; diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 403a1aacf..c979ace04 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -123,19 +123,7 @@ def template MicroLoadExecute {{ %(ea_code)s; DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); - Twin64_t alignedMem; - fault = read(xc, EA, alignedMem, 0); - int offset = EA & (dataSize - 1); - if(dataSize != 8 || !offset) - { - Mem = bits(alignedMem.a, - (offset + dataSize) * 8 - 1, offset * 8); - } - else - { - Mem = alignedMem.b << (dataSize - offset) * 8; - Mem |= bits(alignedMem.a, dataSize * 8 - 1, offset * 8); - } + fault = read(xc, EA, Mem, 0); if(fault == NoFault) { @@ -162,9 +150,7 @@ def template MicroLoadInitiateAcc {{ %(ea_code)s; DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); - int offset = EA & (dataSize - 1); - Twin64_t alignedMem; - fault = read(xc, EA, alignedMem, offset); + fault = read(xc, EA, Mem, 0); return fault; } @@ -180,18 +166,8 @@ def template MicroLoadCompleteAcc {{ %(op_decl)s; %(op_rd)s; - Twin64_t alignedMem = pkt->get<Twin64_t>(); - int offset = pkt->req->getFlags(); - if(dataSize != 8 || !offset) - { - Mem = bits(alignedMem.a, - (offset + dataSize) * 8 - 1, offset * 8); - } - else - { - Mem = alignedMem.b << (dataSize - offset) * 8; - Mem |= bits(alignedMem.a, dataSize * 8 - 1, offset * 8); - } + Mem = pkt->get<typeof(Mem)>(); + %(code)s; if(fault == NoFault) @@ -221,14 +197,7 @@ def template MicroStoreExecute {{ if(fault == NoFault) { - int offset = EA & (dataSize - 1); - - Twin64_t alignedMem; - alignedMem.a = Mem << (offset * 8); - alignedMem.b = - bits(Mem, dataSize * 8 - 1, (dataSize - offset) * 8); - - fault = write(xc, alignedMem, EA, 0); + fault = write(xc, Mem, EA, 0); if(fault == NoFault) { %(op_wb)s; @@ -255,14 +224,7 @@ def template MicroStoreInitiateAcc {{ if(fault == NoFault) { - int offset = EA & (dataSize - 1); - - Twin64_t alignedMem; - alignedMem.a = Mem << (offset * 8); - alignedMem.b = - bits(Mem, dataSize * 8 - 1, (dataSize - offset) * 8); - - fault = write(xc, alignedMem, EA, 0); + fault = write(xc, Mem, EA, 0); if(fault == NoFault) { %(op_wb)s; diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 608b86a70..616f7a5fc 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -652,17 +652,19 @@ let {{ defineMicroRegOpRd('Rdip', 'DestReg = RIP') defineMicroRegOpRd('Ruflags', 'DestReg = ccFlagBits') defineMicroRegOpRdImm('Ruflag', ''' - int flag = bits(ccFlagBits, (1 << imm8) + 0*psrc1); + int flag = bits(ccFlagBits, imm8 + 0*psrc1); DestReg = merge(DestReg, flag, dataSize); - ccFlagBits = ccFlagBits & ~EZFBit; - ccFlagBits = ccFlagBits | ((flag == 0) ? EZFBit : 0); + ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) : + (ccFlagBits & ~EZFBit); ''') defineMicroRegOpImm('Sext', ''' IntReg val = psrc1; int sign_bit = bits(val, imm8-1, imm8-1); - val = sign_bit ? (val | ~mask(imm8)) : val; - DestReg = merge(DestReg, val, dataSize);''') + uint64_t maskVal = mask(imm8); + val = sign_bit ? (val | ~maskVal) : (val & maskVal); + DestReg = merge(DestReg, val, dataSize); + ''') defineMicroRegOpImm('Zext', 'DestReg = bits(psrc1, imm8-1, 0);') }}; diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 364050994..79422998d 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -93,6 +93,7 @@ #include "base/loader/object_file.hh" #include "base/loader/elf_object.hh" #include "base/misc.hh" +#include "base/trace.hh" #include "cpu/thread_context.hh" #include "mem/page_table.hh" #include "mem/translating_port.hh" diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc new file mode 100644 index 000000000..e29ec58c2 --- /dev/null +++ b/src/arch/x86/tlb.cc @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2007 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use of this software in source and binary forms, + * with or without modification, are permitted provided that the + * following conditions are met: + * + * The software must be used only for Non-Commercial Use which means any + * use which is NOT directed to receiving any direct monetary + * compensation for, or commercial advantage from such use. Illustrative + * examples of non-commercial use are academic research, personal study, + * teaching, education and corporate research & development. + * Illustrative examples of commercial use are distributing products for + * commercial advantage and providing services using the software for + * commercial advantage. + * + * If you wish to use this software or functionality therein that may be + * covered by patents for commercial use, please contact: + * Director of Intellectual Property Licensing + * Office of Strategy and Technology + * Hewlett-Packard Company + * 1501 Page Mill Road + * Palo Alto, California 94304 + * + * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. No right of + * sublicense is granted herewith. Derivatives of the software and + * output created using the software may be prepared, but only for + * Non-Commercial Uses. Derivatives of the software may be shared with + * others provided: (i) the others agree to abide by the list of + * conditions herein which includes the Non-Commercial Use restrictions; + * and (ii) such Derivatives of the software include the above copyright + * notice to acknowledge the contribution from this software where + * applicable, this list of conditions and the disclaimer below. + * + * 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: Gabe Black + */ + +#include <cstring> + +#include "arch/x86/tlb.hh" +#include "params/X86DTB.hh" +#include "params/X86ITB.hh" +#include "sim/serialize.hh" + +namespace X86ISA { + void + TlbEntry::serialize(std::ostream &os) + { + SERIALIZE_SCALAR(pageStart); + } + + void + TlbEntry::unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_SCALAR(pageStart); + } +}; + +X86ISA::ITB * +X86ITBParams::create() +{ + return new X86ISA::ITB(name); +} + +X86ISA::DTB * +X86DTBParams::create() +{ + return new X86ISA::DTB(name); +} diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh index c19ce0b29..4cf65ac08 100644 --- a/src/arch/x86/tlb.hh +++ b/src/arch/x86/tlb.hh @@ -58,10 +58,39 @@ #ifndef __ARCH_X86_TLB_HH__ #define __ARCH_X86_TLB_HH__ -#error X86 is not yet supported! +#include <iostream> +#include <string> + +#include "sim/host.hh" +#include "sim/tlb.hh" + +class Checkpoint; namespace X86ISA { + struct TlbEntry + { + Addr pageStart; + TlbEntry() {} + TlbEntry(Addr paddr) : pageStart(paddr) {} + + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + }; + + class ITB : public GenericITB<false, false> + { + public: + ITB(const std::string &name) : GenericITB<false, false>(name) + {} + }; + + class DTB : public GenericDTB<false, false> + { + public: + DTB(const std::string &name) : GenericDTB<false, false>(name) + {} + }; }; #endif // __ARCH_X86_TLB_HH__ |