summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/alpha/SConscript11
-rw-r--r--src/arch/alpha/ev5.cc104
-rw-r--r--src/arch/alpha/faults.cc67
-rw-r--r--src/arch/alpha/faults.hh44
-rw-r--r--src/arch/alpha/isa_traits.hh9
-rw-r--r--src/arch/alpha/miscregfile.cc25
-rw-r--r--src/arch/alpha/miscregfile.hh7
-rw-r--r--src/arch/alpha/pagetable.cc6
-rw-r--r--src/arch/alpha/pagetable.hh11
-rw-r--r--src/arch/alpha/process.cc6
-rw-r--r--src/arch/alpha/regfile.cc2
-rw-r--r--src/arch/alpha/tlb.cc105
-rw-r--r--src/arch/alpha/tlb.hh34
-rw-r--r--src/arch/alpha/utility.hh4
-rw-r--r--src/arch/micro_asm.py9
-rw-r--r--src/arch/mips/MipsTLB.py20
-rw-r--r--src/arch/mips/SConscript5
-rw-r--r--src/arch/mips/faults.cc40
-rw-r--r--src/arch/mips/faults.hh29
-rw-r--r--src/arch/mips/tlb.cc61
-rw-r--r--src/arch/mips/tlb.hh63
-rw-r--r--src/arch/mips/types.hh2
-rw-r--r--src/arch/sparc/SConscript7
-rw-r--r--src/arch/sparc/faults.cc64
-rw-r--r--src/arch/sparc/faults.hh32
-rw-r--r--src/arch/sparc/handlers.hh8
-rw-r--r--src/arch/sparc/isa/formats/nop.isa3
-rw-r--r--src/arch/sparc/isa_traits.hh12
-rw-r--r--src/arch/sparc/miscregfile.cc148
-rw-r--r--src/arch/sparc/miscregfile.hh38
-rw-r--r--src/arch/sparc/pagetable.hh5
-rw-r--r--src/arch/sparc/process.cc14
-rw-r--r--src/arch/sparc/regfile.cc36
-rw-r--r--src/arch/sparc/tlb.cc377
-rw-r--r--src/arch/sparc/tlb.hh38
-rw-r--r--src/arch/x86/SConscript3
-rw-r--r--src/arch/x86/X86TLB.py75
-rw-r--r--src/arch/x86/faults.hh10
-rw-r--r--src/arch/x86/insts/microldstop.hh38
-rw-r--r--src/arch/x86/isa/decoder/one_byte_opcodes.isa4
-rw-r--r--src/arch/x86/isa/insts/processor_information.py346
-rw-r--r--src/arch/x86/isa/insts/rotate_and_shift/shift.py54
-rw-r--r--src/arch/x86/isa/insts/string/compare_strings.py70
-rw-r--r--src/arch/x86/isa/macroop.isa14
-rw-r--r--src/arch/x86/isa/microasm.isa5
-rw-r--r--src/arch/x86/isa/microops/ldstop.isa50
-rw-r--r--src/arch/x86/isa/microops/regop.isa12
-rw-r--r--src/arch/x86/process.cc1
-rw-r--r--src/arch/x86/tlb.cc89
-rw-r--r--src/arch/x86/tlb.hh31
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 &section);
-#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 &section)
+ TlbEntry::unserialize(Checkpoint *cp, const std::string &section)
{
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 &section)
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 &section);
// 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 &section)
+ {
+ 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 &section);
+ };
+
+ 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 &section)
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 &section)
+{
+ 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 &section);
+
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 &section)
+ {
+ 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 &section);
+ };
+
+ 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__