Pushed most of constants.hh back into isa_traits.hh and regfile.hh and created a seperate file for the syscallreturn class.

--HG--
extra : convert_revision : 9507ea1c09fda959f00aec9ec8ffb887ec8dd0f9
This commit is contained in:
Gabe Black 2006-08-11 19:43:10 -04:00
parent f612f09669
commit 800e6ecc07
37 changed files with 2720 additions and 1090 deletions

View file

@ -47,13 +47,12 @@ sources = []
# List of headers to generate
isa_switch_hdrs = Split('''
arguments.hh
constants.hh
faults.hh
isa_traits.hh
process.hh
regfile.hh
stacktrace.hh
syscallreturn.hh
tlb.hh
types.hh
utility.hh

View file

@ -35,49 +35,12 @@
namespace LittleEndianGuest {}
#include "arch/alpha/types.hh"
#include "arch/alpha/constants.hh"
#include "arch/alpha/regfile.hh"
#include "arch/alpha/isa_traits.hh"
#include "config/full_system.hh"
#include "sim/host.hh"
class StaticInstPtr;
#if !FULL_SYSTEM
class SyscallReturn {
public:
template <class T>
SyscallReturn(T v, bool s)
{
retval = (uint64_t)v;
success = s;
}
template <class T>
SyscallReturn(T v)
{
success = (v >= 0);
retval = (uint64_t)v;
}
~SyscallReturn() {}
SyscallReturn& operator=(const SyscallReturn& s) {
retval = s.retval;
success = s.success;
return *this;
}
bool successful() { return success; }
uint64_t value() { return retval; }
private:
uint64_t retval;
bool success;
};
#endif
#if FULL_SYSTEM
#include "arch/alpha/isa_fullsys_traits.hh"
#endif
@ -86,30 +49,244 @@ class SyscallReturn {
namespace AlphaISA
{
using namespace LittleEndianGuest;
using namespace LittleEndianGuest;
// redirected register map, really only used for the full system case.
extern const int reg_redir[NumIntRegs];
// 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,
Fpcr_DepTag = 72, // floating point control register
Uniq_DepTag = 73,
Lock_Flag_DepTag = 74,
Lock_Addr_DepTag = 75,
IPR_Base_DepTag = 76
};
StaticInstPtr decodeInst(ExtMachInst);
#if !FULL_SYSTEM
static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
const Addr PageShift = 13;
const Addr PageBytes = ULL(1) << PageShift;
const Addr PageMask = ~(PageBytes - 1);
const Addr PageOffset = PageBytes - 1;
#if FULL_SYSTEM
////////////////////////////////////////////////////////////////////////
//
// 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
{
// 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
regs->setIntReg(SyscallSuccessReg, 0);
regs->setIntReg(ReturnValueReg, return_value.value());
} else {
// got an error, return details
regs->setIntReg(SyscallSuccessReg, (IntReg)-1);
regs->setIntReg(ReturnValueReg, -return_value.value());
}
}
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
};
#endif
#if FULL_SYSTEM
////////////////////////////////////////////////////////////////////////
//
// Internal Processor Reigsters
//
enum md_ipr_names
{
IPR_ISR = 0x100, // interrupt summary register
IPR_ITB_TAG = 0x101, // ITLB tag register
IPR_ITB_PTE = 0x102, // ITLB page table entry register
IPR_ITB_ASN = 0x103, // ITLB address space register
IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register
IPR_ITB_IA = 0x105, // ITLB invalidate all register
IPR_ITB_IAP = 0x106, // ITLB invalidate all process register
IPR_ITB_IS = 0x107, // ITLB invalidate select register
IPR_SIRR = 0x108, // software interrupt request register
IPR_ASTRR = 0x109, // asynchronous system trap request register
IPR_ASTER = 0x10a, // asynchronous system trap enable register
IPR_EXC_ADDR = 0x10b, // exception address register
IPR_EXC_SUM = 0x10c, // exception summary register
IPR_EXC_MASK = 0x10d, // exception mask register
IPR_PAL_BASE = 0x10e, // PAL base address register
IPR_ICM = 0x10f, // instruction current mode
IPR_IPLR = 0x110, // interrupt priority level register
IPR_INTID = 0x111, // interrupt ID register
IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register
IPR_IVPTBR = 0x113, // virtual page table base register
IPR_HWINT_CLR = 0x115, // H/W interrupt clear register
IPR_SL_XMIT = 0x116, // serial line transmit register
IPR_SL_RCV = 0x117, // serial line receive register
IPR_ICSR = 0x118, // instruction control and status register
IPR_IC_FLUSH = 0x119, // instruction cache flush control
IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register
IPR_PMCTR = 0x11c, // performance counter register
// PAL temporary registers...
// register meanings gleaned from osfpal.s source code
IPR_PALtemp0 = 0x140, // local scratch
IPR_PALtemp1 = 0x141, // local scratch
IPR_PALtemp2 = 0x142, // entUna
IPR_PALtemp3 = 0x143, // CPU specific impure area pointer
IPR_PALtemp4 = 0x144, // memory management temp
IPR_PALtemp5 = 0x145, // memory management temp
IPR_PALtemp6 = 0x146, // memory management temp
IPR_PALtemp7 = 0x147, // entIF
IPR_PALtemp8 = 0x148, // intmask
IPR_PALtemp9 = 0x149, // entSys
IPR_PALtemp10 = 0x14a, // ??
IPR_PALtemp11 = 0x14b, // entInt
IPR_PALtemp12 = 0x14c, // entArith
IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL
IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL
IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL
IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0>
IPR_PALtemp17 = 0x151, // sysval
IPR_PALtemp18 = 0x152, // usp
IPR_PALtemp19 = 0x153, // ksp
IPR_PALtemp20 = 0x154, // PTBR
IPR_PALtemp21 = 0x155, // entMM
IPR_PALtemp22 = 0x156, // kgp
IPR_PALtemp23 = 0x157, // PCBB
IPR_DTB_ASN = 0x200, // DTLB address space number register
IPR_DTB_CM = 0x201, // DTLB current mode register
IPR_DTB_TAG = 0x202, // DTLB tag register
IPR_DTB_PTE = 0x203, // DTLB page table entry register
IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register
IPR_MM_STAT = 0x205, // data MMU fault status register
IPR_VA = 0x206, // fault virtual address register
IPR_VA_FORM = 0x207, // formatted virtual address register
IPR_MVPTBR = 0x208, // MTU virtual page table base register
IPR_DTB_IAP = 0x209, // DTLB invalidate all process register
IPR_DTB_IA = 0x20a, // DTLB invalidate all register
IPR_DTB_IS = 0x20b, // DTLB invalidate single register
IPR_ALT_MODE = 0x20c, // alternate mode register
IPR_CC = 0x20d, // cycle counter register
IPR_CC_CTL = 0x20e, // cycle counter control register
IPR_MCSR = 0x20f, // MTU control register
IPR_DC_FLUSH = 0x210,
IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register
IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register
IPR_DC_TEST_TAG = 0x214, // Dcache test tag register
IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary register
IPR_DC_MODE = 0x216, // Dcache mode register
IPR_MAF_MODE = 0x217, // miss address file mode register
NumInternalProcRegs // number of IPR registers
};
#else
const int NumInternalProcRegs = 0;
#endif
// 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 = 32;
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;
// Static instruction parameters
const int MaxInstSrcRegs = 3;
const int MaxInstDestRegs = 2;
// 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 ArgumentReg0 = 16;
const int ArgumentReg1 = 17;
const int ArgumentReg2 = 18;
const int ArgumentReg3 = 19;
const int ArgumentReg4 = 20;
const int ArgumentReg5 = 21;
const int SyscallNumReg = ReturnValueReg;
const int SyscallPseudoReturnReg = ArgumentReg4;
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;
// redirected register map, really only used for the full system case.
extern const int reg_redir[NumIntRegs];
};
#endif // __ARCH_ALPHA_ISA_TRAITS_HH__

View file

@ -29,7 +29,7 @@
* Ali Saidi
*/
#include "arch/alpha/constants.hh"
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/process.hh"
#include "base/loader/object_file.hh"
#include "base/misc.hh"

View file

@ -32,14 +32,19 @@
#define __ARCH_ALPHA_REGFILE_HH__
#include "arch/alpha/types.hh"
#include "arch/alpha/constants.hh"
#include "arch/alpha/isa_traits.hh"
#include "sim/faults.hh"
#include <string>
//XXX These should be implemented by someone who knows the alpha stuff better
class Checkpoint;
class ThreadContext;
namespace AlphaISA
{
class IntRegFile
{
protected:
@ -268,14 +273,7 @@ namespace AlphaISA
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
enum ContextParam
{
CONTEXT_PALMODE
};
typedef bool ContextVal;
void changeContext(ContextParam param, ContextVal val)
void changeContext(RegContextParam param, RegContextVal val)
{
//This would be an alternative place to call/implement
//the swapPALShadow function

View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Reinhardt
* Gabe Black
*/
#ifndef __ARCH_ALPHA_SYSCALLRETURN_HH__
#define __ARCH_ALPHA_SYSCALLRETURN_HH__
class SyscallReturn {
public:
template <class T>
SyscallReturn(T v, bool s)
{
retval = (uint64_t)v;
success = s;
}
template <class T>
SyscallReturn(T v)
{
success = (v >= 0);
retval = (uint64_t)v;
}
~SyscallReturn() {}
SyscallReturn& operator=(const SyscallReturn& s) {
retval = s.retval;
success = s.success;
return *this;
}
bool successful() { return success; }
uint64_t value() { return retval; }
private:
uint64_t retval;
bool success;
};
namespace AlphaISA
{
static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
{
// 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
regs->setIntReg(SyscallSuccessReg, 0);
regs->setIntReg(ReturnValueReg, return_value.value());
} else {
// got an error, return details
regs->setIntReg(SyscallSuccessReg, (IntReg)-1);
regs->setIntReg(ReturnValueReg, -return_value.value());
}
}
}
#endif

View file

@ -32,7 +32,7 @@
#ifndef __ARCH_ALPHA_TYPES_HH__
#define __ARCH_ALPHA_TYPES_HH__
#include "sim/host.hh"
#include <inttypes.h>
namespace AlphaISA
{
@ -56,6 +56,13 @@ namespace AlphaISA
MiscReg ctrlreg;
} AnyReg;
enum RegContextParam
{
CONTEXT_PALMODE
};
typedef bool RegContextVal;
enum annotes {
ANNOTE_NONE = 0,
// An impossible number for instruction annotations

View file

@ -34,7 +34,7 @@
#include "config/full_system.hh"
#include "arch/alpha/types.hh"
#include "arch/alpha/constants.hh"
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/regfile.hh"
#include "base/misc.hh"

View file

@ -30,15 +30,13 @@
*/
#include "arch/mips/isa_traits.hh"
//#include "config/full_system.hh"
#include "cpu/static_inst.hh"
#include "arch/mips/regfile/regfile.hh"
#include "sim/serialize.hh"
#include "base/bitfield.hh"
using namespace MipsISA;
using namespace std;
void
MipsISA::copyRegs(ThreadContext *src, ThreadContext *dest)
{

View file

@ -32,149 +32,87 @@
#ifndef __ARCH_MIPS_ISA_TRAITS_HH__
#define __ARCH_MIPS_ISA_TRAITS_HH__
#include "arch/mips/constants.hh"
#include "arch/mips/types.hh"
#include "arch/mips/regfile/regfile.hh"
#include "arch/mips/faults.hh"
#include "arch/mips/utility.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
#include "sim/byteswap.hh"
#include "sim/host.hh"
#include "sim/faults.hh"
#include <vector>
class FastCPU;
class FullCPU;
class Checkpoint;
class ThreadContext;
namespace LittleEndianGuest {};
#define TARGET_MIPS
class StaticInst;
class StaticInstPtr;
class SyscallReturn {
public:
template <class T>
SyscallReturn(T v, bool s)
{
retval = (uint32_t)v;
success = s;
}
template <class T>
SyscallReturn(T v)
{
success = (v >= 0);
retval = (uint32_t)v;
}
~SyscallReturn() {}
SyscallReturn& operator=(const SyscallReturn& s) {
retval = s.retval;
success = s.success;
return *this;
}
bool successful() { return success; }
uint64_t value() { return retval; }
private:
uint64_t retval;
bool success;
};
namespace MipsISA
{
using namespace LittleEndianGuest;
static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
{
if (return_value.successful()) {
// no error
regs->setIntReg(SyscallSuccessReg, 0);
regs->setIntReg(ReturnValueReg1, return_value.value());
} else {
// got an error, return details
regs->setIntReg(SyscallSuccessReg, (IntReg) -1);
regs->setIntReg(ReturnValueReg1, -return_value.value());
}
}
StaticInstPtr decodeInst(ExtMachInst);
static inline ExtMachInst
makeExtMI(MachInst inst, const uint64_t &pc) {
#if FULL_SYSTEM
ExtMachInst ext_inst = inst;
if (pc && 0x1)
return ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
else
return ext_inst;
#else
return ExtMachInst(inst);
#endif
}
const Addr PageShift = 13;
const Addr PageBytes = ULL(1) << PageShift;
const Addr PageMask = ~(PageBytes - 1);
const Addr PageOffset = PageBytes - 1;
/**
* Function to insure ISA semantics about 0 registers.
* @param tc The thread context.
*/
template <class TC>
void zeroRegisters(TC *tc);
// return a no-op instruction... used for instruction fetch faults
const ExtMachInst NoopMachInst = 0x00000000;
// const Addr MaxAddr = (Addr)-1;
// Constants Related to the number of registers
const int NumIntArchRegs = 32;
const int NumIntSpecialRegs = 2;
const int NumFloatArchRegs = 32;
const int NumFloatSpecialRegs = 5;
const int NumControlRegs = 265;
const int NumInternalProcRegs = 0;
void copyRegs(ThreadContext *src, ThreadContext *dest);
const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs; //HI & LO Regs
const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;//
const int NumMiscRegs = NumControlRegs;
// Machine operations
const int TotalNumRegs = NumIntRegs + NumFloatRegs +
NumMiscRegs + 0/*NumInternalProcRegs*/;
void saveMachineReg(AnyReg &savereg, const RegFile &reg_file,
int regnum);
const int TotalDataRegs = NumIntRegs + NumFloatRegs;
void restoreMachineReg(RegFile &regs, const AnyReg &reg,
int regnum);
// Static instruction parameters
const int MaxInstSrcRegs = 3;
const int MaxInstDestRegs = 2;
#if 0
static void serializeSpecialRegs(const Serializable::Proxy &proxy,
const RegFile &regs);
// semantically meaningful register indices
const int ZeroReg = 0;
const int AssemblerReg = 1;
const int ReturnValueReg = 2;
const int ReturnValueReg1 = 2;
const int ReturnValueReg2 = 3;
const int ArgumentReg0 = 4;
const int ArgumentReg1 = 5;
const int ArgumentReg2 = 6;
const int ArgumentReg3 = 7;
const int KernelReg0 = 26;
const int KernelReg1 = 27;
const int GlobalPointerReg = 28;
const int StackPointerReg = 29;
const int FramePointerReg = 30;
const int ReturnAddressReg = 31;
static void unserializeSpecialRegs(const IniFile *db,
const std::string &category,
ConfigNode *node,
RegFile &regs);
#endif
const int SyscallNumReg = ReturnValueReg1;
const int SyscallPseudoReturnReg = ReturnValueReg1;
const int SyscallSuccessReg = ArgumentReg3;
static inline Addr alignAddress(const Addr &addr,
unsigned int nbytes) {
return (addr & ~(nbytes - 1));
}
const int LogVMPageSize = 13; // 8K bytes
const int VMPageSize = (1 << LogVMPageSize);
// Instruction address compression hooks
static inline Addr realPCToFetchPC(const Addr &addr) {
return addr;
}
const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
static inline Addr fetchPCToRealPC(const Addr &addr) {
return addr;
}
const int MachineBytes = 4;
const int WordBytes = 4;
const int HalfwordBytes = 2;
const int ByteBytes = 1;
// the size of "fetched" instructions (not necessarily the size
// of real instructions for PISA)
static inline size_t fetchInstSize() {
return sizeof(MachInst);
}
// These help enumerate all the registers for dependence tracking.
const int FP_Base_DepTag = 34;
const int Ctrl_Base_DepTag = 257;
static inline MachInst makeRegisterCopy(int dest, int src) {
panic("makeRegisterCopy not implemented");
return 0;
}
const int ANNOTE_NONE = 0;
const uint32_t ITOUCH_ANNOTE = 0xffffffff;
};

36
src/arch/mips/regfile.hh Normal file
View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Korey Sewell
*/
#ifndef __ARCH_MIPS_REGFILE_HH__
#define __ARCH_MIPS_REGFILE_HH__
#include "arch/mips/regfile/regfile.hh"
#endif

View file

@ -26,24 +26,56 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ARCH_MIPS_FLOAT_REGFILE_HH__
#define __ARCH_MIPS_FLOAT_REGFILE_HH__
#ifndef __ARCH_MIPS_REGFILE_FLOAT_REGFILE_HH__
#define __ARCH_MIPS_REGFILE_FLOAT_REGFILE_HH__
#include "arch/mips/types.hh"
#include "arch/mips/constants.hh"
#include "arch/mips/isa_traits.hh"
#include "base/misc.hh"
#include "base/bitfield.hh"
#include "config/full_system.hh"
#include "sim/byteswap.hh"
#include "sim/faults.hh"
#include "sim/host.hh"
#include <string>
class Checkpoint;
class ExecContext;
class Regfile;
namespace MipsISA
{
const uint32_t MIPS32_QNAN = 0x7fbfffff;
const uint64_t MIPS64_QNAN = ULL(0x7fbfffffffffffff);
enum FPControlRegNums {
FIR = NumFloatArchRegs,
FCCR,
FEXR,
FENR,
FCSR
};
enum FCSRBits {
Inexact = 1,
Underflow,
Overflow,
DivideByZero,
Invalid,
Unimplemented
};
enum FCSRFields {
Flag_Field = 1,
Enable_Field = 6,
Cause_Field = 11
};
const int SingleWidth = 32;
const int SingleBytes = SingleWidth / 4;
const int DoubleWidth = 64;
const int DoubleBytes = DoubleWidth / 4;
const int QuadWidth = 128;
const int QuadBytes = QuadWidth / 4;
class FloatRegFile
{
protected:

View file

@ -28,20 +28,24 @@
* Authors: Korey Sewell
*/
#ifndef __ARCH_MIPS_INT_REGFILE_HH__
#define __ARCH_MIPS_INT_REGFILE_HH__
#ifndef __ARCH_MIPS_REGFILE_INT_REGFILE_HH__
#define __ARCH_MIPS_REGFILE_INT_REGFILE_HH__
#include "arch/mips/types.hh"
#include "arch/mips/constants.hh"
#include "arch/mips/isa_traits.hh"
#include "base/misc.hh"
#include "sim/faults.hh"
class Checkpoint;
class ThreadContext;
class Regfile;
namespace MipsISA
{
enum MiscIntRegNums {
HI = NumIntArchRegs,
LO
};
class IntRegFile
{
protected:

View file

@ -28,19 +28,164 @@
* Authors: Korey Sewell
*/
#ifndef __ARCH_MIPS_MISC_REGFILE_HH__
#define __ARCH_MIPS_MISC_REGFILE_HH__
#ifndef __ARCH_MIPS_REGFILE_MISC_REGFILE_HH__
#define __ARCH_MIPS_REGFILE_MISC_REGFILE_HH__
#include "arch/mips/isa_traits.hh"
#include "arch/mips/types.hh"
#include "arch/mips/constants.hh"
#include "sim/faults.hh"
class Checkpoint;
class ThreadContext;
class Regfile;
namespace MipsISA
{
//Coprocessor 0 Register Names
enum MiscRegTags {
//Reference MIPS32 Arch. for Programmers, Vol. III, Ch.8
//(Register Number-Register Select) Summary of Register
//------------------------------------------------------
Index = 0, //Bank 0: 0 - 3
MVPControl,
MVPConf0,
MVPConf1,
Random = 8, //Bank 1: 8 - 15
VPEControl,
VPEConf0,
VPEConf1,
YQMask,
VPESchedule,
VPEScheFBack,
VPEOpt,
EntryLo0 = 16, //Bank 2: 16 - 23
TCStatus,
TCBind,
TCRestart,
TCHalt,
TCContext,
TCSchedule,
TCScheFBack,
EntryLo1 = 24, // Bank 3: 24
Context = 32, // Bank 4: 32 - 33
ContextConfig,
//PageMask = 40, //Bank 5: 40 - 41
PageGrain = 41,
Wired = 48, //Bank 6: 48 - 55
SRSConf0,
SRSConf1,
SRSConf2,
SRSConf3,
SRSConf4,
HWRena = 56, //Bank 7: 56
BadVAddr = 63, //Bank 8: 63
Count = 64, //Bank 9: 64
EntryHi = 72, //Bank 10:72 - 79
Compare = 80, //Bank 10:80 - 87
Status = 88, //Bank 12:88 - 96
IntCtl = 89,
SRSCtl = 90,
SRSMap = 91,
Cause = 97, //97-104
EPC = 105, //105-112
PRId = 113, //113-120,
EBase = 114,
Config = 121, //Bank 16: 121-128
Config1 = 122,
Config2 = 123,
Config3 = 124,
Config6 = 127,
Config7 = 128,
LLAddr = 129, //Bank 17: 129-136
WatchLo0 = 137, //Bank 18: 137-144
WatchLo1 = 138,
WatchLo2 = 139,
WatchLo3 = 140,
WatchLo4 = 141,
WatchLo5 = 142,
WatchLo6 = 143,
WatchLo7 = 144,
WatchHi0 = 145,//Bank 19: 145-152
WatchHi1 = 146,
WatchHi2 = 147,
WatchHi3 = 148,
WatchHi4 = 149,
WatchHi5 = 150,
WatchHi6 = 151,
WatchHi7 = 152,
XCContext64 = 153, //Bank 20: 153-160
//Bank 21: 161-168
//Bank 22: 169-176
Debug = 177, //Bank 23: 177-184
TraceControl1 = 178,
TraceControl2 = 179,
UserTraceData = 180,
TraceBPC = 181,
DEPC = 185,//Bank 24: 185-192
PerfCnt0 = 193,//Bank 25: 193 - 200
PerfCnt1 = 194,
PerfCnt2 = 195,
PerfCnt3 = 196,
PerfCnt4 = 197,
PerfCnt5 = 198,
PerfCnt6 = 199,
PerfCnt7 = 200,
ErrCtl = 201, //Bank 26: 201 - 208
CacheErr0 = 209, //Bank 27: 209 - 216
CacheErr1 = 210,
CacheErr2 = 211,
CacheErr3 = 212,
TagLo0 = 217,//Bank 28: 217 - 224
DataLo1 = 218,
TagLo2 = 219,
DataLo3 = 220,
TagLo4 = 221,
DataLo5 = 222,
TagLo6 = 223,
DataLo7 = 234,
TagHi0 = 233,//Bank 29: 233 - 240
DataHi1 = 234,
TagHi2 = 235,
DataHi3 = 236,
TagHi4 = 237,
DataHi5 = 238,
TagHi6 = 239,
DataHi7 = 240,
ErrorEPC = 249,//Bank 30: 241 - 248
DESAVE = 257//Bank 31: 249-256
};
class MiscRegFile {
protected:

View file

@ -28,11 +28,11 @@
* Authors: Korey Sewell
*/
#ifndef __ARCH_MIPS_REGFILE_HH__
#define __ARCH_MIPS_REGFILE_HH__
#ifndef __ARCH_MIPS_REGFILE_REGFILE_HH__
#define __ARCH_MIPS_REGFILE_REGFILE_HH__
#include "arch/mips/types.hh"
#include "arch/mips/constants.hh"
#include "arch/mips/isa_traits.hh"
#include "arch/mips/regfile/int_regfile.hh"
#include "arch/mips/regfile/float_regfile.hh"
#include "arch/mips/regfile/misc_regfile.hh"
@ -171,10 +171,7 @@ namespace MipsISA
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
typedef int ContextParam;
typedef int ContextVal;
void changeContext(ContextParam param, ContextVal val)
void changeContext(RegContextParam param, RegContextVal val)
{
}
};

View file

@ -0,0 +1,84 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
* Korey Sewell
*/
#ifndef __ARCH_MIPS_SYSCALLRETURN_HH__
#define __ARCH_MIPS_SYSCALLRETURN_HH__
class SyscallReturn {
public:
template <class T>
SyscallReturn(T v, bool s)
{
retval = (uint32_t)v;
success = s;
}
template <class T>
SyscallReturn(T v)
{
success = (v >= 0);
retval = (uint32_t)v;
}
~SyscallReturn() {}
SyscallReturn& operator=(const SyscallReturn& s) {
retval = s.retval;
success = s.success;
return *this;
}
bool successful() { return success; }
uint64_t value() { return retval; }
private:
uint64_t retval;
bool success;
};
namespace MipsISA
{
static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
{
if (return_value.successful()) {
// no error
regs->setIntReg(SyscallSuccessReg, 0);
regs->setIntReg(ReturnValueReg1, return_value.value());
} else {
// got an error, return details
regs->setIntReg(SyscallSuccessReg, (IntReg) -1);
regs->setIntReg(ReturnValueReg1, -return_value.value());
}
}
}
#endif

View file

@ -58,6 +58,9 @@ namespace MipsISA
MiscReg ctrlreg;
} AnyReg;
typedef int RegContextParam;
typedef int RegContextVal;
//used in FP convert & round function
enum ConvertType{
SINGLE_TO_DOUBLE,

View file

@ -33,8 +33,10 @@
#define __ARCH_MIPS_UTILITY_HH__
#include "arch/mips/types.hh"
#include "arch/mips/constants.hh"
#include "arch/mips/isa_traits.hh"
#include "base/misc.hh"
//XXX This is needed for size_t. We should use something other than size_t
#include "kern/linux/linux.hh"
#include "sim/host.hh"
namespace MipsISA {
@ -51,6 +53,48 @@ namespace MipsISA {
bool isNan(void *val_ptr, int size);
bool isQnan(void *val_ptr, int size);
bool isSnan(void *val_ptr, int size);
/**
* Function to insure ISA semantics about 0 registers.
* @param tc The thread context.
*/
template <class TC>
void zeroRegisters(TC *tc);
void copyRegs(ThreadContext *src, ThreadContext *dest);
// Instruction address compression hooks
static inline Addr realPCToFetchPC(const Addr &addr) {
return addr;
}
static inline Addr fetchPCToRealPC(const Addr &addr) {
return addr;
}
// the size of "fetched" instructions (not necessarily the size
// of real instructions for PISA)
static inline size_t fetchInstSize() {
return sizeof(MachInst);
}
static inline MachInst makeRegisterCopy(int dest, int src) {
panic("makeRegisterCopy not implemented");
return 0;
}
static inline ExtMachInst
makeExtMI(MachInst inst, const uint64_t &pc) {
#if FULL_SYSTEM
ExtMachInst ext_inst = inst;
if (pc && 0x1)
return ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
else
return ext_inst;
#else
return ExtMachInst(inst);
#endif
}
};

View file

@ -45,22 +45,25 @@ Import('env')
# Base sources used by all configurations.
base_sources = Split('''
faults.cc
isa_traits.cc
floatregfile.cc
intregfile.cc
miscregfile.cc
regfile.cc
''')
# Full-system sources
full_system_sources = Split('''
vtophys.cc
ua2005.cc
vtophys.cc
''')
# Syscall emulation (non-full-system) sources
syscall_emulation_sources = Split('''
linux/linux.cc
linux/process.cc
solaris/solaris.cc
solaris/process.cc
process.cc
solaris/process.cc
solaris/solaris.cc
''')
sources = base_sources

View file

@ -0,0 +1,174 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
* Ali Saidi
*/
#include "arch/sparc/floatregfile.hh"
#include "base/trace.hh"
#include "sim/byteswap.hh"
#include "sim/serialize.hh"
using namespace SparcISA;
using namespace std;
class Checkpoint;
string SparcISA::getFloatRegName(RegIndex index)
{
static std::string floatRegName[NumFloatRegs] =
{"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
"f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
"f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
"f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
"f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63"};
return floatRegName[index];
}
void FloatRegFile::clear()
{
bzero(regSpace, sizeof(regSpace));
}
FloatReg FloatRegFile::readReg(int floatReg, int width)
{
//In each of these cases, we have to copy the value into a temporary
//variable. This is because we may otherwise try to access an
//unaligned portion of memory.
switch(width)
{
case SingleWidth:
float32_t result32;
memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
return htog(result32);
case DoubleWidth:
float64_t result64;
memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
return htog(result64);
case QuadWidth:
float128_t result128;
memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
return htog(result128);
default:
panic("Attempted to read a %d bit floating point register!", width);
}
}
FloatRegBits FloatRegFile::readRegBits(int floatReg, int width)
{
//In each of these cases, we have to copy the value into a temporary
//variable. This is because we may otherwise try to access an
//unaligned portion of memory.
switch(width)
{
case SingleWidth:
uint32_t result32;
memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
return htog(result32);
case DoubleWidth:
uint64_t result64;
memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
return htog(result64);
case QuadWidth:
uint64_t result128;
memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
return htog(result128);
default:
panic("Attempted to read a %d bit floating point register!", width);
}
}
Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width)
{
//In each of these cases, we have to copy the value into a temporary
//variable. This is because we may otherwise try to access an
//unaligned portion of memory.
uint32_t result32;
uint64_t result64;
DPRINTF(Sparc, "Setting floating point register %d\n", floatReg);
switch(width)
{
case SingleWidth:
result32 = gtoh((uint32_t)val);
memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
break;
case DoubleWidth:
result64 = gtoh((uint64_t)val);
memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
break;
case QuadWidth:
panic("Quad width FP not implemented.");
break;
default:
panic("Attempted to read a %d bit floating point register!", width);
}
return NoFault;
}
Fault FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width)
{
//In each of these cases, we have to copy the value into a temporary
//variable. This is because we may otherwise try to access an
//unaligned portion of memory.
uint32_t result32;
uint64_t result64;
switch(width)
{
case SingleWidth:
result32 = gtoh((uint32_t)val);
memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
break;
case DoubleWidth:
result64 = gtoh((uint64_t)val);
memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
break;
case QuadWidth:
panic("Quad width FP not implemented.");
break;
default:
panic("Attempted to read a %d bit floating point register!", width);
}
return NoFault;
}
void FloatRegFile::serialize(std::ostream &os)
{
SERIALIZE_ARRAY((unsigned char *)regSpace,
SingleWidth / 8 * NumFloatRegs);
}
void FloatRegFile::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ARRAY((unsigned char *)regSpace,
SingleWidth / 8 * NumFloatRegs);
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
* Ali Saidi
*/
#ifndef __ARCH_SPARC_FLOATREGFILE_HH__
#define __ARCH_SPARC_FLOATREGFILE_HH__
#include "arch/sparc/faults.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/types.hh"
#include <string>
namespace SparcISA
{
std::string getFloatRegName(RegIndex);
typedef float float32_t;
typedef double float64_t;
//FIXME long double refers to a 10 byte float, rather than a
//16 byte float as required. This data type may have to be emulated.
typedef double float128_t;
class FloatRegFile
{
public:
static const int SingleWidth = 32;
static const int DoubleWidth = 64;
static const int QuadWidth = 128;
protected:
//Since the floating point registers overlap each other,
//A generic storage space is used. The float to be returned is
//pulled from the appropriate section of this region.
char regSpace[(SingleWidth / 8) * NumFloatRegs];
public:
void clear();
FloatReg readReg(int floatReg, int width);
FloatRegBits readRegBits(int floatReg, int width);
Fault setReg(int floatReg, const FloatReg &val, int width);
Fault setRegBits(int floatReg, const FloatRegBits &val, int width);
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
};
}
#endif

View file

@ -0,0 +1,133 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
* Ali Saidi
*/
#include "arch/sparc/intregfile.hh"
#include "base/trace.hh"
#include "sim/serialize.hh"
using namespace SparcISA;
using namespace std;
class Checkpoint;
string SparcISA::getIntRegName(RegIndex index)
{
static std::string intRegName[NumIntRegs] =
{"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
"o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
"l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
"i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7"};
return intRegName[index];
}
int IntRegFile::flattenIndex(int reg)
{
int flatIndex = offset[reg >> FrameOffsetBits]
| (reg & FrameOffsetMask);
DPRINTF(Sparc, "Flattened index %d into %d.\n", reg, flatIndex);
return flatIndex;
}
void IntRegFile::clear()
{
int x;
for (x = 0; x < MaxGL; x++)
memset(regGlobals[x], 0, sizeof(regGlobals[x]));
for(int x = 0; x < 2 * NWindows; x++)
bzero(regSegments[x], sizeof(regSegments[x]));
}
IntRegFile::IntRegFile()
{
offset[Globals] = 0;
regView[Globals] = regGlobals[0];
setCWP(0);
clear();
}
IntReg IntRegFile::readReg(int intReg)
{
IntReg val =
regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask];
DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val);
return val;
}
Fault IntRegFile::setReg(int intReg, const IntReg &val)
{
if(intReg)
DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val);
regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val;
return NoFault;
}
//This doesn't effect the actual CWP register.
//It's purpose is to adjust the view of the register file
//to what it would be if CWP = cwp.
void IntRegFile::setCWP(int cwp)
{
int index = ((NWindows - cwp) % NWindows) * 2;
offset[Outputs] = FrameOffset + (index * RegsPerFrame);
offset[Locals] = FrameOffset + ((index+1) * RegsPerFrame);
offset[Inputs] = FrameOffset +
(((index+2) % (NWindows * 2)) * RegsPerFrame);
regView[Outputs] = regSegments[index];
regView[Locals] = regSegments[index+1];
regView[Inputs] = regSegments[(index+2) % (NWindows * 2)];
DPRINTF(Sparc, "Changed the CWP value to %d\n", cwp);
}
void IntRegFile::setGlobals(int gl)
{
DPRINTF(Sparc, "Now using %d globals", gl);
regView[Globals] = regGlobals[gl];
offset[Globals] = RegGlobalOffset + gl * RegsPerFrame;
}
void IntRegFile::serialize(std::ostream &os)
{
unsigned int x;
for(x = 0; x < MaxGL; x++)
SERIALIZE_ARRAY(regGlobals[x], RegsPerFrame);
for(x = 0; x < 2 * NWindows; x++)
SERIALIZE_ARRAY(regSegments[x], RegsPerFrame);
}
void IntRegFile::unserialize(Checkpoint *cp, const std::string &section)
{
unsigned int x;
for(x = 0; x < MaxGL; x++)
UNSERIALIZE_ARRAY(regGlobals[x], RegsPerFrame);
for(unsigned int x = 0; x < 2 * NWindows; x++)
UNSERIALIZE_ARRAY(regSegments[x], RegsPerFrame);
}

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
* Ali Saidi
*/
#ifndef __ARCH_SPARC_INTREGFILE_HH__
#define __ARCH_SPARC_INTREGFILE_HH__
#include "arch/sparc/faults.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/types.hh"
#include <string>
namespace SparcISA
{
class RegFile;
//This function translates integer register file indices into names
std::string getIntRegName(RegIndex);
class IntRegFile
{
private:
friend class RegFile;
protected:
static const int FrameOffsetBits = 3;
static const int FrameNumBits = 2;
static const int RegsPerFrame = 1 << FrameOffsetBits;
static const int FrameNumMask =
(FrameNumBits == sizeof(int)) ?
(unsigned int)(-1) :
(1 << FrameNumBits) - 1;
static const int FrameOffsetMask =
(FrameOffsetBits == sizeof(int)) ?
(unsigned int)(-1) :
(1 << FrameOffsetBits) - 1;
IntReg regGlobals[MaxGL][RegsPerFrame];
IntReg regSegments[2 * NWindows][RegsPerFrame];
enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames};
IntReg * regView[NumFrames];
static const int RegGlobalOffset = 0;
static const int FrameOffset = MaxGL * RegsPerFrame;
int offset[NumFrames];
public:
int flattenIndex(int reg);
void clear();
IntRegFile();
IntReg readReg(int intReg);
Fault setReg(int intReg, const IntReg &val);
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
protected:
//This doesn't effect the actual CWP register.
//It's purpose is to adjust the view of the register file
//to what it would be if CWP = cwp.
void setCWP(int cwp);
void setGlobals(int gl);
};
}
#endif

View file

@ -25,13 +25,13 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Korey Sewell
* Gabe Black
* Authors: Gabe Black
*/
#ifndef __ARCH_SPARC_ISA_TRAITS_HH__
#define __ARCH_SPARC_ISA_TRAITS_HH__
#include "arch/sparc/types.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
#include "sim/host.hh"
@ -46,70 +46,45 @@ class StaticInstPtr;
namespace BigEndianGuest {}
#if !FULL_SYSTEM
class SyscallReturn
{
public:
template <class T>
SyscallReturn(T v, bool s)
{
retval = (uint64_t)v;
success = s;
}
template <class T>
SyscallReturn(T v)
{
success = (v >= 0);
retval = (uint64_t)v;
}
~SyscallReturn() {}
SyscallReturn& operator=(const SyscallReturn& s)
{
retval = s.retval;
success = s.success;
return *this;
}
bool successful() { return success; }
uint64_t value() { return retval; }
private:
uint64_t retval;
bool success;
};
#endif
#if FULL_SYSTEM
#include "arch/sparc/isa_fullsys_traits.hh"
#endif
namespace SparcISA
{
class RegFile;
//This makes sure the big endian versions of certain functions are used.
using namespace BigEndianGuest;
//TODO this needs to be a SPARC Noop
// Alpha UNOP (ldq_u r31,0(r0))
const MachInst NoopMachInst = 0x2ffe0000;
const int NumIntRegs = 32;
const int NumFloatRegs = 64;
const int NumMiscRegs = 40;
// 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 = 32,
Ctrl_Base_DepTag = 96,
// 32..95 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
FP_Base_DepTag = NumIntRegs,
Ctrl_Base_DepTag = NumIntRegs + NumFloatRegs,
//XXX These are here solely to get compilation and won't work
Fpcr_DepTag = 0,
Uniq_DepTag = 0
};
//This makes sure the big endian versions of certain functions are used.
using namespace BigEndianGuest;
typedef uint32_t MachInst;
typedef uint64_t ExtMachInst;
// MAXTL - maximum trap level
const int MaxPTL = 2;
const int MaxTL = 6;
const int MaxGL = 3;
const int MaxPGL = 2;
const int NumIntRegs = 32;
const int NumFloatRegs = 64;
const int NumMiscRegs = 32;
// NWINDOWS - number of register windows, can be 3 to 32
const int NWindows = 32;
// semantically meaningful register indices
const int ZeroReg = 0; // architecturally meaningful
@ -131,14 +106,6 @@ namespace SparcISA
const int MaxInstSrcRegs = 8;
const int MaxInstDestRegs = 9;
typedef uint64_t IntReg;
// control register file contents
typedef uint64_t MiscReg;
typedef double FloatReg;
typedef uint64_t FloatRegBits;
//8K. This value is implmentation specific; and should probably
//be somewhere else.
const int LogVMPageSize = 13;
@ -165,29 +132,4 @@ namespace SparcISA
extern const MachInst NoopMachInst;
}
#include "arch/sparc/regfile.hh"
namespace SparcISA
{
#if !FULL_SYSTEM
static inline void setSyscallReturn(SyscallReturn return_value,
RegFile *regs)
{
// check for error condition. SPARC syscall convention is to
// indicate success/failure in reg the carry bit of the ccr
// and put the return value itself in the standard return value reg ().
if (return_value.successful()) {
// no error, clear XCC.C
regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEF);
regs->setIntReg(ReturnValueReg, return_value.value());
} else {
// got an error, set XCC.C
regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x10);
regs->setIntReg(ReturnValueReg, return_value.value());
}
}
#endif
};
#endif // __ARCH_SPARC_ISA_TRAITS_HH__

View file

@ -0,0 +1,540 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
* Ali Saidi
*/
#include "arch/sparc/miscregfile.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
using namespace SparcISA;
using namespace std;
class Checkpoint;
//These functions map register indices to names
string SparcISA::getMiscRegName(RegIndex index)
{
static::string miscRegName[NumMiscRegs] =
{"y", "ccr", "asi", "tick", "pc", "fprs", "pcr", "pic",
"gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
"stick", "stick_cmpr",
"tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
"pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
"wstate", "gl",
"hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
"hstick_cmpr",
"fsr"};
return miscRegName[index];
}
#if FULL_SYSTEM
//XXX These need an implementation someplace
/** Fullsystem only register version of ReadRegWithEffect() */
MiscReg MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
/** Fullsystem only register version of SetRegWithEffect() */
Fault MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
ThreadContext * tc);
#endif
void MiscRegFile::reset()
{
pstateFields.pef = 0; //No FPU
//pstateFields.pef = 1; //FPU
#if FULL_SYSTEM
//For SPARC, when a system is first started, there is a power
//on reset Trap which sets the processor into the following state.
//Bits that aren't set aren't defined on startup.
tl = MaxTL;
gl = MaxGL;
tickFields.counter = 0; //The TICK register is unreadable bya
tickFields.npt = 1; //The TICK register is unreadable by by !priv
softint = 0; // Clear all the soft interrupt bits
tick_cmprFields.int_dis = 1; // disable timer compare interrupts
tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
stickFields.npt = 1; //The TICK register is unreadable by by !priv
stick_cmprFields.int_dis = 1; // disable timer compare interrupts
stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
tt[tl] = power_on_reset;
pstate = 0; // fields 0 but pef
pstateFields.pef = 1;
hpstate = 0;
hpstateFields.red = 1;
hpstateFields.hpriv = 1;
hpstateFields.tlz = 0; // this is a guess
hintp = 0; // no interrupts pending
hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
#else
/* //This sets up the initial state of the processor for usermode processes
pstateFields.priv = 0; //Process runs in user mode
pstateFields.ie = 1; //Interrupts are enabled
fsrFields.rd = 0; //Round to nearest
fsrFields.tem = 0; //Floating point traps not enabled
fsrFields.ns = 0; //Non standard mode off
fsrFields.qne = 0; //Floating point queue is empty
fsrFields.aexc = 0; //No accrued exceptions
fsrFields.cexc = 0; //No current exceptions
//Register window management registers
otherwin = 0; //No windows contain info from other programs
canrestore = 0; //There are no windows to pop
cansave = MaxTL - 2; //All windows are available to save into
cleanwin = MaxTL;*/
#endif
}
MiscReg MiscRegFile::readReg(int miscReg)
{
switch (miscReg) {
case MISCREG_Y:
return y;
case MISCREG_CCR:
return ccr;
case MISCREG_ASI:
return asi;
case MISCREG_FPRS:
return fprs;
case MISCREG_TICK:
return tick;
case MISCREG_PCR:
case MISCREG_PIC:
panic("ASR number %d not implemented\n", miscReg - AsrStart);
case MISCREG_GSR:
return gsr;
case MISCREG_SOFTINT:
return softint;
case MISCREG_TICK_CMPR:
return tick_cmpr;
case MISCREG_STICK:
return stick;
case MISCREG_STICK_CMPR:
return stick_cmpr;
/** Privilged Registers */
case MISCREG_TPC:
return tpc[tl-1];
case MISCREG_TNPC:
return tnpc[tl-1];
case MISCREG_TSTATE:
return tstate[tl-1];
case MISCREG_TT:
return tt[tl-1];
case MISCREG_PRIVTICK:
panic("Priviliged access to tick registers not implemented\n");
case MISCREG_TBA:
return tba;
case MISCREG_PSTATE:
return pstate;
case MISCREG_TL:
return tl;
case MISCREG_PIL:
return pil;
case MISCREG_CWP:
return cwp;
case MISCREG_CANSAVE:
return cansave;
case MISCREG_CANRESTORE:
return canrestore;
case MISCREG_CLEANWIN:
return cleanwin;
case MISCREG_OTHERWIN:
return otherwin;
case MISCREG_WSTATE:
return wstate;
case MISCREG_GL:
return gl;
/** Hyper privileged registers */
case MISCREG_HPSTATE:
return hpstate;
case MISCREG_HTSTATE:
return htstate[tl-1];
case MISCREG_HINTP:
panic("HINTP not implemented\n");
case MISCREG_HTBA:
return htba;
case MISCREG_HVER:
return NWindows | MaxTL << 8 | MaxGL << 16;
case MISCREG_STRAND_STS_REG:
return strandStatusReg;
case MISCREG_HSTICK_CMPR:
return hstick_cmpr;
/** Floating Point Status Register */
case MISCREG_FSR:
return fsr;
default:
panic("Miscellaneous register %d not implemented\n", miscReg);
}
}
MiscReg MiscRegFile::readRegWithEffect(int miscReg,
Fault &fault, ThreadContext * tc)
{
fault = NoFault;
switch (miscReg) {
case MISCREG_Y:
case MISCREG_CCR:
case MISCREG_ASI:
return readReg(miscReg);
case MISCREG_TICK:
case MISCREG_PRIVTICK:
// Check for reading privilege
if (tickFields.npt && !isNonPriv()) {
fault = new PrivilegedAction;
return 0;
}
return tc->getCpuPtr()->curCycle() - tickFields.counter |
tickFields.npt << 63;
case MISCREG_PC:
return tc->readPC();
case MISCREG_FPRS:
fault = new UnimpFault("FPU not implemented\n");
return 0;
case MISCREG_PCR:
fault = new UnimpFault("Performance Instrumentation not impl\n");
return 0;
case MISCREG_PIC:
fault = new UnimpFault("Performance Instrumentation not impl\n");
return 0;
case MISCREG_GSR:
return readReg(miscReg);
/** Privilged Registers */
case MISCREG_TPC:
case MISCREG_TNPC:
case MISCREG_TSTATE:
case MISCREG_TT:
if (tl == 0) {
fault = new IllegalInstruction;
return 0;
} // NOTE THE FALL THROUGH!
case MISCREG_PSTATE:
case MISCREG_TL:
return readReg(miscReg);
case MISCREG_TBA:
return readReg(miscReg) & ULL(~0x7FFF);
case MISCREG_PIL:
case MISCREG_CWP:
case MISCREG_CANSAVE:
case MISCREG_CANRESTORE:
case MISCREG_CLEANWIN:
case MISCREG_OTHERWIN:
case MISCREG_WSTATE:
case MISCREG_GL:
return readReg(miscReg);
/** Floating Point Status Register */
case MISCREG_FSR:
panic("Floating Point not implemented\n");
default:
#if FULL_SYSTEM
return readFSRegWithEffect(miscReg, fault, tc);
#else
fault = new IllegalInstruction;
return 0;
#endif
}
}
Fault MiscRegFile::setReg(int miscReg, const MiscReg &val)
{
switch (miscReg) {
case MISCREG_Y:
y = val;
return NoFault;
case MISCREG_CCR:
ccr = val;
return NoFault;
case MISCREG_ASI:
asi = val;
return NoFault;
case MISCREG_FPRS:
fprs = val;
return NoFault;
case MISCREG_TICK:
tick = val;
return NoFault;
case MISCREG_PCR:
case MISCREG_PIC:
panic("ASR number %d not implemented\n", miscReg - AsrStart);
case MISCREG_GSR:
gsr = val;
case MISCREG_SOFTINT:
softint = val;
return NoFault;
case MISCREG_TICK_CMPR:
tick_cmpr = val;
return NoFault;
case MISCREG_STICK:
stick = val;
return NoFault;
case MISCREG_STICK_CMPR:
stick_cmpr = val;
return NoFault;
/** Privilged Registers */
case MISCREG_TPC:
tpc[tl-1] = val;
return NoFault;
case MISCREG_TNPC:
tnpc[tl-1] = val;
return NoFault;
case MISCREG_TSTATE:
tstate[tl-1] = val;
return NoFault;
case MISCREG_TT:
tt[tl-1] = val;
return NoFault;
case MISCREG_PRIVTICK:
panic("Priviliged access to tick regesiters not implemented\n");
case MISCREG_TBA:
tba = val;
return NoFault;
case MISCREG_PSTATE:
pstate = val;
return NoFault;
case MISCREG_TL:
tl = val;
return NoFault;
case MISCREG_PIL:
pil = val;
return NoFault;
case MISCREG_CWP:
cwp = val;
return NoFault;
case MISCREG_CANSAVE:
cansave = val;
return NoFault;
case MISCREG_CANRESTORE:
canrestore = val;
return NoFault;
case MISCREG_CLEANWIN:
cleanwin = val;
return NoFault;
case MISCREG_OTHERWIN:
otherwin = val;
return NoFault;
case MISCREG_WSTATE:
wstate = val;
return NoFault;
case MISCREG_GL:
gl = val;
return NoFault;
/** Hyper privileged registers */
case MISCREG_HPSTATE:
hpstate = val;
return NoFault;
case MISCREG_HTSTATE:
htstate[tl-1] = val;
return NoFault;
case MISCREG_HINTP:
panic("HINTP not implemented\n");
case MISCREG_HTBA:
htba = val;
return NoFault;
case MISCREG_STRAND_STS_REG:
strandStatusReg = val;
return NoFault;
case MISCREG_HSTICK_CMPR:
hstick_cmpr = val;
return NoFault;
/** Floating Point Status Register */
case MISCREG_FSR:
fsr = val;
return NoFault;
default:
panic("Miscellaneous register %d not implemented\n", miscReg);
}
}
Fault MiscRegFile::setRegWithEffect(int miscReg,
const MiscReg &val, ThreadContext * tc)
{
const uint64_t Bit64 = (1ULL << 63);
switch (miscReg) {
case MISCREG_Y:
case MISCREG_CCR:
case MISCREG_ASI:
setReg(miscReg, val);
return NoFault;
case MISCREG_PRIVTICK:
case MISCREG_TICK:
if (isNonPriv())
return new PrivilegedOpcode;
if (isPriv())
return new PrivilegedAction;
tickFields.counter = tc->getCpuPtr()->curCycle() - val & ~Bit64;
tickFields.npt = val & Bit64 ? 1 : 0;
return NoFault;
case MISCREG_PC:
return new IllegalInstruction;
case MISCREG_FPRS:
return new UnimpFault("FPU not implemented\n");
case MISCREG_PCR:
return new UnimpFault("Performance Instrumentation not impl\n");
case MISCREG_PIC:
return new UnimpFault("Performance Instrumentation not impl\n");
case MISCREG_GSR:
return setReg(miscReg, val);
/** Privilged Registers */
case MISCREG_TPC:
case MISCREG_TNPC:
case MISCREG_TSTATE:
case MISCREG_TT:
if (tl == 0)
return new IllegalInstruction;
setReg(miscReg, val);
return NoFault;
case MISCREG_TBA:
// clear lower 7 bits on writes.
setReg(miscReg, val & ULL(~0x7FFF));
return NoFault;
case MISCREG_PSTATE:
setReg(miscReg, val);
return NoFault;
case MISCREG_TL:
if (isHyperPriv() && val > MaxTL)
setReg(miscReg, MaxTL);
else if (isPriv() && !isHyperPriv() && val > MaxPTL)
setReg(miscReg, MaxPTL);
else
setReg(miscReg, val);
return NoFault;
case MISCREG_CWP:
tc->changeRegFileContext(CONTEXT_CWP, val);
case MISCREG_CANSAVE:
case MISCREG_CANRESTORE:
case MISCREG_CLEANWIN:
case MISCREG_OTHERWIN:
case MISCREG_WSTATE:
setReg(miscReg, val);
return NoFault;
case MISCREG_GL:
int newval;
if (isHyperPriv() && val > MaxGL)
newval = MaxGL;
else if (isPriv() && !isHyperPriv() && val > MaxPGL)
newval = MaxPGL;
else
newval = val;
tc->changeRegFileContext(CONTEXT_GLOBALS, newval);
setReg(miscReg, newval);
return NoFault;
/** Floating Point Status Register */
case MISCREG_FSR:
panic("Floating Point not implemented\n");
default:
#if FULL_SYSTEM
setFSRegWithEffect(miscReg, val, tc);
#else
return new IllegalInstruction;
#endif
}
}
void MiscRegFile::serialize(std::ostream & os)
{
SERIALIZE_SCALAR(pstate);
SERIALIZE_SCALAR(tba);
SERIALIZE_SCALAR(y);
SERIALIZE_SCALAR(pil);
SERIALIZE_SCALAR(gl);
SERIALIZE_SCALAR(cwp);
SERIALIZE_ARRAY(tt, MaxTL);
SERIALIZE_SCALAR(ccr);
SERIALIZE_SCALAR(asi);
SERIALIZE_SCALAR(tl);
SERIALIZE_ARRAY(tpc, MaxTL);
SERIALIZE_ARRAY(tnpc, MaxTL);
SERIALIZE_ARRAY(tstate, MaxTL);
SERIALIZE_SCALAR(tick);
SERIALIZE_SCALAR(cansave);
SERIALIZE_SCALAR(canrestore);
SERIALIZE_SCALAR(otherwin);
SERIALIZE_SCALAR(cleanwin);
SERIALIZE_SCALAR(wstate);
SERIALIZE_SCALAR(fsr);
SERIALIZE_SCALAR(fprs);
SERIALIZE_SCALAR(hpstate);
SERIALIZE_ARRAY(htstate, MaxTL);
SERIALIZE_SCALAR(htba);
SERIALIZE_SCALAR(hstick_cmpr);
}
void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
{
UNSERIALIZE_SCALAR(pstate);
UNSERIALIZE_SCALAR(tba);
UNSERIALIZE_SCALAR(y);
UNSERIALIZE_SCALAR(pil);
UNSERIALIZE_SCALAR(gl);
UNSERIALIZE_SCALAR(cwp);
UNSERIALIZE_ARRAY(tt, MaxTL);
UNSERIALIZE_SCALAR(ccr);
UNSERIALIZE_SCALAR(asi);
UNSERIALIZE_SCALAR(tl);
UNSERIALIZE_ARRAY(tpc, MaxTL);
UNSERIALIZE_ARRAY(tnpc, MaxTL);
UNSERIALIZE_ARRAY(tstate, MaxTL);
UNSERIALIZE_SCALAR(tick);
UNSERIALIZE_SCALAR(cansave);
UNSERIALIZE_SCALAR(canrestore);
UNSERIALIZE_SCALAR(otherwin);
UNSERIALIZE_SCALAR(cleanwin);
UNSERIALIZE_SCALAR(wstate);
UNSERIALIZE_SCALAR(fsr);
UNSERIALIZE_SCALAR(fprs);
UNSERIALIZE_SCALAR(hpstate);
UNSERIALIZE_ARRAY(htstate, MaxTL);
UNSERIALIZE_SCALAR(htba);
UNSERIALIZE_SCALAR(hstick_cmpr);
}

View file

@ -0,0 +1,410 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
* Ali Saidi
*/
#ifndef __ARCH_SPARC_MISCREGFILE_HH__
#define __ARCH_SPARC_MISCREGFILE_HH__
#include "arch/sparc/faults.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/types.hh"
#include <string>
namespace SparcISA
{
//These functions map register indices to names
std::string getMiscRegName(RegIndex);
const int AsrStart = 0;
const int PrStart = 32;
const int HprStart = 64;
const int MiscStart = 96;
enum MiscRegIndex
{
/** Ancillary State Registers */
MISCREG_Y = AsrStart + 0,
MISCREG_CCR = AsrStart + 2,
MISCREG_ASI = AsrStart + 3,
MISCREG_TICK = AsrStart + 4,
MISCREG_PC = AsrStart + 5,
MISCREG_FPRS = AsrStart + 6,
MISCREG_PCR = AsrStart + 16,
MISCREG_PIC = AsrStart + 17,
MISCREG_GSR = AsrStart + 19,
MISCREG_SOFTINT_SET = AsrStart + 20,
MISCREG_SOFTINT_CLR = AsrStart + 21,
MISCREG_SOFTINT = AsrStart + 22,
MISCREG_TICK_CMPR = AsrStart + 23,
MISCREG_STICK = AsrStart + 24,
MISCREG_STICK_CMPR = AsrStart + 25,
/** Privilged Registers */
MISCREG_TPC = PrStart + 0,
MISCREG_TNPC = PrStart + 1,
MISCREG_TSTATE = PrStart + 2,
MISCREG_TT = PrStart + 3,
MISCREG_PRIVTICK = PrStart + 4,
MISCREG_TBA = PrStart + 5,
MISCREG_PSTATE = PrStart + 6,
MISCREG_TL = PrStart + 7,
MISCREG_PIL = PrStart + 8,
MISCREG_CWP = PrStart + 9,
MISCREG_CANSAVE = PrStart + 10,
MISCREG_CANRESTORE = PrStart + 11,
MISCREG_CLEANWIN = PrStart + 12,
MISCREG_OTHERWIN = PrStart + 13,
MISCREG_WSTATE = PrStart + 14,
MISCREG_GL = PrStart + 16,
/** Hyper privileged registers */
MISCREG_HPSTATE = HprStart + 0,
MISCREG_HTSTATE = HprStart + 1,
MISCREG_HINTP = HprStart + 3,
MISCREG_HTBA = HprStart + 5,
MISCREG_HVER = HprStart + 6,
MISCREG_STRAND_STS_REG = HprStart + 16,
MISCREG_HSTICK_CMPR = HprStart + 31,
/** Floating Point Status Register */
MISCREG_FSR = MiscStart + 0
};
// The control registers, broken out into fields
class MiscRegFile
{
private:
/* ASR Registers */
union {
uint64_t y; // Y (used in obsolete multiplication)
struct {
uint64_t value:32; // The actual value stored in y
uint64_t :32; // reserved bits
} yFields;
};
union {
uint8_t ccr; // Condition Code Register
struct {
union {
uint8_t icc:4; // 32-bit condition codes
struct {
uint8_t c:1; // Carry
uint8_t v:1; // Overflow
uint8_t z:1; // Zero
uint8_t n:1; // Negative
} iccFields;
};
union {
uint8_t xcc:4; // 64-bit condition codes
struct {
uint8_t c:1; // Carry
uint8_t v:1; // Overflow
uint8_t z:1; // Zero
uint8_t n:1; // Negative
} xccFields;
};
} ccrFields;
};
uint8_t asi; // Address Space Identifier
union {
uint64_t tick; // Hardware clock-tick counter
struct {
int64_t counter:63; // Clock-tick count
uint64_t npt:1; // Non-priveleged trap
} tickFields;
};
union {
uint8_t fprs; // Floating-Point Register State
struct {
uint8_t dl:1; // Dirty lower
uint8_t du:1; // Dirty upper
uint8_t fef:1; // FPRS enable floating-Point
} fprsFields;
};
union {
uint64_t gsr; //General Status Register
struct {
uint64_t mask:32;
uint64_t :4;
uint64_t im:1;
uint64_t irnd:2;
uint64_t :17;
uint64_t scale:5;
uint64_t align:3;
} gsrFields;
};
union {
uint64_t softint;
struct {
uint64_t tm:1;
uint64_t int_level:14;
uint64_t sm:1;
} softintFields;
};
union {
uint64_t tick_cmpr; // Hardware tick compare registers
struct {
uint64_t tick_cmpr:63; // Clock-tick count
uint64_t int_dis:1; // Non-priveleged trap
} tick_cmprFields;
};
union {
uint64_t stick; // Hardware clock-tick counter
struct {
int64_t :63; // Not used, storage in SparcSystem
uint64_t npt:1; // Non-priveleged trap
} stickFields;
};
union {
uint64_t stick_cmpr; // Hardware tick compare registers
struct {
uint64_t tick_cmpr:63; // Clock-tick count
uint64_t int_dis:1; // Non-priveleged trap
} stick_cmprFields;
};
/* Privileged Registers */
uint64_t tpc[MaxTL]; // Trap Program Counter (value from
// previous trap level)
uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
// previous trap level)
union {
uint64_t tstate[MaxTL]; // Trap State
struct {
//Values are from previous trap level
uint64_t cwp:5; // Current Window Pointer
uint64_t :3; // Reserved bits
uint64_t pstate:13; // Process State
uint64_t :3; // Reserved bits
uint64_t asi:8; // Address Space Identifier
uint64_t ccr:8; // Condition Code Register
uint64_t gl:8; // Global level
} tstateFields[MaxTL];
};
uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
// on the previous level)
uint64_t tba; // Trap Base Address
union {
uint16_t pstate; // Process State Register
struct {
uint16_t :1; // reserved
uint16_t ie:1; // Interrupt enable
uint16_t priv:1; // Privelege mode
uint16_t am:1; // Address mask
uint16_t pef:1; // PSTATE enable floating-point
uint16_t :1; // reserved2
uint16_t mm:2; // Memory Model
uint16_t tle:1; // Trap little-endian
uint16_t cle:1; // Current little-endian
} pstateFields;
};
uint8_t tl; // Trap Level
uint8_t pil; // Process Interrupt Register
uint8_t cwp; // Current Window Pointer
uint8_t cansave; // Savable windows
uint8_t canrestore; // Restorable windows
uint8_t cleanwin; // Clean windows
uint8_t otherwin; // Other windows
union {
uint8_t wstate; // Window State
struct {
uint8_t normal:3; // Bits TT<4:2> are set to on a normal
// register window trap
uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin"
// register window trap
} wstateFields;
};
uint8_t gl; // Global level register
/** Hyperprivileged Registers */
union {
uint64_t hpstate; // Hyperprivileged State Register
struct {
uint8_t tlz: 1;
uint8_t :1;
uint8_t hpriv:1;
uint8_t :2;
uint8_t red:1;
uint8_t :4;
uint8_t ibe:1;
uint8_t id:1;
} hpstateFields;
};
uint64_t htstate[MaxTL]; // Hyperprivileged Trap State Register
uint64_t hintp;
uint64_t htba; // Hyperprivileged Trap Base Address register
union {
uint64_t hstick_cmpr; // Hardware tick compare registers
struct {
uint64_t tick_cmpr:63; // Clock-tick count
uint64_t int_dis:1; // Non-priveleged trap
} hstick_cmprFields;
};
uint64_t strandStatusReg; // Per strand status register
/** Floating point misc registers. */
union {
uint64_t fsr; // Floating-Point State Register
struct {
union {
uint64_t cexc:5; // Current excpetion
struct {
uint64_t nxc:1; // Inexact
uint64_t dzc:1; // Divide by zero
uint64_t ufc:1; // Underflow
uint64_t ofc:1; // Overflow
uint64_t nvc:1; // Invalid operand
} cexcFields;
};
union {
uint64_t aexc:5; // Accrued exception
struct {
uint64_t nxc:1; // Inexact
uint64_t dzc:1; // Divide by zero
uint64_t ufc:1; // Underflow
uint64_t ofc:1; // Overflow
uint64_t nvc:1; // Invalid operand
} aexcFields;
};
uint64_t fcc0:2; // Floating-Point condtion codes
uint64_t :1; // Reserved bits
uint64_t qne:1; // Deferred trap queue not empty
// with no queue, it should read 0
uint64_t ftt:3; // Floating-Point trap type
uint64_t ver:3; // Version (of the FPU)
uint64_t :2; // Reserved bits
uint64_t ns:1; // Nonstandard floating point
union {
uint64_t tem:5; // Trap Enable Mask
struct {
uint64_t nxm:1; // Inexact
uint64_t dzm:1; // Divide by zero
uint64_t ufm:1; // Underflow
uint64_t ofm:1; // Overflow
uint64_t nvm:1; // Invalid operand
} temFields;
};
uint64_t :2; // Reserved bits
uint64_t rd:2; // Rounding direction
uint64_t fcc1:2; // Floating-Point condition codes
uint64_t fcc2:2; // Floating-Point condition codes
uint64_t fcc3:2; // Floating-Point condition codes
uint64_t :26; // Reserved bits
} fsrFields;
};
// These need to check the int_dis field and if 0 then
// set appropriate bit in softint and checkinterrutps on the cpu
#if FULL_SYSTEM
/** Process a tick compare event and generate an interrupt on the cpu if
* appropriate. */
void processTickCompare(ThreadContext *tc);
void processSTickCompare(ThreadContext *tc);
void processHSTickCompare(ThreadContext *tc);
typedef CpuEventWrapper<MiscRegFile,
&MiscRegFile::processTickCompare> TickCompareEvent;
TickCompareEvent *tickCompare;
typedef CpuEventWrapper<MiscRegFile,
&MiscRegFile::processSTickCompare> STickCompareEvent;
STickCompareEvent *sTickCompare;
typedef CpuEventWrapper<MiscRegFile,
&MiscRegFile::processHSTickCompare> HSTickCompareEvent;
HSTickCompareEvent *hSTickCompare;
/** Fullsystem only register version of ReadRegWithEffect() */
MiscReg readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
/** Fullsystem only register version of SetRegWithEffect() */
Fault setFSRegWithEffect(int miscReg, const MiscReg &val,
ThreadContext * tc);
#endif
public:
void reset();
MiscRegFile()
{
reset();
}
/** read a value out of an either an SE or FS IPR. No checking is done
* about SE vs. FS as this is mostly used to copy the regfile. Thus more
* register are copied that are necessary for FS. However this prevents
* a bunch of ifdefs and is rarely called so is not performance
* criticial. */
MiscReg readReg(int miscReg);
/** Read a value from an IPR. Only the SE iprs are here and the rest
* are are readFSRegWithEffect (which is called by readRegWithEffect()).
* Checking is done for permission based on state bits in the miscreg
* file. */
MiscReg readRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
/** write a value into an either an SE or FS IPR. No checking is done
* about SE vs. FS as this is mostly used to copy the regfile. Thus more
* register are copied that are necessary for FS. However this prevents
* a bunch of ifdefs and is rarely called so is not performance
* criticial.*/
Fault setReg(int miscReg, const MiscReg &val);
/** Write a value into an IPR. Only the SE iprs are here and the rest
* are are setFSRegWithEffect (which is called by setRegWithEffect()).
* Checking is done for permission based on state bits in the miscreg
* file. */
Fault setRegWithEffect(int miscReg,
const MiscReg &val, ThreadContext * tc);
void serialize(std::ostream & os);
void unserialize(Checkpoint * cp, const std::string & section);
void copyMiscRegs(ThreadContext * tc);
protected:
bool isHyperPriv() { return hpstateFields.hpriv; }
bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; }
bool isNonPriv() { return !isPriv(); }
};
}
#endif

279
src/arch/sparc/regfile.cc Normal file
View file

@ -0,0 +1,279 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
* Ali Saidi
*/
#include "arch/sparc/regfile.hh"
#include "cpu/thread_context.hh"
class Checkpoint;
using namespace SparcISA;
using namespace std;
//RegFile class methods
Addr RegFile::readPC()
{
return pc;
}
void RegFile::setPC(Addr val)
{
pc = val;
}
Addr RegFile::readNextPC()
{
return npc;
}
void RegFile::setNextPC(Addr val)
{
npc = val;
}
Addr RegFile::readNextNPC()
{
return nnpc;
}
void RegFile::setNextNPC(Addr val)
{
nnpc = val;
}
void RegFile::clear()
{
intRegFile.clear();
floatRegFile.clear();
}
MiscReg RegFile::readMiscReg(int miscReg)
{
return miscRegFile.readReg(miscReg);
}
MiscReg RegFile::readMiscRegWithEffect(int miscReg,
Fault &fault, ThreadContext *tc)
{
return miscRegFile.readRegWithEffect(miscReg, fault, tc);
}
Fault RegFile::setMiscReg(int miscReg, const MiscReg &val)
{
return miscRegFile.setReg(miscReg, val);
}
Fault RegFile::setMiscRegWithEffect(int miscReg, const MiscReg &val,
ThreadContext * tc)
{
return miscRegFile.setRegWithEffect(miscReg, val, tc);
}
FloatReg RegFile::readFloatReg(int floatReg, int width)
{
return floatRegFile.readReg(floatReg, width);
}
FloatReg RegFile::readFloatReg(int floatReg)
{
//Use the "natural" width of a single float
return floatRegFile.readReg(floatReg, FloatRegFile::SingleWidth);
}
FloatRegBits RegFile::readFloatRegBits(int floatReg, int width)
{
return floatRegFile.readRegBits(floatReg, width);
}
FloatRegBits RegFile::readFloatRegBits(int floatReg)
{
//Use the "natural" width of a single float
return floatRegFile.readRegBits(floatReg,
FloatRegFile::SingleWidth);
}
Fault RegFile::setFloatReg(int floatReg, const FloatReg &val, int width)
{
return floatRegFile.setReg(floatReg, val, width);
}
Fault RegFile::setFloatReg(int floatReg, const FloatReg &val)
{
//Use the "natural" width of a single float
return setFloatReg(floatReg, val, FloatRegFile::SingleWidth);
}
Fault RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
{
return floatRegFile.setRegBits(floatReg, val, width);
}
Fault RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val)
{
//Use the "natural" width of a single float
return floatRegFile.setRegBits(floatReg, val,
FloatRegFile::SingleWidth);
}
IntReg RegFile::readIntReg(int intReg)
{
return intRegFile.readReg(intReg);
}
Fault RegFile::setIntReg(int intReg, const IntReg &val)
{
return intRegFile.setReg(intReg, val);
}
void RegFile::serialize(std::ostream &os)
{
intRegFile.serialize(os);
floatRegFile.serialize(os);
miscRegFile.serialize(os);
SERIALIZE_SCALAR(pc);
SERIALIZE_SCALAR(npc);
}
void RegFile::unserialize(Checkpoint *cp, const std::string &section)
{
intRegFile.unserialize(cp, section);
floatRegFile.unserialize(cp, section);
miscRegFile.unserialize(cp, section);
UNSERIALIZE_SCALAR(pc);
UNSERIALIZE_SCALAR(npc);
}
void RegFile::changeContext(RegContextParam param, RegContextVal val)
{
switch(param)
{
case CONTEXT_CWP:
intRegFile.setCWP(val);
break;
case CONTEXT_GLOBALS:
intRegFile.setGlobals(val);
break;
default:
panic("Tried to set illegal context parameter in the SPARC regfile.\n");
}
}
int SparcISA::InterruptLevel(uint64_t softint)
{
if (softint & 0x10000 || softint & 0x1)
return 14;
int level = 14;
while (level >= 0 && !(1 << (level + 1) & softint))
level--;
if (1 << (level + 1) & softint)
return level;
return 0;
}
void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
{
uint8_t tl = src->readMiscReg(MISCREG_TL);
// Read all the trap level dependent registers and save them off
for(int i = 1; i <= MaxTL; i++)
{
src->setMiscReg(MISCREG_TL, i);
dest->setMiscReg(MISCREG_TL, i);
dest->setMiscReg(MISCREG_TT, src->readMiscReg(MISCREG_TT));
dest->setMiscReg(MISCREG_TPC, src->readMiscReg(MISCREG_TPC));
dest->setMiscReg(MISCREG_TNPC, src->readMiscReg(MISCREG_TNPC));
dest->setMiscReg(MISCREG_TSTATE, src->readMiscReg(MISCREG_TSTATE));
}
// Save off the traplevel
dest->setMiscReg(MISCREG_TL, tl);
src->setMiscReg(MISCREG_TL, tl);
// ASRs
dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y));
dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR));
dest->setMiscReg(MISCREG_ASI, src->readMiscReg(MISCREG_ASI));
dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK));
dest->setMiscReg(MISCREG_FPRS, src->readMiscReg(MISCREG_FPRS));
dest->setMiscReg(MISCREG_SOFTINT, src->readMiscReg(MISCREG_SOFTINT));
dest->setMiscReg(MISCREG_TICK_CMPR, src->readMiscReg(MISCREG_TICK_CMPR));
dest->setMiscReg(MISCREG_STICK, src->readMiscReg(MISCREG_STICK));
dest->setMiscReg(MISCREG_STICK_CMPR, src->readMiscReg(MISCREG_STICK_CMPR));
// Priv Registers
dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK));
dest->setMiscReg(MISCREG_TBA, src->readMiscReg(MISCREG_TBA));
dest->setMiscReg(MISCREG_PSTATE, src->readMiscReg(MISCREG_PSTATE));
dest->setMiscReg(MISCREG_PIL, src->readMiscReg(MISCREG_PIL));
dest->setMiscReg(MISCREG_CWP, src->readMiscReg(MISCREG_CWP));
dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE));
dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE));
dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN));
dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN));
dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE));
dest->setMiscReg(MISCREG_GL, src->readMiscReg(MISCREG_GL));
// Hyperprivilged registers
dest->setMiscReg(MISCREG_HPSTATE, src->readMiscReg(MISCREG_HPSTATE));
dest->setMiscReg(MISCREG_HINTP, src->readMiscReg(MISCREG_HINTP));
dest->setMiscReg(MISCREG_HTBA, src->readMiscReg(MISCREG_HTBA));
dest->setMiscReg(MISCREG_STRAND_STS_REG,
src->readMiscReg(MISCREG_STRAND_STS_REG));
dest->setMiscReg(MISCREG_HSTICK_CMPR,
src->readMiscReg(MISCREG_HSTICK_CMPR));
// FSR
dest->setMiscReg(MISCREG_FSR, src->readMiscReg(MISCREG_FSR));
}
void SparcISA::copyRegs(ThreadContext *src, ThreadContext *dest)
{
// First loop through the integer registers.
for (int i = 0; i < TheISA::NumIntRegs; ++i) {
dest->setIntReg(i, src->readIntReg(i));
}
// Then loop through the floating point registers.
for (int i = 0; i < TheISA::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());
dest->setNextNPC(src->readNextNPC());
}

View file

@ -32,672 +32,20 @@
#ifndef __ARCH_SPARC_REGFILE_HH__
#define __ARCH_SPARC_REGFILE_HH__
#include "arch/sparc/exceptions.hh"
#include "arch/sparc/faults.hh"
#include "base/trace.hh"
#include "sim/byteswap.hh"
#include "cpu/cpuevent.hh"
#include "arch/sparc/floatregfile.hh"
#include "arch/sparc/intregfile.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/miscregfile.hh"
#include "arch/sparc/types.hh"
#include "sim/host.hh"
#include <string>
class Checkpoint;
namespace SparcISA
{
typedef uint8_t RegIndex;
// MAXTL - maximum trap level
const int MaxPTL = 2;
const int MaxTL = 6;
const int MaxGL = 3;
const int MaxPGL = 2;
// NWINDOWS - number of register windows, can be 3 to 32
const int NWindows = 32;
const int AsrStart = 0;
const int PrStart = 32;
const int HprStart = 64;
const int MiscStart = 96;
const uint64_t Bit64 = (1ULL << 63);
class IntRegFile
{
protected:
static const int FrameOffsetBits = 3;
static const int FrameNumBits = 2;
static const int RegsPerFrame = 1 << FrameOffsetBits;
static const int FrameNumMask =
(FrameNumBits == sizeof(int)) ?
(unsigned int)(-1) :
(1 << FrameNumBits) - 1;
static const int FrameOffsetMask =
(FrameOffsetBits == sizeof(int)) ?
(unsigned int)(-1) :
(1 << FrameOffsetBits) - 1;
IntReg regGlobals[MaxGL][RegsPerFrame];
IntReg regSegments[2 * NWindows][RegsPerFrame];
enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames};
IntReg * regView[NumFrames];
static const int RegGlobalOffset = 0;
static const int FrameOffset = MaxGL * RegsPerFrame;
int offset[NumFrames];
public:
int flattenIndex(int reg)
{
int flatIndex = offset[reg >> FrameOffsetBits]
| (reg & FrameOffsetMask);
DPRINTF(Sparc, "Flattened index %d into %d.\n", reg, flatIndex);
return flatIndex;
}
void clear()
{
int x;
for (x = 0; x < MaxGL; x++)
memset(regGlobals[x], 0, sizeof(regGlobals[x]));
for(int x = 0; x < 2 * NWindows; x++)
bzero(regSegments[x], sizeof(regSegments[x]));
}
IntRegFile()
{
offset[Globals] = 0;
regView[Globals] = regGlobals[0];
setCWP(0);
clear();
}
IntReg readReg(int intReg)
{
IntReg val =
regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask];
DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val);
return val;
}
Fault setReg(int intReg, const IntReg &val)
{
if(intReg)
DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val);
regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val;
return NoFault;
}
//This doesn't effect the actual CWP register.
//It's purpose is to adjust the view of the register file
//to what it would be if CWP = cwp.
void setCWP(int cwp)
{
int index = ((NWindows - cwp) % NWindows) * 2;
offset[Outputs] = FrameOffset + (index * RegsPerFrame);
offset[Locals] = FrameOffset + ((index+1) * RegsPerFrame);
offset[Inputs] = FrameOffset +
(((index+2) % (NWindows * 2)) * RegsPerFrame);
regView[Outputs] = regSegments[index];
regView[Locals] = regSegments[index+1];
regView[Inputs] = regSegments[(index+2) % (NWindows * 2)];
DPRINTF(Sparc, "Changed the CWP value to %d\n", cwp);
}
void setGlobals(int gl)
{
DPRINTF(Sparc, "Now using %d globals", gl);
regView[Globals] = regGlobals[gl];
offset[Globals] = RegGlobalOffset + gl * RegsPerFrame;
}
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
};
typedef float float32_t;
typedef double float64_t;
//FIXME long double refers to a 10 byte float, rather than a
//16 byte float as required. This data type may have to be emulated.
typedef double float128_t;
class FloatRegFile
{
public:
static const int SingleWidth = 32;
static const int DoubleWidth = 64;
static const int QuadWidth = 128;
protected:
//Since the floating point registers overlap each other,
//A generic storage space is used. The float to be returned is
//pulled from the appropriate section of this region.
char regSpace[(SingleWidth / 8) * NumFloatRegs];
public:
void clear()
{
bzero(regSpace, sizeof(regSpace));
}
FloatReg readReg(int floatReg, int width)
{
//In each of these cases, we have to copy the value into a temporary
//variable. This is because we may otherwise try to access an
//unaligned portion of memory.
switch(width)
{
case SingleWidth:
float32_t result32;
memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
return htog(result32);
case DoubleWidth:
float64_t result64;
memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
return htog(result64);
case QuadWidth:
float128_t result128;
memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
return htog(result128);
default:
panic("Attempted to read a %d bit floating point register!", width);
}
}
FloatRegBits readRegBits(int floatReg, int width)
{
//In each of these cases, we have to copy the value into a temporary
//variable. This is because we may otherwise try to access an
//unaligned portion of memory.
switch(width)
{
case SingleWidth:
uint32_t result32;
memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
return htog(result32);
case DoubleWidth:
uint64_t result64;
memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
return htog(result64);
case QuadWidth:
uint64_t result128;
memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
return htog(result128);
default:
panic("Attempted to read a %d bit floating point register!", width);
}
}
Fault setReg(int floatReg, const FloatReg &val, int width)
{
//In each of these cases, we have to copy the value into a temporary
//variable. This is because we may otherwise try to access an
//unaligned portion of memory.
uint32_t result32;
uint64_t result64;
DPRINTF(Sparc, "Setting floating point register %d\n", floatReg);
switch(width)
{
case SingleWidth:
result32 = gtoh((uint32_t)val);
memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
break;
case DoubleWidth:
result64 = gtoh((uint64_t)val);
memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
break;
case QuadWidth:
panic("Quad width FP not implemented.");
break;
default:
panic("Attempted to read a %d bit floating point register!", width);
}
return NoFault;
}
Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
{
//In each of these cases, we have to copy the value into a temporary
//variable. This is because we may otherwise try to access an
//unaligned portion of memory.
uint32_t result32;
uint64_t result64;
switch(width)
{
case SingleWidth:
result32 = gtoh((uint32_t)val);
memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
break;
case DoubleWidth:
result64 = gtoh((uint64_t)val);
memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
break;
case QuadWidth:
panic("Quad width FP not implemented.");
break;
default:
panic("Attempted to read a %d bit floating point register!", width);
}
return NoFault;
}
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
};
enum MiscRegIndex
{
/** Ancillary State Registers */
MISCREG_Y = AsrStart + 0,
MISCREG_CCR = AsrStart + 2,
MISCREG_ASI = AsrStart + 3,
MISCREG_TICK = AsrStart + 4,
MISCREG_PC = AsrStart + 5,
MISCREG_FPRS = AsrStart + 6,
MISCREG_PCR = AsrStart + 16,
MISCREG_PIC = AsrStart + 17,
MISCREG_GSR = AsrStart + 19,
MISCREG_SOFTINT_SET = AsrStart + 20,
MISCREG_SOFTINT_CLR = AsrStart + 21,
MISCREG_SOFTINT = AsrStart + 22,
MISCREG_TICK_CMPR = AsrStart + 23,
MISCREG_STICK = AsrStart + 24,
MISCREG_STICK_CMPR = AsrStart + 25,
/** Privilged Registers */
MISCREG_TPC = PrStart + 0,
MISCREG_TNPC = PrStart + 1,
MISCREG_TSTATE = PrStart + 2,
MISCREG_TT = PrStart + 3,
MISCREG_PRIVTICK = PrStart + 4,
MISCREG_TBA = PrStart + 5,
MISCREG_PSTATE = PrStart + 6,
MISCREG_TL = PrStart + 7,
MISCREG_PIL = PrStart + 8,
MISCREG_CWP = PrStart + 9,
MISCREG_CANSAVE = PrStart + 10,
MISCREG_CANRESTORE = PrStart + 11,
MISCREG_CLEANWIN = PrStart + 12,
MISCREG_OTHERWIN = PrStart + 13,
MISCREG_WSTATE = PrStart + 14,
MISCREG_GL = PrStart + 16,
/** Hyper privileged registers */
MISCREG_HPSTATE = HprStart + 0,
MISCREG_HTSTATE = HprStart + 1,
MISCREG_HINTP = HprStart + 3,
MISCREG_HTBA = HprStart + 5,
MISCREG_HVER = HprStart + 6,
MISCREG_STRAND_STS_REG = HprStart + 16,
MISCREG_HSTICK_CMPR = HprStart + 31,
/** Floating Point Status Register */
MISCREG_FSR = MiscStart + 0
};
// The control registers, broken out into fields
class MiscRegFile
{
private:
/* ASR Registers */
union {
uint64_t y; // Y (used in obsolete multiplication)
struct {
uint64_t value:32; // The actual value stored in y
uint64_t :32; // reserved bits
} yFields;
};
union {
uint8_t ccr; // Condition Code Register
struct {
union {
uint8_t icc:4; // 32-bit condition codes
struct {
uint8_t c:1; // Carry
uint8_t v:1; // Overflow
uint8_t z:1; // Zero
uint8_t n:1; // Negative
} iccFields;
};
union {
uint8_t xcc:4; // 64-bit condition codes
struct {
uint8_t c:1; // Carry
uint8_t v:1; // Overflow
uint8_t z:1; // Zero
uint8_t n:1; // Negative
} xccFields;
};
} ccrFields;
};
uint8_t asi; // Address Space Identifier
union {
uint64_t tick; // Hardware clock-tick counter
struct {
int64_t counter:63; // Clock-tick count
uint64_t npt:1; // Non-priveleged trap
} tickFields;
};
union {
uint8_t fprs; // Floating-Point Register State
struct {
uint8_t dl:1; // Dirty lower
uint8_t du:1; // Dirty upper
uint8_t fef:1; // FPRS enable floating-Point
} fprsFields;
};
union {
uint64_t softint;
struct {
uint64_t tm:1;
uint64_t int_level:14;
uint64_t sm:1;
} softintFields;
};
union {
uint64_t tick_cmpr; // Hardware tick compare registers
struct {
uint64_t tick_cmpr:63; // Clock-tick count
uint64_t int_dis:1; // Non-priveleged trap
} tick_cmprFields;
};
union {
uint64_t stick; // Hardware clock-tick counter
struct {
int64_t :63; // Not used, storage in SparcSystem
uint64_t npt:1; // Non-priveleged trap
} stickFields;
};
union {
uint64_t stick_cmpr; // Hardware tick compare registers
struct {
uint64_t tick_cmpr:63; // Clock-tick count
uint64_t int_dis:1; // Non-priveleged trap
} stick_cmprFields;
};
/* Privileged Registers */
uint64_t tpc[MaxTL]; // Trap Program Counter (value from
// previous trap level)
uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
// previous trap level)
union {
uint64_t tstate[MaxTL]; // Trap State
struct {
//Values are from previous trap level
uint64_t cwp:5; // Current Window Pointer
uint64_t :3; // Reserved bits
uint64_t pstate:13; // Process State
uint64_t :3; // Reserved bits
uint64_t asi:8; // Address Space Identifier
uint64_t ccr:8; // Condition Code Register
uint64_t gl:8; // Global level
} tstateFields[MaxTL];
};
uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
// on the previous level)
uint64_t tba; // Trap Base Address
union {
uint16_t pstate; // Process State Register
struct {
uint16_t :1; // reserved
uint16_t ie:1; // Interrupt enable
uint16_t priv:1; // Privelege mode
uint16_t am:1; // Address mask
uint16_t pef:1; // PSTATE enable floating-point
uint16_t :1; // reserved2
uint16_t mm:2; // Memory Model
uint16_t tle:1; // Trap little-endian
uint16_t cle:1; // Current little-endian
} pstateFields;
};
uint8_t tl; // Trap Level
uint8_t pil; // Process Interrupt Register
uint8_t cwp; // Current Window Pointer
uint8_t cansave; // Savable windows
uint8_t canrestore; // Restorable windows
uint8_t cleanwin; // Clean windows
uint8_t otherwin; // Other windows
union {
uint8_t wstate; // Window State
struct {
uint8_t normal:3; // Bits TT<4:2> are set to on a normal
// register window trap
uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin"
// register window trap
} wstateFields;
};
uint8_t gl; // Global level register
/** Hyperprivileged Registers */
union {
uint64_t hpstate; // Hyperprivileged State Register
struct {
uint8_t tlz: 1;
uint8_t :1;
uint8_t hpriv:1;
uint8_t :2;
uint8_t red:1;
uint8_t :4;
uint8_t ibe:1;
uint8_t id:1;
} hpstateFields;
};
uint64_t htstate[MaxTL]; // Hyperprivileged Trap State Register
uint64_t hintp;
uint64_t htba; // Hyperprivileged Trap Base Address register
union {
uint64_t hstick_cmpr; // Hardware tick compare registers
struct {
uint64_t tick_cmpr:63; // Clock-tick count
uint64_t int_dis:1; // Non-priveleged trap
} hstick_cmprFields;
};
uint64_t strandStatusReg; // Per strand status register
/** Floating point misc registers. */
union {
uint64_t fsr; // Floating-Point State Register
struct {
union {
uint64_t cexc:5; // Current excpetion
struct {
uint64_t nxc:1; // Inexact
uint64_t dzc:1; // Divide by zero
uint64_t ufc:1; // Underflow
uint64_t ofc:1; // Overflow
uint64_t nvc:1; // Invalid operand
} cexcFields;
};
union {
uint64_t aexc:5; // Accrued exception
struct {
uint64_t nxc:1; // Inexact
uint64_t dzc:1; // Divide by zero
uint64_t ufc:1; // Underflow
uint64_t ofc:1; // Overflow
uint64_t nvc:1; // Invalid operand
} aexcFields;
};
uint64_t fcc0:2; // Floating-Point condtion codes
uint64_t :1; // Reserved bits
uint64_t qne:1; // Deferred trap queue not empty
// with no queue, it should read 0
uint64_t ftt:3; // Floating-Point trap type
uint64_t ver:3; // Version (of the FPU)
uint64_t :2; // Reserved bits
uint64_t ns:1; // Nonstandard floating point
union {
uint64_t tem:5; // Trap Enable Mask
struct {
uint64_t nxm:1; // Inexact
uint64_t dzm:1; // Divide by zero
uint64_t ufm:1; // Underflow
uint64_t ofm:1; // Overflow
uint64_t nvm:1; // Invalid operand
} temFields;
};
uint64_t :2; // Reserved bits
uint64_t rd:2; // Rounding direction
uint64_t fcc1:2; // Floating-Point condition codes
uint64_t fcc2:2; // Floating-Point condition codes
uint64_t fcc3:2; // Floating-Point condition codes
uint64_t :26; // Reserved bits
} fsrFields;
};
// These need to check the int_dis field and if 0 then
// set appropriate bit in softint and checkinterrutps on the cpu
#if FULL_SYSTEM
/** Process a tick compare event and generate an interrupt on the cpu if
* appropriate. */
void processTickCompare(ThreadContext *tc);
void processSTickCompare(ThreadContext *tc);
void processHSTickCompare(ThreadContext *tc);
typedef CpuEventWrapper<MiscRegFile,
&MiscRegFile::processTickCompare> TickCompareEvent;
TickCompareEvent *tickCompare;
typedef CpuEventWrapper<MiscRegFile,
&MiscRegFile::processSTickCompare> STickCompareEvent;
STickCompareEvent *sTickCompare;
typedef CpuEventWrapper<MiscRegFile,
&MiscRegFile::processHSTickCompare> HSTickCompareEvent;
HSTickCompareEvent *hSTickCompare;
/** Fullsystem only register version of ReadRegWithEffect() */
MiscReg readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
/** Fullsystem only register version of SetRegWithEffect() */
Fault setFSRegWithEffect(int miscReg, const MiscReg &val,
ThreadContext * tc);
#endif
public:
void reset()
{
pstateFields.pef = 0; //No FPU
//pstateFields.pef = 1; //FPU
#if FULL_SYSTEM
//For SPARC, when a system is first started, there is a power
//on reset Trap which sets the processor into the following state.
//Bits that aren't set aren't defined on startup.
tl = MaxTL;
gl = MaxGL;
tickFields.counter = 0; //The TICK register is unreadable bya
tickFields.npt = 1; //The TICK register is unreadable by by !priv
softint = 0; // Clear all the soft interrupt bits
tick_cmprFields.int_dis = 1; // disable timer compare interrupts
tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
stickFields.npt = 1; //The TICK register is unreadable by by !priv
stick_cmprFields.int_dis = 1; // disable timer compare interrupts
stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
tt[tl] = power_on_reset;
pstate = 0; // fields 0 but pef
pstateFields.pef = 1;
hpstate = 0;
hpstateFields.red = 1;
hpstateFields.hpriv = 1;
hpstateFields.tlz = 0; // this is a guess
hintp = 0; // no interrupts pending
hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
#else
/* //This sets up the initial state of the processor for usermode processes
pstateFields.priv = 0; //Process runs in user mode
pstateFields.ie = 1; //Interrupts are enabled
fsrFields.rd = 0; //Round to nearest
fsrFields.tem = 0; //Floating point traps not enabled
fsrFields.ns = 0; //Non standard mode off
fsrFields.qne = 0; //Floating point queue is empty
fsrFields.aexc = 0; //No accrued exceptions
fsrFields.cexc = 0; //No current exceptions
//Register window management registers
otherwin = 0; //No windows contain info from other programs
canrestore = 0; //There are no windows to pop
cansave = MaxTL - 2; //All windows are available to save into
cleanwin = MaxTL;*/
#endif
}
MiscRegFile()
{
reset();
}
/** read a value out of an either an SE or FS IPR. No checking is done
* about SE vs. FS as this is mostly used to copy the regfile. Thus more
* register are copied that are necessary for FS. However this prevents
* a bunch of ifdefs and is rarely called so is not performance
* criticial. */
MiscReg readReg(int miscReg);
/** Read a value from an IPR. Only the SE iprs are here and the rest
* are are readFSRegWithEffect (which is called by readRegWithEffect()).
* Checking is done for permission based on state bits in the miscreg
* file. */
MiscReg readRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
/** write a value into an either an SE or FS IPR. No checking is done
* about SE vs. FS as this is mostly used to copy the regfile. Thus more
* register are copied that are necessary for FS. However this prevents
* a bunch of ifdefs and is rarely called so is not performance
* criticial.*/
Fault setReg(int miscReg, const MiscReg &val);
/** Write a value into an IPR. Only the SE iprs are here and the rest
* are are setFSRegWithEffect (which is called by setRegWithEffect()).
* Checking is done for permission based on state bits in the miscreg
* file. */
Fault setRegWithEffect(int miscReg,
const MiscReg &val, ThreadContext * tc);
void serialize(std::ostream & os);
void unserialize(Checkpoint * cp, const std::string & section);
void copyMiscRegs(ThreadContext * tc);
protected:
bool isHyperPriv() { return hpstateFields.hpriv; }
bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; }
bool isNonPriv() { return !isPriv(); }
};
typedef union
{
IntReg intreg;
FloatReg fpreg;
MiscReg ctrlreg;
} AnyReg;
class RegFile
{
protected:
@ -706,35 +54,14 @@ namespace SparcISA
Addr nnpc;
public:
Addr readPC()
{
return pc;
}
Addr readPC();
void setPC(Addr val);
void setPC(Addr val)
{
pc = val;
}
Addr readNextPC();
void setNextPC(Addr val);
Addr readNextPC()
{
return npc;
}
void setNextPC(Addr val)
{
npc = val;
}
Addr readNextNPC()
{
return nnpc;
}
void setNextNPC(Addr val)
{
nnpc = val;
}
Addr readNextNPC();
void setNextNPC(Addr val);
protected:
IntRegFile intRegFile; // integer register file
@ -743,121 +70,46 @@ namespace SparcISA
public:
void clear()
{
intRegFile.clear();
floatRegFile.clear();
}
void clear();
int FlattenIntIndex(int reg)
{
return intRegFile.flattenIndex(reg);
}
int FlattenIntIndex(int reg);
MiscReg readMiscReg(int miscReg)
{
return miscRegFile.readReg(miscReg);
}
MiscReg readMiscReg(int miscReg);
MiscReg readMiscRegWithEffect(int miscReg,
Fault &fault, ThreadContext *tc)
{
return miscRegFile.readRegWithEffect(miscReg, fault, tc);
}
Fault &fault, ThreadContext *tc);
Fault setMiscReg(int miscReg, const MiscReg &val)
{
return miscRegFile.setReg(miscReg, val);
}
Fault setMiscReg(int miscReg, const MiscReg &val);
Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
ThreadContext * tc)
{
return miscRegFile.setRegWithEffect(miscReg, val, tc);
}
ThreadContext * tc);
FloatReg readFloatReg(int floatReg, int width)
{
return floatRegFile.readReg(floatReg, width);
}
FloatReg readFloatReg(int floatReg, int width);
FloatReg readFloatReg(int floatReg)
{
//Use the "natural" width of a single float
return floatRegFile.readReg(floatReg, FloatRegFile::SingleWidth);
}
FloatReg readFloatReg(int floatReg);
FloatRegBits readFloatRegBits(int floatReg, int width)
{
return floatRegFile.readRegBits(floatReg, width);
}
FloatRegBits readFloatRegBits(int floatReg, int width);
FloatRegBits readFloatRegBits(int floatReg)
{
//Use the "natural" width of a single float
return floatRegFile.readRegBits(floatReg,
FloatRegFile::SingleWidth);
}
FloatRegBits readFloatRegBits(int floatReg);
Fault setFloatReg(int floatReg, const FloatReg &val, int width)
{
return floatRegFile.setReg(floatReg, val, width);
}
Fault setFloatReg(int floatReg, const FloatReg &val, int width);
Fault setFloatReg(int floatReg, const FloatReg &val)
{
//Use the "natural" width of a single float
return setFloatReg(floatReg, val, FloatRegFile::SingleWidth);
}
Fault setFloatReg(int floatReg, const FloatReg &val);
Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
{
return floatRegFile.setRegBits(floatReg, val, width);
}
Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width);
Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
{
//Use the "natural" width of a single float
return floatRegFile.setRegBits(floatReg, val,
FloatRegFile::SingleWidth);
}
Fault setFloatRegBits(int floatReg, const FloatRegBits &val);
IntReg readIntReg(int intReg)
{
return intRegFile.readReg(intReg);
}
IntReg readIntReg(int intReg);
Fault setIntReg(int intReg, const IntReg &val)
{
return intRegFile.setReg(intReg, val);
}
Fault setIntReg(int intReg, const IntReg &val);
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
public:
enum ContextParam
{
CONTEXT_CWP,
CONTEXT_GLOBALS
};
typedef int ContextVal;
void changeContext(ContextParam param, ContextVal val)
{
switch(param)
{
case CONTEXT_CWP:
intRegFile.setCWP(val);
break;
case CONTEXT_GLOBALS:
intRegFile.setGlobals(val);
break;
default:
panic("Tried to set illegal context parameter in the SPARC regfile.\n");
}
}
void changeContext(RegContextParam param, RegContextVal val);
};
void copyRegs(ThreadContext *src, ThreadContext *dest);

View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#ifndef __ARCH_SPARC_SYSCALLRETURN_HH__
#define __ARCH_SPARC_SYSCALLRETURN_HH__
#include <inttypes.h>
class SyscallReturn
{
public:
template <class T>
SyscallReturn(T v, bool s)
{
retval = (uint64_t)v;
success = s;
}
template <class T>
SyscallReturn(T v)
{
success = (v >= 0);
retval = (uint64_t)v;
}
~SyscallReturn() {}
SyscallReturn& operator=(const SyscallReturn& s)
{
retval = s.retval;
success = s.success;
return *this;
}
bool successful() { return success; }
uint64_t value() { return retval; }
private:
uint64_t retval;
bool success;
};
namespace SparcISA
{
static inline void setSyscallReturn(SyscallReturn return_value,
RegFile *regs)
{
// check for error condition. SPARC syscall convention is to
// indicate success/failure in reg the carry bit of the ccr
// and put the return value itself in the standard return value reg ().
if (return_value.successful()) {
// no error, clear XCC.C
regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEF);
regs->setIntReg(ReturnValueReg, return_value.value());
} else {
// got an error, set XCC.C
regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x10);
regs->setIntReg(ReturnValueReg, return_value.value());
}
}
};
#endif

63
src/arch/sparc/types.hh Normal file
View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
*/
#ifndef __ARCH_SPARC_TYPES_HH__
#define __ARCH_SPARC_TYPES_HH__
#include <inttypes.h>
namespace SparcISA
{
typedef uint32_t MachInst;
typedef uint64_t ExtMachInst;
typedef uint64_t IntReg;
typedef uint64_t MiscReg;
typedef double FloatReg;
typedef uint64_t FloatRegBits;
typedef union
{
IntReg intReg;
FloatReg fpreg;
MiscReg ctrlreg;
} AnyReg;
enum RegContextParam
{
CONTEXT_CWP,
CONTEXT_GLOBALS
};
typedef int RegContextVal;
typedef uint8_t RegIndex;
}
#endif

View file

@ -31,6 +31,7 @@
#ifndef __CPU_CHECKER_THREAD_CONTEXT_HH__
#define __CPU_CHECKER_THREAD_CONTEXT_HH__
#include "arch/types.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
@ -295,8 +296,8 @@ class CheckerThreadContext : public ThreadContext
Counter readFuncExeInst() { return actualTC->readFuncExeInst(); }
#endif
void changeRegFileContext(RegFile::ContextParam param,
RegFile::ContextVal val)
void changeRegFileContext(TheISA::RegContextParam param,
TheISA::RegContextVal val)
{
actualTC->changeRegFileContext(param, val);
checkerTC->changeRegFileContext(param, val);

View file

@ -28,6 +28,7 @@
* Authors: Kevin Lim
*/
#include "arch/alpha/types.hh"
#include "cpu/o3/thread_context.hh"
template <class Impl>
@ -64,8 +65,8 @@ class AlphaTC : public O3ThreadContext<Impl>
panic("Alpha has no NextNPC!");
}
virtual void changeRegFileContext(TheISA::RegFile::ContextParam param,
TheISA::RegFile::ContextVal val)
virtual void changeRegFileContext(TheISA::RegContextParam param,
TheISA::RegContextVal val)
{ panic("Not supported on Alpha!"); }

View file

@ -29,6 +29,7 @@
* Korey Sewell
*/
#include "arch/mips/types.hh"
#include "cpu/o3/thread_context.hh"
template <class Impl>
@ -45,8 +46,8 @@ class MipsTC : public O3ThreadContext<Impl>
this->cpu->setNextNPC(val, this->thread->readTid());
}
virtual void changeRegFileContext(TheISA::RegFile::ContextParam param,
TheISA::RegFile::ContextVal val)
virtual void changeRegFileContext(TheISA::RegContextParam param,
TheISA::RegContextVal val)
{ panic("Not supported on Mips!"); }
/** This function exits the thread context in the CPU and returns

View file

@ -449,8 +449,8 @@ class SimpleThread : public ThreadState
}
#endif
void changeRegFileContext(RegFile::ContextParam param,
RegFile::ContextVal val)
void changeRegFileContext(TheISA::RegContextParam param,
TheISA::RegContextVal val)
{
regs.changeContext(param, val);
}

View file

@ -34,6 +34,8 @@
#include <bitset>
#include <string>
#include "arch/isa_traits.hh"
#include "arch/faults.hh"
#include "base/bitfield.hh"
#include "base/hashmap.hh"
#include "base/misc.hh"
@ -41,7 +43,6 @@
#include "cpu/op_class.hh"
#include "cpu/o3/dyn_inst.hh"
#include "sim/host.hh"
#include "arch/isa_traits.hh"
// forward declarations
struct AlphaSimpleImpl;

View file

@ -31,6 +31,9 @@
#ifndef __CPU_THREAD_CONTEXT_HH__
#define __CPU_THREAD_CONTEXT_HH__
#include "arch/types.hh"
#include "arch/regfile.hh"
#include "arch/syscallreturn.hh"
#include "config/full_system.hh"
#include "mem/request.hh"
#include "sim/faults.hh"
@ -254,8 +257,8 @@ class ThreadContext
virtual int exit() { return 1; };
#endif
virtual void changeRegFileContext(RegFile::ContextParam param,
RegFile::ContextVal val) = 0;
virtual void changeRegFileContext(TheISA::RegContextParam param,
TheISA::RegContextVal val) = 0;
};
/**
@ -438,8 +441,8 @@ class ProxyThreadContext : public ThreadContext
Counter readFuncExeInst() { return actualTC->readFuncExeInst(); }
#endif
void changeRegFileContext(RegFile::ContextParam param,
RegFile::ContextVal val)
void changeRegFileContext(TheISA::RegContextParam param,
TheISA::RegContextVal val)
{
actualTC->changeRegFileContext(param, val);
}

View file

@ -38,6 +38,7 @@
#include <string>
#include "arch/faults.hh"
#include "arch/isa_traits.hh"
#include "base/hashmap.hh"
#include "base/trace.hh"

View file

@ -39,6 +39,7 @@
#define __MEM_REQUEST_HH__
#include "arch/isa_traits.hh"
#include "sim/root.hh"
class Request;