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:
parent
f612f09669
commit
800e6ecc07
|
@ -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
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 §ion);
|
||||
|
||||
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
|
||||
|
|
87
src/arch/alpha/syscallreturn.hh
Normal file
87
src/arch/alpha/syscallreturn.hh
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 ®_file,
|
||||
int regnum);
|
||||
const int TotalDataRegs = NumIntRegs + NumFloatRegs;
|
||||
|
||||
void restoreMachineReg(RegFile ®s, const AnyReg ®,
|
||||
int regnum);
|
||||
// Static instruction parameters
|
||||
const int MaxInstSrcRegs = 3;
|
||||
const int MaxInstDestRegs = 2;
|
||||
|
||||
#if 0
|
||||
static void serializeSpecialRegs(const Serializable::Proxy &proxy,
|
||||
const RegFile ®s);
|
||||
// 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 ®s);
|
||||
#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
36
src/arch/mips/regfile.hh
Normal 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
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 §ion);
|
||||
|
||||
typedef int ContextParam;
|
||||
typedef int ContextVal;
|
||||
|
||||
void changeContext(ContextParam param, ContextVal val)
|
||||
void changeContext(RegContextParam param, RegContextVal val)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
84
src/arch/mips/syscallreturn.hh
Normal file
84
src/arch/mips/syscallreturn.hh
Normal 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
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
174
src/arch/sparc/floatregfile.cc
Normal file
174
src/arch/sparc/floatregfile.cc
Normal 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 §ion)
|
||||
{
|
||||
UNSERIALIZE_ARRAY((unsigned char *)regSpace,
|
||||
SingleWidth / 8 * NumFloatRegs);
|
||||
}
|
||||
|
83
src/arch/sparc/floatregfile.hh
Normal file
83
src/arch/sparc/floatregfile.hh
Normal 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 §ion);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
133
src/arch/sparc/intregfile.cc
Normal file
133
src/arch/sparc/intregfile.cc
Normal 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 §ion)
|
||||
{
|
||||
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);
|
||||
}
|
103
src/arch/sparc/intregfile.hh
Normal file
103
src/arch/sparc/intregfile.hh
Normal 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 §ion);
|
||||
|
||||
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
|
|
@ -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__
|
||||
|
|
540
src/arch/sparc/miscregfile.cc
Normal file
540
src/arch/sparc/miscregfile.cc
Normal 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);
|
||||
}
|
||||
|
410
src/arch/sparc/miscregfile.hh
Normal file
410
src/arch/sparc/miscregfile.hh
Normal 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
279
src/arch/sparc/regfile.cc
Normal 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 §ion)
|
||||
{
|
||||
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());
|
||||
}
|
|
@ -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 §ion);
|
||||
};
|
||||
|
||||
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 §ion);
|
||||
};
|
||||
|
||||
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 §ion);
|
||||
|
||||
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);
|
||||
|
|
90
src/arch/sparc/syscallreturn.hh
Normal file
90
src/arch/sparc/syscallreturn.hh
Normal 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
63
src/arch/sparc/types.hh
Normal 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
|
|
@ -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);
|
||||
|
|
|
@ -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!"); }
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "arch/faults.hh"
|
||||
#include "arch/isa_traits.hh"
|
||||
#include "base/hashmap.hh"
|
||||
#include "base/trace.hh"
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#define __MEM_REQUEST_HH__
|
||||
|
||||
#include "arch/isa_traits.hh"
|
||||
#include "sim/root.hh"
|
||||
|
||||
class Request;
|
||||
|
||||
|
|
Loading…
Reference in a new issue