summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
-rw-r--r--src/cpu/BaseCPU.py41
-rw-r--r--src/cpu/base_dyn_inst.hh12
-rw-r--r--src/cpu/checker/thread_context.hh8
-rw-r--r--src/cpu/o3/O3CPU.py4
-rw-r--r--src/cpu/o3/alpha/cpu.hh39
-rw-r--r--src/cpu/o3/alpha/cpu_builder.cc5
-rw-r--r--src/cpu/o3/alpha/params.hh2
-rw-r--r--src/cpu/o3/checker_builder.cc2
-rw-r--r--src/cpu/o3/cpu.cc2
-rw-r--r--src/cpu/o3/cpu.hh22
-rw-r--r--src/cpu/o3/fetch_impl.hh7
-rwxr-xr-xsrc/cpu/o3/mips/cpu.hh18
-rw-r--r--src/cpu/o3/mips/params.hh13
-rw-r--r--src/cpu/o3/sparc/cpu.hh39
-rw-r--r--src/cpu/o3/sparc/cpu_builder.cc5
-rw-r--r--src/cpu/o3/sparc/params.hh2
-rwxr-xr-xsrc/cpu/o3/thread_context.hh2
-rw-r--r--src/cpu/ozone/checker_builder.cc2
-rw-r--r--src/cpu/ozone/cpu.hh8
-rw-r--r--src/cpu/ozone/cpu_builder.cc5
-rw-r--r--src/cpu/ozone/cpu_impl.hh4
-rw-r--r--src/cpu/ozone/simple_cpu_builder.cc5
-rw-r--r--src/cpu/ozone/simple_params.hh3
-rw-r--r--src/cpu/simple/atomic.cc238
-rw-r--r--src/cpu/simple/base.cc8
-rw-r--r--src/cpu/simple/base.hh11
-rw-r--r--src/cpu/simple/timing.cc30
-rw-r--r--src/cpu/simple_thread.cc6
-rw-r--r--src/cpu/simple_thread.hh36
-rw-r--r--src/cpu/thread_context.hh12
-rw-r--r--src/mem/page_table.cc81
-rw-r--r--src/mem/page_table.hh38
-rw-r--r--src/sim/SConscript1
-rw-r--r--src/sim/faults.cc8
-rw-r--r--src/sim/faults.hh16
-rw-r--r--src/sim/process.cc1
-rw-r--r--src/sim/process.hh4
-rw-r--r--src/sim/system.cc1
-rw-r--r--src/sim/system.hh9
-rw-r--r--src/sim/tlb.cc50
-rw-r--r--src/sim/tlb.hh94
91 files changed, 1953 insertions, 1189 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__
diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py
index 7a51650e6..9b2b99c58 100644
--- a/src/cpu/BaseCPU.py
+++ b/src/cpu/BaseCPU.py
@@ -37,12 +37,14 @@ import sys
default_tracer = ExeTracer()
-if build_env['FULL_SYSTEM']:
- if build_env['TARGET_ISA'] == 'alpha':
- from AlphaTLB import AlphaDTB, AlphaITB
-
- if build_env['TARGET_ISA'] == 'sparc':
- from SparcTLB import SparcDTB, SparcITB
+if build_env['TARGET_ISA'] == 'alpha':
+ from AlphaTLB import AlphaDTB, AlphaITB
+elif build_env['TARGET_ISA'] == 'sparc':
+ from SparcTLB import SparcDTB, SparcITB
+elif build_env['TARGET_ISA'] == 'x86':
+ from X86TLB import X86DTB, X86ITB
+elif build_env['TARGET_ISA'] == 'mips':
+ from MipsTLB import MipsDTB, MipsITB
class BaseCPU(SimObject):
type = 'BaseCPU'
@@ -57,19 +59,26 @@ class BaseCPU(SimObject):
"enable checkpoint pseudo instructions")
do_statistics_insts = Param.Bool(True,
"enable statistics pseudo instructions")
-
- if build_env['TARGET_ISA'] == 'sparc':
- dtb = Param.SparcDTB(SparcDTB(), "Data TLB")
- itb = Param.SparcITB(SparcITB(), "Instruction TLB")
- elif build_env['TARGET_ISA'] == 'alpha':
- dtb = Param.AlphaDTB(AlphaDTB(), "Data TLB")
- itb = Param.AlphaITB(AlphaITB(), "Instruction TLB")
- else:
- print "Unknown architecture, can't pick TLBs"
- sys.exit(1)
else:
workload = VectorParam.Process("processes to run")
+ if build_env['TARGET_ISA'] == 'sparc':
+ dtb = Param.SparcDTB(SparcDTB(), "Data TLB")
+ itb = Param.SparcITB(SparcITB(), "Instruction TLB")
+ elif build_env['TARGET_ISA'] == 'alpha':
+ dtb = Param.AlphaDTB(AlphaDTB(), "Data TLB")
+ itb = Param.AlphaITB(AlphaITB(), "Instruction TLB")
+ elif build_env['TARGET_ISA'] == 'x86':
+ dtb = Param.X86DTB(X86DTB(), "Data TLB")
+ itb = Param.X86ITB(X86ITB(), "Instruction TLB")
+ elif build_env['TARGET_ISA'] == 'mips':
+ dtb = Param.MipsDTB(MipsDTB(), "Data TLB")
+ itb = Param.MipsITB(MipsITB(), "Instruction TLB")
+ else:
+ print "Don't know what TLB to use for ISA %s" % \
+ build_env['TARGET_ISA']
+ sys.exit(1)
+
max_insts_all_threads = Param.Counter(0,
"terminate when all threads have reached this inst count")
max_insts_any_thread = Param.Counter(0,
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh
index 362babeff..0f2a90bf6 100644
--- a/src/cpu/base_dyn_inst.hh
+++ b/src/cpu/base_dyn_inst.hh
@@ -847,12 +847,6 @@ BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags)
req->setVirt(asid, addr, sizeof(T), flags, this->PC);
req->setThreadContext(thread->readCpuId(), threadNumber);
- if ((req->getVaddr() & (TheISA::VMPageSize - 1)) + req->getSize() >
- TheISA::VMPageSize) {
- delete req;
- return TheISA::genAlignmentFault();
- }
-
fault = cpu->translateDataReadReq(req, thread);
if (req->isUncacheable())
@@ -909,12 +903,6 @@ BaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res)
req->setVirt(asid, addr, sizeof(T), flags, this->PC);
req->setThreadContext(thread->readCpuId(), threadNumber);
- if ((req->getVaddr() & (TheISA::VMPageSize - 1)) + req->getSize() >
- TheISA::VMPageSize) {
- delete req;
- return TheISA::genAlignmentFault();
- }
-
fault = cpu->translateDataWriteReq(req, thread);
if (req->isUncacheable())
diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh
index 3b4d21e13..15454c3fe 100644
--- a/src/cpu/checker/thread_context.hh
+++ b/src/cpu/checker/thread_context.hh
@@ -84,15 +84,15 @@ class CheckerThreadContext : public ThreadContext
int readCpuId() { return actualTC->readCpuId(); }
+ TheISA::ITB *getITBPtr() { return actualTC->getITBPtr(); }
+
+ TheISA::DTB *getDTBPtr() { return actualTC->getDTBPtr(); }
+
#if FULL_SYSTEM
System *getSystemPtr() { return actualTC->getSystemPtr(); }
PhysicalMemory *getPhysMemPtr() { return actualTC->getPhysMemPtr(); }
- TheISA::ITB *getITBPtr() { return actualTC->getITBPtr(); }
-
- TheISA::DTB *getDTBPtr() { return actualTC->getDTBPtr(); }
-
TheISA::Kernel::Statistics *getKernelStats()
{ return actualTC->getKernelStats(); }
diff --git a/src/cpu/o3/O3CPU.py b/src/cpu/o3/O3CPU.py
index e691cfe5d..27ca8ce1e 100644
--- a/src/cpu/o3/O3CPU.py
+++ b/src/cpu/o3/O3CPU.py
@@ -52,8 +52,8 @@ class DerivO3CPU(BaseCPU):
else:
checker = Param.BaseCPU(O3Checker(exitOnError=False, updateOnError=True,
warnOnlyOnLoadError=False), "checker")
- checker.itb = Parent.itb
- checker.dtb = Parent.dtb
+ checker.itb = Parent.itb
+ checker.dtb = Parent.dtb
cachePorts = Param.Unsigned(200, "Cache Ports")
icache_port = Port("Instruction Port")
diff --git a/src/cpu/o3/alpha/cpu.hh b/src/cpu/o3/alpha/cpu.hh
index 676893098..ebc4e7b23 100644
--- a/src/cpu/o3/alpha/cpu.hh
+++ b/src/cpu/o3/alpha/cpu.hh
@@ -66,45 +66,6 @@ class AlphaO3CPU : public FullO3CPU<Impl>
/** Registers statistics. */
void regStats();
-#if FULL_SYSTEM
- /** Translates instruction requestion. */
- Fault translateInstReq(RequestPtr &req, Thread *thread)
- {
- return this->itb->translate(req, thread->getTC());
- }
-
- /** Translates data read request. */
- Fault translateDataReadReq(RequestPtr &req, Thread *thread)
- {
- return this->dtb->translate(req, thread->getTC(), false);
- }
-
- /** Translates data write request. */
- Fault translateDataWriteReq(RequestPtr &req, Thread *thread)
- {
- return this->dtb->translate(req, thread->getTC(), true);
- }
-
-#else
- /** Translates instruction requestion in syscall emulation mode. */
- Fault translateInstReq(RequestPtr &req, Thread *thread)
- {
- return thread->getProcessPtr()->pTable->translate(req);
- }
-
- /** Translates data read request in syscall emulation mode. */
- Fault translateDataReadReq(RequestPtr &req, Thread *thread)
- {
- return thread->getProcessPtr()->pTable->translate(req);
- }
-
- /** Translates data write request in syscall emulation mode. */
- Fault translateDataWriteReq(RequestPtr &req, Thread *thread)
- {
- return thread->getProcessPtr()->pTable->translate(req);
- }
-
-#endif
/** Reads a miscellaneous register. */
TheISA::MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid);
diff --git a/src/cpu/o3/alpha/cpu_builder.cc b/src/cpu/o3/alpha/cpu_builder.cc
index 4db217abf..1aa3d1618 100644
--- a/src/cpu/o3/alpha/cpu_builder.cc
+++ b/src/cpu/o3/alpha/cpu_builder.cc
@@ -77,10 +77,11 @@ DerivO3CPUParams::create()
params->cpu_id = cpu_id;
params->activity = activity;
-#if FULL_SYSTEM
- params->system = system;
params->itb = itb;
params->dtb = dtb;
+
+#if FULL_SYSTEM
+ params->system = system;
params->profile = profile;
params->do_quiesce = do_quiesce;
diff --git a/src/cpu/o3/alpha/params.hh b/src/cpu/o3/alpha/params.hh
index b6b84b2a1..164c25312 100644
--- a/src/cpu/o3/alpha/params.hh
+++ b/src/cpu/o3/alpha/params.hh
@@ -54,10 +54,8 @@ class AlphaSimpleParams : public O3Params
{
public:
-#if FULL_SYSTEM
AlphaISA::ITB *itb;
AlphaISA::DTB *dtb;
-#endif
};
#endif // __CPU_O3_ALPHA_PARAMS_HH__
diff --git a/src/cpu/o3/checker_builder.cc b/src/cpu/o3/checker_builder.cc
index 97425b08c..0799b9cb5 100644
--- a/src/cpu/o3/checker_builder.cc
+++ b/src/cpu/o3/checker_builder.cc
@@ -86,9 +86,9 @@ O3CheckerParams::create()
params->progress_interval = 0;
temp2++;
-#if FULL_SYSTEM
params->itb = itb;
params->dtb = dtb;
+#if FULL_SYSTEM
params->system = system;
params->cpu_id = cpu_id;
params->profile = profile;
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index cae6ae20c..98e200944 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -150,10 +150,8 @@ FullO3CPU<Impl>::DeallocateContextEvent::description()
template <class Impl>
FullO3CPU<Impl>::FullO3CPU(O3CPU *o3_cpu, Params *params)
: BaseO3CPU(params),
-#if FULL_SYSTEM
itb(params->itb),
dtb(params->dtb),
-#endif
tickEvent(this),
removeInstsThisCycle(false),
fetch(o3_cpu, params),
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index 84a7c8673..d97a2080d 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -94,9 +94,9 @@ class FullO3CPU : public BaseO3CPU
public:
// Typedefs from the Impl here.
typedef typename Impl::CPUPol CPUPolicy;
- typedef typename Impl::Params Params;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::O3CPU O3CPU;
+ typedef typename Impl::Params Params;
typedef O3ThreadState<Impl> Thread;
@@ -113,10 +113,8 @@ class FullO3CPU : public BaseO3CPU
SwitchedOut
};
-#if FULL_SYSTEM
TheISA::ITB * itb;
TheISA::DTB * dtb;
-#endif
/** Overall CPU status. */
Status _status;
@@ -265,6 +263,24 @@ class FullO3CPU : public BaseO3CPU
/** Registers statistics. */
void fullCPURegStats();
+ /** Translates instruction requestion. */
+ Fault translateInstReq(RequestPtr &req, Thread *thread)
+ {
+ return this->itb->translate(req, thread->getTC());
+ }
+
+ /** Translates data read request. */
+ Fault translateDataReadReq(RequestPtr &req, Thread *thread)
+ {
+ return this->dtb->translate(req, thread->getTC(), false);
+ }
+
+ /** Translates data write request. */
+ Fault translateDataWriteReq(RequestPtr &req, Thread *thread)
+ {
+ return this->dtb->translate(req, thread->getTC(), true);
+ }
+
/** Returns a specific port. */
Port *getPort(const std::string &if_name, int idx);
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 5a5d19b64..7d344fa33 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -1228,7 +1228,6 @@ DefaultFetch<Impl>::fetch(bool &status_change)
// Send the fault to commit. This thread will not do anything
// until commit handles the fault. The only other way it can
// wake up is if a squash comes along and changes the PC.
-#if FULL_SYSTEM
assert(numInst < fetchWidth);
// Get a sequence number.
inst_seq = cpu->getAndIncrementInstSeq();
@@ -1240,7 +1239,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
fetch_PC, fetch_NPC, fetch_MicroPC,
next_PC, next_NPC, next_MicroPC,
inst_seq, cpu);
- instruction->setPredTarg(next_PC, next_NPC, 1);
+ instruction->setPredTarg(next_NPC, next_NPC + instSize, 0);
instruction->setTid(tid);
instruction->setASID(tid);
@@ -1260,11 +1259,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
fetchStatus[tid] = TrapPending;
status_change = true;
-#else // !FULL_SYSTEM
- fetchStatus[tid] = TrapPending;
- status_change = true;
-#endif // FULL_SYSTEM
DPRINTF(Fetch, "[tid:%i]: fault (%s) detected @ PC %08p",
tid, fault->name(), PC[tid]);
}
diff --git a/src/cpu/o3/mips/cpu.hh b/src/cpu/o3/mips/cpu.hh
index 0361c1814..3724ced46 100755
--- a/src/cpu/o3/mips/cpu.hh
+++ b/src/cpu/o3/mips/cpu.hh
@@ -68,24 +68,6 @@ class MipsO3CPU : public FullO3CPU<Impl>
/** Registers statistics. */
void regStats();
- /** Translates instruction requestion in syscall emulation mode. */
- Fault translateInstReq(RequestPtr &req, Thread *thread)
- {
- return thread->getProcessPtr()->pTable->translate(req);
- }
-
- /** Translates data read request in syscall emulation mode. */
- Fault translateDataReadReq(RequestPtr &req, Thread *thread)
- {
- return thread->getProcessPtr()->pTable->translate(req);
- }
-
- /** Translates data write request in syscall emulation mode. */
- Fault translateDataWriteReq(RequestPtr &req, Thread *thread)
- {
- return thread->getProcessPtr()->pTable->translate(req);
- }
-
/** Reads a miscellaneous register. */
TheISA::MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid);
diff --git a/src/cpu/o3/mips/params.hh b/src/cpu/o3/mips/params.hh
index d1ac62e21..2688d3fb3 100644
--- a/src/cpu/o3/mips/params.hh
+++ b/src/cpu/o3/mips/params.hh
@@ -36,8 +36,11 @@
#include "cpu/o3/params.hh"
//Forward declarations
-//class MipsDTB;
-//class MipsITB;
+namespace MipsISA
+{
+ class MipsDTB;
+ class MipsITB;
+}
class MemObject;
class Process;
class System;
@@ -53,11 +56,9 @@ class MipsSimpleParams : public O3Params
public:
MipsSimpleParams() {}
-#if FULL_SYSTEM
//Full System Paramater Objects place here
- MipsITB *itb;
- MipsDTB *dtb;
-#endif
+ MipsISA::ITB *itb;
+ MipsISA::DTB *dtb;
};
#endif // __CPU_O3_MIPS_PARAMS_HH__
diff --git a/src/cpu/o3/sparc/cpu.hh b/src/cpu/o3/sparc/cpu.hh
index 7b932e429..3fd193e0f 100644
--- a/src/cpu/o3/sparc/cpu.hh
+++ b/src/cpu/o3/sparc/cpu.hh
@@ -66,45 +66,6 @@ class SparcO3CPU : public FullO3CPU<Impl>
/** Registers statistics. */
void regStats();
-#if FULL_SYSTEM
- /** Translates instruction requestion. */
- Fault translateInstReq(RequestPtr &req, Thread *thread)
- {
- return this->itb->translate(req, thread->getTC());
- }
-
- /** Translates data read request. */
- Fault translateDataReadReq(RequestPtr &req, Thread *thread)
- {
- return this->dtb->translate(req, thread->getTC(), false);
- }
-
- /** Translates data write request. */
- Fault translateDataWriteReq(RequestPtr &req, Thread *thread)
- {
- return this->dtb->translate(req, thread->getTC(), true);
- }
-
-#else
- /** Translates instruction requestion in syscall emulation mode. */
- Fault translateInstReq(RequestPtr &req, Thread *thread)
- {
- return thread->getProcessPtr()->pTable->translate(req);
- }
-
- /** Translates data read request in syscall emulation mode. */
- Fault translateDataReadReq(RequestPtr &req, Thread *thread)
- {
- return thread->getProcessPtr()->pTable->translate(req);
- }
-
- /** Translates data write request in syscall emulation mode. */
- Fault translateDataWriteReq(RequestPtr &req, Thread *thread)
- {
- return thread->getProcessPtr()->pTable->translate(req);
- }
-
-#endif
/** Reads a miscellaneous register. */
TheISA::MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid);
diff --git a/src/cpu/o3/sparc/cpu_builder.cc b/src/cpu/o3/sparc/cpu_builder.cc
index 49f0f455d..b7c684431 100644
--- a/src/cpu/o3/sparc/cpu_builder.cc
+++ b/src/cpu/o3/sparc/cpu_builder.cc
@@ -78,10 +78,11 @@ DerivO3CPUParams::create()
params->cpu_id = cpu_id;
params->activity = activity;
-#if FULL_SYSTEM
- params->system = system;
params->itb = itb;
params->dtb = dtb;
+
+#if FULL_SYSTEM
+ params->system = system;
params->profile = profile;
params->do_quiesce = do_quiesce;
diff --git a/src/cpu/o3/sparc/params.hh b/src/cpu/o3/sparc/params.hh
index d399d64c4..09f523818 100644
--- a/src/cpu/o3/sparc/params.hh
+++ b/src/cpu/o3/sparc/params.hh
@@ -54,10 +54,8 @@ class SparcSimpleParams : public O3Params
{
public:
-#if FULL_SYSTEM
SparcISA::ITB *itb;
SparcISA::DTB *dtb;
-#endif
};
#endif // __CPU_O3_SPARC_PARAMS_HH__
diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh
index 93638673b..31e08db4c 100755
--- a/src/cpu/o3/thread_context.hh
+++ b/src/cpu/o3/thread_context.hh
@@ -66,13 +66,11 @@ class O3ThreadContext : public ThreadContext
/** Pointer to the thread state that this TC corrseponds to. */
O3ThreadState<Impl> *thread;
-#if FULL_SYSTEM
/** Returns a pointer to the ITB. */
TheISA::ITB *getITBPtr() { return cpu->itb; }
/** Returns a pointer to the DTB. */
TheISA::DTB *getDTBPtr() { return cpu->dtb; }
-#endif
/** Returns a pointer to this CPU. */
virtual BaseCPU *getCpuPtr() { return cpu; }
diff --git a/src/cpu/ozone/checker_builder.cc b/src/cpu/ozone/checker_builder.cc
index f813e5df2..625b2a39a 100644
--- a/src/cpu/ozone/checker_builder.cc
+++ b/src/cpu/ozone/checker_builder.cc
@@ -87,9 +87,9 @@ OzoneCheckerParams::create()
temp2++;
params->progress_interval = 0;
-#if FULL_SYSTEM
params->itb = itb;
params->dtb = dtb;
+#if FULL_SYSTEM
params->system = system;
params->cpu_id = cpu_id;
params->profile = profile;
diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh
index 92b00af26..78d0892c4 100644
--- a/src/cpu/ozone/cpu.hh
+++ b/src/cpu/ozone/cpu.hh
@@ -120,15 +120,15 @@ class OzoneCPU : public BaseCPU
int readCpuId() { return thread->readCpuId(); }
+ TheISA::ITB *getITBPtr() { return cpu->itb; }
+
+ TheISA::DTB * getDTBPtr() { return cpu->dtb; }
+
#if FULL_SYSTEM
System *getSystemPtr() { return cpu->system; }
PhysicalMemory *getPhysMemPtr() { return cpu->physmem; }
- TheISA::ITB *getITBPtr() { return cpu->itb; }
-
- TheISA::DTB * getDTBPtr() { return cpu->dtb; }
-
TheISA::Kernel::Statistics *getKernelStats()
{ return thread->getKernelStats(); }
diff --git a/src/cpu/ozone/cpu_builder.cc b/src/cpu/ozone/cpu_builder.cc
index 60ee9c4f9..7edbe41c9 100644
--- a/src/cpu/ozone/cpu_builder.cc
+++ b/src/cpu/ozone/cpu_builder.cc
@@ -79,11 +79,12 @@ DerivOzoneCPUParams::create()
params->name = name;
params->numberOfThreads = actual_num_threads;
+ params->itb = itb;
+ params->dtb = dtb;
+
#if FULL_SYSTEM
params->system = system;
params->cpu_id = cpu_id;
- params->itb = itb;
- params->dtb = dtb;
params->profile = profile;
params->do_quiesce = do_quiesce;
params->do_checkpoint_insts = do_checkpoint_insts;
diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh
index d73e5768a..37a91c630 100644
--- a/src/cpu/ozone/cpu_impl.hh
+++ b/src/cpu/ozone/cpu_impl.hh
@@ -129,6 +129,8 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
thread.inSyscall = false;
thread.setStatus(ThreadContext::Suspended);
+ itb = p->itb;
+ dtb = p->dtb;
#if FULL_SYSTEM
// Setup thread state stuff.
thread.cpu = this;
@@ -137,8 +139,6 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
thread.quiesceEvent = new EndQuiesceEvent(tc);
system = p->system;
- itb = p->itb;
- dtb = p->dtb;
physmem = p->system->physmem;
if (p->profile) {
diff --git a/src/cpu/ozone/simple_cpu_builder.cc b/src/cpu/ozone/simple_cpu_builder.cc
index df8e25fd0..ca55cdca4 100644
--- a/src/cpu/ozone/simple_cpu_builder.cc
+++ b/src/cpu/ozone/simple_cpu_builder.cc
@@ -82,11 +82,12 @@ SimpleOzoneCPUParams::create()
params->name = name;
params->numberOfThreads = actual_num_threads;
+ params->itb = itb;
+ params->dtb = dtb;
+
#if FULL_SYSTEM
params->system = system;
params->cpu_id = cpu_id;
- params->itb = itb;
- params->dtb = dtb;
#else
params->workload = workload;
// params->pTable = page_table;
diff --git a/src/cpu/ozone/simple_params.hh b/src/cpu/ozone/simple_params.hh
index d5ba6a923..ec5782c8a 100644
--- a/src/cpu/ozone/simple_params.hh
+++ b/src/cpu/ozone/simple_params.hh
@@ -55,9 +55,8 @@ class SimpleParams : public BaseCPU::Params
{
public:
-#if FULL_SYSTEM
TheISA::ITB *itb; TheISA::DTB *dtb;
-#else
+#if !FULL_SYSTEM
std::vector<Process *> workload;
#endif // FULL_SYSTEM
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index 80faad6e2..06f52e30e 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -285,47 +285,82 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
{
// use the CPU's statically allocated read request and packet objects
Request *req = &data_read_req;
- req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
if (traceData) {
traceData->setAddr(addr);
}
- // translate to physical address
- Fault fault = thread->translateDataReadReq(req);
-
- // Now do the access.
- if (fault == NoFault) {
- Packet pkt =
- Packet(req,
- req->isLocked() ? MemCmd::LoadLockedReq : MemCmd::ReadReq,
- Packet::Broadcast);
- pkt.dataStatic(&data);
-
- if (req->isMmapedIpr())
- dcache_latency = TheISA::handleIprRead(thread->getTC(), &pkt);
- else {
- if (hasPhysMemPort && pkt.getAddr() == physMemAddr)
- dcache_latency = physmemPort.sendAtomic(&pkt);
- else
- dcache_latency = dcachePort.sendAtomic(&pkt);
- }
- dcache_access = true;
+ //The block size of our peer.
+ int blockSize = dcachePort.peerBlockSize();
+ //The size of the data we're trying to read.
+ int dataSize = sizeof(T);
+
+ uint8_t * dataPtr = (uint8_t *)&data;
+
+ //The address of the second part of this access if it needs to be split
+ //across a cache line boundary.
+ Addr secondAddr = roundDown(addr + dataSize - 1, blockSize);
+
+ if(secondAddr > addr)
+ dataSize = secondAddr - addr;
+
+ dcache_latency = 0;
- assert(!pkt.isError());
+ while(1) {
+ req->setVirt(0, addr, dataSize, flags, thread->readPC());
- data = gtoh(data);
+ // translate to physical address
+ Fault fault = thread->translateDataReadReq(req);
- if (req->isLocked()) {
- TheISA::handleLockedRead(thread, req);
+ // Now do the access.
+ if (fault == NoFault) {
+ Packet pkt = Packet(req,
+ req->isLocked() ? MemCmd::LoadLockedReq : MemCmd::ReadReq,
+ Packet::Broadcast);
+ pkt.dataStatic(dataPtr);
+
+ if (req->isMmapedIpr())
+ dcache_latency += TheISA::handleIprRead(thread->getTC(), &pkt);
+ else {
+ if (hasPhysMemPort && pkt.getAddr() == physMemAddr)
+ dcache_latency += physmemPort.sendAtomic(&pkt);
+ else
+ dcache_latency += dcachePort.sendAtomic(&pkt);
+ }
+ dcache_access = true;
+
+ assert(!pkt.isError());
+
+ if (req->isLocked()) {
+ TheISA::handleLockedRead(thread, req);
+ }
}
- }
- // This will need a new way to tell if it has a dcache attached.
- if (req->isUncacheable())
- recordEvent("Uncached Read");
+ // This will need a new way to tell if it has a dcache attached.
+ if (req->isUncacheable())
+ recordEvent("Uncached Read");
+
+ //If there's a fault, return it
+ if (fault != NoFault)
+ return fault;
+ //If we don't need to access a second cache line, stop now.
+ if (secondAddr <= addr)
+ {
+ data = gtoh(data);
+ return fault;
+ }
+
+ /*
+ * Set up for accessing the second cache line.
+ */
- return fault;
+ //Move the pointer we're reading into to the correct location.
+ dataPtr += dataSize;
+ //Adjust the size to get the remaining bytes.
+ dataSize = addr + sizeof(T) - secondAddr;
+ //And access the right address.
+ addr = secondAddr;
+ }
}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -385,65 +420,105 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
// use the CPU's statically allocated write request and packet objects
Request *req = &data_write_req;
- req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
if (traceData) {
traceData->setAddr(addr);
}
- // translate to physical address
- Fault fault = thread->translateDataWriteReq(req);
-
- // Now do the access.
- if (fault == NoFault) {
- MemCmd cmd = MemCmd::WriteReq; // default
- bool do_access = true; // flag to suppress cache access
-
- if (req->isLocked()) {
- cmd = MemCmd::StoreCondReq;
- do_access = TheISA::handleLockedWrite(thread, req);
- } else if (req->isSwap()) {
- cmd = MemCmd::SwapReq;
- if (req->isCondSwap()) {
- assert(res);
- req->setExtraData(*res);
- }
- }
+ //The block size of our peer.
+ int blockSize = dcachePort.peerBlockSize();
+ //The size of the data we're trying to read.
+ int dataSize = sizeof(T);
- if (do_access) {
- Packet pkt = Packet(req, cmd, Packet::Broadcast);
- pkt.dataStatic(&data);
+ uint8_t * dataPtr = (uint8_t *)&data;
- if (req->isMmapedIpr()) {
- dcache_latency = TheISA::handleIprWrite(thread->getTC(), &pkt);
- } else {
- data = htog(data);
- if (hasPhysMemPort && pkt.getAddr() == physMemAddr)
- dcache_latency = physmemPort.sendAtomic(&pkt);
- else
- dcache_latency = dcachePort.sendAtomic(&pkt);
+ //The address of the second part of this access if it needs to be split
+ //across a cache line boundary.
+ Addr secondAddr = roundDown(addr + dataSize - 1, blockSize);
+
+ if(secondAddr > addr)
+ dataSize = secondAddr - addr;
+
+ dcache_latency = 0;
+
+ while(1) {
+ req->setVirt(0, addr, dataSize, flags, thread->readPC());
+
+ // translate to physical address
+ Fault fault = thread->translateDataWriteReq(req);
+
+ // Now do the access.
+ if (fault == NoFault) {
+ MemCmd cmd = MemCmd::WriteReq; // default
+ bool do_access = true; // flag to suppress cache access
+
+ if (req->isLocked()) {
+ cmd = MemCmd::StoreCondReq;
+ do_access = TheISA::handleLockedWrite(thread, req);
+ } else if (req->isSwap()) {
+ cmd = MemCmd::SwapReq;
+ if (req->isCondSwap()) {
+ assert(res);
+ req->setExtraData(*res);
+ }
+ }
+
+ if (do_access) {
+ Packet pkt = Packet(req, cmd, Packet::Broadcast);
+ pkt.dataStatic(dataPtr);
+
+ if (req->isMmapedIpr()) {
+ dcache_latency +=
+ TheISA::handleIprWrite(thread->getTC(), &pkt);
+ } else {
+ //XXX This needs to be outside of the loop in order to
+ //work properly for cache line boundary crossing
+ //accesses in transendian simulations.
+ data = htog(data);
+ if (hasPhysMemPort && pkt.getAddr() == physMemAddr)
+ dcache_latency += physmemPort.sendAtomic(&pkt);
+ else
+ dcache_latency += dcachePort.sendAtomic(&pkt);
+ }
+ dcache_access = true;
+ assert(!pkt.isError());
+
+ if (req->isSwap()) {
+ assert(res);
+ *res = pkt.get<T>();
+ }
}
- dcache_access = true;
- assert(!pkt.isError());
- if (req->isSwap()) {
- assert(res);
- *res = pkt.get<T>();
+ if (res && !req->isSwap()) {
+ *res = req->getExtraData();
}
}
- if (res && !req->isSwap()) {
- *res = req->getExtraData();
+ // This will need a new way to tell if it's hooked up to a cache or not.
+ if (req->isUncacheable())
+ recordEvent("Uncached Write");
+
+ //If there's a fault or we don't need to access a second cache line,
+ //stop now.
+ if (fault != NoFault || secondAddr <= addr)
+ {
+ // If the write needs to have a fault on the access, consider
+ // calling changeStatus() and changing it to "bad addr write"
+ // or something.
+ return fault;
}
- }
- // This will need a new way to tell if it's hooked up to a cache or not.
- if (req->isUncacheable())
- recordEvent("Uncached Write");
+ /*
+ * Set up for accessing the second cache line.
+ */
- // If the write needs to have a fault on the access, consider calling
- // changeStatus() and changing it to "bad addr write" or something.
- return fault;
+ //Move the pointer we're reading into to the correct location.
+ dataPtr += dataSize;
+ //Adjust the size to get the remaining bytes.
+ dataSize = addr + sizeof(T) - secondAddr;
+ //And access the right address.
+ addr = secondAddr;
+ }
}
@@ -545,9 +620,18 @@ AtomicSimpleCPU::tick()
preExecute();
- if(curStaticInst)
- {
+ if (curStaticInst) {
fault = curStaticInst->execute(this, traceData);
+
+ // keep an instruction count
+ if (fault == NoFault)
+ countInst();
+ else if (traceData) {
+ // If there was a fault, we should trace this instruction.
+ delete traceData;
+ traceData = NULL;
+ }
+
postExecute();
}
@@ -604,9 +688,9 @@ AtomicSimpleCPUParams::create()
params->cpu_id = cpu_id;
params->tracer = tracer;
-#if FULL_SYSTEM
params->itb = itb;
params->dtb = dtb;
+#if FULL_SYSTEM
params->profile = profile;
params->do_quiesce = do_quiesce;
params->do_checkpoint_insts = do_checkpoint_insts;
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index d2dd52b64..d6b124efc 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -75,7 +75,7 @@ BaseSimpleCPU::BaseSimpleCPU(Params *p)
thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
#else
thread = new SimpleThread(this, /* thread_num */ 0, p->process,
- /* asid */ 0);
+ p->itb, p->dtb, /* asid */ 0);
#endif // !FULL_SYSTEM
thread->setStatus(ThreadContext::Unallocated);
@@ -357,12 +357,6 @@ BaseSimpleCPU::preExecute()
thread->setFloatReg(ZeroReg, 0.0);
#endif // ALPHA_ISA
- // keep an instruction count
- numInst++;
- numInsts++;
-
- thread->funcExeInst++;
-
// check for instruction-count-based events
comInstEventQueue[0]->serviceEvents(numInst);
diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh
index 22ffff3b9..2bc329b68 100644
--- a/src/cpu/simple/base.hh
+++ b/src/cpu/simple/base.hh
@@ -100,10 +100,9 @@ class BaseSimpleCPU : public BaseCPU
public:
struct Params : public BaseCPU::Params
{
-#if FULL_SYSTEM
TheISA::ITB *itb;
TheISA::DTB *dtb;
-#else
+#if !FULL_SYSTEM
Process *process;
#endif
};
@@ -158,6 +157,14 @@ class BaseSimpleCPU : public BaseCPU
Counter startNumInst;
Stats::Scalar<> numInsts;
+ void countInst()
+ {
+ numInst++;
+ numInsts++;
+
+ thread->funcExeInst++;
+ }
+
virtual Counter totalInstructions() const
{
return numInst - startNumInst;
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index 9891efb81..8d1cf9a17 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -540,13 +540,32 @@ TimingSimpleCPU::completeIfetch(PacketPtr pkt)
delete dcache_pkt->req;
delete dcache_pkt;
dcache_pkt = NULL;
+
+ // keep an instruction count
+ if (fault == NoFault)
+ countInst();
+ } else if (traceData) {
+ // If there was a fault, we shouldn't trace this instruction.
+ delete traceData;
+ traceData = NULL;
}
+
postExecute();
advanceInst(fault);
}
} else {
// non-memory instruction: execute completely now
Fault fault = curStaticInst->execute(this, traceData);
+
+ // keep an instruction count
+ if (fault == NoFault)
+ countInst();
+ else if (traceData) {
+ // If there was a fault, we shouldn't trace this instruction.
+ delete traceData;
+ traceData = NULL;
+ }
+
postExecute();
advanceInst(fault);
}
@@ -615,6 +634,15 @@ TimingSimpleCPU::completeDataAccess(PacketPtr pkt)
Fault fault = curStaticInst->completeAcc(pkt, this, traceData);
+ // keep an instruction count
+ if (fault == NoFault)
+ countInst();
+ else if (traceData) {
+ // If there was a fault, we shouldn't trace this instruction.
+ delete traceData;
+ traceData = NULL;
+ }
+
if (pkt->isRead() && pkt->isLocked()) {
TheISA::handleLockedRead(thread, pkt->req);
}
@@ -727,9 +755,9 @@ TimingSimpleCPUParams::create()
params->cpu_id = cpu_id;
params->tracer = tracer;
-#if FULL_SYSTEM
params->itb = itb;
params->dtb = dtb;
+#if FULL_SYSTEM
params->profile = profile;
params->do_quiesce = do_quiesce;
params->do_checkpoint_insts = do_checkpoint_insts;
diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc
index 191ae2f2e..93772fbe1 100644
--- a/src/cpu/simple_thread.cc
+++ b/src/cpu/simple_thread.cc
@@ -93,10 +93,10 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
}
}
#else
-SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num,
- Process *_process, int _asid)
+SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process,
+ TheISA::ITB *_itb, TheISA::DTB *_dtb, int _asid)
: ThreadState(_cpu, -1, _thread_num, _process, _asid),
- cpu(_cpu)
+ cpu(_cpu), itb(_itb), dtb(_dtb)
{
regs.clear();
tc = new ProxyThreadContext<SimpleThread>(this);
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index 6c6d5f842..1e87b0bb7 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -35,6 +35,7 @@
#include "arch/isa_traits.hh"
#include "arch/regfile.hh"
#include "arch/syscallreturn.hh"
+#include "arch/tlb.hh"
#include "config/full_system.hh"
#include "cpu/thread_context.hh"
#include "cpu/thread_state.hh"
@@ -49,7 +50,6 @@ class BaseCPU;
#if FULL_SYSTEM
#include "sim/system.hh"
-#include "arch/tlb.hh"
class FunctionProfile;
class ProfileNode;
@@ -109,10 +109,8 @@ class SimpleThread : public ThreadState
System *system;
-#if FULL_SYSTEM
TheISA::ITB *itb;
TheISA::DTB *dtb;
-#endif
// constructor: initialize SimpleThread from given process structure
#if FULL_SYSTEM
@@ -120,7 +118,8 @@ class SimpleThread : public ThreadState
TheISA::ITB *_itb, TheISA::DTB *_dtb,
bool use_kernel_stats = true);
#else
- SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid);
+ SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process,
+ TheISA::ITB *_itb, TheISA::DTB *_dtb, int _asid);
#endif
SimpleThread();
@@ -149,10 +148,6 @@ class SimpleThread : public ThreadState
*/
ThreadContext *getTC() { return tc; }
-#if FULL_SYSTEM
- int getInstAsid() { return regs.instAsid(); }
- int getDataAsid() { return regs.dataAsid(); }
-
Fault translateInstReq(RequestPtr &req)
{
return itb->translate(req, tc);
@@ -168,27 +163,16 @@ class SimpleThread : public ThreadState
return dtb->translate(req, tc, true);
}
+#if FULL_SYSTEM
+ int getInstAsid() { return regs.instAsid(); }
+ int getDataAsid() { return regs.dataAsid(); }
+
void dumpFuncProfile();
Fault hwrei();
bool simPalCheck(int palFunc);
-#else
-
- Fault translateInstReq(RequestPtr &req)
- {
- return process->pTable->translate(req);
- }
-
- Fault translateDataReadReq(RequestPtr &req)
- {
- return process->pTable->translate(req);
- }
- Fault translateDataWriteReq(RequestPtr &req)
- {
- return process->pTable->translate(req);
- }
#endif
/*******************************************
@@ -199,13 +183,13 @@ class SimpleThread : public ThreadState
int getThreadNum() { return tid; }
-#if FULL_SYSTEM
- System *getSystemPtr() { return system; }
-
TheISA::ITB *getITBPtr() { return itb; }
TheISA::DTB *getDTBPtr() { return dtb; }
+#if FULL_SYSTEM
+ System *getSystemPtr() { return system; }
+
FunctionalPort *getPhysPort() { return physPort; }
/** Return a virtual port. If no thread context is specified then a static
diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh
index 3706d8543..1af029093 100644
--- a/src/cpu/thread_context.hh
+++ b/src/cpu/thread_context.hh
@@ -119,13 +119,13 @@ class ThreadContext
virtual int readCpuId() = 0;
-#if FULL_SYSTEM
- virtual System *getSystemPtr() = 0;
-
virtual TheISA::ITB *getITBPtr() = 0;
virtual TheISA::DTB *getDTBPtr() = 0;
+#if FULL_SYSTEM
+ virtual System *getSystemPtr() = 0;
+
virtual TheISA::Kernel::Statistics *getKernelStats() = 0;
virtual FunctionalPort *getPhysPort() = 0;
@@ -298,13 +298,13 @@ class ProxyThreadContext : public ThreadContext
int readCpuId() { return actualTC->readCpuId(); }
-#if FULL_SYSTEM
- System *getSystemPtr() { return actualTC->getSystemPtr(); }
-
TheISA::ITB *getITBPtr() { return actualTC->getITBPtr(); }
TheISA::DTB *getDTBPtr() { return actualTC->getDTBPtr(); }
+#if FULL_SYSTEM
+ System *getSystemPtr() { return actualTC->getSystemPtr(); }
+
TheISA::Kernel::Statistics *getKernelStats()
{ return actualTC->getKernelStats(); }
diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc
index a00d743cd..efafc3f19 100644
--- a/src/mem/page_table.cc
+++ b/src/mem/page_table.cc
@@ -63,32 +63,6 @@ PageTable::~PageTable()
{
}
-Fault
-PageTable::page_check(Addr addr, int64_t size) const
-{
- if (size < sizeof(uint64_t)) {
- if (!isPowerOf2(size)) {
- panic("Invalid request size!\n");
- return genMachineCheckFault();
- }
-
- if ((size - 1) & addr)
- return genAlignmentFault();
- }
- else {
- if ((addr & (VMPageSize - 1)) + size > VMPageSize) {
- panic("Invalid request size!\n");
- return genMachineCheckFault();
- }
-
- if ((sizeof(uint64_t) - 1) & addr)
- return genAlignmentFault();
- }
-
- return NoFault;
-}
-
-
void
PageTable::allocate(Addr vaddr, int64_t size)
{
@@ -98,62 +72,73 @@ PageTable::allocate(Addr vaddr, int64_t size)
DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr+ size);
for (; size > 0; size -= pageSize, vaddr += pageSize) {
- m5::hash_map<Addr,Addr>::iterator iter = pTable.find(vaddr);
+ PTableItr iter = pTable.find(vaddr);
if (iter != pTable.end()) {
// already mapped
- fatal("PageTable::allocate: address 0x%x already mapped", vaddr);
+ fatal("PageTable::allocate: address 0x%x already mapped",
+ vaddr);
}
- pTable[vaddr] = system->new_page();
+ pTable[vaddr] = TheISA::TlbEntry(system->new_page());
updateCache(vaddr, pTable[vaddr]);
}
}
-
-
bool
-PageTable::translate(Addr vaddr, Addr &paddr)
+PageTable::lookup(Addr vaddr, TheISA::TlbEntry &entry)
{
Addr page_addr = pageAlign(vaddr);
- paddr = 0;
if (pTableCache[0].vaddr == page_addr) {
- paddr = pTableCache[0].paddr + pageOffset(vaddr);
+ entry = pTableCache[0].entry;
return true;
}
if (pTableCache[1].vaddr == page_addr) {
- paddr = pTableCache[1].paddr + pageOffset(vaddr);
+ entry = pTableCache[1].entry;
return true;
}
if (pTableCache[2].vaddr == page_addr) {
- paddr = pTableCache[2].paddr + pageOffset(vaddr);
+ entry = pTableCache[2].entry;
return true;
}
- m5::hash_map<Addr,Addr>::iterator iter = pTable.find(page_addr);
+ PTableItr iter = pTable.find(page_addr);
if (iter == pTable.end()) {
return false;
}
updateCache(page_addr, iter->second);
- paddr = iter->second + pageOffset(vaddr);
+ entry = iter->second;
return true;
}
+bool
+PageTable::translate(Addr vaddr, Addr &paddr)
+{
+ TheISA::TlbEntry entry;
+ if (!lookup(vaddr, entry))
+ return false;
+ paddr = pageOffset(vaddr) + entry.pageStart;
+ return true;
+}
Fault
-PageTable::translate(RequestPtr &req)
+PageTable::translate(RequestPtr req)
{
Addr paddr;
assert(pageAlign(req->getVaddr() + req->getSize() - 1)
== pageAlign(req->getVaddr()));
if (!translate(req->getVaddr(), paddr)) {
- return Fault(new PageTableFault(req->getVaddr()));
+ return Fault(new GenericPageTableFault(req->getVaddr()));
}
req->setPaddr(paddr);
- return page_check(req->getPaddr(), req->getSize());
+ if ((paddr & (pageSize - 1)) + req->getSize() > pageSize) {
+ panic("Request spans page boundaries!\n");
+ return NoFault;
+ }
+ return NoFault;
}
void
@@ -163,11 +148,11 @@ PageTable::serialize(std::ostream &os)
int count = 0;
- m5::hash_map<Addr,Addr>::iterator iter = pTable.begin();
- m5::hash_map<Addr,Addr>::iterator end = pTable.end();
+ PTableItr iter = pTable.begin();
+ PTableItr end = pTable.end();
while (iter != end) {
paramOut(os, csprintf("ptable.entry%dvaddr", count), iter->first);
- paramOut(os, csprintf("ptable.entry%dpaddr", count), iter->second);
+ iter->second.serialize(os);
++iter;
++count;
@@ -180,16 +165,16 @@ PageTable::unserialize(Checkpoint *cp, const std::string &section)
{
int i = 0, count;
paramIn(cp, section, "ptable.size", count);
- Addr vaddr, paddr;
+ Addr vaddr;
+ TheISA::TlbEntry entry;
pTable.clear();
while(i < count) {
paramIn(cp, section, csprintf("ptable.entry%dvaddr", i), vaddr);
- paramIn(cp, section, csprintf("ptable.entry%dpaddr", i), paddr);
- pTable[vaddr] = paddr;
+ entry.unserialize(cp, section);
+ pTable[vaddr] = entry;
++i;
}
-
}
diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh
index 64c824238..845bb9112 100644
--- a/src/mem/page_table.hh
+++ b/src/mem/page_table.hh
@@ -40,11 +40,11 @@
#include "sim/faults.hh"
#include "arch/isa_traits.hh"
+#include "arch/tlb.hh"
#include "base/hashmap.hh"
-#include "base/trace.hh"
#include "mem/request.hh"
-#include "mem/packet.hh"
-#include "sim/sim_object.hh"
+#include "sim/host.hh"
+#include "sim/serialize.hh"
class System;
@@ -54,12 +54,14 @@ class System;
class PageTable
{
protected:
- m5::hash_map<Addr,Addr> pTable;
+ typedef m5::hash_map<Addr, TheISA::TlbEntry> PTable;
+ typedef PTable::iterator PTableItr;
+ PTable pTable;
struct cacheElement {
- Addr paddr;
Addr vaddr;
- } ;
+ TheISA::TlbEntry entry;
+ };
struct cacheElement pTableCache[3];
@@ -77,11 +79,16 @@ class PageTable
Addr pageAlign(Addr a) { return (a & ~offsetMask); }
Addr pageOffset(Addr a) { return (a & offsetMask); }
- Fault page_check(Addr addr, int64_t size) const;
-
void allocate(Addr vaddr, int64_t size);
/**
+ * Lookup function
+ * @param vaddr The virtual address.
+ * @return entry The page table entry corresponding to vaddr.
+ */
+ bool lookup(Addr vaddr, TheISA::TlbEntry &entry);
+
+ /**
* Translate function
* @param vaddr The virtual address.
* @return Physical address from translation.
@@ -90,28 +97,29 @@ class PageTable
/**
* Perform a translation on the memory request, fills in paddr
- * field of mem_req.
+ * field of req.
* @param req The memory request.
*/
- Fault translate(RequestPtr &req);
+ Fault translate(RequestPtr req);
/**
* Update the page table cache.
* @param vaddr virtual address (page aligned) to check
- * @param paddr physical address (page aligned) to return
+ * @param pte page table entry to return
*/
- inline void updateCache(Addr vaddr, Addr paddr)
+ inline void updateCache(Addr vaddr, TheISA::TlbEntry entry)
{
- pTableCache[2].paddr = pTableCache[1].paddr;
+ pTableCache[2].entry = pTableCache[1].entry;
pTableCache[2].vaddr = pTableCache[1].vaddr;
- pTableCache[1].paddr = pTableCache[0].paddr;
+ pTableCache[1].entry = pTableCache[0].entry;
pTableCache[1].vaddr = pTableCache[0].vaddr;
- pTableCache[0].paddr = paddr;
+ pTableCache[0].entry = entry;
pTableCache[0].vaddr = vaddr;
}
void serialize(std::ostream &os);
+
void unserialize(Checkpoint *cp, const std::string &section);
};
diff --git a/src/sim/SConscript b/src/sim/SConscript
index bfa0c9a0c..b0af4c795 100644
--- a/src/sim/SConscript
+++ b/src/sim/SConscript
@@ -53,6 +53,7 @@ if env['FULL_SYSTEM']:
Source('arguments.cc')
Source('pseudo_inst.cc')
else:
+ Source('tlb.cc')
SimObject('Process.py')
Source('process.cc')
diff --git a/src/sim/faults.cc b/src/sim/faults.cc
index fe62874d7..6d6a8b5f6 100644
--- a/src/sim/faults.cc
+++ b/src/sim/faults.cc
@@ -56,8 +56,9 @@ void UnimpFault::invoke(ThreadContext * tc)
{
panic("Unimpfault: %s\n", panicStr.c_str());
}
+
#if !FULL_SYSTEM
-void PageTableFault::invoke(ThreadContext *tc)
+void GenericPageTableFault::invoke(ThreadContext *tc)
{
Process *p = tc->getProcessPtr();
@@ -65,4 +66,9 @@ void PageTableFault::invoke(ThreadContext *tc)
panic("Page table fault when accessing virtual address %#x\n", vaddr);
}
+
+void GenericAlignmentFault::invoke(ThreadContext *tc)
+{
+ panic("Alignment fault when accessing virtual address %#x\n", vaddr);
+}
#endif
diff --git a/src/sim/faults.hh b/src/sim/faults.hh
index f2e638945..cfc6ad105 100644
--- a/src/sim/faults.hh
+++ b/src/sim/faults.hh
@@ -77,13 +77,23 @@ class UnimpFault : public FaultBase
};
#if !FULL_SYSTEM
-class PageTableFault : public FaultBase
+class GenericPageTableFault : public FaultBase
{
private:
Addr vaddr;
public:
- FaultName name() const {return "M5 page table fault";}
- PageTableFault(Addr va) : vaddr(va) {}
+ FaultName name() const {return "Generic page table fault";}
+ GenericPageTableFault(Addr va) : vaddr(va) {}
+ void invoke(ThreadContext * tc);
+};
+
+class GenericAlignmentFault : public FaultBase
+{
+ private:
+ Addr vaddr;
+ public:
+ FaultName name() const {return "Generic alignment fault";}
+ GenericAlignmentFault(Addr va) : vaddr(va) {}
void invoke(ThreadContext * tc);
};
#endif
diff --git a/src/sim/process.cc b/src/sim/process.cc
index 7343039df..1e6395d55 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -90,6 +90,7 @@ Process::Process(const string &nm,
int stderr_fd)
: SimObject(nm), system(_system)
{
+ M5_pid = system->allocatePID();
// initialize first 3 fds (stdin, stdout, stderr)
fd_map[STDIN_FILENO] = stdin_fd;
fd_map[STDOUT_FILENO] = stdout_fd;
diff --git a/src/sim/process.hh b/src/sim/process.hh
index 8c702da60..83c00a676 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -137,6 +137,10 @@ class Process : public SimObject
public:
PageTable *pTable;
+ //This id is assigned by m5 and is used to keep process' tlb entries
+ //separated.
+ uint64_t M5_pid;
+
private:
// file descriptor remapping support
static const int MAX_FD = 256; // max legal fd value
diff --git a/src/sim/system.cc b/src/sim/system.cc
index eb0655aa5..512d4bdb5 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -64,6 +64,7 @@ System::System(Params *p)
virtPort(p->name + "-vport"),
#else
page_ptr(0),
+ next_PID(0),
#endif
memoryMode(p->mem_mode), _params(p)
{
diff --git a/src/sim/system.hh b/src/sim/system.hh
index 197d9027b..cdd5bebb0 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -125,6 +125,15 @@ class System : public SimObject
int page_ptr;
+ protected:
+ uint64_t next_PID;
+
+ public:
+ uint64_t allocatePID()
+ {
+ return next_PID++;
+ }
+
#endif // FULL_SYSTEM
diff --git a/src/sim/tlb.cc b/src/sim/tlb.cc
new file mode 100644
index 000000000..5ceec637e
--- /dev/null
+++ b/src/sim/tlb.cc
@@ -0,0 +1,50 @@
+/*
+ * 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 "cpu/thread_context.hh"
+#include "mem/page_table.hh"
+#include "sim/process.hh"
+#include "sim/tlb.hh"
+
+Fault
+GenericTLBBase::translate(RequestPtr req, ThreadContext * tc)
+{
+#if FULL_SYSTEM
+ panic("Generic translation shouldn't be used in full system mode.\n");
+#else
+ Process * p = tc->getProcessPtr();
+
+ Fault fault = p->pTable->translate(req);
+ if(fault != NoFault)
+ return fault;
+
+ return NoFault;
+#endif
+}
diff --git a/src/sim/tlb.hh b/src/sim/tlb.hh
new file mode 100644
index 000000000..c4c171015
--- /dev/null
+++ b/src/sim/tlb.hh
@@ -0,0 +1,94 @@
+/*
+ * 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 __SIM_TLB_HH__
+#define __SIM_TLB_HH__
+
+#include "base/misc.hh"
+#include "mem/request.hh"
+#include "sim/faults.hh"
+#include "sim/sim_object.hh"
+
+class ThreadContext;
+class Packet;
+
+class GenericTLBBase : public SimObject
+{
+ protected:
+ GenericTLBBase(const std::string &name) : SimObject(name)
+ {}
+
+ Fault translate(RequestPtr req, ThreadContext *tc);
+};
+
+template <bool doSizeCheck=true, bool doAlignmentCheck=true>
+class GenericTLB : public GenericTLBBase
+{
+ public:
+ GenericTLB(const std::string &name) : GenericTLBBase(name)
+ {}
+
+ Fault translate(RequestPtr req, ThreadContext *tc, bool=false)
+ {
+ Fault fault = GenericTLBBase::translate(req, tc);
+ if (fault != NoFault)
+ return fault;
+
+ typeof(req->getSize()) size = req->getSize();
+ Addr paddr = req->getPaddr();
+
+ if(doSizeCheck && !isPowerOf2(size))
+ panic("Invalid request size!\n");
+ if (doAlignmentCheck && ((size - 1) & paddr))
+ return new GenericAlignmentFault(paddr);
+
+ return NoFault;
+ }
+};
+
+template <bool doSizeCheck=true, bool doAlignmentCheck=true>
+class GenericITB : public GenericTLB<doSizeCheck, doAlignmentCheck>
+{
+ public:
+ GenericITB(const std::string &name) :
+ GenericTLB<doSizeCheck, doAlignmentCheck>(name)
+ {}
+};
+
+template <bool doSizeCheck=true, bool doAlignmentCheck=true>
+class GenericDTB : public GenericTLB<doSizeCheck, doAlignmentCheck>
+{
+ public:
+ GenericDTB(const std::string &name) :
+ GenericTLB<doSizeCheck, doAlignmentCheck>(name)
+ {}
+};
+
+#endif // __ARCH_SPARC_TLB_HH__