style: Make a style pass over the whole arch/alpha directory.
This commit is contained in:
parent
82f5723c7a
commit
cf7ddd8e8a
52 changed files with 1952 additions and 1899 deletions
|
@ -459,8 +459,7 @@ MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
|
|||
// really a control write
|
||||
ipr[idx] = val;
|
||||
|
||||
tc->getDTBPtr()->flushAddr(val,
|
||||
DTB_ASN_ASN(ipr[IPR_DTB_ASN]));
|
||||
tc->getDTBPtr()->flushAddr(val, DTB_ASN_ASN(ipr[IPR_DTB_ASN]));
|
||||
break;
|
||||
|
||||
case IPR_DTB_TAG: {
|
||||
|
@ -529,8 +528,7 @@ MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
|
|||
// really a control write
|
||||
ipr[idx] = val;
|
||||
|
||||
tc->getITBPtr()->flushAddr(val,
|
||||
ITB_ASN_ASN(ipr[IPR_ITB_ASN]));
|
||||
tc->getITBPtr()->flushAddr(val, ITB_ASN_ASN(ipr[IPR_ITB_ASN]));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -541,18 +539,17 @@ MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
|
|||
// no error...
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
copyIprs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
for (int i = 0; i < NumInternalProcRegs; ++i) {
|
||||
for (int i = 0; i < NumInternalProcRegs; ++i)
|
||||
dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#if FULL_SYSTEM
|
||||
|
||||
using namespace AlphaISA;
|
||||
|
||||
Fault
|
||||
|
|
|
@ -65,7 +65,9 @@ const Addr PAddrUncachedBit39 = ULL(0x8000000000);
|
|||
const Addr PAddrUncachedBit40 = ULL(0x10000000000);
|
||||
const Addr PAddrUncachedBit43 = ULL(0x80000000000);
|
||||
const Addr PAddrUncachedMask = ULL(0x807ffffffff); // Clear PA<42:35>
|
||||
inline Addr Phys2K0Seg(Addr addr)
|
||||
|
||||
inline Addr
|
||||
Phys2K0Seg(Addr addr)
|
||||
{
|
||||
#if !ALPHA_TLASER
|
||||
if (addr & PAddrUncachedBit43) {
|
||||
|
|
|
@ -40,8 +40,7 @@
|
|||
#include "mem/page_table.hh"
|
||||
#endif
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
namespace AlphaISA {
|
||||
|
||||
FaultName MachineCheckFault::_name = "mchk";
|
||||
FaultVect MachineCheckFault::_vect = 0x0401;
|
||||
|
@ -109,7 +108,8 @@ FaultStat IntegerOverflowFault::_count;
|
|||
|
||||
#if FULL_SYSTEM
|
||||
|
||||
void AlphaFault::invoke(ThreadContext * tc)
|
||||
void
|
||||
AlphaFault::invoke(ThreadContext *tc)
|
||||
{
|
||||
FaultBase::invoke(tc);
|
||||
countStat()++;
|
||||
|
@ -128,29 +128,31 @@ void AlphaFault::invoke(ThreadContext * tc)
|
|||
tc->setNextPC(tc->readPC() + sizeof(MachInst));
|
||||
}
|
||||
|
||||
void ArithmeticFault::invoke(ThreadContext * tc)
|
||||
void
|
||||
ArithmeticFault::invoke(ThreadContext *tc)
|
||||
{
|
||||
FaultBase::invoke(tc);
|
||||
panic("Arithmetic traps are unimplemented!");
|
||||
}
|
||||
|
||||
void DtbFault::invoke(ThreadContext * tc)
|
||||
void
|
||||
DtbFault::invoke(ThreadContext *tc)
|
||||
{
|
||||
// Set fault address and flags. Even though we're modeling an
|
||||
// EV5, we use the EV6 technique of not latching fault registers
|
||||
// on VPTE loads (instead of locking the registers until IPR_VA is
|
||||
// read, like the EV5). The EV6 approach is cleaner and seems to
|
||||
// work with EV5 PAL code, but not the other way around.
|
||||
if (!tc->misspeculating()
|
||||
&& !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) {
|
||||
if (!tc->misspeculating() &&
|
||||
!(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) {
|
||||
// set VA register with faulting address
|
||||
tc->setMiscRegNoEffect(IPR_VA, vaddr);
|
||||
|
||||
// set MM_STAT register flags
|
||||
tc->setMiscRegNoEffect(IPR_MM_STAT,
|
||||
(((Opcode(tc->getInst()) & 0x3f) << 11)
|
||||
| ((Ra(tc->getInst()) & 0x1f) << 6)
|
||||
| (flags & 0x3f)));
|
||||
(((Opcode(tc->getInst()) & 0x3f) << 11) |
|
||||
((Ra(tc->getInst()) & 0x1f) << 6) |
|
||||
(flags & 0x3f)));
|
||||
|
||||
// set VA_FORM register with faulting formatted address
|
||||
tc->setMiscRegNoEffect(IPR_VA_FORM,
|
||||
|
@ -160,13 +162,13 @@ void DtbFault::invoke(ThreadContext * tc)
|
|||
AlphaFault::invoke(tc);
|
||||
}
|
||||
|
||||
void ItbFault::invoke(ThreadContext * tc)
|
||||
void
|
||||
ItbFault::invoke(ThreadContext *tc)
|
||||
{
|
||||
if (!tc->misspeculating()) {
|
||||
tc->setMiscRegNoEffect(IPR_ITB_TAG, pc);
|
||||
tc->setMiscRegNoEffect(IPR_IFAULT_VA_FORM,
|
||||
tc->readMiscRegNoEffect(IPR_IVPTBR) |
|
||||
(VAddr(pc).vpn() << 3));
|
||||
tc->readMiscRegNoEffect(IPR_IVPTBR) | (VAddr(pc).vpn() << 3));
|
||||
}
|
||||
|
||||
AlphaFault::invoke(tc);
|
||||
|
@ -174,12 +176,13 @@ void ItbFault::invoke(ThreadContext * tc)
|
|||
|
||||
#else
|
||||
|
||||
void ItbPageFault::invoke(ThreadContext * tc)
|
||||
void
|
||||
ItbPageFault::invoke(ThreadContext *tc)
|
||||
{
|
||||
Process *p = tc->getProcessPtr();
|
||||
TlbEntry entry;
|
||||
bool success = p->pTable->lookup(pc, entry);
|
||||
if(!success) {
|
||||
if (!success) {
|
||||
panic("Tried to execute unmapped address %#x.\n", pc);
|
||||
} else {
|
||||
VAddr vaddr(pc);
|
||||
|
@ -187,16 +190,17 @@ void ItbPageFault::invoke(ThreadContext * tc)
|
|||
}
|
||||
}
|
||||
|
||||
void NDtbMissFault::invoke(ThreadContext * tc)
|
||||
void
|
||||
NDtbMissFault::invoke(ThreadContext *tc)
|
||||
{
|
||||
Process *p = tc->getProcessPtr();
|
||||
TlbEntry entry;
|
||||
bool success = p->pTable->lookup(vaddr, entry);
|
||||
if(!success) {
|
||||
if (!success) {
|
||||
p->checkAndAllocNextPage(vaddr);
|
||||
success = p->pTable->lookup(vaddr, entry);
|
||||
}
|
||||
if(!success) {
|
||||
if (!success) {
|
||||
panic("Tried to access unmapped address %#x.\n", (Addr)vaddr);
|
||||
} else {
|
||||
tc->getDTBPtr()->insert(vaddr.page(), entry);
|
||||
|
|
|
@ -29,18 +29,16 @@
|
|||
* Kevin Lim
|
||||
*/
|
||||
|
||||
#ifndef __ALPHA_FAULTS_HH__
|
||||
#define __ALPHA_FAULTS_HH__
|
||||
#ifndef __ARCH_ALPHA_FAULTS_HH__
|
||||
#define __ARCH_ALPHA_FAULTS_HH__
|
||||
|
||||
#include "arch/alpha/pagetable.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "sim/faults.hh"
|
||||
|
||||
#include "arch/alpha/pagetable.hh"
|
||||
|
||||
// The design of the "name" and "vect" functions is in sim/faults.hh
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
namespace AlphaISA {
|
||||
|
||||
typedef const Addr FaultVect;
|
||||
|
||||
|
@ -63,6 +61,7 @@ class MachineCheckFault : public AlphaFault
|
|||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
|
||||
public:
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
|
@ -76,6 +75,7 @@ class AlignmentFault : public AlphaFault
|
|||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
|
||||
public:
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
|
@ -94,6 +94,7 @@ class ResetFault : public AlphaFault
|
|||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
|
||||
public:
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
|
@ -102,12 +103,14 @@ class ResetFault : public AlphaFault
|
|||
|
||||
class ArithmeticFault : public AlphaFault
|
||||
{
|
||||
protected:
|
||||
bool skipFaultingInstruction() {return true;}
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
|
||||
protected:
|
||||
bool skipFaultingInstruction() {return true;}
|
||||
|
||||
public:
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
|
@ -119,12 +122,14 @@ class ArithmeticFault : public AlphaFault
|
|||
|
||||
class InterruptFault : public AlphaFault
|
||||
{
|
||||
protected:
|
||||
bool setRestartAddress() {return false;}
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
|
||||
protected:
|
||||
bool setRestartAddress() {return false;}
|
||||
|
||||
public:
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
|
@ -137,6 +142,7 @@ class DtbFault : public AlphaFault
|
|||
VAddr vaddr;
|
||||
uint32_t reqFlags;
|
||||
uint64_t flags;
|
||||
|
||||
public:
|
||||
DtbFault(VAddr _vaddr, uint32_t _reqFlags, uint64_t _flags)
|
||||
: vaddr(_vaddr), reqFlags(_reqFlags), flags(_flags)
|
||||
|
@ -155,6 +161,7 @@ class NDtbMissFault : public DtbFault
|
|||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
|
||||
public:
|
||||
NDtbMissFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
||||
: DtbFault(vaddr, reqFlags, flags)
|
||||
|
@ -173,6 +180,7 @@ class PDtbMissFault : public DtbFault
|
|||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
|
||||
public:
|
||||
PDtbMissFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
||||
: DtbFault(vaddr, reqFlags, flags)
|
||||
|
@ -188,6 +196,7 @@ class DtbPageFault : public DtbFault
|
|||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
|
||||
public:
|
||||
DtbPageFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
||||
: DtbFault(vaddr, reqFlags, flags)
|
||||
|
@ -203,6 +212,7 @@ class DtbAcvFault : public DtbFault
|
|||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
|
||||
public:
|
||||
DtbAcvFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
||||
: DtbFault(vaddr, reqFlags, flags)
|
||||
|
@ -218,6 +228,7 @@ class DtbAlignmentFault : public DtbFault
|
|||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
|
||||
public:
|
||||
DtbAlignmentFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags)
|
||||
: DtbFault(vaddr, reqFlags, flags)
|
||||
|
@ -231,10 +242,9 @@ class ItbFault : public AlphaFault
|
|||
{
|
||||
protected:
|
||||
Addr pc;
|
||||
|
||||
public:
|
||||
ItbFault(Addr _pc)
|
||||
: pc(_pc)
|
||||
{ }
|
||||
ItbFault(Addr _pc) : pc(_pc) { }
|
||||
FaultName name() const = 0;
|
||||
FaultVect vect() = 0;
|
||||
FaultStat & countStat() = 0;
|
||||
|
@ -249,10 +259,9 @@ class ItbPageFault : public ItbFault
|
|||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
|
||||
public:
|
||||
ItbPageFault(Addr pc)
|
||||
: ItbFault(pc)
|
||||
{ }
|
||||
ItbPageFault(Addr pc) : ItbFault(pc) { }
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
|
@ -267,10 +276,9 @@ class ItbAcvFault : public ItbFault
|
|||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
|
||||
public:
|
||||
ItbAcvFault(Addr pc)
|
||||
: ItbFault(pc)
|
||||
{ }
|
||||
ItbAcvFault(Addr pc) : ItbFault(pc) { }
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
|
@ -282,6 +290,7 @@ class UnimplementedOpcodeFault : public AlphaFault
|
|||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
|
||||
public:
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
|
@ -294,6 +303,7 @@ class FloatEnableFault : public AlphaFault
|
|||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
|
||||
public:
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
|
@ -302,12 +312,14 @@ class FloatEnableFault : public AlphaFault
|
|||
|
||||
class PalFault : public AlphaFault
|
||||
{
|
||||
protected:
|
||||
bool skipFaultingInstruction() {return true;}
|
||||
private:
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
|
||||
protected:
|
||||
bool skipFaultingInstruction() {return true;}
|
||||
|
||||
public:
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
|
@ -320,12 +332,13 @@ class IntegerOverflowFault : public AlphaFault
|
|||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
|
||||
public:
|
||||
FaultName name() const {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
} // AlphaISA namespace
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __FAULTS_HH__
|
||||
#endif // __ARCH_ALPHA_FAULTS_HH__
|
||||
|
|
|
@ -33,17 +33,23 @@
|
|||
#include "arch/alpha/floatregfile.hh"
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
void
|
||||
FloatRegFile::clear()
|
||||
{
|
||||
void
|
||||
FloatRegFile::serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_ARRAY(q, NumFloatRegs);
|
||||
}
|
||||
|
||||
void
|
||||
FloatRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_ARRAY(q, NumFloatRegs);
|
||||
}
|
||||
std::memset(d, 0, sizeof(d));
|
||||
}
|
||||
|
||||
void
|
||||
FloatRegFile::serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_ARRAY(q, NumFloatRegs);
|
||||
}
|
||||
|
||||
void
|
||||
FloatRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_ARRAY(q, NumFloatRegs);
|
||||
}
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
|
|
@ -32,37 +32,36 @@
|
|||
#ifndef __ARCH_ALPHA_FLOATREGFILE_HH__
|
||||
#define __ARCH_ALPHA_FLOATREGFILE_HH__
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
#include "arch/alpha/isa_traits.hh"
|
||||
#include "arch/alpha/types.hh"
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
class Checkpoint;
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
static inline std::string
|
||||
getFloatRegName(RegIndex)
|
||||
{
|
||||
static inline std::string getFloatRegName(RegIndex)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
class FloatRegFile
|
||||
{
|
||||
public:
|
||||
|
||||
union {
|
||||
uint64_t q[NumFloatRegs]; // integer qword view
|
||||
double d[NumFloatRegs]; // double-precision floating point view
|
||||
};
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
void clear()
|
||||
{ std::memset(d, 0, sizeof(d)); }
|
||||
};
|
||||
return "";
|
||||
}
|
||||
|
||||
#endif
|
||||
class FloatRegFile
|
||||
{
|
||||
public:
|
||||
union {
|
||||
uint64_t q[NumFloatRegs]; // integer qword view
|
||||
double d[NumFloatRegs]; // double-precision floating point view
|
||||
};
|
||||
|
||||
void clear();
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ARCH_ALPHA_FLOATREGFILE_HH__
|
||||
|
|
|
@ -62,14 +62,12 @@ FreebsdAlphaSystem::FreebsdAlphaSystem(Params *p)
|
|||
addKernelFuncEvent<SkipCalibrateClocksEvent>("calibrate_clocks");
|
||||
}
|
||||
|
||||
|
||||
FreebsdAlphaSystem::~FreebsdAlphaSystem()
|
||||
{
|
||||
delete skipDelayEvent;
|
||||
delete skipCalibrateClocks;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc)
|
||||
{
|
||||
|
@ -84,7 +82,6 @@ FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc)
|
|||
virtPort.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ThreadContext *tc)
|
||||
{
|
||||
|
|
|
@ -57,7 +57,6 @@ class FreebsdAlphaSystem : public AlphaSystem
|
|||
~FreebsdAlphaSystem();
|
||||
|
||||
void doCalibrateClocks(ThreadContext *tc);
|
||||
|
||||
};
|
||||
|
||||
#endif // __ARCH_ALPHA_FREEBSD_SYSTEM_HH__
|
||||
|
|
|
@ -38,8 +38,9 @@ using namespace AlphaISA;
|
|||
void
|
||||
IdleStartEvent::process(ThreadContext *tc)
|
||||
{
|
||||
if (tc->getKernelStats())
|
||||
tc->getKernelStats()->setIdleProcess(
|
||||
tc->readMiscRegNoEffect(IPR_PALtemp23), tc);
|
||||
if (tc->getKernelStats()) {
|
||||
MiscReg val = tc->readMiscRegNoEffect(IPR_PALtemp23);
|
||||
tc->getKernelStats()->setIdleProcess(val, tc);
|
||||
}
|
||||
remove();
|
||||
}
|
||||
|
|
|
@ -30,36 +30,45 @@
|
|||
* Kevin Lim
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "arch/alpha/isa_traits.hh"
|
||||
#include "arch/alpha/intregfile.hh"
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
namespace AlphaISA {
|
||||
|
||||
#if FULL_SYSTEM
|
||||
const int reg_redir[NumIntRegs] = {
|
||||
/* 0 */ 0, 1, 2, 3, 4, 5, 6, 7,
|
||||
/* 8 */ 32, 33, 34, 35, 36, 37, 38, 15,
|
||||
/* 16 */ 16, 17, 18, 19, 20, 21, 22, 23,
|
||||
/* 24 */ 24, 39, 26, 27, 28, 29, 30, 31 };
|
||||
const int reg_redir[NumIntRegs] = {
|
||||
/* 0 */ 0, 1, 2, 3, 4, 5, 6, 7,
|
||||
/* 8 */ 32, 33, 34, 35, 36, 37, 38, 15,
|
||||
/* 16 */ 16, 17, 18, 19, 20, 21, 22, 23,
|
||||
/* 24 */ 24, 39, 26, 27, 28, 29, 30, 31 };
|
||||
#else
|
||||
const int reg_redir[NumIntRegs] = {
|
||||
/* 0 */ 0, 1, 2, 3, 4, 5, 6, 7,
|
||||
/* 8 */ 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
/* 16 */ 16, 17, 18, 19, 20, 21, 22, 23,
|
||||
/* 24 */ 24, 25, 26, 27, 28, 29, 30, 31 };
|
||||
const int reg_redir[NumIntRegs] = {
|
||||
/* 0 */ 0, 1, 2, 3, 4, 5, 6, 7,
|
||||
/* 8 */ 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
/* 16 */ 16, 17, 18, 19, 20, 21, 22, 23,
|
||||
/* 24 */ 24, 25, 26, 27, 28, 29, 30, 31 };
|
||||
#endif
|
||||
|
||||
void
|
||||
IntRegFile::serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_ARRAY(regs, NumIntRegs);
|
||||
}
|
||||
|
||||
void
|
||||
IntRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_ARRAY(regs, NumIntRegs);
|
||||
}
|
||||
void
|
||||
IntRegFile::clear()
|
||||
{
|
||||
std::memset(regs, 0, sizeof(regs));
|
||||
}
|
||||
|
||||
void
|
||||
IntRegFile::serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_ARRAY(regs, NumIntRegs);
|
||||
}
|
||||
|
||||
void
|
||||
IntRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_ARRAY(regs, NumIntRegs);
|
||||
}
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
|
|
|
@ -32,47 +32,48 @@
|
|||
#ifndef __ARCH_ALPHA_INTREGFILE_HH__
|
||||
#define __ARCH_ALPHA_INTREGFILE_HH__
|
||||
|
||||
#include "arch/alpha/types.hh"
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include "arch/alpha/types.hh"
|
||||
|
||||
class Checkpoint;
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
static inline std::string
|
||||
getIntRegName(RegIndex)
|
||||
{
|
||||
static inline std::string getIntRegName(RegIndex)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// redirected register map, really only used for the full system case.
|
||||
extern const int reg_redir[NumIntRegs];
|
||||
|
||||
class IntRegFile
|
||||
{
|
||||
protected:
|
||||
IntReg regs[NumIntRegs];
|
||||
|
||||
public:
|
||||
|
||||
IntReg readReg(int intReg)
|
||||
{
|
||||
return regs[intReg];
|
||||
}
|
||||
|
||||
void setReg(int intReg, const IntReg &val)
|
||||
{
|
||||
regs[intReg] = val;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
void clear()
|
||||
{ std::memset(regs, 0, sizeof(regs)); }
|
||||
};
|
||||
return "";
|
||||
}
|
||||
|
||||
#endif
|
||||
// redirected register map, really only used for the full system case.
|
||||
extern const int reg_redir[NumIntRegs];
|
||||
|
||||
class IntRegFile
|
||||
{
|
||||
protected:
|
||||
IntReg regs[NumIntRegs];
|
||||
|
||||
public:
|
||||
IntReg
|
||||
readReg(int intReg)
|
||||
{
|
||||
return regs[intReg];
|
||||
}
|
||||
|
||||
void
|
||||
setReg(int intReg, const IntReg &val)
|
||||
{
|
||||
regs[intReg] = val;
|
||||
}
|
||||
|
||||
void clear();
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ARCH_ALPHA_INTREGFILE_HH__
|
||||
|
|
|
@ -28,113 +28,115 @@
|
|||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "arch/alpha/ipr.hh"
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs] = {
|
||||
|
||||
//Write only
|
||||
RAW_IPR_HWINT_CLR, // H/W interrupt clear register
|
||||
RAW_IPR_SL_XMIT, // serial line transmit register
|
||||
RAW_IPR_DC_FLUSH,
|
||||
RAW_IPR_IC_FLUSH, // instruction cache flush control
|
||||
RAW_IPR_ALT_MODE, // alternate mode register
|
||||
RAW_IPR_DTB_IA, // DTLB invalidate all register
|
||||
RAW_IPR_DTB_IAP, // DTLB invalidate all process register
|
||||
RAW_IPR_ITB_IA, // ITLB invalidate all register
|
||||
RAW_IPR_ITB_IAP, // ITLB invalidate all process register
|
||||
|
||||
//Read only
|
||||
RAW_IPR_INTID, // interrupt ID register
|
||||
RAW_IPR_SL_RCV, // serial line receive register
|
||||
RAW_IPR_MM_STAT, // data MMU fault status register
|
||||
RAW_IPR_ITB_PTE_TEMP, // ITLB page table entry temp register
|
||||
RAW_IPR_DTB_PTE_TEMP, // DTLB page table entry temporary register
|
||||
|
||||
RAW_IPR_ISR, // interrupt summary register
|
||||
RAW_IPR_ITB_TAG, // ITLB tag register
|
||||
RAW_IPR_ITB_PTE, // ITLB page table entry register
|
||||
RAW_IPR_ITB_ASN, // ITLB address space register
|
||||
RAW_IPR_ITB_IS, // ITLB invalidate select register
|
||||
RAW_IPR_SIRR, // software interrupt request register
|
||||
RAW_IPR_ASTRR, // asynchronous system trap request register
|
||||
RAW_IPR_ASTER, // asynchronous system trap enable register
|
||||
RAW_IPR_EXC_ADDR, // exception address register
|
||||
RAW_IPR_EXC_SUM, // exception summary register
|
||||
RAW_IPR_EXC_MASK, // exception mask register
|
||||
RAW_IPR_PAL_BASE, // PAL base address register
|
||||
RAW_IPR_ICM, // instruction current mode
|
||||
RAW_IPR_IPLR, // interrupt priority level register
|
||||
RAW_IPR_IFAULT_VA_FORM, // formatted faulting virtual addr register
|
||||
RAW_IPR_IVPTBR, // virtual page table base register
|
||||
RAW_IPR_ICSR, // instruction control and status register
|
||||
RAW_IPR_IC_PERR_STAT, // inst cache parity error status register
|
||||
RAW_IPR_PMCTR, // performance counter register
|
||||
|
||||
// PAL temporary registers...
|
||||
// register meanings gleaned from osfpal.s source code
|
||||
RAW_IPR_PALtemp0, // local scratch
|
||||
RAW_IPR_PALtemp1, // local scratch
|
||||
RAW_IPR_PALtemp2, // entUna
|
||||
RAW_IPR_PALtemp3, // CPU specific impure area pointer
|
||||
RAW_IPR_PALtemp4, // memory management temp
|
||||
RAW_IPR_PALtemp5, // memory management temp
|
||||
RAW_IPR_PALtemp6, // memory management temp
|
||||
RAW_IPR_PALtemp7, // entIF
|
||||
RAW_IPR_PALtemp8, // intmask
|
||||
RAW_IPR_PALtemp9, // entSys
|
||||
RAW_IPR_PALtemp10, // ??
|
||||
RAW_IPR_PALtemp11, // entInt
|
||||
RAW_IPR_PALtemp12, // entArith
|
||||
RAW_IPR_PALtemp13, // reserved for platform specific PAL
|
||||
RAW_IPR_PALtemp14, // reserved for platform specific PAL
|
||||
RAW_IPR_PALtemp15, // reserved for platform specific PAL
|
||||
RAW_IPR_PALtemp16, // scratch / whami<7:0> / mces<4:0>
|
||||
RAW_IPR_PALtemp17, // sysval
|
||||
RAW_IPR_PALtemp18, // usp
|
||||
RAW_IPR_PALtemp19, // ksp
|
||||
RAW_IPR_PALtemp20, // PTBR
|
||||
RAW_IPR_PALtemp21, // entMM
|
||||
RAW_IPR_PALtemp22, // kgp
|
||||
RAW_IPR_PALtemp23, // PCBB
|
||||
|
||||
RAW_IPR_DTB_ASN, // DTLB address space number register
|
||||
RAW_IPR_DTB_CM, // DTLB current mode register
|
||||
RAW_IPR_DTB_TAG, // DTLB tag register
|
||||
RAW_IPR_DTB_PTE, // DTLB page table entry register
|
||||
|
||||
RAW_IPR_VA, // fault virtual address register
|
||||
RAW_IPR_VA_FORM, // formatted virtual address register
|
||||
RAW_IPR_MVPTBR, // MTU virtual page table base register
|
||||
RAW_IPR_DTB_IS, // DTLB invalidate single register
|
||||
RAW_IPR_CC, // cycle counter register
|
||||
RAW_IPR_CC_CTL, // cycle counter control register
|
||||
RAW_IPR_MCSR, // MTU control register
|
||||
|
||||
RAW_IPR_DC_PERR_STAT, // Dcache parity error status register
|
||||
RAW_IPR_DC_TEST_CTL, // Dcache test tag control register
|
||||
RAW_IPR_DC_TEST_TAG, // Dcache test tag register
|
||||
RAW_IPR_DC_TEST_TAG_TEMP, // Dcache test tag temporary register
|
||||
RAW_IPR_DC_MODE, // Dcache mode register
|
||||
RAW_IPR_MAF_MODE // miss address file mode register
|
||||
};
|
||||
|
||||
int IprToMiscRegIndex[MaxInternalProcRegs];
|
||||
|
||||
void
|
||||
initializeIprTable()
|
||||
{
|
||||
md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs] =
|
||||
{
|
||||
//Write only
|
||||
RAW_IPR_HWINT_CLR, // H/W interrupt clear register
|
||||
RAW_IPR_SL_XMIT, // serial line transmit register
|
||||
RAW_IPR_DC_FLUSH,
|
||||
RAW_IPR_IC_FLUSH, // instruction cache flush control
|
||||
RAW_IPR_ALT_MODE, // alternate mode register
|
||||
RAW_IPR_DTB_IA, // DTLB invalidate all register
|
||||
RAW_IPR_DTB_IAP, // DTLB invalidate all process register
|
||||
RAW_IPR_ITB_IA, // ITLB invalidate all register
|
||||
RAW_IPR_ITB_IAP, // ITLB invalidate all process register
|
||||
static bool initialized = false;
|
||||
if (initialized)
|
||||
return;
|
||||
|
||||
//Read only
|
||||
RAW_IPR_INTID, // interrupt ID register
|
||||
RAW_IPR_SL_RCV, // serial line receive register
|
||||
RAW_IPR_MM_STAT, // data MMU fault status register
|
||||
RAW_IPR_ITB_PTE_TEMP, // ITLB page table entry temp register
|
||||
RAW_IPR_DTB_PTE_TEMP, // DTLB page table entry temporary register
|
||||
memset(IprToMiscRegIndex, -1, MaxInternalProcRegs * sizeof(int));
|
||||
|
||||
RAW_IPR_ISR, // interrupt summary register
|
||||
RAW_IPR_ITB_TAG, // ITLB tag register
|
||||
RAW_IPR_ITB_PTE, // ITLB page table entry register
|
||||
RAW_IPR_ITB_ASN, // ITLB address space register
|
||||
RAW_IPR_ITB_IS, // ITLB invalidate select register
|
||||
RAW_IPR_SIRR, // software interrupt request register
|
||||
RAW_IPR_ASTRR, // asynchronous system trap request register
|
||||
RAW_IPR_ASTER, // asynchronous system trap enable register
|
||||
RAW_IPR_EXC_ADDR, // exception address register
|
||||
RAW_IPR_EXC_SUM, // exception summary register
|
||||
RAW_IPR_EXC_MASK, // exception mask register
|
||||
RAW_IPR_PAL_BASE, // PAL base address register
|
||||
RAW_IPR_ICM, // instruction current mode
|
||||
RAW_IPR_IPLR, // interrupt priority level register
|
||||
RAW_IPR_IFAULT_VA_FORM, // formatted faulting virtual addr register
|
||||
RAW_IPR_IVPTBR, // virtual page table base register
|
||||
RAW_IPR_ICSR, // instruction control and status register
|
||||
RAW_IPR_IC_PERR_STAT, // inst cache parity error status register
|
||||
RAW_IPR_PMCTR, // performance counter register
|
||||
|
||||
// PAL temporary registers...
|
||||
// register meanings gleaned from osfpal.s source code
|
||||
RAW_IPR_PALtemp0, // local scratch
|
||||
RAW_IPR_PALtemp1, // local scratch
|
||||
RAW_IPR_PALtemp2, // entUna
|
||||
RAW_IPR_PALtemp3, // CPU specific impure area pointer
|
||||
RAW_IPR_PALtemp4, // memory management temp
|
||||
RAW_IPR_PALtemp5, // memory management temp
|
||||
RAW_IPR_PALtemp6, // memory management temp
|
||||
RAW_IPR_PALtemp7, // entIF
|
||||
RAW_IPR_PALtemp8, // intmask
|
||||
RAW_IPR_PALtemp9, // entSys
|
||||
RAW_IPR_PALtemp10, // ??
|
||||
RAW_IPR_PALtemp11, // entInt
|
||||
RAW_IPR_PALtemp12, // entArith
|
||||
RAW_IPR_PALtemp13, // reserved for platform specific PAL
|
||||
RAW_IPR_PALtemp14, // reserved for platform specific PAL
|
||||
RAW_IPR_PALtemp15, // reserved for platform specific PAL
|
||||
RAW_IPR_PALtemp16, // scratch / whami<7:0> / mces<4:0>
|
||||
RAW_IPR_PALtemp17, // sysval
|
||||
RAW_IPR_PALtemp18, // usp
|
||||
RAW_IPR_PALtemp19, // ksp
|
||||
RAW_IPR_PALtemp20, // PTBR
|
||||
RAW_IPR_PALtemp21, // entMM
|
||||
RAW_IPR_PALtemp22, // kgp
|
||||
RAW_IPR_PALtemp23, // PCBB
|
||||
|
||||
RAW_IPR_DTB_ASN, // DTLB address space number register
|
||||
RAW_IPR_DTB_CM, // DTLB current mode register
|
||||
RAW_IPR_DTB_TAG, // DTLB tag register
|
||||
RAW_IPR_DTB_PTE, // DTLB page table entry register
|
||||
|
||||
RAW_IPR_VA, // fault virtual address register
|
||||
RAW_IPR_VA_FORM, // formatted virtual address register
|
||||
RAW_IPR_MVPTBR, // MTU virtual page table base register
|
||||
RAW_IPR_DTB_IS, // DTLB invalidate single register
|
||||
RAW_IPR_CC, // cycle counter register
|
||||
RAW_IPR_CC_CTL, // cycle counter control register
|
||||
RAW_IPR_MCSR, // MTU control register
|
||||
|
||||
RAW_IPR_DC_PERR_STAT, // Dcache parity error status register
|
||||
RAW_IPR_DC_TEST_CTL, // Dcache test tag control register
|
||||
RAW_IPR_DC_TEST_TAG, // Dcache test tag register
|
||||
RAW_IPR_DC_TEST_TAG_TEMP, // Dcache test tag temporary register
|
||||
RAW_IPR_DC_MODE, // Dcache mode register
|
||||
RAW_IPR_MAF_MODE // miss address file mode register
|
||||
};
|
||||
|
||||
int IprToMiscRegIndex[MaxInternalProcRegs];
|
||||
|
||||
void initializeIprTable()
|
||||
{
|
||||
static bool initialized = false;
|
||||
if(initialized)
|
||||
return;
|
||||
|
||||
memset(IprToMiscRegIndex, -1, MaxInternalProcRegs * sizeof(int));
|
||||
|
||||
for(int x = 0; x < NumInternalProcRegs; x++)
|
||||
IprToMiscRegIndex[MiscRegIndexToIpr[x]] = x;
|
||||
}
|
||||
for (int x = 0; x < NumInternalProcRegs; x++)
|
||||
IprToMiscRegIndex[MiscRegIndexToIpr[x]] = x;
|
||||
}
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
|
|
|
@ -32,206 +32,208 @@
|
|||
#ifndef __ARCH_ALPHA_IPR_HH__
|
||||
#define __ARCH_ALPHA_IPR_HH__
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Internal Processor Reigsters
|
||||
//
|
||||
enum md_ipr_names {
|
||||
RAW_IPR_ISR = 0x100, // interrupt summary
|
||||
RAW_IPR_ITB_TAG = 0x101, // ITLB tag
|
||||
RAW_IPR_ITB_PTE = 0x102, // ITLB page table entry
|
||||
RAW_IPR_ITB_ASN = 0x103, // ITLB address space
|
||||
RAW_IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp
|
||||
RAW_IPR_ITB_IA = 0x105, // ITLB invalidate all
|
||||
RAW_IPR_ITB_IAP = 0x106, // ITLB invalidate all process
|
||||
RAW_IPR_ITB_IS = 0x107, // ITLB invalidate select
|
||||
RAW_IPR_SIRR = 0x108, // software interrupt request
|
||||
RAW_IPR_ASTRR = 0x109, // asynchronous system trap request
|
||||
RAW_IPR_ASTER = 0x10a, // asynchronous system trap enable
|
||||
RAW_IPR_EXC_ADDR = 0x10b, // exception address
|
||||
RAW_IPR_EXC_SUM = 0x10c, // exception summary
|
||||
RAW_IPR_EXC_MASK = 0x10d, // exception mask
|
||||
RAW_IPR_PAL_BASE = 0x10e, // PAL base address
|
||||
RAW_IPR_ICM = 0x10f, // instruction current mode
|
||||
RAW_IPR_IPLR = 0x110, // interrupt priority level
|
||||
RAW_IPR_INTID = 0x111, // interrupt ID
|
||||
RAW_IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr
|
||||
RAW_IPR_IVPTBR = 0x113, // virtual page table base
|
||||
RAW_IPR_HWINT_CLR = 0x115, // H/W interrupt clear
|
||||
RAW_IPR_SL_XMIT = 0x116, // serial line transmit
|
||||
RAW_IPR_SL_RCV = 0x117, // serial line receive
|
||||
RAW_IPR_ICSR = 0x118, // instruction control and status
|
||||
RAW_IPR_IC_FLUSH = 0x119, // instruction cache flush control
|
||||
RAW_IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status
|
||||
RAW_IPR_PMCTR = 0x11c, // performance counter
|
||||
|
||||
// PAL temporary registers...
|
||||
// register meanings gleaned from osfpal.s source code
|
||||
RAW_IPR_PALtemp0 = 0x140, // local scratch
|
||||
RAW_IPR_PALtemp1 = 0x141, // local scratch
|
||||
RAW_IPR_PALtemp2 = 0x142, // entUna
|
||||
RAW_IPR_PALtemp3 = 0x143, // CPU specific impure area pointer
|
||||
RAW_IPR_PALtemp4 = 0x144, // memory management temp
|
||||
RAW_IPR_PALtemp5 = 0x145, // memory management temp
|
||||
RAW_IPR_PALtemp6 = 0x146, // memory management temp
|
||||
RAW_IPR_PALtemp7 = 0x147, // entIF
|
||||
RAW_IPR_PALtemp8 = 0x148, // intmask
|
||||
RAW_IPR_PALtemp9 = 0x149, // entSys
|
||||
RAW_IPR_PALtemp10 = 0x14a, // ??
|
||||
RAW_IPR_PALtemp11 = 0x14b, // entInt
|
||||
RAW_IPR_PALtemp12 = 0x14c, // entArith
|
||||
RAW_IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL
|
||||
RAW_IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL
|
||||
RAW_IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL
|
||||
RAW_IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0>
|
||||
RAW_IPR_PALtemp17 = 0x151, // sysval
|
||||
RAW_IPR_PALtemp18 = 0x152, // usp
|
||||
RAW_IPR_PALtemp19 = 0x153, // ksp
|
||||
RAW_IPR_PALtemp20 = 0x154, // PTBR
|
||||
RAW_IPR_PALtemp21 = 0x155, // entMM
|
||||
RAW_IPR_PALtemp22 = 0x156, // kgp
|
||||
RAW_IPR_PALtemp23 = 0x157, // PCBB
|
||||
|
||||
RAW_IPR_DTB_ASN = 0x200, // DTLB address space number
|
||||
RAW_IPR_DTB_CM = 0x201, // DTLB current mode
|
||||
RAW_IPR_DTB_TAG = 0x202, // DTLB tag
|
||||
RAW_IPR_DTB_PTE = 0x203, // DTLB page table entry
|
||||
RAW_IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary
|
||||
|
||||
RAW_IPR_MM_STAT = 0x205, // data MMU fault status
|
||||
RAW_IPR_VA = 0x206, // fault virtual address
|
||||
RAW_IPR_VA_FORM = 0x207, // formatted virtual address
|
||||
RAW_IPR_MVPTBR = 0x208, // MTU virtual page table base
|
||||
RAW_IPR_DTB_IAP = 0x209, // DTLB invalidate all process
|
||||
RAW_IPR_DTB_IA = 0x20a, // DTLB invalidate all
|
||||
RAW_IPR_DTB_IS = 0x20b, // DTLB invalidate single
|
||||
RAW_IPR_ALT_MODE = 0x20c, // alternate mode
|
||||
RAW_IPR_CC = 0x20d, // cycle counter
|
||||
RAW_IPR_CC_CTL = 0x20e, // cycle counter control
|
||||
RAW_IPR_MCSR = 0x20f, // MTU control
|
||||
|
||||
RAW_IPR_DC_FLUSH = 0x210,
|
||||
RAW_IPR_DC_PERR_STAT = 0x212, // Dcache parity error status
|
||||
RAW_IPR_DC_TEST_CTL = 0x213, // Dcache test tag control
|
||||
RAW_IPR_DC_TEST_TAG = 0x214, // Dcache test tag
|
||||
RAW_IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary
|
||||
RAW_IPR_DC_MODE = 0x216, // Dcache mode
|
||||
RAW_IPR_MAF_MODE = 0x217, // miss address file mode
|
||||
|
||||
MaxInternalProcRegs // number of IPRs
|
||||
};
|
||||
|
||||
enum MiscRegIpr
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Internal Processor Reigsters
|
||||
//
|
||||
enum md_ipr_names
|
||||
{
|
||||
RAW_IPR_ISR = 0x100, // interrupt summary register
|
||||
RAW_IPR_ITB_TAG = 0x101, // ITLB tag register
|
||||
RAW_IPR_ITB_PTE = 0x102, // ITLB page table entry register
|
||||
RAW_IPR_ITB_ASN = 0x103, // ITLB address space register
|
||||
RAW_IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register
|
||||
RAW_IPR_ITB_IA = 0x105, // ITLB invalidate all register
|
||||
RAW_IPR_ITB_IAP = 0x106, // ITLB invalidate all process register
|
||||
RAW_IPR_ITB_IS = 0x107, // ITLB invalidate select register
|
||||
RAW_IPR_SIRR = 0x108, // software interrupt request register
|
||||
RAW_IPR_ASTRR = 0x109, // asynchronous system trap request register
|
||||
RAW_IPR_ASTER = 0x10a, // asynchronous system trap enable register
|
||||
RAW_IPR_EXC_ADDR = 0x10b, // exception address register
|
||||
RAW_IPR_EXC_SUM = 0x10c, // exception summary register
|
||||
RAW_IPR_EXC_MASK = 0x10d, // exception mask register
|
||||
RAW_IPR_PAL_BASE = 0x10e, // PAL base address register
|
||||
RAW_IPR_ICM = 0x10f, // instruction current mode
|
||||
RAW_IPR_IPLR = 0x110, // interrupt priority level register
|
||||
RAW_IPR_INTID = 0x111, // interrupt ID register
|
||||
RAW_IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register
|
||||
RAW_IPR_IVPTBR = 0x113, // virtual page table base register
|
||||
RAW_IPR_HWINT_CLR = 0x115, // H/W interrupt clear register
|
||||
RAW_IPR_SL_XMIT = 0x116, // serial line transmit register
|
||||
RAW_IPR_SL_RCV = 0x117, // serial line receive register
|
||||
RAW_IPR_ICSR = 0x118, // instruction control and status register
|
||||
RAW_IPR_IC_FLUSH = 0x119, // instruction cache flush control
|
||||
RAW_IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register
|
||||
RAW_IPR_PMCTR = 0x11c, // performance counter register
|
||||
//Write only
|
||||
MinWriteOnlyIpr,
|
||||
IPR_HWINT_CLR = MinWriteOnlyIpr,
|
||||
IPR_SL_XMIT,
|
||||
IPR_DC_FLUSH,
|
||||
IPR_IC_FLUSH,
|
||||
IPR_ALT_MODE,
|
||||
IPR_DTB_IA,
|
||||
IPR_DTB_IAP,
|
||||
IPR_ITB_IA,
|
||||
MaxWriteOnlyIpr,
|
||||
IPR_ITB_IAP = MaxWriteOnlyIpr,
|
||||
|
||||
// PAL temporary registers...
|
||||
// register meanings gleaned from osfpal.s source code
|
||||
RAW_IPR_PALtemp0 = 0x140, // local scratch
|
||||
RAW_IPR_PALtemp1 = 0x141, // local scratch
|
||||
RAW_IPR_PALtemp2 = 0x142, // entUna
|
||||
RAW_IPR_PALtemp3 = 0x143, // CPU specific impure area pointer
|
||||
RAW_IPR_PALtemp4 = 0x144, // memory management temp
|
||||
RAW_IPR_PALtemp5 = 0x145, // memory management temp
|
||||
RAW_IPR_PALtemp6 = 0x146, // memory management temp
|
||||
RAW_IPR_PALtemp7 = 0x147, // entIF
|
||||
RAW_IPR_PALtemp8 = 0x148, // intmask
|
||||
RAW_IPR_PALtemp9 = 0x149, // entSys
|
||||
RAW_IPR_PALtemp10 = 0x14a, // ??
|
||||
RAW_IPR_PALtemp11 = 0x14b, // entInt
|
||||
RAW_IPR_PALtemp12 = 0x14c, // entArith
|
||||
RAW_IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL
|
||||
RAW_IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL
|
||||
RAW_IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL
|
||||
RAW_IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0>
|
||||
RAW_IPR_PALtemp17 = 0x151, // sysval
|
||||
RAW_IPR_PALtemp18 = 0x152, // usp
|
||||
RAW_IPR_PALtemp19 = 0x153, // ksp
|
||||
RAW_IPR_PALtemp20 = 0x154, // PTBR
|
||||
RAW_IPR_PALtemp21 = 0x155, // entMM
|
||||
RAW_IPR_PALtemp22 = 0x156, // kgp
|
||||
RAW_IPR_PALtemp23 = 0x157, // PCBB
|
||||
//Read only
|
||||
MinReadOnlyIpr,
|
||||
IPR_INTID = MinReadOnlyIpr,
|
||||
IPR_SL_RCV,
|
||||
IPR_MM_STAT,
|
||||
IPR_ITB_PTE_TEMP,
|
||||
MaxReadOnlyIpr,
|
||||
IPR_DTB_PTE_TEMP = MaxReadOnlyIpr,
|
||||
|
||||
RAW_IPR_DTB_ASN = 0x200, // DTLB address space number register
|
||||
RAW_IPR_DTB_CM = 0x201, // DTLB current mode register
|
||||
RAW_IPR_DTB_TAG = 0x202, // DTLB tag register
|
||||
RAW_IPR_DTB_PTE = 0x203, // DTLB page table entry register
|
||||
RAW_IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register
|
||||
IPR_ISR,
|
||||
IPR_ITB_TAG,
|
||||
IPR_ITB_PTE,
|
||||
IPR_ITB_ASN,
|
||||
IPR_ITB_IS,
|
||||
IPR_SIRR,
|
||||
IPR_ASTRR,
|
||||
IPR_ASTER,
|
||||
IPR_EXC_ADDR,
|
||||
IPR_EXC_SUM,
|
||||
IPR_EXC_MASK,
|
||||
IPR_PAL_BASE,
|
||||
IPR_ICM,
|
||||
IPR_IPLR,
|
||||
IPR_IFAULT_VA_FORM,
|
||||
IPR_IVPTBR,
|
||||
IPR_ICSR,
|
||||
IPR_IC_PERR_STAT,
|
||||
IPR_PMCTR,
|
||||
|
||||
RAW_IPR_MM_STAT = 0x205, // data MMU fault status register
|
||||
RAW_IPR_VA = 0x206, // fault virtual address register
|
||||
RAW_IPR_VA_FORM = 0x207, // formatted virtual address register
|
||||
RAW_IPR_MVPTBR = 0x208, // MTU virtual page table base register
|
||||
RAW_IPR_DTB_IAP = 0x209, // DTLB invalidate all process register
|
||||
RAW_IPR_DTB_IA = 0x20a, // DTLB invalidate all register
|
||||
RAW_IPR_DTB_IS = 0x20b, // DTLB invalidate single register
|
||||
RAW_IPR_ALT_MODE = 0x20c, // alternate mode register
|
||||
RAW_IPR_CC = 0x20d, // cycle counter register
|
||||
RAW_IPR_CC_CTL = 0x20e, // cycle counter control register
|
||||
RAW_IPR_MCSR = 0x20f, // MTU control register
|
||||
// PAL temporary registers...
|
||||
// register meanings gleaned from osfpal.s source code
|
||||
IPR_PALtemp0,
|
||||
IPR_PALtemp1,
|
||||
IPR_PALtemp2,
|
||||
IPR_PALtemp3,
|
||||
IPR_PALtemp4,
|
||||
IPR_PALtemp5,
|
||||
IPR_PALtemp6,
|
||||
IPR_PALtemp7,
|
||||
IPR_PALtemp8,
|
||||
IPR_PALtemp9,
|
||||
IPR_PALtemp10,
|
||||
IPR_PALtemp11,
|
||||
IPR_PALtemp12,
|
||||
IPR_PALtemp13,
|
||||
IPR_PALtemp14,
|
||||
IPR_PALtemp15,
|
||||
IPR_PALtemp16,
|
||||
IPR_PALtemp17,
|
||||
IPR_PALtemp18,
|
||||
IPR_PALtemp19,
|
||||
IPR_PALtemp20,
|
||||
IPR_PALtemp21,
|
||||
IPR_PALtemp22,
|
||||
IPR_PALtemp23,
|
||||
|
||||
RAW_IPR_DC_FLUSH = 0x210,
|
||||
RAW_IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register
|
||||
RAW_IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register
|
||||
RAW_IPR_DC_TEST_TAG = 0x214, // Dcache test tag register
|
||||
RAW_IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary register
|
||||
RAW_IPR_DC_MODE = 0x216, // Dcache mode register
|
||||
RAW_IPR_MAF_MODE = 0x217, // miss address file mode register
|
||||
IPR_DTB_ASN,
|
||||
IPR_DTB_CM,
|
||||
IPR_DTB_TAG,
|
||||
IPR_DTB_PTE,
|
||||
|
||||
MaxInternalProcRegs // number of IPR registers
|
||||
};
|
||||
IPR_VA,
|
||||
IPR_VA_FORM,
|
||||
IPR_MVPTBR,
|
||||
IPR_DTB_IS,
|
||||
IPR_CC,
|
||||
IPR_CC_CTL,
|
||||
IPR_MCSR,
|
||||
|
||||
enum MiscRegIpr
|
||||
{
|
||||
//Write only
|
||||
MinWriteOnlyIpr,
|
||||
IPR_HWINT_CLR = MinWriteOnlyIpr,
|
||||
IPR_SL_XMIT,
|
||||
IPR_DC_FLUSH,
|
||||
IPR_IC_FLUSH,
|
||||
IPR_ALT_MODE,
|
||||
IPR_DTB_IA,
|
||||
IPR_DTB_IAP,
|
||||
IPR_ITB_IA,
|
||||
MaxWriteOnlyIpr,
|
||||
IPR_ITB_IAP = MaxWriteOnlyIpr,
|
||||
IPR_DC_PERR_STAT,
|
||||
IPR_DC_TEST_CTL,
|
||||
IPR_DC_TEST_TAG,
|
||||
IPR_DC_TEST_TAG_TEMP,
|
||||
IPR_DC_MODE,
|
||||
IPR_MAF_MODE,
|
||||
|
||||
//Read only
|
||||
MinReadOnlyIpr,
|
||||
IPR_INTID = MinReadOnlyIpr,
|
||||
IPR_SL_RCV,
|
||||
IPR_MM_STAT,
|
||||
IPR_ITB_PTE_TEMP,
|
||||
MaxReadOnlyIpr,
|
||||
IPR_DTB_PTE_TEMP = MaxReadOnlyIpr,
|
||||
NumInternalProcRegs // number of IPR registers
|
||||
};
|
||||
|
||||
IPR_ISR,
|
||||
IPR_ITB_TAG,
|
||||
IPR_ITB_PTE,
|
||||
IPR_ITB_ASN,
|
||||
IPR_ITB_IS,
|
||||
IPR_SIRR,
|
||||
IPR_ASTRR,
|
||||
IPR_ASTER,
|
||||
IPR_EXC_ADDR,
|
||||
IPR_EXC_SUM,
|
||||
IPR_EXC_MASK,
|
||||
IPR_PAL_BASE,
|
||||
IPR_ICM,
|
||||
IPR_IPLR,
|
||||
IPR_IFAULT_VA_FORM,
|
||||
IPR_IVPTBR,
|
||||
IPR_ICSR,
|
||||
IPR_IC_PERR_STAT,
|
||||
IPR_PMCTR,
|
||||
|
||||
// PAL temporary registers...
|
||||
// register meanings gleaned from osfpal.s source code
|
||||
IPR_PALtemp0,
|
||||
IPR_PALtemp1,
|
||||
IPR_PALtemp2,
|
||||
IPR_PALtemp3,
|
||||
IPR_PALtemp4,
|
||||
IPR_PALtemp5,
|
||||
IPR_PALtemp6,
|
||||
IPR_PALtemp7,
|
||||
IPR_PALtemp8,
|
||||
IPR_PALtemp9,
|
||||
IPR_PALtemp10,
|
||||
IPR_PALtemp11,
|
||||
IPR_PALtemp12,
|
||||
IPR_PALtemp13,
|
||||
IPR_PALtemp14,
|
||||
IPR_PALtemp15,
|
||||
IPR_PALtemp16,
|
||||
IPR_PALtemp17,
|
||||
IPR_PALtemp18,
|
||||
IPR_PALtemp19,
|
||||
IPR_PALtemp20,
|
||||
IPR_PALtemp21,
|
||||
IPR_PALtemp22,
|
||||
IPR_PALtemp23,
|
||||
|
||||
IPR_DTB_ASN,
|
||||
IPR_DTB_CM,
|
||||
IPR_DTB_TAG,
|
||||
IPR_DTB_PTE,
|
||||
|
||||
IPR_VA,
|
||||
IPR_VA_FORM,
|
||||
IPR_MVPTBR,
|
||||
IPR_DTB_IS,
|
||||
IPR_CC,
|
||||
IPR_CC_CTL,
|
||||
IPR_MCSR,
|
||||
|
||||
IPR_DC_PERR_STAT,
|
||||
IPR_DC_TEST_CTL,
|
||||
IPR_DC_TEST_TAG,
|
||||
IPR_DC_TEST_TAG_TEMP,
|
||||
IPR_DC_MODE,
|
||||
IPR_MAF_MODE,
|
||||
|
||||
NumInternalProcRegs // number of IPR registers
|
||||
};
|
||||
|
||||
inline bool IprIsWritable(int index)
|
||||
{
|
||||
return index < MinReadOnlyIpr || index > MaxReadOnlyIpr;
|
||||
}
|
||||
|
||||
inline bool IprIsReadable(int index)
|
||||
{
|
||||
return index < MinWriteOnlyIpr || index > MaxWriteOnlyIpr;
|
||||
}
|
||||
|
||||
extern md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs];
|
||||
extern int IprToMiscRegIndex[MaxInternalProcRegs];
|
||||
|
||||
void initializeIprTable();
|
||||
inline bool
|
||||
IprIsWritable(int index)
|
||||
{
|
||||
return index < MinReadOnlyIpr || index > MaxReadOnlyIpr;
|
||||
}
|
||||
|
||||
#endif
|
||||
inline bool
|
||||
IprIsReadable(int index)
|
||||
{
|
||||
return index < MinWriteOnlyIpr || index > MaxWriteOnlyIpr;
|
||||
}
|
||||
|
||||
extern md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs];
|
||||
extern int IprToMiscRegIndex[MaxInternalProcRegs];
|
||||
|
||||
void initializeIprTable();
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ARCH_ALPHA_IPR_HH__
|
||||
|
|
|
@ -42,142 +42,137 @@ namespace LittleEndianGuest {}
|
|||
|
||||
class StaticInstPtr;
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
using namespace LittleEndianGuest;
|
||||
using AlphaISAInst::MaxInstSrcRegs;
|
||||
using AlphaISAInst::MaxInstDestRegs;
|
||||
namespace AlphaISA {
|
||||
|
||||
// These enumerate all the registers for dependence tracking.
|
||||
enum DependenceTags {
|
||||
// 0..31 are the integer regs 0..31
|
||||
// 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
|
||||
FP_Base_DepTag = 40,
|
||||
Ctrl_Base_DepTag = 72
|
||||
};
|
||||
|
||||
StaticInstPtr decodeInst(ExtMachInst);
|
||||
|
||||
// Alpha Does NOT have a delay slot
|
||||
#define ISA_HAS_DELAY_SLOT 0
|
||||
|
||||
const Addr PageShift = 13;
|
||||
const Addr PageBytes = ULL(1) << PageShift;
|
||||
const Addr PageMask = ~(PageBytes - 1);
|
||||
const Addr PageOffset = PageBytes - 1;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Translation stuff
|
||||
//
|
||||
|
||||
const Addr PteShift = 3;
|
||||
const Addr NPtePageShift = PageShift - PteShift;
|
||||
const Addr NPtePage = ULL(1) << NPtePageShift;
|
||||
const Addr PteMask = NPtePage - 1;
|
||||
|
||||
// User Virtual
|
||||
const Addr USegBase = ULL(0x0);
|
||||
const Addr USegEnd = ULL(0x000003ffffffffff);
|
||||
|
||||
// Kernel Direct Mapped
|
||||
const Addr K0SegBase = ULL(0xfffffc0000000000);
|
||||
const Addr K0SegEnd = ULL(0xfffffdffffffffff);
|
||||
|
||||
// Kernel Virtual
|
||||
const Addr K1SegBase = ULL(0xfffffe0000000000);
|
||||
const Addr K1SegEnd = ULL(0xffffffffffffffff);
|
||||
|
||||
// For loading... XXX This maybe could be USegEnd?? --ali
|
||||
const Addr LoadAddrMask = ULL(0xffffffffff);
|
||||
|
||||
#if FULL_SYSTEM
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Interrupt levels
|
||||
//
|
||||
enum InterruptLevels
|
||||
{
|
||||
INTLEVEL_SOFTWARE_MIN = 4,
|
||||
INTLEVEL_SOFTWARE_MAX = 19,
|
||||
|
||||
INTLEVEL_EXTERNAL_MIN = 20,
|
||||
INTLEVEL_EXTERNAL_MAX = 34,
|
||||
|
||||
INTLEVEL_IRQ0 = 20,
|
||||
INTLEVEL_IRQ1 = 21,
|
||||
INTINDEX_ETHERNET = 0,
|
||||
INTINDEX_SCSI = 1,
|
||||
INTLEVEL_IRQ2 = 22,
|
||||
INTLEVEL_IRQ3 = 23,
|
||||
|
||||
INTLEVEL_SERIAL = 33,
|
||||
|
||||
NumInterruptLevels = INTLEVEL_EXTERNAL_MAX
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// EV5 modes
|
||||
enum mode_type
|
||||
{
|
||||
mode_kernel = 0, // kernel
|
||||
mode_executive = 1, // executive (unused by unix)
|
||||
mode_supervisor = 2, // supervisor (unused by unix)
|
||||
mode_user = 3, // user mode
|
||||
mode_number // number of modes
|
||||
};
|
||||
|
||||
// Constants Related to the number of registers
|
||||
|
||||
const int NumIntArchRegs = 32;
|
||||
const int NumPALShadowRegs = 8;
|
||||
const int NumFloatArchRegs = 32;
|
||||
// @todo: Figure out what this number really should be.
|
||||
const int NumMiscArchRegs = 77;
|
||||
|
||||
const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
|
||||
const int NumFloatRegs = NumFloatArchRegs;
|
||||
const int NumMiscRegs = NumMiscArchRegs;
|
||||
|
||||
const int TotalNumRegs = NumIntRegs + NumFloatRegs +
|
||||
NumMiscRegs + NumInternalProcRegs;
|
||||
|
||||
const int TotalDataRegs = NumIntRegs + NumFloatRegs;
|
||||
|
||||
// semantically meaningful register indices
|
||||
const int ZeroReg = 31; // architecturally meaningful
|
||||
// the rest of these depend on the ABI
|
||||
const int StackPointerReg = 30;
|
||||
const int GlobalPointerReg = 29;
|
||||
const int ProcedureValueReg = 27;
|
||||
const int ReturnAddressReg = 26;
|
||||
const int ReturnValueReg = 0;
|
||||
const int FramePointerReg = 15;
|
||||
|
||||
const int ArgumentReg[] = {16, 17, 18, 19, 20, 21};
|
||||
const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
|
||||
|
||||
const int SyscallNumReg = ReturnValueReg;
|
||||
const int SyscallPseudoReturnReg = ArgumentReg[4];
|
||||
const int SyscallSuccessReg = 19;
|
||||
|
||||
const int LogVMPageSize = 13; // 8K bytes
|
||||
const int VMPageSize = (1 << LogVMPageSize);
|
||||
|
||||
const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
|
||||
|
||||
const int MachineBytes = 8;
|
||||
const int WordBytes = 4;
|
||||
const int HalfwordBytes = 2;
|
||||
const int ByteBytes = 1;
|
||||
|
||||
// return a no-op instruction... used for instruction fetch faults
|
||||
// Alpha UNOP (ldq_u r31,0(r0))
|
||||
const ExtMachInst NoopMachInst = 0x2ffe0000;
|
||||
using namespace LittleEndianGuest;
|
||||
using AlphaISAInst::MaxInstSrcRegs;
|
||||
using AlphaISAInst::MaxInstDestRegs;
|
||||
|
||||
// These enumerate all the registers for dependence tracking.
|
||||
enum DependenceTags {
|
||||
// 0..31 are the integer regs 0..31
|
||||
// 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
|
||||
FP_Base_DepTag = 40,
|
||||
Ctrl_Base_DepTag = 72
|
||||
};
|
||||
|
||||
StaticInstPtr decodeInst(ExtMachInst);
|
||||
|
||||
// Alpha Does NOT have a delay slot
|
||||
#define ISA_HAS_DELAY_SLOT 0
|
||||
|
||||
const Addr PageShift = 13;
|
||||
const Addr PageBytes = ULL(1) << PageShift;
|
||||
const Addr PageMask = ~(PageBytes - 1);
|
||||
const Addr PageOffset = PageBytes - 1;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Translation stuff
|
||||
//
|
||||
|
||||
const Addr PteShift = 3;
|
||||
const Addr NPtePageShift = PageShift - PteShift;
|
||||
const Addr NPtePage = ULL(1) << NPtePageShift;
|
||||
const Addr PteMask = NPtePage - 1;
|
||||
|
||||
// User Virtual
|
||||
const Addr USegBase = ULL(0x0);
|
||||
const Addr USegEnd = ULL(0x000003ffffffffff);
|
||||
|
||||
// Kernel Direct Mapped
|
||||
const Addr K0SegBase = ULL(0xfffffc0000000000);
|
||||
const Addr K0SegEnd = ULL(0xfffffdffffffffff);
|
||||
|
||||
// Kernel Virtual
|
||||
const Addr K1SegBase = ULL(0xfffffe0000000000);
|
||||
const Addr K1SegEnd = ULL(0xffffffffffffffff);
|
||||
|
||||
// For loading... XXX This maybe could be USegEnd?? --ali
|
||||
const Addr LoadAddrMask = ULL(0xffffffffff);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Interrupt levels
|
||||
//
|
||||
enum InterruptLevels
|
||||
{
|
||||
INTLEVEL_SOFTWARE_MIN = 4,
|
||||
INTLEVEL_SOFTWARE_MAX = 19,
|
||||
|
||||
INTLEVEL_EXTERNAL_MIN = 20,
|
||||
INTLEVEL_EXTERNAL_MAX = 34,
|
||||
|
||||
INTLEVEL_IRQ0 = 20,
|
||||
INTLEVEL_IRQ1 = 21,
|
||||
INTINDEX_ETHERNET = 0,
|
||||
INTINDEX_SCSI = 1,
|
||||
INTLEVEL_IRQ2 = 22,
|
||||
INTLEVEL_IRQ3 = 23,
|
||||
|
||||
INTLEVEL_SERIAL = 33,
|
||||
|
||||
NumInterruptLevels = INTLEVEL_EXTERNAL_MAX
|
||||
};
|
||||
|
||||
// EV5 modes
|
||||
enum mode_type
|
||||
{
|
||||
mode_kernel = 0, // kernel
|
||||
mode_executive = 1, // executive (unused by unix)
|
||||
mode_supervisor = 2, // supervisor (unused by unix)
|
||||
mode_user = 3, // user mode
|
||||
mode_number // number of modes
|
||||
};
|
||||
|
||||
// Constants Related to the number of registers
|
||||
|
||||
const int NumIntArchRegs = 32;
|
||||
const int NumPALShadowRegs = 8;
|
||||
const int NumFloatArchRegs = 32;
|
||||
// @todo: Figure out what this number really should be.
|
||||
const int NumMiscArchRegs = 77;
|
||||
|
||||
const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
|
||||
const int NumFloatRegs = NumFloatArchRegs;
|
||||
const int NumMiscRegs = NumMiscArchRegs;
|
||||
|
||||
const int TotalNumRegs =
|
||||
NumIntRegs + NumFloatRegs + NumMiscRegs + NumInternalProcRegs;
|
||||
|
||||
const int TotalDataRegs = NumIntRegs + NumFloatRegs;
|
||||
|
||||
// semantically meaningful register indices
|
||||
const int ZeroReg = 31; // architecturally meaningful
|
||||
// the rest of these depend on the ABI
|
||||
const int StackPointerReg = 30;
|
||||
const int GlobalPointerReg = 29;
|
||||
const int ProcedureValueReg = 27;
|
||||
const int ReturnAddressReg = 26;
|
||||
const int ReturnValueReg = 0;
|
||||
const int FramePointerReg = 15;
|
||||
|
||||
const int ArgumentReg[] = {16, 17, 18, 19, 20, 21};
|
||||
const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int);
|
||||
|
||||
const int SyscallNumReg = ReturnValueReg;
|
||||
const int SyscallPseudoReturnReg = ArgumentReg[4];
|
||||
const int SyscallSuccessReg = 19;
|
||||
|
||||
const int LogVMPageSize = 13; // 8K bytes
|
||||
const int VMPageSize = (1 << LogVMPageSize);
|
||||
|
||||
const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
|
||||
|
||||
const int MachineBytes = 8;
|
||||
const int WordBytes = 4;
|
||||
const int HalfwordBytes = 2;
|
||||
const int ByteBytes = 1;
|
||||
|
||||
// return a no-op instruction... used for instruction fetch faults
|
||||
// Alpha UNOP (ldq_u r31,0(r0))
|
||||
const ExtMachInst NoopMachInst = 0x2ffe0000;
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ARCH_ALPHA_ISA_TRAITS_HH__
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
* Authors: Korey Sewell
|
||||
*/
|
||||
|
||||
#include "arch/alpha/linux/linux.hh"
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "arch/alpha/linux/linux.hh"
|
||||
|
||||
// open(2) flags translation table
|
||||
OpenFlagTransTable AlphaLinux::openFlagTable[] = {
|
||||
#ifdef _MSC_VER
|
||||
|
@ -68,7 +68,4 @@ OpenFlagTransTable AlphaLinux::openFlagTable[] = {
|
|||
};
|
||||
|
||||
const int AlphaLinux::NUM_OPEN_FLAGS =
|
||||
(sizeof(AlphaLinux::openFlagTable)/sizeof(AlphaLinux::openFlagTable[0]));
|
||||
|
||||
|
||||
|
||||
(sizeof(AlphaLinux::openFlagTable)/sizeof(AlphaLinux::openFlagTable[0]));
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
* Authors: Korey Sewell
|
||||
*/
|
||||
|
||||
#ifndef __ALPHA_ALPHA_LINUX_HH
|
||||
#define __ALPHA_ALPHA_LINUX_HH
|
||||
#ifndef __ALPHA_ALPHA_LINUX_LINUX_HH__
|
||||
#define __ALPHA_ALPHA_LINUX_LINUX_HH__
|
||||
|
||||
#include "kern/linux/linux.hh"
|
||||
|
||||
|
@ -72,13 +72,13 @@ class AlphaLinux : public Linux
|
|||
|
||||
//@{
|
||||
/// For getsysinfo().
|
||||
static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
|
||||
static const unsigned GSI_CPU_INFO = 59; //!< CPU information
|
||||
static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
|
||||
static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine
|
||||
static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
|
||||
static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB
|
||||
static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
|
||||
static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
|
||||
static const unsigned GSI_CPU_INFO = 59; //!< CPU information
|
||||
static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
|
||||
static const unsigned GSI_MAX_CPU = 30; //!< max # CPUs on machine
|
||||
static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
|
||||
static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB
|
||||
static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
|
||||
static const unsigned GSI_IEEE_FP_CONTROL = 45;
|
||||
//@}
|
||||
|
||||
|
@ -127,4 +127,4 @@ class AlphaLinux : public Linux
|
|||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // __ALPHA_ALPHA_LINUX_LINUX_HH__
|
||||
|
|
|
@ -43,8 +43,6 @@
|
|||
using namespace std;
|
||||
using namespace AlphaISA;
|
||||
|
||||
|
||||
|
||||
/// Target uname() handler.
|
||||
static SyscallReturn
|
||||
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
|
|
|
@ -51,4 +51,5 @@ class AlphaLinuxProcess : public AlphaLiveProcess
|
|||
};
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ALPHA_LINUX_PROCESS_HH__
|
||||
|
|
|
@ -157,7 +157,6 @@ LinuxAlphaSystem::~LinuxAlphaSystem()
|
|||
delete printThreadEvent;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LinuxAlphaSystem::setDelayLoop(ThreadContext *tc)
|
||||
{
|
||||
|
@ -172,7 +171,6 @@ LinuxAlphaSystem::setDelayLoop(ThreadContext *tc)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LinuxAlphaSystem::SkipDelayLoopEvent::process(ThreadContext *tc)
|
||||
{
|
||||
|
|
|
@ -54,23 +54,20 @@ using namespace Linux;
|
|||
class LinuxAlphaSystem : public AlphaSystem
|
||||
{
|
||||
private:
|
||||
class SkipDelayLoopEvent : public SkipFuncEvent
|
||||
struct SkipDelayLoopEvent : public SkipFuncEvent
|
||||
{
|
||||
public:
|
||||
SkipDelayLoopEvent(PCEventQueue *q, const std::string &desc, Addr addr)
|
||||
: SkipFuncEvent(q, desc, addr) {}
|
||||
virtual void process(ThreadContext *tc);
|
||||
};
|
||||
|
||||
class PrintThreadInfo : public PCEvent
|
||||
struct PrintThreadInfo : public PCEvent
|
||||
{
|
||||
public:
|
||||
PrintThreadInfo(PCEventQueue *q, const std::string &desc, Addr addr)
|
||||
: PCEvent(q, desc, addr) {}
|
||||
virtual void process(ThreadContext *tc);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Addresses defining where the kernel bootloader places various
|
||||
* elements. Details found in include/asm-alpha/system.h
|
||||
|
|
|
@ -147,6 +147,6 @@ class ThreadInfo
|
|||
}
|
||||
};
|
||||
|
||||
/* namespace Linux */ }
|
||||
} // namespace Linux
|
||||
|
||||
#endif // __ARCH_ALPHA_LINUX_LINUX_THREADINFO_HH__
|
||||
|
|
|
@ -49,9 +49,8 @@
|
|||
#include "base/misc.hh"
|
||||
#include "mem/request.hh"
|
||||
|
||||
namespace AlphaISA {
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
template <class XC>
|
||||
inline void
|
||||
handleLockedRead(XC *xc, Request *req)
|
||||
|
@ -99,7 +98,6 @@ handleLockedWrite(XC *xc, Request *req)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif
|
||||
#endif // __ARCH_ALPHA_LOCKED_MEM_HH__
|
||||
|
|
|
@ -33,118 +33,116 @@
|
|||
#include "arch/alpha/miscregfile.hh"
|
||||
#include "base/misc.hh"
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
void
|
||||
MiscRegFile::serialize(std::ostream &os)
|
||||
{
|
||||
|
||||
void
|
||||
MiscRegFile::serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_SCALAR(fpcr);
|
||||
SERIALIZE_SCALAR(uniq);
|
||||
SERIALIZE_SCALAR(lock_flag);
|
||||
SERIALIZE_SCALAR(lock_addr);
|
||||
SERIALIZE_ARRAY(ipr, NumInternalProcRegs);
|
||||
}
|
||||
|
||||
void
|
||||
MiscRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_SCALAR(fpcr);
|
||||
UNSERIALIZE_SCALAR(uniq);
|
||||
UNSERIALIZE_SCALAR(lock_flag);
|
||||
UNSERIALIZE_SCALAR(lock_addr);
|
||||
UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
|
||||
}
|
||||
|
||||
MiscReg
|
||||
MiscRegFile::readRegNoEffect(int misc_reg)
|
||||
{
|
||||
switch(misc_reg) {
|
||||
case MISCREG_FPCR:
|
||||
return fpcr;
|
||||
case MISCREG_UNIQ:
|
||||
return uniq;
|
||||
case MISCREG_LOCKFLAG:
|
||||
return lock_flag;
|
||||
case MISCREG_LOCKADDR:
|
||||
return lock_addr;
|
||||
case MISCREG_INTR:
|
||||
return intr_flag;
|
||||
default:
|
||||
assert(misc_reg < NumInternalProcRegs);
|
||||
return ipr[misc_reg];
|
||||
}
|
||||
}
|
||||
|
||||
MiscReg
|
||||
MiscRegFile::readReg(int misc_reg, ThreadContext *tc)
|
||||
{
|
||||
switch(misc_reg) {
|
||||
case MISCREG_FPCR:
|
||||
return fpcr;
|
||||
case MISCREG_UNIQ:
|
||||
return uniq;
|
||||
case MISCREG_LOCKFLAG:
|
||||
return lock_flag;
|
||||
case MISCREG_LOCKADDR:
|
||||
return lock_addr;
|
||||
case MISCREG_INTR:
|
||||
return intr_flag;
|
||||
default:
|
||||
return readIpr(misc_reg, tc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
switch(misc_reg) {
|
||||
case MISCREG_FPCR:
|
||||
fpcr = val;
|
||||
return;
|
||||
case MISCREG_UNIQ:
|
||||
uniq = val;
|
||||
return;
|
||||
case MISCREG_LOCKFLAG:
|
||||
lock_flag = val;
|
||||
return;
|
||||
case MISCREG_LOCKADDR:
|
||||
lock_addr = val;
|
||||
return;
|
||||
case MISCREG_INTR:
|
||||
intr_flag = val;
|
||||
return;
|
||||
default:
|
||||
assert(misc_reg < NumInternalProcRegs);
|
||||
ipr[misc_reg] = val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MiscRegFile::setReg(int misc_reg, const MiscReg &val,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
switch(misc_reg) {
|
||||
case MISCREG_FPCR:
|
||||
fpcr = val;
|
||||
return;
|
||||
case MISCREG_UNIQ:
|
||||
uniq = val;
|
||||
return;
|
||||
case MISCREG_LOCKFLAG:
|
||||
lock_flag = val;
|
||||
return;
|
||||
case MISCREG_LOCKADDR:
|
||||
lock_addr = val;
|
||||
return;
|
||||
case MISCREG_INTR:
|
||||
intr_flag = val;
|
||||
return;
|
||||
default:
|
||||
setIpr(misc_reg, val, tc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SERIALIZE_SCALAR(fpcr);
|
||||
SERIALIZE_SCALAR(uniq);
|
||||
SERIALIZE_SCALAR(lock_flag);
|
||||
SERIALIZE_SCALAR(lock_addr);
|
||||
SERIALIZE_ARRAY(ipr, NumInternalProcRegs);
|
||||
}
|
||||
|
||||
void
|
||||
MiscRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_SCALAR(fpcr);
|
||||
UNSERIALIZE_SCALAR(uniq);
|
||||
UNSERIALIZE_SCALAR(lock_flag);
|
||||
UNSERIALIZE_SCALAR(lock_addr);
|
||||
UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
|
||||
}
|
||||
|
||||
MiscReg
|
||||
MiscRegFile::readRegNoEffect(int misc_reg)
|
||||
{
|
||||
switch (misc_reg) {
|
||||
case MISCREG_FPCR:
|
||||
return fpcr;
|
||||
case MISCREG_UNIQ:
|
||||
return uniq;
|
||||
case MISCREG_LOCKFLAG:
|
||||
return lock_flag;
|
||||
case MISCREG_LOCKADDR:
|
||||
return lock_addr;
|
||||
case MISCREG_INTR:
|
||||
return intr_flag;
|
||||
default:
|
||||
assert(misc_reg < NumInternalProcRegs);
|
||||
return ipr[misc_reg];
|
||||
}
|
||||
}
|
||||
|
||||
MiscReg
|
||||
MiscRegFile::readReg(int misc_reg, ThreadContext *tc)
|
||||
{
|
||||
switch (misc_reg) {
|
||||
case MISCREG_FPCR:
|
||||
return fpcr;
|
||||
case MISCREG_UNIQ:
|
||||
return uniq;
|
||||
case MISCREG_LOCKFLAG:
|
||||
return lock_flag;
|
||||
case MISCREG_LOCKADDR:
|
||||
return lock_addr;
|
||||
case MISCREG_INTR:
|
||||
return intr_flag;
|
||||
default:
|
||||
return readIpr(misc_reg, tc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
switch (misc_reg) {
|
||||
case MISCREG_FPCR:
|
||||
fpcr = val;
|
||||
return;
|
||||
case MISCREG_UNIQ:
|
||||
uniq = val;
|
||||
return;
|
||||
case MISCREG_LOCKFLAG:
|
||||
lock_flag = val;
|
||||
return;
|
||||
case MISCREG_LOCKADDR:
|
||||
lock_addr = val;
|
||||
return;
|
||||
case MISCREG_INTR:
|
||||
intr_flag = val;
|
||||
return;
|
||||
default:
|
||||
assert(misc_reg < NumInternalProcRegs);
|
||||
ipr[misc_reg] = val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MiscRegFile::setReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
|
||||
{
|
||||
switch (misc_reg) {
|
||||
case MISCREG_FPCR:
|
||||
fpcr = val;
|
||||
return;
|
||||
case MISCREG_UNIQ:
|
||||
uniq = val;
|
||||
return;
|
||||
case MISCREG_LOCKFLAG:
|
||||
lock_flag = val;
|
||||
return;
|
||||
case MISCREG_LOCKADDR:
|
||||
lock_addr = val;
|
||||
return;
|
||||
case MISCREG_INTR:
|
||||
intr_flag = val;
|
||||
return;
|
||||
default:
|
||||
setIpr(misc_reg, val, tc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
|
|
@ -32,85 +32,85 @@
|
|||
#ifndef __ARCH_ALPHA_MISCREGFILE_HH__
|
||||
#define __ARCH_ALPHA_MISCREGFILE_HH__
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
#include "arch/alpha/ipr.hh"
|
||||
#include "arch/alpha/types.hh"
|
||||
#include "sim/host.hh"
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class Checkpoint;
|
||||
class ThreadContext;
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
enum MiscRegIndex
|
||||
{
|
||||
enum MiscRegIndex
|
||||
{
|
||||
MISCREG_FPCR = NumInternalProcRegs,
|
||||
MISCREG_UNIQ,
|
||||
MISCREG_LOCKFLAG,
|
||||
MISCREG_LOCKADDR,
|
||||
MISCREG_INTR
|
||||
};
|
||||
|
||||
static inline std::string getMiscRegName(RegIndex)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
class MiscRegFile {
|
||||
protected:
|
||||
uint64_t fpcr; // floating point condition codes
|
||||
uint64_t uniq; // process-unique register
|
||||
bool lock_flag; // lock flag for LL/SC
|
||||
Addr lock_addr; // lock address for LL/SC
|
||||
int intr_flag;
|
||||
|
||||
public:
|
||||
MiscRegFile()
|
||||
{
|
||||
initializeIprTable();
|
||||
}
|
||||
|
||||
MiscReg readRegNoEffect(int misc_reg);
|
||||
|
||||
MiscReg readReg(int misc_reg, ThreadContext *tc);
|
||||
|
||||
//These functions should be removed once the simplescalar cpu model
|
||||
//has been replaced.
|
||||
int getInstAsid();
|
||||
int getDataAsid();
|
||||
|
||||
void setRegNoEffect(int misc_reg, const MiscReg &val);
|
||||
|
||||
void setReg(int misc_reg, const MiscReg &val,
|
||||
ThreadContext *tc);
|
||||
|
||||
void clear()
|
||||
{
|
||||
fpcr = uniq = 0;
|
||||
lock_flag = 0;
|
||||
lock_addr = 0;
|
||||
intr_flag = 0;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
protected:
|
||||
typedef uint64_t InternalProcReg;
|
||||
|
||||
InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
|
||||
|
||||
private:
|
||||
InternalProcReg readIpr(int idx, ThreadContext *tc);
|
||||
|
||||
void setIpr(int idx, InternalProcReg val, ThreadContext *tc);
|
||||
friend class RegFile;
|
||||
};
|
||||
|
||||
void copyIprs(ThreadContext *src, ThreadContext *dest);
|
||||
MISCREG_FPCR = NumInternalProcRegs,
|
||||
MISCREG_UNIQ,
|
||||
MISCREG_LOCKFLAG,
|
||||
MISCREG_LOCKADDR,
|
||||
MISCREG_INTR
|
||||
};
|
||||
|
||||
static inline std::string
|
||||
getMiscRegName(RegIndex)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
#endif
|
||||
class MiscRegFile
|
||||
{
|
||||
public:
|
||||
friend class RegFile;
|
||||
typedef uint64_t InternalProcReg;
|
||||
|
||||
protected:
|
||||
uint64_t fpcr; // floating point condition codes
|
||||
uint64_t uniq; // process-unique register
|
||||
bool lock_flag; // lock flag for LL/SC
|
||||
Addr lock_addr; // lock address for LL/SC
|
||||
int intr_flag;
|
||||
|
||||
InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
|
||||
|
||||
protected:
|
||||
InternalProcReg readIpr(int idx, ThreadContext *tc);
|
||||
void setIpr(int idx, InternalProcReg val, ThreadContext *tc);
|
||||
|
||||
public:
|
||||
MiscRegFile()
|
||||
{
|
||||
initializeIprTable();
|
||||
}
|
||||
|
||||
// These functions should be removed once the simplescalar cpu
|
||||
// model has been replaced.
|
||||
int getInstAsid();
|
||||
int getDataAsid();
|
||||
|
||||
MiscReg readRegNoEffect(int misc_reg);
|
||||
MiscReg readReg(int misc_reg, ThreadContext *tc);
|
||||
|
||||
void setRegNoEffect(int misc_reg, const MiscReg &val);
|
||||
void setReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
|
||||
|
||||
void
|
||||
clear()
|
||||
{
|
||||
fpcr = 0;
|
||||
uniq = 0;
|
||||
lock_flag = 0;
|
||||
lock_addr = 0;
|
||||
intr_flag = 0;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
void copyIprs(ThreadContext *src, ThreadContext *dest);
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ARCH_ALPHA_MISCREGFILE_HH__
|
||||
|
|
|
@ -39,9 +39,8 @@
|
|||
|
||||
#include "mem/packet.hh"
|
||||
|
||||
namespace AlphaISA {
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
inline Tick
|
||||
handleIprRead(ThreadContext *xc, Packet *pkt)
|
||||
{
|
||||
|
@ -58,4 +57,4 @@ handleIprWrite(ThreadContext *xc, Packet *pkt)
|
|||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif
|
||||
#endif // __ARCH_ALPHA_MMAPED_IPR_HH__
|
||||
|
|
|
@ -30,8 +30,10 @@
|
|||
|
||||
#include "arch/alpha/osfpal.hh"
|
||||
|
||||
namespace {
|
||||
const char *strings[PAL::NumCodes] = {
|
||||
const char *
|
||||
PAL::name(int index)
|
||||
{
|
||||
static const char *strings[PAL::NumCodes] = {
|
||||
// Priviledged PAL instructions
|
||||
"halt", // 0x00
|
||||
"cflush", // 0x01
|
||||
|
@ -294,11 +296,7 @@ namespace {
|
|||
0 // 0xff
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
const char *
|
||||
PAL::name(int index)
|
||||
{
|
||||
if (index > NumCodes || index < 0)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
* Authors: Nathan Binkert
|
||||
*/
|
||||
|
||||
#ifndef __OSFPAL_HH__
|
||||
#define __OSFPAL_HH__
|
||||
#ifndef __ARCH_ALPHA_OSFPAL_HH__
|
||||
#define __ARCH_ALPHA_OSFPAL_HH__
|
||||
|
||||
struct PAL
|
||||
{
|
||||
|
@ -79,4 +79,4 @@ struct PAL
|
|||
static const char *name(int index);
|
||||
};
|
||||
|
||||
#endif // __OSFPAL_HH__
|
||||
#endif // __ARCH_ALPHA_OSFPAL_HH__
|
||||
|
|
|
@ -31,33 +31,34 @@
|
|||
#include "arch/alpha/pagetable.hh"
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
void
|
||||
TlbEntry::serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_SCALAR(tag);
|
||||
SERIALIZE_SCALAR(ppn);
|
||||
SERIALIZE_SCALAR(xre);
|
||||
SERIALIZE_SCALAR(xwe);
|
||||
SERIALIZE_SCALAR(asn);
|
||||
SERIALIZE_SCALAR(asma);
|
||||
SERIALIZE_SCALAR(fonr);
|
||||
SERIALIZE_SCALAR(fonw);
|
||||
SERIALIZE_SCALAR(valid);
|
||||
}
|
||||
namespace AlphaISA {
|
||||
|
||||
void
|
||||
TlbEntry::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_SCALAR(tag);
|
||||
UNSERIALIZE_SCALAR(ppn);
|
||||
UNSERIALIZE_SCALAR(xre);
|
||||
UNSERIALIZE_SCALAR(xwe);
|
||||
UNSERIALIZE_SCALAR(asn);
|
||||
UNSERIALIZE_SCALAR(asma);
|
||||
UNSERIALIZE_SCALAR(fonr);
|
||||
UNSERIALIZE_SCALAR(fonw);
|
||||
UNSERIALIZE_SCALAR(valid);
|
||||
}
|
||||
void
|
||||
TlbEntry::serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_SCALAR(tag);
|
||||
SERIALIZE_SCALAR(ppn);
|
||||
SERIALIZE_SCALAR(xre);
|
||||
SERIALIZE_SCALAR(xwe);
|
||||
SERIALIZE_SCALAR(asn);
|
||||
SERIALIZE_SCALAR(asma);
|
||||
SERIALIZE_SCALAR(fonr);
|
||||
SERIALIZE_SCALAR(fonw);
|
||||
SERIALIZE_SCALAR(valid);
|
||||
}
|
||||
|
||||
void
|
||||
TlbEntry::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_SCALAR(tag);
|
||||
UNSERIALIZE_SCALAR(ppn);
|
||||
UNSERIALIZE_SCALAR(xre);
|
||||
UNSERIALIZE_SCALAR(xwe);
|
||||
UNSERIALIZE_SCALAR(asn);
|
||||
UNSERIALIZE_SCALAR(asma);
|
||||
UNSERIALIZE_SCALAR(fonr);
|
||||
UNSERIALIZE_SCALAR(fonw);
|
||||
UNSERIALIZE_SCALAR(valid);
|
||||
}
|
||||
|
||||
} //namespace AlphaISA
|
||||
|
|
|
@ -38,97 +38,102 @@
|
|||
|
||||
namespace AlphaISA {
|
||||
|
||||
struct VAddr
|
||||
{
|
||||
static const int ImplBits = 43;
|
||||
static const Addr ImplMask = (ULL(1) << ImplBits) - 1;
|
||||
static const Addr UnImplMask = ~ImplMask;
|
||||
struct VAddr
|
||||
{
|
||||
static const int ImplBits = 43;
|
||||
static const Addr ImplMask = (ULL(1) << ImplBits) - 1;
|
||||
static const Addr UnImplMask = ~ImplMask;
|
||||
|
||||
VAddr(Addr a) : addr(a) {}
|
||||
Addr addr;
|
||||
operator Addr() const { return addr; }
|
||||
const VAddr &operator=(Addr a) { addr = a; return *this; }
|
||||
Addr addr;
|
||||
|
||||
Addr vpn() const { return (addr & ImplMask) >> PageShift; }
|
||||
Addr page() const { return addr & PageMask; }
|
||||
Addr offset() const { return addr & PageOffset; }
|
||||
VAddr(Addr a) : addr(a) {}
|
||||
operator Addr() const { return addr; }
|
||||
const VAddr &operator=(Addr a) { addr = a; return *this; }
|
||||
|
||||
Addr level3() const
|
||||
{ return PteAddr(addr >> PageShift); }
|
||||
Addr level2() const
|
||||
{ return PteAddr(addr >> NPtePageShift + PageShift); }
|
||||
Addr level1() const
|
||||
{ return PteAddr(addr >> 2 * NPtePageShift + PageShift); }
|
||||
};
|
||||
|
||||
struct PageTableEntry
|
||||
{
|
||||
PageTableEntry(uint64_t e) : entry(e) {}
|
||||
uint64_t entry;
|
||||
operator uint64_t() const { return entry; }
|
||||
const PageTableEntry &operator=(uint64_t e) { entry = e; return *this; }
|
||||
const PageTableEntry &operator=(const PageTableEntry &e)
|
||||
{ entry = e.entry; return *this; }
|
||||
|
||||
Addr _pfn() const { return (entry >> 32) & 0xffffffff; }
|
||||
Addr _sw() const { return (entry >> 16) & 0xffff; }
|
||||
int _rsv0() const { return (entry >> 14) & 0x3; }
|
||||
bool _uwe() const { return (entry >> 13) & 0x1; }
|
||||
bool _kwe() const { return (entry >> 12) & 0x1; }
|
||||
int _rsv1() const { return (entry >> 10) & 0x3; }
|
||||
bool _ure() const { return (entry >> 9) & 0x1; }
|
||||
bool _kre() const { return (entry >> 8) & 0x1; }
|
||||
bool _nomb() const { return (entry >> 7) & 0x1; }
|
||||
int _gh() const { return (entry >> 5) & 0x3; }
|
||||
bool _asm_() const { return (entry >> 4) & 0x1; }
|
||||
bool _foe() const { return (entry >> 3) & 0x1; }
|
||||
bool _fow() const { return (entry >> 2) & 0x1; }
|
||||
bool _for() const { return (entry >> 1) & 0x1; }
|
||||
bool valid() const { return (entry >> 0) & 0x1; }
|
||||
|
||||
Addr paddr() const { return _pfn() << PageShift; }
|
||||
};
|
||||
|
||||
// ITB/DTB table entry
|
||||
struct TlbEntry
|
||||
{
|
||||
//Construct an entry that maps to physical address addr.
|
||||
TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr)
|
||||
{
|
||||
VAddr vaddr(_vaddr);
|
||||
VAddr paddr(_paddr);
|
||||
tag = vaddr.vpn();
|
||||
ppn = paddr.vpn();
|
||||
xre = 15;
|
||||
xwe = 15;
|
||||
asn = _asn;
|
||||
asma = false;
|
||||
fonr = false;
|
||||
fonw = false;
|
||||
valid = true;
|
||||
}
|
||||
TlbEntry()
|
||||
{}
|
||||
|
||||
Addr tag; // virtual page number tag
|
||||
Addr ppn; // physical page number
|
||||
uint8_t xre; // read permissions - VMEM_PERM_* mask
|
||||
uint8_t xwe; // write permissions - VMEM_PERM_* mask
|
||||
uint8_t asn; // address space number
|
||||
bool asma; // address space match
|
||||
bool fonr; // fault on read
|
||||
bool fonw; // fault on write
|
||||
bool valid; // valid page table entry
|
||||
|
||||
Addr pageStart()
|
||||
{
|
||||
return ppn << PageShift;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
Addr vpn() const { return (addr & ImplMask) >> PageShift; }
|
||||
Addr page() const { return addr & PageMask; }
|
||||
Addr offset() const { return addr & PageOffset; }
|
||||
|
||||
Addr level3() const
|
||||
{ return PteAddr(addr >> PageShift); }
|
||||
Addr level2() const
|
||||
{ return PteAddr(addr >> NPtePageShift + PageShift); }
|
||||
Addr level1() const
|
||||
{ return PteAddr(addr >> 2 * NPtePageShift + PageShift); }
|
||||
};
|
||||
|
||||
struct PageTableEntry
|
||||
{
|
||||
PageTableEntry(uint64_t e) : entry(e) {}
|
||||
uint64_t entry;
|
||||
operator uint64_t() const { return entry; }
|
||||
const PageTableEntry &operator=(uint64_t e) { entry = e; return *this; }
|
||||
const PageTableEntry &operator=(const PageTableEntry &e)
|
||||
{ entry = e.entry; return *this; }
|
||||
|
||||
Addr _pfn() const { return (entry >> 32) & 0xffffffff; }
|
||||
Addr _sw() const { return (entry >> 16) & 0xffff; }
|
||||
int _rsv0() const { return (entry >> 14) & 0x3; }
|
||||
bool _uwe() const { return (entry >> 13) & 0x1; }
|
||||
bool _kwe() const { return (entry >> 12) & 0x1; }
|
||||
int _rsv1() const { return (entry >> 10) & 0x3; }
|
||||
bool _ure() const { return (entry >> 9) & 0x1; }
|
||||
bool _kre() const { return (entry >> 8) & 0x1; }
|
||||
bool _nomb() const { return (entry >> 7) & 0x1; }
|
||||
int _gh() const { return (entry >> 5) & 0x3; }
|
||||
bool _asm_() const { return (entry >> 4) & 0x1; }
|
||||
bool _foe() const { return (entry >> 3) & 0x1; }
|
||||
bool _fow() const { return (entry >> 2) & 0x1; }
|
||||
bool _for() const { return (entry >> 1) & 0x1; }
|
||||
bool valid() const { return (entry >> 0) & 0x1; }
|
||||
|
||||
Addr paddr() const { return _pfn() << PageShift; }
|
||||
};
|
||||
|
||||
// ITB/DTB table entry
|
||||
struct TlbEntry
|
||||
{
|
||||
Addr tag; // virtual page number tag
|
||||
Addr ppn; // physical page number
|
||||
uint8_t xre; // read permissions - VMEM_PERM_* mask
|
||||
uint8_t xwe; // write permissions - VMEM_PERM_* mask
|
||||
uint8_t asn; // address space number
|
||||
bool asma; // address space match
|
||||
bool fonr; // fault on read
|
||||
bool fonw; // fault on write
|
||||
bool valid; // valid page table entry
|
||||
|
||||
|
||||
//Construct an entry that maps to physical address addr.
|
||||
TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr)
|
||||
{
|
||||
VAddr vaddr(_vaddr);
|
||||
VAddr paddr(_paddr);
|
||||
tag = vaddr.vpn();
|
||||
ppn = paddr.vpn();
|
||||
xre = 15;
|
||||
xwe = 15;
|
||||
asn = _asn;
|
||||
asma = false;
|
||||
fonr = false;
|
||||
fonw = false;
|
||||
valid = true;
|
||||
}
|
||||
|
||||
TlbEntry()
|
||||
{}
|
||||
|
||||
Addr
|
||||
pageStart()
|
||||
{
|
||||
return ppn << PageShift;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ARCH_ALPHA_PAGETABLE_H__
|
||||
|
||||
|
|
|
@ -38,62 +38,72 @@
|
|||
|
||||
class ThreadContext;
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
class Predecoder
|
||||
{
|
||||
class Predecoder
|
||||
protected:
|
||||
ThreadContext *tc;
|
||||
|
||||
// The extended machine instruction being generated
|
||||
ExtMachInst ext_inst;
|
||||
|
||||
public:
|
||||
Predecoder(ThreadContext * _tc)
|
||||
: tc(_tc)
|
||||
{}
|
||||
|
||||
ThreadContext *
|
||||
getTC()
|
||||
{
|
||||
protected:
|
||||
ThreadContext * tc;
|
||||
//The extended machine instruction being generated
|
||||
ExtMachInst ext_inst;
|
||||
return tc;
|
||||
}
|
||||
|
||||
public:
|
||||
Predecoder(ThreadContext * _tc) : tc(_tc)
|
||||
{}
|
||||
void
|
||||
setTC(ThreadContext * _tc)
|
||||
{
|
||||
tc = _tc;
|
||||
}
|
||||
|
||||
ThreadContext * getTC()
|
||||
{
|
||||
return tc;
|
||||
}
|
||||
void
|
||||
process()
|
||||
{ }
|
||||
|
||||
void setTC(ThreadContext * _tc)
|
||||
{
|
||||
tc = _tc;
|
||||
}
|
||||
void
|
||||
reset()
|
||||
{ }
|
||||
|
||||
void process()
|
||||
{
|
||||
}
|
||||
|
||||
void reset()
|
||||
{}
|
||||
|
||||
//Use this to give data to the predecoder. This should be used
|
||||
//when there is control flow.
|
||||
void moreBytes(Addr pc, Addr fetchPC, MachInst inst)
|
||||
{
|
||||
ext_inst = inst;
|
||||
// Use this to give data to the predecoder. This should be used
|
||||
// when there is control flow.
|
||||
void
|
||||
moreBytes(Addr pc, Addr fetchPC, MachInst inst)
|
||||
{
|
||||
ext_inst = inst;
|
||||
#if FULL_SYSTEM
|
||||
ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
|
||||
ext_inst |= (static_cast<ExtMachInst>(pc & 0x1) << 32);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool needMoreBytes()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool
|
||||
needMoreBytes()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool extMachInstReady()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool
|
||||
extMachInstReady()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//This returns a constant reference to the ExtMachInst to avoid a copy
|
||||
const ExtMachInst & getExtMachInst()
|
||||
{
|
||||
return ext_inst;
|
||||
}
|
||||
};
|
||||
// This returns a constant reference to the ExtMachInst to avoid a copy
|
||||
const ExtMachInst &
|
||||
getExtMachInst()
|
||||
{
|
||||
return ext_inst;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ARCH_ALPHA_PREDECODER_HH__
|
||||
|
|
|
@ -36,12 +36,11 @@
|
|||
#include "cpu/thread_context.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
|
||||
using namespace AlphaISA;
|
||||
using namespace std;
|
||||
|
||||
AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams * params,
|
||||
ObjectFile *objFile)
|
||||
AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams *params,
|
||||
ObjectFile *objFile)
|
||||
: LiveProcess(params, objFile)
|
||||
{
|
||||
brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
|
||||
|
@ -77,4 +76,3 @@ AlphaLiveProcess::startup()
|
|||
threadContexts[0]->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,24 +29,20 @@
|
|||
* Ali Saidi
|
||||
*/
|
||||
|
||||
#ifndef __ALPHA_PROCESS_HH__
|
||||
#define __ALPHA_PROCESS_HH__
|
||||
#ifndef __ARCH_ALPHA_PROCESS_HH__
|
||||
#define __ARCH_ALPHA_PROCESS_HH__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "sim/process.hh"
|
||||
|
||||
class ObjectFile;
|
||||
class System;
|
||||
|
||||
|
||||
class AlphaLiveProcess : public LiveProcess
|
||||
{
|
||||
protected:
|
||||
AlphaLiveProcess(LiveProcessParams * params, ObjectFile *objFile);
|
||||
AlphaLiveProcess(LiveProcessParams *params, ObjectFile *objFile);
|
||||
|
||||
void startup();
|
||||
};
|
||||
|
||||
|
||||
#endif // __ALPHA_PROCESS_HH__
|
||||
#endif // __ARCH_ALPHA_PROCESS_HH__
|
||||
|
|
|
@ -33,67 +33,66 @@
|
|||
#include "arch/alpha/regfile.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
void
|
||||
RegFile::serialize(std::ostream &os)
|
||||
{
|
||||
void
|
||||
RegFile::serialize(std::ostream &os)
|
||||
{
|
||||
intRegFile.serialize(os);
|
||||
floatRegFile.serialize(os);
|
||||
miscRegFile.serialize(os);
|
||||
SERIALIZE_SCALAR(pc);
|
||||
SERIALIZE_SCALAR(npc);
|
||||
intRegFile.serialize(os);
|
||||
floatRegFile.serialize(os);
|
||||
miscRegFile.serialize(os);
|
||||
SERIALIZE_SCALAR(pc);
|
||||
SERIALIZE_SCALAR(npc);
|
||||
#if FULL_SYSTEM
|
||||
SERIALIZE_SCALAR(intrflag);
|
||||
SERIALIZE_SCALAR(intrflag);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
RegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
intRegFile.unserialize(cp, section);
|
||||
floatRegFile.unserialize(cp, section);
|
||||
miscRegFile.unserialize(cp, section);
|
||||
UNSERIALIZE_SCALAR(pc);
|
||||
UNSERIALIZE_SCALAR(npc);
|
||||
#if FULL_SYSTEM
|
||||
UNSERIALIZE_SCALAR(intrflag);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
copyRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
// First loop through the integer registers.
|
||||
for (int i = 0; i < NumIntRegs; ++i) {
|
||||
dest->setIntReg(i, src->readIntReg(i));
|
||||
}
|
||||
|
||||
// Then loop through the floating point registers.
|
||||
for (int i = 0; i < NumFloatRegs; ++i) {
|
||||
dest->setFloatRegBits(i, src->readFloatRegBits(i));
|
||||
}
|
||||
|
||||
// Copy misc. registers
|
||||
copyMiscRegs(src, dest);
|
||||
|
||||
// Lastly copy PC/NPC
|
||||
dest->setPC(src->readPC());
|
||||
dest->setNextPC(src->readNextPC());
|
||||
}
|
||||
|
||||
void
|
||||
copyMiscRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
dest->setMiscRegNoEffect(MISCREG_FPCR,
|
||||
src->readMiscRegNoEffect(MISCREG_FPCR));
|
||||
dest->setMiscRegNoEffect(MISCREG_UNIQ,
|
||||
src->readMiscRegNoEffect(MISCREG_UNIQ));
|
||||
dest->setMiscRegNoEffect(MISCREG_LOCKFLAG,
|
||||
src->readMiscRegNoEffect(MISCREG_LOCKFLAG));
|
||||
dest->setMiscRegNoEffect(MISCREG_LOCKADDR,
|
||||
src->readMiscRegNoEffect(MISCREG_LOCKADDR));
|
||||
|
||||
copyIprs(src, dest);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
intRegFile.unserialize(cp, section);
|
||||
floatRegFile.unserialize(cp, section);
|
||||
miscRegFile.unserialize(cp, section);
|
||||
UNSERIALIZE_SCALAR(pc);
|
||||
UNSERIALIZE_SCALAR(npc);
|
||||
#if FULL_SYSTEM
|
||||
UNSERIALIZE_SCALAR(intrflag);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
copyRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
// First loop through the integer registers.
|
||||
for (int i = 0; i < NumIntRegs; ++i)
|
||||
dest->setIntReg(i, src->readIntReg(i));
|
||||
|
||||
// Then loop through the floating point registers.
|
||||
for (int i = 0; i < NumFloatRegs; ++i)
|
||||
dest->setFloatRegBits(i, src->readFloatRegBits(i));
|
||||
|
||||
// Copy misc. registers
|
||||
copyMiscRegs(src, dest);
|
||||
|
||||
// Lastly copy PC/NPC
|
||||
dest->setPC(src->readPC());
|
||||
dest->setNextPC(src->readNextPC());
|
||||
}
|
||||
|
||||
void
|
||||
copyMiscRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
dest->setMiscRegNoEffect(MISCREG_FPCR,
|
||||
src->readMiscRegNoEffect(MISCREG_FPCR));
|
||||
dest->setMiscRegNoEffect(MISCREG_UNIQ,
|
||||
src->readMiscRegNoEffect(MISCREG_UNIQ));
|
||||
dest->setMiscRegNoEffect(MISCREG_LOCKFLAG,
|
||||
src->readMiscRegNoEffect(MISCREG_LOCKFLAG));
|
||||
dest->setMiscRegNoEffect(MISCREG_LOCKADDR,
|
||||
src->readMiscRegNoEffect(MISCREG_LOCKADDR));
|
||||
|
||||
copyIprs(src, dest);
|
||||
}
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
|
|
@ -45,161 +45,190 @@
|
|||
class Checkpoint;
|
||||
class ThreadContext;
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
namespace AlphaISA {
|
||||
|
||||
class RegFile {
|
||||
class RegFile {
|
||||
protected:
|
||||
Addr pc; // program counter
|
||||
Addr npc; // next-cycle program counter
|
||||
Addr nnpc; // next next-cycle program counter
|
||||
|
||||
protected:
|
||||
Addr pc; // program counter
|
||||
Addr npc; // next-cycle program counter
|
||||
Addr nnpc;
|
||||
public:
|
||||
Addr
|
||||
readPC()
|
||||
{
|
||||
return pc;
|
||||
}
|
||||
|
||||
public:
|
||||
Addr readPC()
|
||||
{
|
||||
return pc;
|
||||
}
|
||||
void
|
||||
setPC(Addr val)
|
||||
{
|
||||
pc = val;
|
||||
}
|
||||
|
||||
void setPC(Addr val)
|
||||
{
|
||||
pc = val;
|
||||
}
|
||||
Addr
|
||||
readNextPC()
|
||||
{
|
||||
return npc;
|
||||
}
|
||||
|
||||
Addr readNextPC()
|
||||
{
|
||||
return npc;
|
||||
}
|
||||
void
|
||||
setNextPC(Addr val)
|
||||
{
|
||||
npc = val;
|
||||
}
|
||||
|
||||
void setNextPC(Addr val)
|
||||
{
|
||||
npc = val;
|
||||
}
|
||||
Addr
|
||||
readNextNPC()
|
||||
{
|
||||
return npc + sizeof(MachInst);
|
||||
}
|
||||
|
||||
Addr readNextNPC()
|
||||
{
|
||||
return npc + sizeof(MachInst);
|
||||
}
|
||||
void
|
||||
setNextNPC(Addr val)
|
||||
{ }
|
||||
|
||||
void setNextNPC(Addr val)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
IntRegFile intRegFile; // (signed) integer register file
|
||||
FloatRegFile floatRegFile; // floating point register file
|
||||
MiscRegFile miscRegFile; // control register file
|
||||
|
||||
public:
|
||||
protected:
|
||||
IntRegFile intRegFile; // (signed) integer register file
|
||||
FloatRegFile floatRegFile; // floating point register file
|
||||
MiscRegFile miscRegFile; // control register file
|
||||
|
||||
public:
|
||||
#if FULL_SYSTEM
|
||||
int intrflag; // interrupt flag
|
||||
inline int instAsid()
|
||||
{ return miscRegFile.getInstAsid(); }
|
||||
inline int dataAsid()
|
||||
{ return miscRegFile.getDataAsid(); }
|
||||
int intrflag; // interrupt flag
|
||||
|
||||
int
|
||||
instAsid()
|
||||
{
|
||||
return miscRegFile.getInstAsid();
|
||||
}
|
||||
|
||||
int
|
||||
dataAsid()
|
||||
{
|
||||
return miscRegFile.getDataAsid();
|
||||
}
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
void clear()
|
||||
{
|
||||
intRegFile.clear();
|
||||
floatRegFile.clear();
|
||||
miscRegFile.clear();
|
||||
}
|
||||
|
||||
MiscReg readMiscRegNoEffect(int miscReg)
|
||||
{
|
||||
return miscRegFile.readRegNoEffect(miscReg);
|
||||
}
|
||||
|
||||
MiscReg readMiscReg(int miscReg, ThreadContext *tc)
|
||||
{
|
||||
return miscRegFile.readReg(miscReg, tc);
|
||||
}
|
||||
|
||||
void setMiscRegNoEffect(int miscReg, const MiscReg &val)
|
||||
{
|
||||
miscRegFile.setRegNoEffect(miscReg, val);
|
||||
}
|
||||
|
||||
void setMiscReg(int miscReg, const MiscReg &val,
|
||||
ThreadContext * tc)
|
||||
{
|
||||
miscRegFile.setReg(miscReg, val, tc);
|
||||
}
|
||||
|
||||
FloatReg readFloatReg(int floatReg)
|
||||
{
|
||||
return floatRegFile.d[floatReg];
|
||||
}
|
||||
|
||||
FloatReg readFloatReg(int floatReg, int width)
|
||||
{
|
||||
return readFloatReg(floatReg);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegBits(int floatReg)
|
||||
{
|
||||
return floatRegFile.q[floatReg];
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegBits(int floatReg, int width)
|
||||
{
|
||||
return readFloatRegBits(floatReg);
|
||||
}
|
||||
|
||||
void setFloatReg(int floatReg, const FloatReg &val)
|
||||
{
|
||||
floatRegFile.d[floatReg] = val;
|
||||
}
|
||||
|
||||
void setFloatReg(int floatReg, const FloatReg &val, int width)
|
||||
{
|
||||
setFloatReg(floatReg, val);
|
||||
}
|
||||
|
||||
void setFloatRegBits(int floatReg, const FloatRegBits &val)
|
||||
{
|
||||
floatRegFile.q[floatReg] = val;
|
||||
}
|
||||
|
||||
void setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
|
||||
{
|
||||
setFloatRegBits(floatReg, val);
|
||||
}
|
||||
|
||||
IntReg readIntReg(int intReg)
|
||||
{
|
||||
return intRegFile.readReg(intReg);
|
||||
}
|
||||
|
||||
void setIntReg(int intReg, const IntReg &val)
|
||||
{
|
||||
intRegFile.setReg(intReg, val);
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
void changeContext(RegContextParam param, RegContextVal val)
|
||||
{
|
||||
//This would be an alternative place to call/implement
|
||||
//the swapPALShadow function
|
||||
}
|
||||
};
|
||||
|
||||
static inline int flattenIntIndex(ThreadContext * tc, int reg)
|
||||
void
|
||||
clear()
|
||||
{
|
||||
return reg;
|
||||
intRegFile.clear();
|
||||
floatRegFile.clear();
|
||||
miscRegFile.clear();
|
||||
}
|
||||
|
||||
static inline int flattenFloatIndex(ThreadContext * tc, int reg)
|
||||
MiscReg
|
||||
readMiscRegNoEffect(int miscReg)
|
||||
{
|
||||
return reg;
|
||||
return miscRegFile.readRegNoEffect(miscReg);
|
||||
}
|
||||
|
||||
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
||||
MiscReg
|
||||
readMiscReg(int miscReg, ThreadContext *tc)
|
||||
{
|
||||
return miscRegFile.readReg(miscReg, tc);
|
||||
}
|
||||
|
||||
void
|
||||
setMiscRegNoEffect(int miscReg, const MiscReg &val)
|
||||
{
|
||||
miscRegFile.setRegNoEffect(miscReg, val);
|
||||
}
|
||||
|
||||
void
|
||||
setMiscReg(int miscReg, const MiscReg &val, ThreadContext *tc)
|
||||
{
|
||||
miscRegFile.setReg(miscReg, val, tc);
|
||||
}
|
||||
|
||||
FloatReg
|
||||
readFloatReg(int floatReg)
|
||||
{
|
||||
return floatRegFile.d[floatReg];
|
||||
}
|
||||
|
||||
FloatReg
|
||||
readFloatReg(int floatReg, int width)
|
||||
{
|
||||
return readFloatReg(floatReg);
|
||||
}
|
||||
|
||||
FloatRegBits
|
||||
readFloatRegBits(int floatReg)
|
||||
{
|
||||
return floatRegFile.q[floatReg];
|
||||
}
|
||||
|
||||
FloatRegBits
|
||||
readFloatRegBits(int floatReg, int width)
|
||||
{
|
||||
return readFloatRegBits(floatReg);
|
||||
}
|
||||
|
||||
void
|
||||
setFloatReg(int floatReg, const FloatReg &val)
|
||||
{
|
||||
floatRegFile.d[floatReg] = val;
|
||||
}
|
||||
|
||||
void
|
||||
setFloatReg(int floatReg, const FloatReg &val, int width)
|
||||
{
|
||||
setFloatReg(floatReg, val);
|
||||
}
|
||||
|
||||
void
|
||||
setFloatRegBits(int floatReg, const FloatRegBits &val)
|
||||
{
|
||||
floatRegFile.q[floatReg] = val;
|
||||
}
|
||||
|
||||
void
|
||||
setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
|
||||
{
|
||||
setFloatRegBits(floatReg, val);
|
||||
}
|
||||
|
||||
IntReg
|
||||
readIntReg(int intReg)
|
||||
{
|
||||
return intRegFile.readReg(intReg);
|
||||
}
|
||||
|
||||
void
|
||||
setIntReg(int intReg, const IntReg &val)
|
||||
{
|
||||
intRegFile.setReg(intReg, val);
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
void
|
||||
changeContext(RegContextParam param, RegContextVal val)
|
||||
{
|
||||
//This would be an alternative place to call/implement
|
||||
//the swapPALShadow function
|
||||
}
|
||||
};
|
||||
|
||||
static inline int
|
||||
flattenIntIndex(ThreadContext * tc, int reg)
|
||||
{
|
||||
return reg;
|
||||
}
|
||||
|
||||
static inline int
|
||||
flattenFloatIndex(ThreadContext * tc, int reg)
|
||||
{
|
||||
return reg;
|
||||
}
|
||||
|
||||
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
||||
|
||||
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
|
||||
|
||||
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif
|
||||
#endif // __ARCH_ALPHA_REGFILE_HH__
|
||||
|
|
|
@ -117,9 +117,9 @@
|
|||
*/
|
||||
|
||||
#include <sys/signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "config/full_system.hh"
|
||||
#if FULL_SYSTEM
|
||||
|
@ -142,17 +142,15 @@
|
|||
using namespace std;
|
||||
using namespace AlphaISA;
|
||||
|
||||
RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
|
||||
: BaseRemoteGDB(_system, c, KGDB_NUMREGS)
|
||||
RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc)
|
||||
: BaseRemoteGDB(_system, tc, KGDB_NUMREGS)
|
||||
{
|
||||
memset(gdbregs.regs, 0, gdbregs.bytes());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// RemoteGDB::acc
|
||||
//
|
||||
// Determine if the mapping at va..(va+len) is valid.
|
||||
//
|
||||
/*
|
||||
* Determine if the mapping at va..(va+len) is valid.
|
||||
*/
|
||||
bool
|
||||
RemoteGDB::acc(Addr va, size_t len)
|
||||
{
|
||||
|
@ -177,18 +175,20 @@ RemoteGDB::acc(Addr va, size_t len)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This code says that all accesses to palcode (instruction and data)
|
||||
* are valid since there isn't a va->pa mapping because palcode is
|
||||
* accessed physically. At some point this should probably be cleaned up
|
||||
* but there is no easy way to do it.
|
||||
*/
|
||||
/**
|
||||
* This code says that all accesses to palcode (instruction
|
||||
* and data) are valid since there isn't a va->pa mapping
|
||||
* because palcode is accessed physically. At some point this
|
||||
* should probably be cleaned up but there is no easy way to
|
||||
* do it.
|
||||
*/
|
||||
|
||||
if (PcPAL(va) || va < 0x10000)
|
||||
return true;
|
||||
|
||||
Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20);
|
||||
PageTableEntry pte = kernel_pte_lookup(context->getPhysPort(), ptbr, va);
|
||||
PageTableEntry pte =
|
||||
kernel_pte_lookup(context->getPhysPort(), ptbr, va);
|
||||
if (!pte.valid()) {
|
||||
DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
|
||||
return false;
|
||||
|
@ -201,11 +201,10 @@ RemoteGDB::acc(Addr va, size_t len)
|
|||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// RemoteGDB::getregs
|
||||
//
|
||||
// Translate the kernel debugger register format into
|
||||
// the GDB register format.
|
||||
/*
|
||||
* Translate the kernel debugger register format into the GDB register
|
||||
* format.
|
||||
*/
|
||||
void
|
||||
RemoteGDB::getregs()
|
||||
{
|
||||
|
@ -231,12 +230,10 @@ RemoteGDB::getregs()
|
|||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// RemoteGDB::setregs
|
||||
//
|
||||
// Translate the GDB register format into the kernel
|
||||
// debugger register format.
|
||||
//
|
||||
/*
|
||||
* Translate the GDB register format into the kernel debugger register
|
||||
* format.
|
||||
*/
|
||||
void
|
||||
RemoteGDB::setregs()
|
||||
{
|
||||
|
|
|
@ -44,31 +44,29 @@ class System;
|
|||
class ThreadContext;
|
||||
class PhysicalMemory;
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
class RemoteGDB : public BaseRemoteGDB
|
||||
{
|
||||
class RemoteGDB : public BaseRemoteGDB
|
||||
{
|
||||
protected:
|
||||
// Machine memory
|
||||
bool write(Addr addr, size_t size, const char *data);
|
||||
protected:
|
||||
Addr notTakenBkpt;
|
||||
Addr takenBkpt;
|
||||
|
||||
public:
|
||||
RemoteGDB(System *system, ThreadContext *context);
|
||||
protected:
|
||||
void getregs();
|
||||
void setregs();
|
||||
|
||||
bool acc(Addr addr, size_t len);
|
||||
void clearSingleStep();
|
||||
void setSingleStep();
|
||||
|
||||
protected:
|
||||
void getregs();
|
||||
void setregs();
|
||||
// Machine memory
|
||||
bool acc(Addr addr, size_t len);
|
||||
bool write(Addr addr, size_t size, const char *data);
|
||||
|
||||
void clearSingleStep();
|
||||
void setSingleStep();
|
||||
public:
|
||||
RemoteGDB(System *system, ThreadContext *context);
|
||||
};
|
||||
|
||||
protected:
|
||||
} // namespace AlphaISA
|
||||
|
||||
Addr notTakenBkpt;
|
||||
Addr takenBkpt;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __ARCH_ALPHA_REMOTE_GDB_H__ */
|
||||
#endif // __ARCH_ALPHA_REMOTE_GDB_HH__
|
||||
|
|
|
@ -41,326 +41,326 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
ProcessInfo::ProcessInfo(ThreadContext *_tc)
|
||||
: tc(_tc)
|
||||
{
|
||||
ProcessInfo::ProcessInfo(ThreadContext *_tc)
|
||||
: tc(_tc)
|
||||
{
|
||||
Addr addr = 0;
|
||||
Addr addr = 0;
|
||||
VirtualPort *vp = tc->getVirtPort();
|
||||
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
|
||||
|
||||
VirtualPort *vp;
|
||||
if (!symtab->findAddress("thread_info_size", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
thread_info_size = vp->readGtoH<int32_t>(addr);
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
if (!symtab->findAddress("task_struct_size", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
task_struct_size = vp->readGtoH<int32_t>(addr);
|
||||
|
||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
thread_info_size = vp->readGtoH<int32_t>(addr);
|
||||
if (!symtab->findAddress("thread_info_task", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
task_off = vp->readGtoH<int32_t>(addr);
|
||||
|
||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
task_struct_size = vp->readGtoH<int32_t>(addr);
|
||||
if (!symtab->findAddress("task_struct_pid", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
pid_off = vp->readGtoH<int32_t>(addr);
|
||||
|
||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
task_off = vp->readGtoH<int32_t>(addr);
|
||||
if (!symtab->findAddress("task_struct_comm", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
name_off = vp->readGtoH<int32_t>(addr);
|
||||
}
|
||||
|
||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
pid_off = vp->readGtoH<int32_t>(addr);
|
||||
Addr
|
||||
ProcessInfo::task(Addr ksp) const
|
||||
{
|
||||
Addr base = ksp & ~0x3fff;
|
||||
if (base == ULL(0xfffffc0000000000))
|
||||
return 0;
|
||||
|
||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
|
||||
panic("thread info not compiled into kernel\n");
|
||||
name_off = vp->readGtoH<int32_t>(addr);
|
||||
Addr tsk;
|
||||
|
||||
VirtualPort *vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
tsk = vp->readGtoH<Addr>(base + task_off);
|
||||
|
||||
return tsk;
|
||||
}
|
||||
|
||||
int
|
||||
ProcessInfo::pid(Addr ksp) const
|
||||
{
|
||||
Addr task = this->task(ksp);
|
||||
if (!task)
|
||||
return -1;
|
||||
|
||||
uint16_t pd;
|
||||
|
||||
VirtualPort *vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
||||
|
||||
return pd;
|
||||
}
|
||||
|
||||
string
|
||||
ProcessInfo::name(Addr ksp) const
|
||||
{
|
||||
Addr task = this->task(ksp);
|
||||
if (!task)
|
||||
return "console";
|
||||
|
||||
char comm[256];
|
||||
CopyStringOut(tc, comm, task + name_off, sizeof(comm));
|
||||
if (!comm[0])
|
||||
return "startup";
|
||||
|
||||
return comm;
|
||||
}
|
||||
|
||||
StackTrace::StackTrace()
|
||||
: tc(0), stack(64)
|
||||
{
|
||||
}
|
||||
|
||||
StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst)
|
||||
: tc(0), stack(64)
|
||||
{
|
||||
trace(_tc, inst);
|
||||
}
|
||||
|
||||
StackTrace::~StackTrace()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
StackTrace::trace(ThreadContext *_tc, bool is_call)
|
||||
{
|
||||
tc = _tc;
|
||||
|
||||
System *sys = tc->getSystemPtr();
|
||||
|
||||
bool usermode =
|
||||
(tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0;
|
||||
|
||||
Addr pc = tc->readNextPC();
|
||||
bool kernel = sys->kernelStart <= pc && pc <= sys->kernelEnd;
|
||||
|
||||
if (usermode) {
|
||||
stack.push_back(user);
|
||||
return;
|
||||
}
|
||||
|
||||
Addr
|
||||
ProcessInfo::task(Addr ksp) const
|
||||
{
|
||||
Addr base = ksp & ~0x3fff;
|
||||
if (base == ULL(0xfffffc0000000000))
|
||||
return 0;
|
||||
|
||||
Addr tsk;
|
||||
|
||||
VirtualPort *vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
tsk = vp->readGtoH<Addr>(base + task_off);
|
||||
|
||||
return tsk;
|
||||
if (!kernel) {
|
||||
stack.push_back(console);
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
ProcessInfo::pid(Addr ksp) const
|
||||
{
|
||||
Addr task = this->task(ksp);
|
||||
if (!task)
|
||||
return -1;
|
||||
SymbolTable *symtab = sys->kernelSymtab;
|
||||
Addr ksp = tc->readIntReg(StackPointerReg);
|
||||
Addr bottom = ksp & ~0x3fff;
|
||||
|
||||
uint16_t pd;
|
||||
|
||||
VirtualPort *vp;
|
||||
|
||||
vp = tc->getVirtPort();
|
||||
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
||||
|
||||
return pd;
|
||||
}
|
||||
|
||||
string
|
||||
ProcessInfo::name(Addr ksp) const
|
||||
{
|
||||
Addr task = this->task(ksp);
|
||||
if (!task)
|
||||
return "console";
|
||||
|
||||
char comm[256];
|
||||
CopyStringOut(tc, comm, task + name_off, sizeof(comm));
|
||||
if (!comm[0])
|
||||
return "startup";
|
||||
|
||||
return comm;
|
||||
}
|
||||
|
||||
StackTrace::StackTrace()
|
||||
: tc(0), stack(64)
|
||||
{
|
||||
}
|
||||
|
||||
StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst)
|
||||
: tc(0), stack(64)
|
||||
{
|
||||
trace(_tc, inst);
|
||||
}
|
||||
|
||||
StackTrace::~StackTrace()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
StackTrace::trace(ThreadContext *_tc, bool is_call)
|
||||
{
|
||||
tc = _tc;
|
||||
|
||||
bool usermode = (tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0;
|
||||
|
||||
Addr pc = tc->readNextPC();
|
||||
bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
|
||||
pc <= tc->getSystemPtr()->kernelEnd;
|
||||
|
||||
if (usermode) {
|
||||
stack.push_back(user);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!kernel) {
|
||||
stack.push_back(console);
|
||||
return;
|
||||
}
|
||||
|
||||
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
|
||||
Addr ksp = tc->readIntReg(StackPointerReg);
|
||||
Addr bottom = ksp & ~0x3fff;
|
||||
if (is_call) {
|
||||
Addr addr;
|
||||
if (!symtab->findNearestAddr(pc, addr))
|
||||
panic("could not find address %#x", pc);
|
||||
|
||||
if (is_call) {
|
||||
if (!symtab->findNearestAddr(pc, addr))
|
||||
panic("could not find address %#x", pc);
|
||||
stack.push_back(addr);
|
||||
pc = tc->readPC();
|
||||
}
|
||||
|
||||
stack.push_back(addr);
|
||||
pc = tc->readPC();
|
||||
}
|
||||
while (ksp > bottom) {
|
||||
Addr addr;
|
||||
if (!symtab->findNearestAddr(pc, addr))
|
||||
panic("could not find symbol for pc=%#x", pc);
|
||||
assert(pc >= addr && "symbol botch: callpc < func");
|
||||
|
||||
stack.push_back(addr);
|
||||
|
||||
if (isEntry(addr))
|
||||
return;
|
||||
|
||||
Addr ra;
|
||||
int size;
|
||||
|
||||
while (ksp > bottom) {
|
||||
if (!symtab->findNearestAddr(pc, addr))
|
||||
panic("could not find symbol for pc=%#x", pc);
|
||||
assert(pc >= addr && "symbol botch: callpc < func");
|
||||
|
||||
stack.push_back(addr);
|
||||
|
||||
if (isEntry(addr))
|
||||
if (decodePrologue(ksp, pc, addr, size, ra)) {
|
||||
if (!ra)
|
||||
return;
|
||||
|
||||
if (decodePrologue(ksp, pc, addr, size, ra)) {
|
||||
if (!ra)
|
||||
return;
|
||||
|
||||
if (size <= 0) {
|
||||
stack.push_back(unknown);
|
||||
return;
|
||||
}
|
||||
|
||||
pc = ra;
|
||||
ksp += size;
|
||||
} else {
|
||||
if (size <= 0) {
|
||||
stack.push_back(unknown);
|
||||
return;
|
||||
}
|
||||
|
||||
bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
|
||||
pc <= tc->getSystemPtr()->kernelEnd;
|
||||
if (!kernel)
|
||||
return;
|
||||
|
||||
if (stack.size() >= 1000)
|
||||
panic("unwinding too far");
|
||||
pc = ra;
|
||||
ksp += size;
|
||||
} else {
|
||||
stack.push_back(unknown);
|
||||
return;
|
||||
}
|
||||
|
||||
panic("unwinding too far");
|
||||
bool kernel = sys->kernelStart <= pc && pc <= sys->kernelEnd;
|
||||
if (!kernel)
|
||||
return;
|
||||
|
||||
if (stack.size() >= 1000)
|
||||
panic("unwinding too far");
|
||||
}
|
||||
|
||||
bool
|
||||
StackTrace::isEntry(Addr addr)
|
||||
{
|
||||
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp12))
|
||||
return true;
|
||||
panic("unwinding too far");
|
||||
}
|
||||
|
||||
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp7))
|
||||
return true;
|
||||
bool
|
||||
StackTrace::isEntry(Addr addr)
|
||||
{
|
||||
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp12))
|
||||
return true;
|
||||
|
||||
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp11))
|
||||
return true;
|
||||
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp7))
|
||||
return true;
|
||||
|
||||
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp21))
|
||||
return true;
|
||||
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp11))
|
||||
return true;
|
||||
|
||||
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp9))
|
||||
return true;
|
||||
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp21))
|
||||
return true;
|
||||
|
||||
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp2))
|
||||
return true;
|
||||
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp9))
|
||||
return true;
|
||||
|
||||
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp2))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
StackTrace::decodeStack(MachInst inst, int &disp)
|
||||
{
|
||||
// lda $sp, -disp($sp)
|
||||
//
|
||||
// Opcode<31:26> == 0x08
|
||||
// RA<25:21> == 30
|
||||
// RB<20:16> == 30
|
||||
// Disp<15:0>
|
||||
const MachInst mem_mask = 0xffff0000;
|
||||
const MachInst lda_pattern = 0x23de0000;
|
||||
const MachInst lda_disp_mask = 0x0000ffff;
|
||||
|
||||
// subq $sp, disp, $sp
|
||||
// addq $sp, disp, $sp
|
||||
//
|
||||
// Opcode<31:26> == 0x10
|
||||
// RA<25:21> == 30
|
||||
// Lit<20:13>
|
||||
// One<12> = 1
|
||||
// Func<11:5> == 0x20 (addq)
|
||||
// Func<11:5> == 0x29 (subq)
|
||||
// RC<4:0> == 30
|
||||
const MachInst intop_mask = 0xffe01fff;
|
||||
const MachInst addq_pattern = 0x43c0141e;
|
||||
const MachInst subq_pattern = 0x43c0153e;
|
||||
const MachInst intop_disp_mask = 0x001fe000;
|
||||
const int intop_disp_shift = 13;
|
||||
|
||||
if ((inst & mem_mask) == lda_pattern)
|
||||
disp = -sext<16>(inst & lda_disp_mask);
|
||||
else if ((inst & intop_mask) == addq_pattern)
|
||||
disp = -int((inst & intop_disp_mask) >> intop_disp_shift);
|
||||
else if ((inst & intop_mask) == subq_pattern)
|
||||
disp = int((inst & intop_disp_mask) >> intop_disp_shift);
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
StackTrace::decodeSave(MachInst inst, int ®, int &disp)
|
||||
{
|
||||
// lda $stq, disp($sp)
|
||||
//
|
||||
// Opcode<31:26> == 0x08
|
||||
// RA<25:21> == ?
|
||||
// RB<20:16> == 30
|
||||
// Disp<15:0>
|
||||
const MachInst stq_mask = 0xfc1f0000;
|
||||
const MachInst stq_pattern = 0xb41e0000;
|
||||
const MachInst stq_disp_mask = 0x0000ffff;
|
||||
const MachInst reg_mask = 0x03e00000;
|
||||
const int reg_shift = 21;
|
||||
|
||||
if ((inst & stq_mask) == stq_pattern) {
|
||||
reg = (inst & reg_mask) >> reg_shift;
|
||||
disp = sext<16>(inst & stq_disp_mask);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
StackTrace::decodeStack(MachInst inst, int &disp)
|
||||
{
|
||||
// lda $sp, -disp($sp)
|
||||
//
|
||||
// Opcode<31:26> == 0x08
|
||||
// RA<25:21> == 30
|
||||
// RB<20:16> == 30
|
||||
// Disp<15:0>
|
||||
const MachInst mem_mask = 0xffff0000;
|
||||
const MachInst lda_pattern = 0x23de0000;
|
||||
const MachInst lda_disp_mask = 0x0000ffff;
|
||||
return true;
|
||||
}
|
||||
|
||||
// subq $sp, disp, $sp
|
||||
// addq $sp, disp, $sp
|
||||
//
|
||||
// Opcode<31:26> == 0x10
|
||||
// RA<25:21> == 30
|
||||
// Lit<20:13>
|
||||
// One<12> = 1
|
||||
// Func<11:5> == 0x20 (addq)
|
||||
// Func<11:5> == 0x29 (subq)
|
||||
// RC<4:0> == 30
|
||||
const MachInst intop_mask = 0xffe01fff;
|
||||
const MachInst addq_pattern = 0x43c0141e;
|
||||
const MachInst subq_pattern = 0x43c0153e;
|
||||
const MachInst intop_disp_mask = 0x001fe000;
|
||||
const int intop_disp_shift = 13;
|
||||
/*
|
||||
* Decode the function prologue for the function we're in, and note
|
||||
* which registers are stored where, and how large the stack frame is.
|
||||
*/
|
||||
bool
|
||||
StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, int &size,
|
||||
Addr &ra)
|
||||
{
|
||||
size = 0;
|
||||
ra = 0;
|
||||
|
||||
if ((inst & mem_mask) == lda_pattern)
|
||||
disp = -sext<16>(inst & lda_disp_mask);
|
||||
else if ((inst & intop_mask) == addq_pattern)
|
||||
disp = -int((inst & intop_disp_mask) >> intop_disp_shift);
|
||||
else if ((inst & intop_mask) == subq_pattern)
|
||||
disp = int((inst & intop_disp_mask) >> intop_disp_shift);
|
||||
else
|
||||
return false;
|
||||
for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
|
||||
MachInst inst;
|
||||
CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
StackTrace::decodeSave(MachInst inst, int ®, int &disp)
|
||||
{
|
||||
// lda $stq, disp($sp)
|
||||
//
|
||||
// Opcode<31:26> == 0x08
|
||||
// RA<25:21> == ?
|
||||
// RB<20:16> == 30
|
||||
// Disp<15:0>
|
||||
const MachInst stq_mask = 0xfc1f0000;
|
||||
const MachInst stq_pattern = 0xb41e0000;
|
||||
const MachInst stq_disp_mask = 0x0000ffff;
|
||||
const MachInst reg_mask = 0x03e00000;
|
||||
const int reg_shift = 21;
|
||||
|
||||
if ((inst & stq_mask) == stq_pattern) {
|
||||
reg = (inst & reg_mask) >> reg_shift;
|
||||
disp = sext<16>(inst & stq_disp_mask);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode the function prologue for the function we're in, and note
|
||||
* which registers are stored where, and how large the stack frame is.
|
||||
*/
|
||||
bool
|
||||
StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
|
||||
int &size, Addr &ra)
|
||||
{
|
||||
size = 0;
|
||||
ra = 0;
|
||||
|
||||
for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
|
||||
MachInst inst;
|
||||
CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst));
|
||||
|
||||
int reg, disp;
|
||||
if (decodeStack(inst, disp)) {
|
||||
if (size) {
|
||||
// panic("decoding frame size again");
|
||||
return true;
|
||||
}
|
||||
size += disp;
|
||||
} else if (decodeSave(inst, reg, disp)) {
|
||||
if (!ra && reg == ReturnAddressReg) {
|
||||
CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
|
||||
if (!ra) {
|
||||
// panic("no return address value pc=%#x\n", pc);
|
||||
return false;
|
||||
}
|
||||
int reg, disp;
|
||||
if (decodeStack(inst, disp)) {
|
||||
if (size) {
|
||||
// panic("decoding frame size again");
|
||||
return true;
|
||||
}
|
||||
size += disp;
|
||||
} else if (decodeSave(inst, reg, disp)) {
|
||||
if (!ra && reg == ReturnAddressReg) {
|
||||
CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
|
||||
if (!ra) {
|
||||
// panic("no return address value pc=%#x\n", pc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if TRACING_ON
|
||||
void
|
||||
StackTrace::dump()
|
||||
{
|
||||
StringWrap name(tc->getCpuPtr()->name());
|
||||
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
|
||||
void
|
||||
StackTrace::dump()
|
||||
{
|
||||
StringWrap name(tc->getCpuPtr()->name());
|
||||
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
|
||||
|
||||
DPRINTFN("------ Stack ------\n");
|
||||
DPRINTFN("------ Stack ------\n");
|
||||
|
||||
string symbol;
|
||||
for (int i = 0, size = stack.size(); i < size; ++i) {
|
||||
Addr addr = stack[size - i - 1];
|
||||
if (addr == user)
|
||||
symbol = "user";
|
||||
else if (addr == console)
|
||||
symbol = "console";
|
||||
else if (addr == unknown)
|
||||
symbol = "unknown";
|
||||
else
|
||||
symtab->findSymbol(addr, symbol);
|
||||
string symbol;
|
||||
for (int i = 0, size = stack.size(); i < size; ++i) {
|
||||
Addr addr = stack[size - i - 1];
|
||||
if (addr == user)
|
||||
symbol = "user";
|
||||
else if (addr == console)
|
||||
symbol = "console";
|
||||
else if (addr == unknown)
|
||||
symbol = "unknown";
|
||||
else
|
||||
symtab->findSymbol(addr, symbol);
|
||||
|
||||
DPRINTFN("%#x: %s\n", addr, symbol);
|
||||
}
|
||||
DPRINTFN("%#x: %s\n", addr, symbol);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
|
|
@ -36,88 +36,90 @@
|
|||
|
||||
class ThreadContext;
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
class StackTrace;
|
||||
|
||||
class ProcessInfo
|
||||
{
|
||||
class StackTrace;
|
||||
private:
|
||||
ThreadContext *tc;
|
||||
|
||||
class ProcessInfo
|
||||
int thread_info_size;
|
||||
int task_struct_size;
|
||||
int task_off;
|
||||
int pid_off;
|
||||
int name_off;
|
||||
|
||||
public:
|
||||
ProcessInfo(ThreadContext *_tc);
|
||||
|
||||
Addr task(Addr ksp) const;
|
||||
int pid(Addr ksp) const;
|
||||
std::string name(Addr ksp) const;
|
||||
};
|
||||
|
||||
class StackTrace
|
||||
{
|
||||
private:
|
||||
ThreadContext *tc;
|
||||
std::vector<Addr> stack;
|
||||
|
||||
private:
|
||||
bool isEntry(Addr addr);
|
||||
bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
|
||||
bool decodeSave(MachInst inst, int ®, int &disp);
|
||||
bool decodeStack(MachInst inst, int &disp);
|
||||
|
||||
void trace(ThreadContext *tc, bool is_call);
|
||||
|
||||
public:
|
||||
StackTrace();
|
||||
StackTrace(ThreadContext *tc, StaticInstPtr inst);
|
||||
~StackTrace();
|
||||
|
||||
void
|
||||
clear()
|
||||
{
|
||||
private:
|
||||
ThreadContext *tc;
|
||||
tc = 0;
|
||||
stack.clear();
|
||||
}
|
||||
|
||||
int thread_info_size;
|
||||
int task_struct_size;
|
||||
int task_off;
|
||||
int pid_off;
|
||||
int name_off;
|
||||
bool valid() const { return tc != NULL; }
|
||||
bool trace(ThreadContext *tc, StaticInstPtr inst);
|
||||
|
||||
public:
|
||||
ProcessInfo(ThreadContext *_tc);
|
||||
public:
|
||||
const std::vector<Addr> &getstack() const { return stack; }
|
||||
|
||||
Addr task(Addr ksp) const;
|
||||
int pid(Addr ksp) const;
|
||||
std::string name(Addr ksp) const;
|
||||
};
|
||||
|
||||
class StackTrace
|
||||
{
|
||||
private:
|
||||
ThreadContext *tc;
|
||||
std::vector<Addr> stack;
|
||||
|
||||
private:
|
||||
bool isEntry(Addr addr);
|
||||
bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
|
||||
bool decodeSave(MachInst inst, int ®, int &disp);
|
||||
bool decodeStack(MachInst inst, int &disp);
|
||||
|
||||
void trace(ThreadContext *tc, bool is_call);
|
||||
|
||||
public:
|
||||
StackTrace();
|
||||
StackTrace(ThreadContext *tc, StaticInstPtr inst);
|
||||
~StackTrace();
|
||||
|
||||
void clear()
|
||||
{
|
||||
tc = 0;
|
||||
stack.clear();
|
||||
}
|
||||
|
||||
bool valid() const { return tc != NULL; }
|
||||
bool trace(ThreadContext *tc, StaticInstPtr inst);
|
||||
|
||||
public:
|
||||
const std::vector<Addr> &getstack() const { return stack; }
|
||||
|
||||
static const int user = 1;
|
||||
static const int console = 2;
|
||||
static const int unknown = 3;
|
||||
static const int user = 1;
|
||||
static const int console = 2;
|
||||
static const int unknown = 3;
|
||||
|
||||
#if TRACING_ON
|
||||
private:
|
||||
void dump();
|
||||
private:
|
||||
void dump();
|
||||
|
||||
public:
|
||||
void dprintf() { if (DTRACE(Stack)) dump(); }
|
||||
public:
|
||||
void dprintf() { if (DTRACE(Stack)) dump(); }
|
||||
#else
|
||||
public:
|
||||
void dprintf() {}
|
||||
public:
|
||||
void dprintf() {}
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
inline bool
|
||||
StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
|
||||
{
|
||||
if (!inst->isCall() && !inst->isReturn())
|
||||
return false;
|
||||
inline bool
|
||||
StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
|
||||
{
|
||||
if (!inst->isCall() && !inst->isReturn())
|
||||
return false;
|
||||
|
||||
if (valid())
|
||||
clear();
|
||||
if (valid())
|
||||
clear();
|
||||
|
||||
trace(tc, !inst->isReturn());
|
||||
return true;
|
||||
}
|
||||
trace(tc, !inst->isReturn());
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ARCH_ALPHA_STACKTRACE_HH__
|
||||
|
|
|
@ -35,24 +35,25 @@
|
|||
#include "cpu/thread_context.hh"
|
||||
#include "sim/syscallreturn.hh"
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
static inline void
|
||||
setSyscallReturn(SyscallReturn return_value, ThreadContext *tc)
|
||||
{
|
||||
static inline void setSyscallReturn(SyscallReturn return_value,
|
||||
ThreadContext * tc)
|
||||
{
|
||||
// check for error condition. Alpha syscall convention is to
|
||||
// indicate success/failure in reg a3 (r19) and put the
|
||||
// return value itself in the standard return value reg (v0).
|
||||
if (return_value.successful()) {
|
||||
// no error
|
||||
tc->setIntReg(SyscallSuccessReg, 0);
|
||||
tc->setIntReg(ReturnValueReg, return_value.value());
|
||||
} else {
|
||||
// got an error, return details
|
||||
tc->setIntReg(SyscallSuccessReg, (IntReg)-1);
|
||||
tc->setIntReg(ReturnValueReg, -return_value.value());
|
||||
}
|
||||
// check for error condition. Alpha syscall convention is to
|
||||
// indicate success/failure in reg a3 (r19) and put the
|
||||
// return value itself in the standard return value reg (v0).
|
||||
if (return_value.successful()) {
|
||||
// no error
|
||||
tc->setIntReg(SyscallSuccessReg, 0);
|
||||
tc->setIntReg(ReturnValueReg, return_value.value());
|
||||
} else {
|
||||
// got an error, return details
|
||||
tc->setIntReg(SyscallSuccessReg, (IntReg)-1);
|
||||
tc->setIntReg(ReturnValueReg, -return_value.value());
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ARCH_ALPHA_SYSCALLRETURN_HH__
|
||||
|
|
|
@ -116,7 +116,6 @@ AlphaSystem::AlphaSystem(Params *p)
|
|||
virtPort.write(addr+0x58, data);
|
||||
} else
|
||||
panic("could not find hwrpb\n");
|
||||
|
||||
}
|
||||
|
||||
AlphaSystem::~AlphaSystem()
|
||||
|
@ -175,7 +174,7 @@ AlphaSystem::fixFuncEventAddr(Addr addr)
|
|||
|
||||
if ((i1 & inst_mask) == gp_ldah_pattern &&
|
||||
(i2 & inst_mask) == gp_lda_pattern) {
|
||||
Addr new_addr = addr + 2* sizeof(MachInst);
|
||||
Addr new_addr = addr + 2 * sizeof(MachInst);
|
||||
DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr);
|
||||
return new_addr;
|
||||
} else {
|
||||
|
@ -183,15 +182,15 @@ AlphaSystem::fixFuncEventAddr(Addr addr)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlphaSystem::setAlphaAccess(Addr access)
|
||||
{
|
||||
Addr addr = 0;
|
||||
if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
|
||||
virtPort.write(addr, htog(Phys2K0Seg(access)));
|
||||
} else
|
||||
} else {
|
||||
panic("could not find m5AlphaAccess\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -202,7 +201,6 @@ AlphaSystem::serialize(std::ostream &os)
|
|||
palSymtab->serialize("pal_symtab", os);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlphaSystem::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
|
|
|
@ -49,10 +49,10 @@ class AlphaSystem : public System
|
|||
AlphaSystem(Params *p);
|
||||
~AlphaSystem();
|
||||
|
||||
/**
|
||||
* Serialization stuff
|
||||
*/
|
||||
public:
|
||||
/**
|
||||
* Serialization stuff
|
||||
*/
|
||||
virtual void serialize(std::ostream &os);
|
||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
|
@ -77,26 +77,28 @@ class AlphaSystem : public System
|
|||
/** Event to halt the simulator if the console calls panic() */
|
||||
BreakPCEvent *consolePanicEvent;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
const Params *params() const { return (const Params *)_params; }
|
||||
|
||||
/** Add a function-based event to PALcode. */
|
||||
template <class T>
|
||||
T *addPalFuncEvent(const char *lbl)
|
||||
T *
|
||||
addPalFuncEvent(const char *lbl)
|
||||
{
|
||||
return addFuncEvent<T>(palSymtab, lbl);
|
||||
}
|
||||
|
||||
/** Add a function-based event to the console code. */
|
||||
template <class T>
|
||||
T *addConsoleFuncEvent(const char *lbl)
|
||||
T *
|
||||
addConsoleFuncEvent(const char *lbl)
|
||||
{
|
||||
return addFuncEvent<T>(consoleSymtab, lbl);
|
||||
}
|
||||
|
||||
virtual Addr fixFuncEventAddr(Addr addr);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // __ARCH_ALPHA_SYSTEM_HH__
|
||||
|
||||
|
|
|
@ -45,16 +45,18 @@
|
|||
using namespace std;
|
||||
|
||||
namespace AlphaISA {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Alpha TLB
|
||||
//
|
||||
|
||||
#ifdef DEBUG
|
||||
bool uncacheBit39 = false;
|
||||
bool uncacheBit40 = false;
|
||||
#endif
|
||||
|
||||
#define MODE2MASK(X) (1 << (X))
|
||||
#define MODE2MASK(X) (1 << (X))
|
||||
|
||||
TLB::TLB(const Params *p)
|
||||
: BaseTLB(p), size(p->size), nlu(0)
|
||||
|
@ -113,20 +115,20 @@ TLB::lookup(Addr vpn, uint8_t asn)
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
Fault
|
||||
TLB::checkCacheability(RequestPtr &req, bool itb)
|
||||
{
|
||||
// in Alpha, cacheability is controlled by upper-level bits of the
|
||||
// physical address
|
||||
// in Alpha, cacheability is controlled by upper-level bits of the
|
||||
// physical address
|
||||
|
||||
/*
|
||||
* We support having the uncacheable bit in either bit 39 or bit 40.
|
||||
* The Turbolaser platform (and EV5) support having the bit in 39, but
|
||||
* Tsunami (which Linux assumes uses an EV6) generates accesses with
|
||||
* the bit in 40. So we must check for both, but we have debug flags
|
||||
* to catch a weird case where both are used, which shouldn't happen.
|
||||
*/
|
||||
/*
|
||||
* We support having the uncacheable bit in either bit 39 or bit
|
||||
* 40. The Turbolaser platform (and EV5) support having the bit
|
||||
* in 39, but Tsunami (which Linux assumes uses an EV6) generates
|
||||
* accesses with the bit in 40. So we must check for both, but we
|
||||
* have debug flags to catch a weird case where both are used,
|
||||
* which shouldn't happen.
|
||||
*/
|
||||
|
||||
|
||||
#if ALPHA_TLASER
|
||||
|
@ -143,7 +145,8 @@ TLB::checkCacheability(RequestPtr &req, bool itb)
|
|||
req->setFlags(req->getFlags() | UNCACHEABLE);
|
||||
|
||||
#if !ALPHA_TLASER
|
||||
// Clear bits 42:35 of the physical address (10-2 in Tsunami manual)
|
||||
// Clear bits 42:35 of the physical address (10-2 in
|
||||
// Tsunami manual)
|
||||
req->setPaddr(req->getPaddr() & PAddrUncachedMask);
|
||||
#endif
|
||||
}
|
||||
|
@ -221,7 +224,8 @@ TLB::flushProcesses()
|
|||
++i;
|
||||
|
||||
if (!entry->asma) {
|
||||
DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, entry->tag, entry->ppn);
|
||||
DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index,
|
||||
entry->tag, entry->ppn);
|
||||
entry->valid = false;
|
||||
lookupTable.erase(cur);
|
||||
}
|
||||
|
@ -284,7 +288,6 @@ TLB::unserialize(Checkpoint *cp, const string §ion)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Alpha ITB
|
||||
|
@ -313,12 +316,11 @@ ITB::regStats()
|
|||
accesses = hits + misses;
|
||||
}
|
||||
|
||||
|
||||
Fault
|
||||
ITB::translate(RequestPtr &req, ThreadContext *tc)
|
||||
{
|
||||
//If this is a pal pc, then set PHYSICAL
|
||||
if(FULL_SYSTEM && PcPAL(req->getPC()))
|
||||
if (FULL_SYSTEM && PcPAL(req->getPC()))
|
||||
req->setFlags(req->getFlags() | PHYSICAL);
|
||||
|
||||
if (PcPAL(req->getPC())) {
|
||||
|
@ -403,7 +405,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
|
|||
//
|
||||
// Alpha DTB
|
||||
//
|
||||
DTB::DTB(const Params *p)
|
||||
DTB::DTB(const Params *p)
|
||||
: TLB(p)
|
||||
{}
|
||||
|
||||
|
@ -484,7 +486,6 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
|||
mode_type mode =
|
||||
(mode_type)DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM));
|
||||
|
||||
|
||||
/**
|
||||
* Check for alignment faults
|
||||
*/
|
||||
|
@ -522,14 +523,15 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
|||
if (VAddrSpaceEV6(req->getVaddr()) == 0x7e)
|
||||
#endif
|
||||
{
|
||||
|
||||
// only valid in kernel mode
|
||||
if (DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)) !=
|
||||
mode_kernel) {
|
||||
if (write) { write_acv++; } else { read_acv++; }
|
||||
uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) |
|
||||
MM_STAT_ACV_MASK);
|
||||
return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
|
||||
|
||||
return new DtbAcvFault(req->getVaddr(), req->getFlags(),
|
||||
flags);
|
||||
}
|
||||
|
||||
req->setPaddr(req->getVaddr() & PAddrImplMask);
|
||||
|
@ -575,25 +577,28 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
|||
uint64_t flags = MM_STAT_WR_MASK |
|
||||
MM_STAT_ACV_MASK |
|
||||
(entry->fonw ? MM_STAT_FONW_MASK : 0);
|
||||
return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
|
||||
return new DtbPageFault(req->getVaddr(), req->getFlags(),
|
||||
flags);
|
||||
}
|
||||
if (entry->fonw) {
|
||||
write_acv++;
|
||||
uint64_t flags = MM_STAT_WR_MASK |
|
||||
MM_STAT_FONW_MASK;
|
||||
return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
|
||||
uint64_t flags = MM_STAT_WR_MASK | MM_STAT_FONW_MASK;
|
||||
return new DtbPageFault(req->getVaddr(), req->getFlags(),
|
||||
flags);
|
||||
}
|
||||
} else {
|
||||
if (!(entry->xre & MODE2MASK(mode))) {
|
||||
read_acv++;
|
||||
uint64_t flags = MM_STAT_ACV_MASK |
|
||||
(entry->fonr ? MM_STAT_FONR_MASK : 0);
|
||||
return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
|
||||
return new DtbAcvFault(req->getVaddr(), req->getFlags(),
|
||||
flags);
|
||||
}
|
||||
if (entry->fonr) {
|
||||
read_acv++;
|
||||
uint64_t flags = MM_STAT_FONR_MASK;
|
||||
return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
|
||||
return new DtbPageFault(req->getVaddr(), req->getFlags(),
|
||||
flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -622,7 +627,7 @@ TLB::index(bool advance)
|
|||
return *entry;
|
||||
}
|
||||
|
||||
} // namespace AlphaISA
|
||||
/* end namespace AlphaISA */ }
|
||||
|
||||
AlphaISA::ITB *
|
||||
AlphaITBParams::create()
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
* Steve Reinhardt
|
||||
*/
|
||||
|
||||
#ifndef __ALPHA_MEMORY_HH__
|
||||
#define __ALPHA_MEMORY_HH__
|
||||
#ifndef __ARCH_ALPHA_TLB_HH__
|
||||
#define __ARCH_ALPHA_TLB_HH__
|
||||
|
||||
#include <map>
|
||||
|
||||
|
@ -48,110 +48,116 @@
|
|||
|
||||
class ThreadContext;
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
class TlbEntry;
|
||||
|
||||
class TLB : public BaseTLB
|
||||
{
|
||||
class TlbEntry;
|
||||
protected:
|
||||
typedef std::multimap<Addr, int> PageTable;
|
||||
PageTable lookupTable; // Quick lookup into page table
|
||||
|
||||
class TLB : public BaseTLB
|
||||
TlbEntry *table; // the Page Table
|
||||
int size; // TLB Size
|
||||
int nlu; // not last used entry (for replacement)
|
||||
|
||||
void nextnlu() { if (++nlu >= size) nlu = 0; }
|
||||
TlbEntry *lookup(Addr vpn, uint8_t asn);
|
||||
|
||||
public:
|
||||
typedef AlphaTLBParams Params;
|
||||
TLB(const Params *p);
|
||||
virtual ~TLB();
|
||||
|
||||
int getsize() const { return size; }
|
||||
|
||||
TlbEntry &index(bool advance = true);
|
||||
void insert(Addr vaddr, TlbEntry &entry);
|
||||
|
||||
void flushAll();
|
||||
void flushProcesses();
|
||||
void flushAddr(Addr addr, uint8_t asn);
|
||||
|
||||
void
|
||||
demapPage(Addr vaddr, uint64_t asn)
|
||||
{
|
||||
protected:
|
||||
typedef std::multimap<Addr, int> PageTable;
|
||||
PageTable lookupTable; // Quick lookup into page table
|
||||
assert(asn < (1 << 8));
|
||||
flushAddr(vaddr, asn);
|
||||
}
|
||||
|
||||
TlbEntry *table; // the Page Table
|
||||
int size; // TLB Size
|
||||
int nlu; // not last used entry (for replacement)
|
||||
|
||||
void nextnlu() { if (++nlu >= size) nlu = 0; }
|
||||
TlbEntry *lookup(Addr vpn, uint8_t asn);
|
||||
|
||||
public:
|
||||
typedef AlphaTLBParams Params;
|
||||
TLB(const Params *p);
|
||||
virtual ~TLB();
|
||||
|
||||
int getsize() const { return size; }
|
||||
|
||||
TlbEntry &index(bool advance = true);
|
||||
void insert(Addr vaddr, TlbEntry &entry);
|
||||
|
||||
void flushAll();
|
||||
void flushProcesses();
|
||||
void flushAddr(Addr addr, uint8_t asn);
|
||||
|
||||
void demapPage(Addr vaddr, uint64_t asn)
|
||||
{
|
||||
assert(asn < (1 << 8));
|
||||
flushAddr(vaddr, asn);
|
||||
}
|
||||
|
||||
// static helper functions... really EV5 VM traits
|
||||
static bool validVirtualAddress(Addr vaddr) {
|
||||
// unimplemented bits must be all 0 or all 1
|
||||
Addr unimplBits = vaddr & VAddrUnImplMask;
|
||||
return (unimplBits == 0) || (unimplBits == VAddrUnImplMask);
|
||||
}
|
||||
|
||||
static Fault checkCacheability(RequestPtr &req, bool itb = false);
|
||||
|
||||
// Checkpointing
|
||||
virtual void serialize(std::ostream &os);
|
||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
// Most recently used page table entries
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
class ITB : public TLB
|
||||
// static helper functions... really EV5 VM traits
|
||||
static bool
|
||||
validVirtualAddress(Addr vaddr)
|
||||
{
|
||||
protected:
|
||||
mutable Stats::Scalar<> hits;
|
||||
mutable Stats::Scalar<> misses;
|
||||
mutable Stats::Scalar<> acv;
|
||||
mutable Stats::Formula accesses;
|
||||
// unimplemented bits must be all 0 or all 1
|
||||
Addr unimplBits = vaddr & VAddrUnImplMask;
|
||||
return unimplBits == 0 || unimplBits == VAddrUnImplMask;
|
||||
}
|
||||
|
||||
public:
|
||||
typedef AlphaITBParams Params;
|
||||
ITB(const Params *p);
|
||||
virtual void regStats();
|
||||
static Fault checkCacheability(RequestPtr &req, bool itb = false);
|
||||
|
||||
Fault translate(RequestPtr &req, ThreadContext *tc);
|
||||
};
|
||||
// Checkpointing
|
||||
virtual void serialize(std::ostream &os);
|
||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
class DTB : public TLB
|
||||
// Most recently used page table entries
|
||||
TlbEntry *EntryCache[3];
|
||||
inline void
|
||||
flushCache()
|
||||
{
|
||||
protected:
|
||||
mutable Stats::Scalar<> read_hits;
|
||||
mutable Stats::Scalar<> read_misses;
|
||||
mutable Stats::Scalar<> read_acv;
|
||||
mutable Stats::Scalar<> read_accesses;
|
||||
mutable Stats::Scalar<> write_hits;
|
||||
mutable Stats::Scalar<> write_misses;
|
||||
mutable Stats::Scalar<> write_acv;
|
||||
mutable Stats::Scalar<> write_accesses;
|
||||
Stats::Formula hits;
|
||||
Stats::Formula misses;
|
||||
Stats::Formula acv;
|
||||
Stats::Formula accesses;
|
||||
memset(EntryCache, 0, 3 * sizeof(TlbEntry*));
|
||||
}
|
||||
|
||||
public:
|
||||
typedef AlphaDTBParams Params;
|
||||
DTB(const Params *p);
|
||||
virtual void regStats();
|
||||
inline TlbEntry *
|
||||
updateCache(TlbEntry *entry) {
|
||||
EntryCache[2] = EntryCache[1];
|
||||
EntryCache[1] = EntryCache[0];
|
||||
EntryCache[0] = entry;
|
||||
return entry;
|
||||
}
|
||||
};
|
||||
|
||||
Fault translate(RequestPtr &req, ThreadContext *tc, bool write);
|
||||
};
|
||||
}
|
||||
class ITB : public TLB
|
||||
{
|
||||
protected:
|
||||
mutable Stats::Scalar<> hits;
|
||||
mutable Stats::Scalar<> misses;
|
||||
mutable Stats::Scalar<> acv;
|
||||
mutable Stats::Formula accesses;
|
||||
|
||||
#endif // __ALPHA_MEMORY_HH__
|
||||
public:
|
||||
typedef AlphaITBParams Params;
|
||||
ITB(const Params *p);
|
||||
virtual void regStats();
|
||||
|
||||
Fault translate(RequestPtr &req, ThreadContext *tc);
|
||||
};
|
||||
|
||||
class DTB : public TLB
|
||||
{
|
||||
protected:
|
||||
mutable Stats::Scalar<> read_hits;
|
||||
mutable Stats::Scalar<> read_misses;
|
||||
mutable Stats::Scalar<> read_acv;
|
||||
mutable Stats::Scalar<> read_accesses;
|
||||
mutable Stats::Scalar<> write_hits;
|
||||
mutable Stats::Scalar<> write_misses;
|
||||
mutable Stats::Scalar<> write_acv;
|
||||
mutable Stats::Scalar<> write_accesses;
|
||||
Stats::Formula hits;
|
||||
Stats::Formula misses;
|
||||
Stats::Formula acv;
|
||||
Stats::Formula accesses;
|
||||
|
||||
public:
|
||||
typedef AlphaDTBParams Params;
|
||||
DTB(const Params *p);
|
||||
virtual void regStats();
|
||||
|
||||
Fault translate(RequestPtr &req, ThreadContext *tc, bool write);
|
||||
};
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ARCH_ALPHA_TLB_HH__
|
||||
|
|
|
@ -32,10 +32,8 @@
|
|||
#include "arch/alpha/tru64/tru64.hh"
|
||||
#include "arch/alpha/isa_traits.hh"
|
||||
#include "arch/alpha/tru64/process.hh"
|
||||
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "kern/tru64/tru64.hh"
|
||||
|
||||
#include "sim/process.hh"
|
||||
#include "sim/syscall_emul.hh"
|
||||
|
||||
|
@ -85,7 +83,7 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
|||
|
||||
case AlphaTru64::GSI_PHYSMEM: {
|
||||
TypedBufferArg<uint64_t> physmem(tc->getSyscallArg(1));
|
||||
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
|
||||
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
|
||||
physmem.copyOut(tc->getMemPort());
|
||||
return 1;
|
||||
}
|
||||
|
@ -159,14 +157,12 @@ setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/// Target table() handler.
|
||||
static
|
||||
SyscallReturn tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
static SyscallReturn
|
||||
tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
using namespace std;
|
||||
using namespace AlphaISA;
|
||||
|
||||
int id = tc->getSyscallArg(0); // table ID
|
||||
int index = tc->getSyscallArg(1); // index into table
|
||||
|
@ -472,15 +468,14 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = {
|
|||
/* 266 */ SyscallDesc("sendfile", unimplementedFunc),
|
||||
};
|
||||
|
||||
|
||||
|
||||
SyscallDesc AlphaTru64Process::machSyscallDescs[] = {
|
||||
/* 0 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 1 */ SyscallDesc("m5_mutex_lock", AlphaTru64::m5_mutex_lockFunc),
|
||||
/* 2 */ SyscallDesc("m5_mutex_trylock", AlphaTru64::m5_mutex_trylockFunc),
|
||||
/* 3 */ SyscallDesc("m5_mutex_unlock", AlphaTru64::m5_mutex_unlockFunc),
|
||||
/* 4 */ SyscallDesc("m5_cond_signal", AlphaTru64::m5_cond_signalFunc),
|
||||
/* 5 */ SyscallDesc("m5_cond_broadcast", AlphaTru64::m5_cond_broadcastFunc),
|
||||
/* 5 */ SyscallDesc("m5_cond_broadcast",
|
||||
AlphaTru64::m5_cond_broadcastFunc),
|
||||
/* 6 */ SyscallDesc("m5_cond_wait", AlphaTru64::m5_cond_waitFunc),
|
||||
/* 7 */ SyscallDesc("m5_thread_exit", AlphaTru64::m5_thread_exitFunc),
|
||||
/* 8 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
|
@ -507,7 +502,8 @@ SyscallDesc AlphaTru64Process::machSyscallDescs[] = {
|
|||
/* 29 */ SyscallDesc("nxm_thread_destroy", unimplementedFunc),
|
||||
/* 30 */ SyscallDesc("lw_wire", unimplementedFunc),
|
||||
/* 31 */ SyscallDesc("lw_unwire", unimplementedFunc),
|
||||
/* 32 */ SyscallDesc("nxm_thread_create", AlphaTru64::nxm_thread_createFunc),
|
||||
/* 32 */ SyscallDesc("nxm_thread_create",
|
||||
AlphaTru64::nxm_thread_createFunc),
|
||||
/* 33 */ SyscallDesc("nxm_task_init", AlphaTru64::nxm_task_initFunc),
|
||||
/* 34 */ SyscallDesc("kern_invalid", unimplementedFunc),
|
||||
/* 35 */ SyscallDesc("nxm_idle", AlphaTru64::nxm_idleFunc),
|
||||
|
@ -572,9 +568,8 @@ AlphaTru64Process::getDesc(int callnum)
|
|||
return &syscallDescs[callnum];
|
||||
}
|
||||
|
||||
|
||||
AlphaTru64Process::AlphaTru64Process(LiveProcessParams * params,
|
||||
ObjectFile *objFile)
|
||||
AlphaTru64Process::AlphaTru64Process(LiveProcessParams *params,
|
||||
ObjectFile *objFile)
|
||||
: AlphaLiveProcess(params, objFile),
|
||||
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)),
|
||||
Num_Mach_Syscall_Descs(sizeof(machSyscallDescs) / sizeof(SyscallDesc))
|
||||
|
|
|
@ -28,12 +28,13 @@
|
|||
* Authors: Steve Reinhardt
|
||||
*/
|
||||
|
||||
#ifndef __ALPHA_TRU64_PROCESS_HH__
|
||||
#define __ALPHA_TRU64_PROCESS_HH__
|
||||
#ifndef __ARCH_ALPHA_TRU64_PROCESS_HH__
|
||||
#define __ARCH_ALPHA_TRU64_PROCESS_HH__
|
||||
|
||||
#include "arch/alpha/process.hh"
|
||||
|
||||
namespace AlphaISA {
|
||||
|
||||
/// A process with emulated Alpha Tru64 syscalls.
|
||||
class AlphaTru64Process : public AlphaLiveProcess
|
||||
{
|
||||
|
@ -51,9 +52,9 @@ class AlphaTru64Process : public AlphaLiveProcess
|
|||
const int Num_Syscall_Descs;
|
||||
const int Num_Mach_Syscall_Descs;
|
||||
|
||||
virtual SyscallDesc* getDesc(int callnum);
|
||||
virtual SyscallDesc *getDesc(int callnum);
|
||||
};
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif // __ALPHA_TRU64_PROCESS_HH__
|
||||
#endif // __ARCH_ALPHA_TRU64_PROCESS_HH__
|
||||
|
|
|
@ -28,14 +28,13 @@
|
|||
* Authors: Korey Sewell
|
||||
*/
|
||||
|
||||
#ifndef __ALPHA_ALPHA_TRU64_HH
|
||||
#define __ALPHA_ALPHA_TRU64_HH
|
||||
#ifndef __ALPHA_ALPHA_TRU64_TRU64_HH__
|
||||
#define __ALPHA_ALPHA_TRU64_TRU64_HH__
|
||||
|
||||
#include "kern/tru64/tru64.hh"
|
||||
|
||||
class AlphaTru64 : public Tru64
|
||||
{
|
||||
|
||||
public:
|
||||
/// This table maps the target open() flags to the corresponding
|
||||
/// host open() flags.
|
||||
|
@ -68,13 +67,13 @@ class AlphaTru64 : public Tru64
|
|||
|
||||
//@{
|
||||
/// For getsysinfo().
|
||||
static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
|
||||
static const unsigned GSI_CPU_INFO = 59; //!< CPU information
|
||||
static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
|
||||
static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine
|
||||
static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
|
||||
static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB
|
||||
static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
|
||||
static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name string
|
||||
static const unsigned GSI_CPU_INFO = 59; //!< CPU information
|
||||
static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
|
||||
static const unsigned GSI_MAX_CPU = 30; //!< max # CPUs on machine
|
||||
static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
|
||||
static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB
|
||||
static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
|
||||
//@}
|
||||
|
||||
//@{
|
||||
|
@ -124,6 +123,4 @@ class AlphaTru64 : public Tru64
|
|||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#endif // __ALPHA_ALPHA_TRU64_TRU64_HH__
|
||||
|
|
|
@ -32,47 +32,50 @@
|
|||
#ifndef __ARCH_ALPHA_TYPES_HH__
|
||||
#define __ARCH_ALPHA_TYPES_HH__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "sim/host.hh"
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
typedef uint32_t MachInst;
|
||||
typedef uint64_t ExtMachInst;
|
||||
typedef uint8_t RegIndex;
|
||||
|
||||
typedef uint64_t IntReg;
|
||||
typedef uint64_t LargestRead;
|
||||
|
||||
// floating point register file entry type
|
||||
typedef double FloatReg;
|
||||
typedef uint64_t FloatRegBits;
|
||||
|
||||
// control register file contents
|
||||
typedef uint64_t MiscReg;
|
||||
|
||||
union AnyReg
|
||||
{
|
||||
IntReg intreg;
|
||||
FloatReg fpreg;
|
||||
MiscReg ctrlreg;
|
||||
};
|
||||
|
||||
typedef uint32_t MachInst;
|
||||
typedef uint64_t ExtMachInst;
|
||||
typedef uint8_t RegIndex;
|
||||
enum RegContextParam
|
||||
{
|
||||
CONTEXT_PALMODE
|
||||
};
|
||||
|
||||
typedef uint64_t IntReg;
|
||||
typedef uint64_t LargestRead;
|
||||
typedef bool RegContextVal;
|
||||
|
||||
// floating point register file entry type
|
||||
typedef double FloatReg;
|
||||
typedef uint64_t FloatRegBits;
|
||||
enum annotes
|
||||
{
|
||||
ANNOTE_NONE = 0,
|
||||
// An impossible number for instruction annotations
|
||||
ITOUCH_ANNOTE = 0xffffffff,
|
||||
};
|
||||
|
||||
// control register file contents
|
||||
typedef uint64_t MiscReg;
|
||||
struct CoreSpecific
|
||||
{
|
||||
int core_type;
|
||||
};
|
||||
|
||||
typedef union {
|
||||
IntReg intreg;
|
||||
FloatReg fpreg;
|
||||
MiscReg ctrlreg;
|
||||
} AnyReg;
|
||||
|
||||
enum RegContextParam
|
||||
{
|
||||
CONTEXT_PALMODE
|
||||
};
|
||||
|
||||
typedef bool RegContextVal;
|
||||
|
||||
enum annotes {
|
||||
ANNOTE_NONE = 0,
|
||||
// An impossible number for instruction annotations
|
||||
ITOUCH_ANNOTE = 0xffffffff,
|
||||
};
|
||||
|
||||
struct CoreSpecific {
|
||||
int core_type;
|
||||
};
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif
|
||||
#endif // __ARCH_ALPHA_TYPES_HH__
|
||||
|
|
|
@ -36,10 +36,10 @@
|
|||
#include "mem/vport.hh"
|
||||
#endif
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
namespace AlphaISA {
|
||||
|
||||
uint64_t getArgument(ThreadContext *tc, int number, bool fp)
|
||||
uint64_t
|
||||
getArgument(ThreadContext *tc, int number, bool fp)
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
if (number < NumArgumentRegs) {
|
||||
|
@ -56,7 +56,7 @@ uint64_t getArgument(ThreadContext *tc, int number, bool fp)
|
|||
}
|
||||
#else
|
||||
panic("getArgument() is Full system only\n");
|
||||
M5_DUMMY_RETURN
|
||||
M5_DUMMY_RETURN;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -32,137 +32,137 @@
|
|||
#ifndef __ARCH_ALPHA_UTILITY_HH__
|
||||
#define __ARCH_ALPHA_UTILITY_HH__
|
||||
|
||||
#include "config/full_system.hh"
|
||||
#include "arch/alpha/types.hh"
|
||||
#include "arch/alpha/isa_traits.hh"
|
||||
#include "arch/alpha/regfile.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
|
||||
namespace AlphaISA
|
||||
namespace AlphaISA {
|
||||
|
||||
uint64_t getArgument(ThreadContext *tc, int number, bool fp);
|
||||
|
||||
inline bool
|
||||
inUserMode(ThreadContext *tc)
|
||||
{
|
||||
uint64_t getArgument(ThreadContext *tc, int number, bool fp);
|
||||
return (tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
inUserMode(ThreadContext *tc)
|
||||
{
|
||||
return (tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0;
|
||||
}
|
||||
inline bool
|
||||
isCallerSaveIntegerRegister(unsigned int reg)
|
||||
{
|
||||
panic("register classification not implemented");
|
||||
return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27);
|
||||
}
|
||||
|
||||
inline bool
|
||||
isCallerSaveIntegerRegister(unsigned int reg)
|
||||
{
|
||||
panic("register classification not implemented");
|
||||
return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27);
|
||||
}
|
||||
inline bool
|
||||
isCalleeSaveIntegerRegister(unsigned int reg)
|
||||
{
|
||||
panic("register classification not implemented");
|
||||
return (reg >= 9 && reg <= 15);
|
||||
}
|
||||
|
||||
inline bool
|
||||
isCalleeSaveIntegerRegister(unsigned int reg)
|
||||
{
|
||||
panic("register classification not implemented");
|
||||
return (reg >= 9 && reg <= 15);
|
||||
}
|
||||
inline bool
|
||||
isCallerSaveFloatRegister(unsigned int reg)
|
||||
{
|
||||
panic("register classification not implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isCallerSaveFloatRegister(unsigned int reg)
|
||||
{
|
||||
panic("register classification not implemented");
|
||||
return false;
|
||||
}
|
||||
inline bool
|
||||
isCalleeSaveFloatRegister(unsigned int reg)
|
||||
{
|
||||
panic("register classification not implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isCalleeSaveFloatRegister(unsigned int reg)
|
||||
{
|
||||
panic("register classification not implemented");
|
||||
return false;
|
||||
}
|
||||
inline Addr
|
||||
alignAddress(const Addr &addr, unsigned int nbytes)
|
||||
{
|
||||
return (addr & ~(nbytes - 1));
|
||||
}
|
||||
|
||||
inline Addr
|
||||
alignAddress(const Addr &addr, unsigned int nbytes)
|
||||
{
|
||||
return (addr & ~(nbytes - 1));
|
||||
}
|
||||
// Instruction address compression hooks
|
||||
inline Addr
|
||||
realPCToFetchPC(const Addr &addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
// Instruction address compression hooks
|
||||
inline Addr
|
||||
realPCToFetchPC(const Addr &addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
inline Addr
|
||||
fetchPCToRealPC(const Addr &addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
inline Addr
|
||||
fetchPCToRealPC(const Addr &addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
// the size of "fetched" instructions (not necessarily the size
|
||||
// of real instructions for PISA)
|
||||
inline size_t
|
||||
fetchInstSize()
|
||||
{
|
||||
return sizeof(MachInst);
|
||||
}
|
||||
|
||||
// the size of "fetched" instructions (not necessarily the size
|
||||
// of real instructions for PISA)
|
||||
inline size_t
|
||||
fetchInstSize()
|
||||
{
|
||||
return sizeof(MachInst);
|
||||
}
|
||||
inline MachInst
|
||||
makeRegisterCopy(int dest, int src)
|
||||
{
|
||||
panic("makeRegisterCopy not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline MachInst
|
||||
makeRegisterCopy(int dest, int src)
|
||||
{
|
||||
panic("makeRegisterCopy not implemented");
|
||||
return 0;
|
||||
}
|
||||
// Machine operations
|
||||
void saveMachineReg(AnyReg &savereg, const RegFile ®_file, int regnum);
|
||||
void restoreMachineReg(RegFile ®s, const AnyReg ®, int regnum);
|
||||
|
||||
// Machine operations
|
||||
void saveMachineReg(AnyReg &savereg, const RegFile ®_file, int regnum);
|
||||
void restoreMachineReg(RegFile ®s, const AnyReg ®, int regnum);
|
||||
/**
|
||||
* Function to insure ISA semantics about 0 registers.
|
||||
* @param tc The thread context.
|
||||
*/
|
||||
template <class TC>
|
||||
void zeroRegisters(TC *tc);
|
||||
|
||||
/**
|
||||
* Function to insure ISA semantics about 0 registers.
|
||||
* @param tc The thread context.
|
||||
*/
|
||||
template <class TC>
|
||||
void zeroRegisters(TC *tc);
|
||||
// Alpha IPR register accessors
|
||||
inline bool PcPAL(Addr addr) { return addr & 0x3; }
|
||||
inline void startupCPU(ThreadContext *tc, int cpuId) { tc->activate(0); }
|
||||
|
||||
// Alpha IPR register accessors
|
||||
inline bool PcPAL(Addr addr) { return addr & 0x3; }
|
||||
inline void startupCPU(ThreadContext *tc, int cpuId) { tc->activate(0); }
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Translation stuff
|
||||
//
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Translation stuff
|
||||
//
|
||||
inline Addr PteAddr(Addr a) { return (a & PteMask) << PteShift; }
|
||||
|
||||
inline Addr PteAddr(Addr a) { return (a & PteMask) << PteShift; }
|
||||
// User Virtual
|
||||
inline bool IsUSeg(Addr a) { return USegBase <= a && a <= USegEnd; }
|
||||
|
||||
// User Virtual
|
||||
inline bool IsUSeg(Addr a) { return USegBase <= a && a <= USegEnd; }
|
||||
// Kernel Direct Mapped
|
||||
inline bool IsK0Seg(Addr a) { return K0SegBase <= a && a <= K0SegEnd; }
|
||||
inline Addr K0Seg2Phys(Addr addr) { return addr & ~K0SegBase; }
|
||||
|
||||
// Kernel Direct Mapped
|
||||
inline bool IsK0Seg(Addr a) { return K0SegBase <= a && a <= K0SegEnd; }
|
||||
inline Addr K0Seg2Phys(Addr addr) { return addr & ~K0SegBase; }
|
||||
// Kernel Virtual
|
||||
inline bool IsK1Seg(Addr a) { return K1SegBase <= a && a <= K1SegEnd; }
|
||||
|
||||
// Kernel Virtual
|
||||
inline bool IsK1Seg(Addr a) { return K1SegBase <= a && a <= K1SegEnd; }
|
||||
inline Addr
|
||||
TruncPage(Addr addr)
|
||||
{ return addr & ~(PageBytes - 1); }
|
||||
|
||||
inline Addr
|
||||
TruncPage(Addr addr)
|
||||
{ return addr & ~(PageBytes - 1); }
|
||||
inline Addr
|
||||
RoundPage(Addr addr)
|
||||
{ return (addr + PageBytes - 1) & ~(PageBytes - 1); }
|
||||
|
||||
inline Addr
|
||||
RoundPage(Addr addr)
|
||||
{ return (addr + PageBytes - 1) & ~(PageBytes - 1); }
|
||||
|
||||
void initIPRs(ThreadContext *tc, int cpuId);
|
||||
void initIPRs(ThreadContext *tc, int cpuId);
|
||||
#if FULL_SYSTEM
|
||||
void initCPU(ThreadContext *tc, int cpuId);
|
||||
void initCPU(ThreadContext *tc, int cpuId);
|
||||
|
||||
/**
|
||||
* Function to check for and process any interrupts.
|
||||
* @param tc The thread context.
|
||||
*/
|
||||
template <class TC>
|
||||
void processInterrupts(TC *tc);
|
||||
/**
|
||||
* Function to check for and process any interrupts.
|
||||
* @param tc The thread context.
|
||||
*/
|
||||
template <class TC>
|
||||
void processInterrupts(TC *tc);
|
||||
#endif
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif
|
||||
#endif // __ARCH_ALPHA_UTILITY_HH__
|
||||
|
|
|
@ -115,4 +115,3 @@ vtophys(ThreadContext *tc, Addr addr)
|
|||
}
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
|
|
|
@ -41,12 +41,13 @@ class FunctionalPort;
|
|||
|
||||
namespace AlphaISA {
|
||||
|
||||
PageTableEntry
|
||||
kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, VAddr vaddr);
|
||||
PageTableEntry kernel_pte_lookup(FunctionalPort *mem, Addr ptbr,
|
||||
VAddr vaddr);
|
||||
|
||||
Addr vtophys(Addr vaddr);
|
||||
Addr vtophys(ThreadContext *tc, Addr vaddr);
|
||||
Addr vtophys(Addr vaddr);
|
||||
Addr vtophys(ThreadContext *tc, Addr vaddr);
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
};
|
||||
#endif // __ARCH_ALPHA_VTOPHYS_H__
|
||||
|
||||
|
|
|
@ -59,20 +59,19 @@ BadAddrEvent::process(ThreadContext *tc)
|
|||
bool found = false;
|
||||
|
||||
tc->getPhysPort()->getPeerAddressRanges(resp, snoop);
|
||||
for(iter = resp.begin(); iter != resp.end(); iter++)
|
||||
{
|
||||
if (*iter == (TheISA::K0Seg2Phys(a0) & AlphaISA::PAddrImplMask))
|
||||
for (iter = resp.begin(); iter != resp.end(); iter++) {
|
||||
if (*iter == (K0Seg2Phys(a0) & PAddrImplMask))
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!TheISA::IsK0Seg(a0) || found ) {
|
||||
if (!IsK0Seg(a0) || found ) {
|
||||
|
||||
DPRINTF(BADADDR, "badaddr arg=%#x bad\n", a0);
|
||||
tc->setIntReg(ReturnValueReg, 0x1);
|
||||
SkipFuncEvent::process(tc);
|
||||
}
|
||||
else
|
||||
} else {
|
||||
DPRINTF(BADADDR, "badaddr arg=%#x good\n", a0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue