mips import pt. 1

src/arch/mips/SConscript:
    "mips import pt.1".

--HG--
extra : convert_revision : 2e393341938bebf32fb638a209262d074fad4cc1
This commit is contained in:
Korey Sewell 2007-06-22 19:03:42 -04:00
parent 16c1b5484f
commit 753adb38d5
44 changed files with 5277 additions and 631 deletions

View file

@ -35,7 +35,9 @@ Import('*')
if env['TARGET_ISA'] == 'mips':
Source('faults.cc')
Source('isa_traits.cc')
Source('regfile/misc_regfile.cc')
Source('utility.cc')
Source('dsp.cc')
if env['FULL_SYSTEM']:
#Insert Full-System Files Here

41
src/arch/mips/constants.hh Executable file
View file

@ -0,0 +1,41 @@
/*
* 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_CONSTANTS_HH__
#define __ARCH_MIPS_CONSTANTS_HH__
#include "arch/mips/types.hh"
//#include "config/full_system.hh"
namespace MipsISA
{
} // namespace MipsISA
#endif

1227
src/arch/mips/dsp.cc Executable file

File diff suppressed because it is too large Load diff

171
src/arch/mips/dsp.hh Executable file
View file

@ -0,0 +1,171 @@
/*
* 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: Brett Miller
*/
#ifndef __ARCH_MIPS_DSP_HH__
#define __ARCH_MIPS_DSP_HH__
#include "arch/mips/types.hh"
#include "arch/mips/isa_traits.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
#include "sim/host.hh"
class ThreadContext;
namespace MipsISA {
// SIMD formats
enum {
SIMD_FMT_L, // long word
SIMD_FMT_W, // word
SIMD_FMT_PH, // paired halfword
SIMD_FMT_QB, // quad byte
SIMD_NUM_FMTS
};
// DSPControl Fields
enum {
DSP_POS, // insertion bitfield position
DSP_SCOUNT, // insertion bitfield size
DSP_C, // carry bit
DSP_OUFLAG, // overflow-underflow flag
DSP_CCOND, // condition code
DSP_EFI, // extract fail indicator bit
DSP_NUM_FIELDS
};
// compare instruction operations
enum {
CMP_EQ, // equal
CMP_LT, // less than
CMP_LE // less than or equal
};
// SIMD operation order modes
enum {
MODE_L, // left
MODE_R, // right
MODE_LA, // left-alternate
MODE_RA, // right-alternate
MODE_X // cross
};
// dsp operation parameters
enum { UNSIGNED, SIGNED };
enum { NOSATURATE, SATURATE };
enum { NOROUND, ROUND };
// DSPControl field positions and masks
const uint32_t DSP_CTL_POS[DSP_NUM_FIELDS] = { 0, 7, 13, 16, 24, 14 };
const uint32_t DSP_CTL_MASK[DSP_NUM_FIELDS] = { 0x0000003f, 0x00001f80, 0x00002000,
0x00ff0000, 0x0f000000, 0x00004000 };
// SIMD format constants
const uint32_t SIMD_MAX_VALS = 4; // maximum values per register
const uint32_t SIMD_NVALS[SIMD_NUM_FMTS] = { 1, 1, 2, 4 }; // number of values in fmt
const uint32_t SIMD_NBITS[SIMD_NUM_FMTS] = { 64, 32, 16, 8 }; // number of bits per value
const uint32_t SIMD_LOG2N[SIMD_NUM_FMTS] = { 6, 5, 4, 3 }; // log2( bits per value )
// DSP maximum values
const uint64_t FIXED_L_SMAX = ULL(0x7fffffffffffffff);
const uint64_t FIXED_W_SMAX = ULL(0x000000007fffffff);
const uint64_t FIXED_H_SMAX = ULL(0x0000000000007fff);
const uint64_t FIXED_B_SMAX = ULL(0x000000000000007f);
const uint64_t FIXED_L_UMAX = ULL(0xffffffffffffffff);
const uint64_t FIXED_W_UMAX = ULL(0x00000000ffffffff);
const uint64_t FIXED_H_UMAX = ULL(0x000000000000ffff);
const uint64_t FIXED_B_UMAX = ULL(0x00000000000000ff);
const uint64_t FIXED_SMAX[SIMD_NUM_FMTS] = { FIXED_L_SMAX, FIXED_W_SMAX, FIXED_H_SMAX, FIXED_B_SMAX };
const uint64_t FIXED_UMAX[SIMD_NUM_FMTS] = { FIXED_L_UMAX, FIXED_W_UMAX, FIXED_H_UMAX, FIXED_B_UMAX };
// DSP minimum values
const uint64_t FIXED_L_SMIN = ULL(0x8000000000000000);
const uint64_t FIXED_W_SMIN = ULL(0xffffffff80000000);
const uint64_t FIXED_H_SMIN = ULL(0xffffffffffff8000);
const uint64_t FIXED_B_SMIN = ULL(0xffffffffffffff80);
const uint64_t FIXED_L_UMIN = ULL(0x0000000000000000);
const uint64_t FIXED_W_UMIN = ULL(0x0000000000000000);
const uint64_t FIXED_H_UMIN = ULL(0x0000000000000000);
const uint64_t FIXED_B_UMIN = ULL(0x0000000000000000);
const uint64_t FIXED_SMIN[SIMD_NUM_FMTS] = { FIXED_L_SMIN, FIXED_W_SMIN, FIXED_H_SMIN, FIXED_B_SMIN };
const uint64_t FIXED_UMIN[SIMD_NUM_FMTS] = { FIXED_L_UMIN, FIXED_W_UMIN, FIXED_H_UMIN, FIXED_B_UMIN };
// DSP utility functions
int32_t bitrev( int32_t value );
uint64_t dspSaturate( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow );
uint64_t checkOverflow( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow );
uint64_t signExtend( uint64_t value, int32_t signpos );
uint64_t addHalfLsb( uint64_t value, int32_t lsbpos );
int32_t dspAbs( int32_t a, int32_t fmt, uint32_t *dspctl );
int32_t dspAdd( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl );
int32_t dspAddh( int32_t a, int32_t b, int32_t fmt, int32_t round, int32_t sign );
int32_t dspSub( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl );
int32_t dspSubh( int32_t a, int32_t b, int32_t fmt, int32_t round, int32_t sign );
int32_t dspShll( int32_t a, uint32_t sa, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl );
int32_t dspShrl( int32_t a, uint32_t sa, int32_t fmt, int32_t sign );
int32_t dspShra( int32_t a, uint32_t sa, int32_t fmt, int32_t round, int32_t sign, uint32_t *dspctl );
int32_t dspMul( int32_t a, int32_t b, int32_t fmt, int32_t saturate, uint32_t *dspctl );
int32_t dspMulq( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t round, uint32_t *dspctl );
int32_t dspMuleu( int32_t a, int32_t b, int32_t mode, uint32_t *dspctl );
int32_t dspMuleq( int32_t a, int32_t b, int32_t mode, uint32_t *dspctl );
int64_t dspDpaq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t infmt,
int32_t outfmt, int32_t postsat, int32_t mode, uint32_t *dspctl );
int64_t dspDpsq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t infmt,
int32_t outfmt, int32_t postsat, int32_t mode, uint32_t *dspctl );
int64_t dspDpa( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt, int32_t sign, int32_t mode );
int64_t dspDps( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt, int32_t sign, int32_t mode );
int64_t dspMaq( int64_t dspac, int32_t a, int32_t b, int32_t ac,
int32_t fmt, int32_t mode, int32_t saturate, uint32_t *dspctl );
int64_t dspMulsa( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt );
int64_t dspMulsaq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt, uint32_t *dspctl );
void dspCmp( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, uint32_t *dspctl );
int32_t dspCmpg( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op );
int32_t dspCmpgd( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, uint32_t *dspctl );
int32_t dspPrece( int32_t a, int32_t infmt, int32_t insign, int32_t outfmt, int32_t outsign, int32_t mode );
int32_t dspPrecrqu( int32_t a, int32_t b, uint32_t *dspctl );
int32_t dspPrecrq( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl );
int32_t dspPrecrSra( int32_t a, int32_t b, int32_t sa, int32_t fmt, int32_t round );
int32_t dspPick( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl );
int32_t dspPack( int32_t a, int32_t b, int32_t fmt );
int32_t dspExtr( int64_t dspac, int32_t fmt, int32_t sa, int32_t round,
int32_t saturate, uint32_t *dspctl );
int32_t dspExtp( int64_t dspac, int32_t size, uint32_t *dspctl );
int32_t dspExtpd( int64_t dspac, int32_t size, uint32_t *dspctl );
// SIMD pack/unpack utility functions
void simdPack( uint64_t *values_ptr, int32_t *reg, int32_t fmt );
void simdUnpack( int32_t reg, uint64_t *values_ptr, int32_t fmt, int32_t sign );
// DSPControl r/w utility functions
void writeDSPControl( uint32_t *dspctl, uint32_t value, uint32_t mask );
uint32_t readDSPControl( uint32_t *dspctl, uint32_t mask );
};
#endif

216
src/arch/mips/dt_constants.hh Executable file
View file

@ -0,0 +1,216 @@
/*
* 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: Jaidev Patwardhan
*/
#ifndef __ARCH_MIPS_DT_CONSTANTS_HH__
#define __ARCH_MIPS_DT_CONSTANTS_HH__
#include "arch/mips/types.hh"
//#include "config/full_system.hh"
namespace MipsISA
{
// See the EJTAG Specification - Revision 4.10
// Also see PDTrace Specification - Revision 4.30
// Debug Register - CP0 Reg 23, Sel 0
const unsigned Debug_DBD = 31;
const unsigned Debug_DM_HI = 30;
const unsigned Debug_DM_LO = 30;
const unsigned Debug_NODCR = 29;
const unsigned Debug_LSNM = 28;
const unsigned Debug_DOZE = 27;
const unsigned Debug_HALT = 26;
const unsigned Debug_COUNTDM = 25;
const unsigned Debug_IBUSEP = 24;
const unsigned Debug_MCHECKEP = 23;
const unsigned Debug_CACHEEP = 22;
const unsigned Debug_DBUSEP = 21;
const unsigned Debug_IEXI_HI = 20;
const unsigned Debug_IEXI_LO = 20;
const unsigned Debug_DDBS_IMPR = 19;
const unsigned Debug_DDBL_IMPR = 18;
const unsigned Debug_EJTAGVER_2 =17;
const unsigned Debug_EJTAGVER_1 =16;
const unsigned Debug_EJTAGVER_0 =15;
const unsigned Debug_EJTAGVER_HI = 17;
const unsigned Debug_EJTAGVER_LO = 15;
const unsigned Debug_DEXC_CODE_HI = 14;
const unsigned Debug_DEXC_CODE_LO = 10;
const unsigned Debug_NOSST = 9;
const unsigned Debug_SST = 8;
const unsigned Debug_OFFLINE = 7;
const unsigned Debug_DIBIMPR = 6;
const unsigned Debug_DINT = 5;
const unsigned Debug_DIB = 4;
const unsigned Debug_DDBS = 3;
const unsigned Debug_DDBL = 2;
const unsigned Debug_DBp = 1;
const unsigned Debug_DSS = 0;
// TraceControl Register - CP0 Reg 23, Sel 1
const unsigned TraceControl_TS = 31;
const unsigned TraceControl_UT = 30;
const unsigned TraceControl_TB = 27;
const unsigned TraceControl_IO = 26;
const unsigned TraceControl_D = 25;
const unsigned TraceControl_E = 24;
const unsigned TraceControl_K = 23;
const unsigned TraceControl_S = 22;
const unsigned TraceControl_U = 21;
const unsigned TraceControl_ASID_M_HI = 20;
const unsigned TraceControl_ASID_M_LO = 13;
const unsigned TraceControl_ASID_HI = 12;
const unsigned TraceControl_ASID_LO = 5;
const unsigned TraceControl_G = 4;
const unsigned TraceControl_TFCR = 3;
const unsigned TraceControl_TLSM = 2;
const unsigned TraceControl_TIM = 1;
const unsigned TraceControl_ON = 0;
// TraceControl2 Register - CP0 Reg 23, Sel 2
const unsigned TraceControl2_CPUIDV = 29;
const unsigned TraceControl2_CPUID_HI = 28;
const unsigned TraceControl2_CPUID_LO = 21;
const unsigned TraceControl2_TCV = 20;
const unsigned TraceControl2_TCNUM_HI = 19;
const unsigned TraceControl2_TCNUM_LO = 12;
const unsigned TraceControl2_MODE_HI = 11;
const unsigned TraceControl2_MODE_LO = 7;
const unsigned TraceControl2_VALIDMODES_HI = 6;
const unsigned TraceControl2_VALIDMODES_LO = 5;
const unsigned TraceControl2_TBI = 4;
const unsigned TraceControl2_TBU = 3;
const unsigned TraceControl2_SYP_HI = 2;
const unsigned TraceControl2_SYP_LO = 0;
// UserTraceData Register - CP0 Reg 23, Sel 3
// Just holds 32-bits (or 64-bits) of data
// TraceIBPC Register - CP0 Reg 23, Sel 4
const unsigned TraceIBPC_MB = 31;
const unsigned TraceIBPC_IE = 28;
const unsigned TraceIBPC_ATE = 27;
const unsigned TraceIBPC_IBPC8_HI = 26;
const unsigned TraceIBPC_IBPC8_LO = 24;
const unsigned TraceIBPC_IBPC7_HI = 23;
const unsigned TraceIBPC_IBPC7_LO = 21;
const unsigned TraceIBPC_IBPC6_HI = 20;
const unsigned TraceIBPC_IBPC6_LO = 18;
const unsigned TraceIBPC_IBPC5_HI = 17;
const unsigned TraceIBPC_IBPC5_LO = 15;
const unsigned TraceIBPC_IBPC4_HI = 14;
const unsigned TraceIBPC_IBPC4_LO = 12;
const unsigned TraceIBPC_IBPC3_HI = 11;
const unsigned TraceIBPC_IBPC3_LO = 9;
const unsigned TraceIBPC_IBPC2_HI = 8;
const unsigned TraceIBPC_IBPC2_LO = 6;
const unsigned TraceIBPC_IBPC1_HI = 5;
const unsigned TraceIBPC_IBPC1_LO = 3;
const unsigned TraceIBPC_IBPC0_HI = 2;
const unsigned TraceIBPC_IBPC0_LO = 0;
// TraceDBPC Register - CP0 Reg 23, Sel 5
const unsigned TRACEDBPC_MB = 31;
const unsigned TRACEDBPC_DE = 28;
const unsigned TRACEDBPC_ATE = 27;
const unsigned TRACEDBPC_DBPC8_HI = 26;
const unsigned TRACEDBPC_DBPC8_LO = 24;
const unsigned TRACEDBPC_DBPC7_HI = 23;
const unsigned TRACEDBPC_DBPC7_LO = 21;
const unsigned TRACEDBPC_DBPC6_HI = 20;
const unsigned TRACEDBPC_DBPC6_LO = 18;
const unsigned TRACEDBPC_DBPC5_HI = 17;
const unsigned TRACEDBPC_DBPC5_LO = 15;
const unsigned TRACEDBPC_DBPC4_HI = 14;
const unsigned TRACEDBPC_DBPC4_LO = 12;
const unsigned TRACEDBPC_DBPC3_HI = 11;
const unsigned TRACEDBPC_DBPC3_LO = 9;
const unsigned TRACEDBPC_DBPC2_HI = 8;
const unsigned TRACEDBPC_DBPC2_LO = 6;
const unsigned TRACEDBPC_DBPC1_HI = 5;
const unsigned TRACEDBPC_DBPC1_LO = 3;
const unsigned TRACEDBPC_DBPC0_HI = 2;
const unsigned TRACEDBPC_DBPC0_LO = 0;
// TraceIBPC2 - Not part of CP0, but part of TRACE
const unsigned TraceIBPC_IBPC14_HI = 17;
const unsigned TraceIBPC_IBPC14_LO = 15;
const unsigned TraceIBPC_IBPC13_HI = 14;
const unsigned TraceIBPC_IBPC13_LO = 12;
const unsigned TraceIBPC_IBPC12_HI = 11;
const unsigned TraceIBPC_IBPC12_LO = 9;
const unsigned TraceIBPC_IBPC11_HI = 8;
const unsigned TraceIBPC_IBPC11_LO = 6;
const unsigned TraceIBPC_IBPC10_HI = 5;
const unsigned TraceIBPC_IBPC10_LO = 3;
const unsigned TraceIBPC_IBPC9_HI = 2;
const unsigned TraceIBPC_IBPC9_LO = 0;
// TraceDBPC2 - Not part of CP0, but part of TRACE
const unsigned TRACEDBPC_DBPC14_HI = 17;
const unsigned TRACEDBPC_DBPC14_LO = 15;
const unsigned TRACEDBPC_DBPC13_HI = 14;
const unsigned TRACEDBPC_DBPC13_LO = 12;
const unsigned TRACEDBPC_DBPC12_HI = 11;
const unsigned TRACEDBPC_DBPC12_LO = 9;
const unsigned TRACEDBPC_DBPC11_HI = 8;
const unsigned TRACEDBPC_DBPC11_LO = 6;
const unsigned TRACEDBPC_DBPC10_HI = 5;
const unsigned TRACEDBPC_DBPC10_LO = 3;
const unsigned TRACEDBPC_DBPC9_HI = 2;
const unsigned TRACEDBPC_DBPC9_LO = 0;
// Debug Register 2 - CP0 Reg 23, Sel 6
const unsigned DEBUG2_PRM = 3;
const unsigned DEBUG2_DQ = 2;
const unsigned DEBUG2_TUP = 1;
const unsigned DEBUG2_PACO = 0;
// DEPC Register - CP0 Reg 24, Sel 0
// Debug Exception Program Counter
const unsigned DEPC_HI = 31;
const unsigned DEPC_LO = 0;
// DESAVE - CP0 Reg 31, Sel 0
// Debug Exception Save Register
const unsigned DESAVE_HI = 31;
const unsigned DESAVE_LO = 0;
} // namespace MipsISA
#endif

View file

@ -54,10 +54,33 @@ FaultName ResetFault::_name = "reset";
FaultVect ResetFault::_vect = 0x0001;
FaultStat ResetFault::_count;
FaultName CoprocessorUnusableFault::_name = "Coprocessor Unusable";
FaultVect CoprocessorUnusableFault::_vect = 0xF001;
FaultStat CoprocessorUnusableFault::_count;
FaultName ReservedInstructionFault::_name = "Reserved Instruction";
FaultVect ReservedInstructionFault::_vect = 0x0F01;
FaultStat ReservedInstructionFault::_count;
FaultName ThreadFault::_name = "thread";
FaultVect ThreadFault::_vect = 0x00F1;
FaultStat ThreadFault::_count;
FaultName ArithmeticFault::_name = "arith";
FaultVect ArithmeticFault::_vect = 0x0501;
FaultStat ArithmeticFault::_count;
FaultName UnimplementedOpcodeFault::_name = "opdec";
FaultVect UnimplementedOpcodeFault::_vect = 0x0481;
FaultStat UnimplementedOpcodeFault::_count;
#if !FULL_SYSTEM
//FaultName PageTableFault::_name = "page_table_fault";
//FaultVect PageTableFault::_vect = 0x0000;
//FaultStat PageTableFault::_count;
#endif
FaultName InterruptFault::_name = "interrupt";
FaultVect InterruptFault::_vect = 0x0101;
FaultStat InterruptFault::_count;
@ -90,21 +113,77 @@ FaultName ItbAcvFault::_name = "iaccvio";
FaultVect ItbAcvFault::_vect = 0x0081;
FaultStat ItbAcvFault::_count;
FaultName UnimplementedOpcodeFault::_name = "opdec";
FaultVect UnimplementedOpcodeFault::_vect = 0x0481;
FaultStat UnimplementedOpcodeFault::_count;
FaultName FloatEnableFault::_name = "fen";
FaultVect FloatEnableFault::_vect = 0x0581;
FaultStat FloatEnableFault::_count;
FaultName PalFault::_name = "pal";
FaultVect PalFault::_vect = 0x2001;
FaultStat PalFault::_count;
FaultName IntegerOverflowFault::_name = "intover";
FaultVect IntegerOverflowFault::_vect = 0x0501;
FaultStat IntegerOverflowFault::_count;
FaultName DspStateDisabledFault::_name = "intover";
FaultVect DspStateDisabledFault::_vect = 0x001a;
FaultStat DspStateDisabledFault::_count;
/*void PageTableFault::invoke(ThreadContext *tc)
{
Process *p = tc->getProcessPtr();
Addr page_addr = p->pTable->pageAlign(vaddr);
warn("%i: [tid:%i]: %s encountered @ addr %x. Allocating new page for address range %x - %x.\n",
curTick, tc->getThreadNum(), name(), vaddr, page_addr, page_addr+VMPageSize);
p->pTable->allocate(page_addr, VMPageSize);
return;
}
*/
/* address is higher than the stack region or in the current stack region
if (vaddr > p->stack_base || vaddr > p->stack_min)
FaultBase::invoke(tc);
// We've accessed the next page
if (vaddr > p->stack_min - PageBytes) {
p->stack_min -= PageBytes;
if (p->stack_base - p->stack_min > 8*1024*1024) {
warn("Already allocated Over max stack size for one thread\n");
}
warn("%i: Allocating page for range %x - %x",
curTick, p->stack_min, p->stack_min-PageBytes);
p->pTable->allocate(p->stack_min, PageBytes);
warn("Increasing stack size by one page.");
} else {
FaultBase::invoke(tc);
}*/
void ResetFault::invoke(ThreadContext *tc)
{
warn("[tid:%i]: %s encountered.\n", tc->getThreadNum(), name());
//tc->getCpuPtr()->reset();
}
void CoprocessorUnusableFault::invoke(ThreadContext *tc)
{
panic("[tid:%i]: %s encountered.\n", tc->getThreadNum(), name());
}
void ReservedInstructionFault::invoke(ThreadContext *tc)
{
panic("[tid:%i]: %s encountered.\n", tc->getThreadNum(), name());
}
void ThreadFault::invoke(ThreadContext *tc)
{
panic("[tid:%i]: %s encountered.\n", tc->getThreadNum(), name());
}
void DspStateDisabledFault::invoke(ThreadContext *tc)
{
panic("[tid:%i]: %s encountered.\n", tc->getThreadNum(), name());
}
} // namespace MipsISA

View file

@ -80,6 +80,42 @@ class AlignmentFault : public MipsFault
bool isAlignmentFault() {return true;}
};
class UnimplementedOpcodeFault : public MipsFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
FaultName name() {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
};
#if !FULL_SYSTEM
//class PageTableFault : public MipsFault
//{
//private:
// Addr vaddr;
// static FaultName _name;
// static FaultVect _vect;
// static FaultStat _count;
//public:
// PageTableFault(Addr va)
// : vaddr(va) {}
// FaultName name() {return _name;}
// FaultVect vect() {return _vect;}
// FaultStat & countStat() {return _count;}
// void invoke(ThreadContext * tc);
//};
static inline Fault genPageTableFault(Addr va)
{
return new PageTableFault(va);
}
#endif
static inline Fault genMachineCheckFault()
{
return new MachineCheckFault;
@ -100,8 +136,49 @@ class ResetFault : public MipsFault
FaultName name() {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
void invoke(ThreadContext * tc);
};
class CoprocessorUnusableFault : public MipsFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
FaultName name() {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
void invoke(ThreadContext * tc);
};
class ReservedInstructionFault : public MipsFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
FaultName name() {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
void invoke(ThreadContext * tc);
};
class ThreadFault : public MipsFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
FaultName name() {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
void invoke(ThreadContext * tc);
};
class ArithmeticFault : public MipsFault
{
protected:
@ -217,18 +294,6 @@ class ItbAcvFault : public MipsFault
FaultStat & countStat() {return _count;}
};
class UnimplementedOpcodeFault : public MipsFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
FaultName name() {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
};
class FloatEnableFault : public MipsFault
{
private:
@ -241,20 +306,6 @@ class FloatEnableFault : public MipsFault
FaultStat & countStat() {return _count;}
};
class PalFault : public MipsFault
{
protected:
bool skipFaultingInstruction() {return true;}
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
FaultName name() {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
};
class IntegerOverflowFault : public MipsFault
{
private:
@ -267,6 +318,19 @@ class IntegerOverflowFault : public MipsFault
FaultStat & countStat() {return _count;}
};
class DspStateDisabledFault : public MipsFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
FaultName name() {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
void invoke(ThreadContext * tc);
};
} // MipsISA namespace
#endif // __FAULTS_HH__

View file

@ -28,6 +28,7 @@
//
// Authors: Korey Sewell
//@TODO: Make sure the naming convention is consistent here.
////////////////////////////////////////////////////////////////////
//
// Bitfield definitions.
@ -58,6 +59,7 @@ def bitfield RT_RD <20:11>;
def bitfield RD <15:11>;
def bitfield INTIMM <15: 0>;
def bitfield RS_RT_INTIMM <25: 0>;
// Floating-point operate format
def bitfield FMT <25:21>;
@ -81,7 +83,7 @@ def bitfield BRANCH_CC <20:18>;
// CP0 Register Select
def bitfield SEL < 2: 0>;
// Interrupts
// INTERRUPTS
def bitfield SC < 5: 5>;
// Branch format
@ -100,3 +102,20 @@ def bitfield LSB <10: 6>;
// M5 instructions
def bitfield M5FUNC <7:0>;
// DSP instructions
def bitfield OP <10:6>;
def bitfield OP_HI <10:9>;
def bitfield OP_LO <8:6>;
def bitfield DSPSA <23:21>;
def bitfield HILOSA <25:20>;
def bitfield RDDSPMASK <21:16>;
def bitfield WRDSPMASK <16:11>;
def bitfield ACSRC <22:21>;
def bitfield ACDST <12:11>;
def bitfield BP <12:11>;
// MT Instructions
def bitfield POS <10: 6>;
def bitfield MT_U <5:5>;
def bitfield MT_H <4:4>;

File diff suppressed because it is too large Load diff

View file

@ -36,6 +36,7 @@
output header {{
#include <iostream>
using namespace std;
/**
* Base class for instructions whose disassembly is not purely a
@ -216,7 +217,7 @@ output decoder {{
}
}};
def format Branch(code,*opt_flags) {{
def format Branch(code, *opt_flags) {{
not_taken_code = ' NNPC = NNPC;\n'
not_taken_code += '} \n'
@ -230,13 +231,13 @@ def format Branch(code,*opt_flags) {{
not_taken_code = ' NPC = NNPC;\n'
not_taken_code += ' NNPC = NNPC + 4;\n'
not_taken_code += '} \n'
inst_flags = ('IsCondDelaySlot', )
inst_flags += ('IsCondDelaySlot', )
else:
inst_flags += (x, )
#Take into account uncond. branch instruction
if 'cond == 1' in code:
inst_flags += ('IsUnCondControl', )
if 'cond = 1' in code:
inst_flags += ('IsUncondControl', )
else:
inst_flags += ('IsCondControl', )
@ -254,6 +255,51 @@ def format Branch(code,*opt_flags) {{
exec_output = BasicExecute.subst(iop)
}};
def format DspBranch(code, *opt_flags) {{
not_taken_code = ' NNPC = NNPC;\n'
not_taken_code += '} \n'
#Build Instruction Flags
#Use Link & Likely Flags to Add Link/Condition Code
inst_flags = ('IsDirectControl', )
for x in opt_flags:
if x == 'Link':
code += 'R31 = NNPC;\n'
elif x == 'Likely':
not_taken_code = ' NPC = NNPC;\n'
not_taken_code += ' NNPC = NNPC + 4;\n'
not_taken_code += '} \n'
inst_flags += ('IsCondDelaySlot', )
else:
inst_flags += (x, )
#Take into account uncond. branch instruction
if 'cond = 1' in code:
inst_flags += ('IsUncondControl', )
else:
inst_flags += ('IsCondControl', )
#Declaration code
decl_code = 'bool cond;\n'
decl_code += 'uint32_t dspctl;\n'
#Fetch code
fetch_code = 'dspctl = DSPControl;\n'
#Condition code
code = decl_code + fetch_code + code
code += 'if (cond) {\n'
code += ' NNPC = NPC + disp;\n'
code += '} else {\n'
code += not_taken_code
iop = InstObjParams(name, Name, 'Branch', code, inst_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format Jump(code, *opt_flags) {{
#Build Instruction Flags
#Use Link Flag to Add Link Code

View file

@ -30,18 +30,18 @@
////////////////////////////////////////////////////////////////////
//
// Integer operate instructions
// Coprocessor instructions
//
//Outputs to decoder.hh
output header {{
class Control : public MipsStaticInst
class CP0Control : public MipsStaticInst
{
protected:
/// Constructor
Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
MipsStaticInst(mnem, _machInst, __opClass)
{
}
@ -49,26 +49,13 @@ output header {{
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class CP0Control : public Control
{
protected:
/// Constructor
CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
Control(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class CP1Control : public Control
class CP1Control : public MipsStaticInst
{
protected:
/// Constructor
CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
Control(mnem, _machInst, __opClass)
MipsStaticInst(mnem, _machInst, __opClass)
{
}
@ -77,46 +64,34 @@ output header {{
}};
// Basic instruction class execute method template.
def template ControlExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
if (isCoprocessorEnabled(xc, 0)) {
%(code)s;
} else {
fault = new CoprocessorUnusableFault();
}
if(fault == NoFault)
{
%(op_wb)s;
}
return fault;
}
}};
//Outputs to decoder.cc
output decoder {{
std::string Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
if (mnemonic == "mfc0" || mnemonic == "mtc0") {
ccprintf(ss, "%-10s %d,%d,%d", mnemonic,RT,RD,SEL);
} else {
// just print the first dest... if there's a second one,
// it's generally implicit
if (_numDestRegs > 0) {
printReg(ss, _destRegIdx[0]);
}
ss << ", ";
// just print the first two source regs... if there's
// a third one, it's a read-modify-write dest (Rc),
// e.g. for CMOVxx
if (_numSrcRegs > 0) {
printReg(ss, _srcRegIdx[0]);
}
if (_numSrcRegs > 1) {
ss << ", ";
printReg(ss, _srcRegIdx[1]);
}
}
return ss.str();
}
std::string CP0Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s r%d, r%d, %d", mnemonic, RT, RD, SEL);
ccprintf(ss, "%-10s r%d, %d, %d", mnemonic, RT, RD, SEL);
return ss.str();
}
@ -129,28 +104,50 @@ output decoder {{
}};
def format System(code, *flags) {{
iop = InstObjParams(name, Name, 'Control', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
output exec {{
bool isCoprocessorEnabled(%(CPU_exec_context)s *xc, unsigned cop_num)
{
switch(cop_num)
{
case 0:
#if FULL_SYSTEM
if((xc->readMiscReg(MipsISA::Status) & 0x10000006) == 0 && (xc->readMiscReg(MipsISA::Debug) & 0x40000000 ) == 0) {
// Unable to use Status_CU0, etc directly, using bitfields & masks
return false;
}
#else
//printf("Syscall Emulation Mode: CP0 Enable Check defaults to TRUE\n");
#endif
break;
case 1:
break;
case 2:
break;
case 3:
break;
default: panic("Invalid Coprocessor Number Specified");
break;
}
return true;
}
}};
def format CP0Control(code, *flags) {{
iop = InstObjParams(name, Name, 'CP0Control', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
flags += ('IsNonSpeculative', )
iop = InstObjParams(name, Name, 'CP0Control', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = ControlExecute.subst(iop)
}};
def format CP1Control(code, *flags) {{
iop = InstObjParams(name, Name, 'CP1Control', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
flags += ('IsNonSpeculative', )
iop = InstObjParams(name, Name, 'CP1Control', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = ControlExecute.subst(iop)
}};

218
src/arch/mips/isa/formats/dsp.isa Executable file
View file

@ -0,0 +1,218 @@
// -*- mode:c++ -*-
// 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
////////////////////////////////////////////////////////////////////
//
// DSP integer operate instructions
//
output header {{
#include <iostream>
using namespace std;
/**
* Base class for integer operations.
*/
class DspIntOp : public MipsStaticInst
{
protected:
/// Constructor
DspIntOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
MipsStaticInst(mnem, _machInst, __opClass)
{
}
};
class DspHiLoOp : public MipsStaticInst
{
protected:
/// Constructor
DspHiLoOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
MipsStaticInst(mnem, _machInst, __opClass)
{
}
};
}};
// Dsp instruction class execute method template.
def template DspExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
if (isDspPresent(xc))
{
if (isDspEnabled(xc))
{
%(op_rd)s;
%(code)s;
}
else
{
fault = new DspStateDisabledFault();
}
}
else
{
fault = new ReservedInstructionFault();
}
if(fault == NoFault)
{
%(op_wb)s;
}
return fault;
}
}};
// DspHiLo instruction class execute method template.
def template DspHiLoExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
if (isDspPresent(xc))
{
if (isDspEnabled(xc))
{
%(op_rd)s;
%(code)s;
}
else
{
fault = new DspStateDisabledFault();
}
}
else
{
fault = new ReservedInstructionFault();
}
if(fault == NoFault)
{
%(op_wb)s;
//If there are 2 Destination Registers then
//concatenate the values for the traceData
if(traceData && _numDestRegs == 2) {
// FIXME - set the trace value correctly here
//uint64_t hilo_final_val = (uint64_t)HI_RD_SEL << 32 | LO_RD_SEL;
//traceData->setData(hilo_final_val);
}
}
return fault;
}
}};
//Outputs to decoder.cc
output decoder {{
}};
output exec {{
bool isDspEnabled(%(CPU_exec_context)s *xc)
{
#if FULL_SYSTEM
if( bits( xc->readMiscReg(MipsISA::Status), 24, 24 ) == 0 )
return false;
#else
//printf("Syscall Emulation Mode: isDspEnabled() check defaults to TRUE\n");
#endif
return true;
}
}};
output exec {{
bool isDspPresent(%(CPU_exec_context)s *xc)
{
#if FULL_SYSTEM
if( bits( xc->readMiscReg(MipsISA::Config3), 10, 10 ) == 0 )
return false;
#else
//printf("Syscall Emulation Mode: isDspPresent() check defaults to TRUE\n");
#endif
return true;
}
}};
// add code to fetch the DSPControl register
// and write it back after execution, giving
// the instruction the opportunity to modify
// it if necessary
def format DspIntOp(code, *opt_flags) {{
decl_code = 'uint32_t dspctl;\n'
decl_code += 'dspctl = DSPControl;\n'
write_code = 'DSPControl = dspctl;\n'
code = decl_code + code + write_code
iop = InstObjParams(name, Name, 'DspIntOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = DspExecute.subst(iop)
}};
// add code to fetch the DSPControl register
// and write it back after execution, giving
// the instruction the opportunity to modify
// it if necessary; also, fetch the appropriate
// HI/LO register pair, based on the AC
// instruction field.
def format DspHiLoOp(code, *opt_flags) {{
decl_code = 'int64_t dspac;\n'
decl_code += 'uint32_t dspctl;\n'
fetch_code = 'dspctl = DSPControl;\n'
fetch_code += 'dspac = HI_RD_SEL;\n'
fetch_code += 'dspac = dspac << 32 | LO_RD_SEL;\n'
write_code = 'DSPControl = dspctl;\n'
write_code += 'HI_RD_SEL = dspac<63:32>;\n'
write_code += 'LO_RD_SEL = dspac<31:0>;\n'
code = decl_code + fetch_code + code + write_code
iop = InstObjParams(name, Name, 'DspHiLoOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = DspHiLoExecute.subst(iop)
}};

View file

@ -44,6 +44,9 @@
//Include the integer formats
##include "int.isa"
//Include the DSP integer format
##include "dsp.isa"
//Include the floatOp format
##include "fp.isa"

View file

@ -87,6 +87,12 @@ output decoder {{
}};
output exec {{
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
{
//@TODO: Implement correct CP0 checks to see if the CP1
// unit is enable or not
return NoFault;
}
//If any operand is Nan return the appropriate QNaN
template <class T>
@ -145,7 +151,7 @@ output exec {{
uint32_t fcsr_bits = cpu->tcBase()->readFloatRegBits(FCSR);
//Write FCSR from FloatRegFile
cpu->tcBase()->setFloatRegBits(FCSR, genInvalidVector(fcsr_bits));
cpu->tcBase()->setFloatRegOperandBits(FCSR, genInvalidVector(fcsr_bits));
if (traceData) { traceData->setData(mips_nan); }
return true;
@ -160,6 +166,7 @@ output exec {{
//Read FCSR from FloatRegFile
uint32_t fcsr = cpu->tcBase()->readFloatRegBits(FCSR);
// TODO: Use utility function here
fcsr = bits(fcsr, 31, 18) << 18 | bits(fcsr, 11, 0);
//Write FCSR from FloatRegFile

View file

@ -34,6 +34,7 @@
//
output header {{
#include <iostream>
using namespace std;
/**
* Base class for integer operations.
*/
@ -64,12 +65,12 @@ output header {{
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class HiLoMiscOp: public HiLoOp
class HiLoRsSelOp: public HiLoOp
{
protected:
/// Constructor
HiLoMiscOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
HiLoRsSelOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
HiLoOp(mnem, _machInst, __opClass)
{
}
@ -77,6 +78,31 @@ output header {{
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class HiLoRdSelOp: public HiLoOp
{
protected:
/// Constructor
HiLoRdSelOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
HiLoOp(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class HiLoRdSelValOp: public HiLoOp
{
protected:
/// Constructor
HiLoRdSelValOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
HiLoOp(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class IntImmOp : public MipsStaticInst
{
@ -105,9 +131,7 @@ output header {{
}};
// HiLo<Misc> instruction class execute method template.
// Mainly to get instruction trace data to print out
// correctly
// HiLo instruction class execute method template.
def template HiLoExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
@ -121,12 +145,58 @@ def template HiLoExecute {{
if(fault == NoFault)
{
%(op_wb)s;
//If there are 2 Destination Registers then
//concatenate the values for the traceData
if(traceData && _numDestRegs == 2) {
uint64_t hilo_final_val = (uint64_t)HI << 32 | LO;
traceData->setData(hilo_final_val);
}
}
return fault;
}
}};
// HiLoRsSel instruction class execute method template.
def template HiLoRsSelExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
if( ACSRC > 0 && !isDspEnabled(xc) )
{
fault = new DspStateDisabledFault();
}
else
{
%(op_rd)s;
%(code)s;
}
if(fault == NoFault)
{
%(op_wb)s;
}
return fault;
}
}};
// HiLoRdSel instruction class execute method template.
def template HiLoRdSelExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
if( ACDST > 0 && !isDspEnabled(xc) )
{
fault = new DspStateDisabledFault();
}
else
{
%(op_rd)s;
%(code)s;
}
if(fault == NoFault)
{
%(op_wb)s;
}
return fault;
}
@ -181,7 +251,37 @@ output decoder {{
return ss.str();
}
std::string HiLoMiscOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
std::string HiLoRsSelOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
if (_numDestRegs > 0 && _destRegIdx[0] < 32) {
printReg(ss, _destRegIdx[0]);
} else if (_numSrcRegs > 0 && _srcRegIdx[0] < 32) {
printReg(ss, _srcRegIdx[0]);
}
return ss.str();
}
std::string HiLoRdSelOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
if (_numDestRegs > 0 && _destRegIdx[0] < 32) {
printReg(ss, _destRegIdx[0]);
} else if (_numSrcRegs > 0 && _srcRegIdx[0] < 32) {
printReg(ss, _srcRegIdx[0]);
}
return ss.str();
}
std::string HiLoRdSelValOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
@ -239,26 +339,43 @@ def format IntImmOp(code, *opt_flags) {{
exec_output = BasicExecute.subst(iop)
}};
def format HiLoOp(code, *opt_flags) {{
code += 'HI = val<63:32>;\n'
code += 'LO = val<31:0>;\n'
def format HiLoRsSelOp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'HiLoRsSelOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = HiLoRsSelExecute.subst(iop)
}};
def format HiLoRdSelOp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'HiLoRdSelOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = HiLoRdSelExecute.subst(iop)
}};
def format HiLoRdSelValOp(code, *opt_flags) {{
if '.sd' in code:
code = 'int64_t ' + code
elif '.ud' in code:
code = 'uint64_t ' + code
code += 'HI_RD_SEL = val<63:32>;\n'
code += 'LO_RD_SEL = val<31:0>;\n'
iop = InstObjParams(name, Name, 'HiLoRdSelOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = HiLoRdSelExecute.subst(iop)
}};
def format HiLoOp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'HiLoOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = HiLoExecute.subst(iop)
}};
def format HiLoMiscOp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'HiLoMiscOp', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};

View file

@ -69,6 +69,8 @@ output header {{
const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
const StaticInstPtr &memAccInst() const { return memAccPtr; }
unsigned memAccFlags() { return memAccessFlags; }
};
/**
@ -108,6 +110,37 @@ output decoder {{
flags[IsFloating] ? FD : RD,
RS, RT);
}
}};
output exec {{
/** return data in cases where there the size of data is only
known in the packet
*/
uint64_t getStoreData(Packet *packet) {
switch (packet->getSize())
{
case 8:
return packet->get<uint8_t>();
case 16:
return packet->get<uint16_t>();
case 32:
return packet->get<uint32_t>();
case 864:
return packet->get<uint64_t>();
default:
std::cerr << "bad store data size = " << packet->getSize() << std::endl;
assert(0);
return 0;
}
}
}};
def template LoadStoreDeclare {{
@ -125,7 +158,7 @@ def template LoadStoreDeclare {{
{
public:
/// Constructor
EAComp(MachInst machInst);
EAComp(ExtMachInst machInst);
%(BasicExecDeclare)s
};
@ -137,7 +170,7 @@ def template LoadStoreDeclare {{
{
public:
/// Constructor
MemAcc(MachInst machInst);
MemAcc(ExtMachInst machInst);
%(BasicExecDeclare)s
};
@ -145,13 +178,15 @@ def template LoadStoreDeclare {{
public:
/// Constructor.
%(class_name)s(MachInst machInst);
%(class_name)s(ExtMachInst machInst);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
%(MemAccSizeDeclare)s
};
}};
@ -162,15 +197,18 @@ def template InitiateAccDeclare {{
def template CompleteAccDeclare {{
Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
Fault completeAcc(Packet *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
def template MemAccSizeDeclare {{
int memAccSize(%(CPU_exec_context)s *xc);
}};
def template EACompConstructor {{
/** TODO: change op_class to AddrGenOp or something (requires
* creating new member of OpClass enum in op_class.hh, updating
* config files, etc.). */
inline %(class_name)s::EAComp::EAComp(MachInst machInst)
inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
{
%(constructor)s;
@ -179,7 +217,7 @@ def template EACompConstructor {{
def template MemAccConstructor {{
inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
{
%(constructor)s;
@ -188,7 +226,7 @@ def template MemAccConstructor {{
def template LoadStoreConstructor {{
inline %(class_name)s::%(class_name)s(MachInst machInst)
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
new EAComp(machInst), new MemAcc(machInst))
{
@ -210,8 +248,8 @@ def template EACompExecute {{
%(op_rd)s;
%(ea_code)s;
// NOTE: Trace Data is written using execute or completeAcc templates
if (fault == NoFault) {
%(op_wb)s;
xc->setEA(EA);
}
@ -227,19 +265,16 @@ def template LoadMemAccExecute {{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
EA = xc->getEA();
if (fault == NoFault) {
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
%(memacc_code)s;
}
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
if (fault == NoFault) {
%(op_wb)s;
}
%(memacc_code)s;
// NOTE: Write back data using execute or completeAcc templates
return fault;
}
@ -292,9 +327,8 @@ def template LoadInitiateAcc {{
}
}};
def template LoadCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt,
Fault %(class_name)s::completeAcc(Packet *pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
@ -302,6 +336,7 @@ def template LoadCompleteAcc {{
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
Mem = pkt->get<typeof(Mem)>();
@ -318,6 +353,15 @@ def template LoadCompleteAcc {{
}};
def template LoadStoreMemAccSize {{
int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
{
// Return the memory access size in bytes
return (%(mem_acc_size)d / 8);
}
}};
def template StoreMemAccExecute {{
Fault
%(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
@ -325,10 +369,12 @@ def template StoreMemAccExecute {{
{
Addr EA;
Fault fault = NoFault;
uint64_t write_result = 0;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
EA = xc->getEA();
if (fault == NoFault) {
@ -337,16 +383,9 @@ def template StoreMemAccExecute {{
if (fault == NoFault) {
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
memAccessFlags, NULL);
if (traceData) { traceData->setData(Mem); }
}
if (fault == NoFault) {
%(postacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
memAccessFlags, &write_result);
// @NOTE: Need to Call Complete Access to Set Trace Data
//if (traceData) { traceData->setData(Mem); }
}
return fault;
@ -389,13 +428,13 @@ def template StoreCondMemAccExecute {{
}
}};
def template StoreExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
uint64_t write_result = 0;
%(fp_enable_check)s;
%(op_decl)s;
@ -408,7 +447,7 @@ def template StoreExecute {{
if (fault == NoFault) {
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
memAccessFlags, NULL);
memAccessFlags, &write_result);
if (traceData) { traceData->setData(Mem); }
}
@ -487,7 +526,7 @@ def template StoreInitiateAcc {{
def template StoreCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt,
Fault %(class_name)s::completeAcc(Packet *pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
@ -502,6 +541,8 @@ def template StoreCompleteAcc {{
if (fault == NoFault) {
%(op_wb)s;
if (traceData) { traceData->setData(getStoreData(pkt)); }
}
return fault;
@ -509,7 +550,7 @@ def template StoreCompleteAcc {{
}};
def template StoreCondCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt,
Fault %(class_name)s::completeAcc(Packet *pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
@ -584,7 +625,7 @@ def template MiscInitiateAcc {{
def template MiscCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt,
Fault %(class_name)s::completeAcc(Packet *pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
@ -594,6 +635,15 @@ def template MiscCompleteAcc {{
}
}};
def template MiscMemAccSize {{
int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
{
panic("Misc instruction does not support split access method!");
return 0;
}
}};
def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
@ -650,6 +700,7 @@ def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3;
decl_code += '\tbyte_offset ^= 3;\n'
decl_code += '#endif\n'
decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n'
#decl_code += 'xc->readFunctional(EA,(uint32_t&)mem_word);'
memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'
(header_output, decoder_output, decode_block, exec_output) = \

View file

@ -37,46 +37,185 @@ output header {{
/**
* Base class for MIPS MT ASE operations.
*/
class MT : public MipsStaticInst
class MTOp : public MipsStaticInst
{
protected:
/// Constructor
MT(const char *mnem, MachInst _machInst, OpClass __opClass) :
MipsStaticInst(mnem, _machInst, __opClass)
MTOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
MipsStaticInst(mnem, _machInst, __opClass), user_mode(false)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
bool user_mode;
};
class MTUserModeOp : public MTOp
{
protected:
/// Constructor
MTUserModeOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
MTOp(mnem, _machInst, __opClass)
{
user_mode = true;
}
//std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
//Edit This Template When MT is Implemented
std::string MT::generateDisassembly(Addr pc, const SymbolTable *symtab) const
std::string MTOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
if (mnemonic == "mttc0" || mnemonic == "mftc0") {
ccprintf(ss, "%-10s r%d, r%d, %d", mnemonic, RT, RD, SEL);
} else if (mnemonic == "mftgpr") {
ccprintf(ss, "%-10s r%d, r%d", mnemonic, RD, RT);
} else {
ccprintf(ss, "%-10s r%d, r%d", mnemonic, RT, RD);
}
return ss.str();
}
}};
output exec {{
void getThrRegExValues(%(CPU_exec_context)s *xc, unsigned &vpe_conf0, unsigned &tc_bind_mt, unsigned &tc_bind, unsigned &vpe_control, unsigned &mvp_conf0)
{
vpe_conf0 = xc->readMiscReg(VPEConf0);
tc_bind_mt = xc->readRegOtherThread(TCBind + Ctrl_Base_DepTag);
tc_bind = xc->readMiscReg(TCBind);
vpe_control = xc->readMiscReg(VPEControl);
mvp_conf0 = xc->readMiscReg(MVPConf0);
}
void getMTExValues(%(CPU_exec_context)s *xc, unsigned &config3)
{
config3 = xc->readMiscReg(Config3_MT);
}
}};
def template ThreadRegisterExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
return "Disassembly of MT instruction\n";
Fault fault = NoFault;
int64_t data;
%(op_decl)s;
%(op_rd)s;
unsigned vpe_conf0, tc_bind_mt, tc_bind, vpe_control, mvp_conf0;
getThrRegExValues(xc, vpe_conf0, tc_bind_mt, tc_bind, vpe_control, mvp_conf0);
if (isCoprocessorEnabled(xc, 0)) {
if (bits(vpe_conf0, VPEC0_MVP) == 0 &&
bits(tc_bind_mt, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO) !=
bits(tc_bind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO)) {
data = -1;
} else if (bits(vpe_control, VPEC_TARG_TC_HI, VPEC_TARG_TC_LO) >
bits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO)) {
data = -1;
} else {
int top_bit = 0;
int bottom_bit = 0;
if (MT_H == 1) {
top_bit = 63;
bottom_bit = 32;
} else {
top_bit = 31;
bottom_bit = 0;
}
%(code)s;
}
} else {
fault = new CoprocessorUnusableFault();
}
if(fault == NoFault)
{
%(op_wb)s;
}
return fault;
}
}};
def template MTExecute {{
//Edit This Template When MT is Implemented
def template MTExecute{{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
//Write the resulting state to the execution context
%(op_wb)s;
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
//Call into the trap handler with the appropriate fault
return No_Fault;
unsigned config3;
getMTExValues(xc, config3);
if (isCoprocessorEnabled(xc, 0)) {
if (bits(config3, CFG3_MT) == 1) {
%(code)s;
} else {
fault = new ReservedInstructionFault();
}
} else {
fault = new CoprocessorUnusableFault();
}
if(fault == NoFault)
{
%(op_wb)s;
}
return fault;
}
}};
// Primary format for integer operate instructions:
def format MipsMT() {{
code = 'panic(\"Mips MT Is Currently Unimplemented.\");\n'
iop = InstObjParams(name, Name, 'MT', code)
def format MT_Control(code, *opt_flags) {{
inst_flags = ('IsNonSpeculative', )
op_type = 'MTOp'
for x in opt_flags:
if x == 'UserMode':
op_type = 'MTUserModeOp'
else:
inst_flags += (x, )
iop = InstObjParams(name, Name, op_type, code, inst_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
exec_output = MTExecute.subst(iop)
}};
def format MT_MFTR(code, *flags) {{
flags += ('IsNonSpeculative', )
# code = 'std::cerr << curTick << \": T\" << xc->tcBase()->getThreadNum() << \": Executing MT INST: ' + name + '\" << endl;\n' + code
code += 'if (MT_H == 1) {\n'
code += 'data = bits(data, top_bit, bottom_bit);\n'
code += '}\n'
code += 'Rd = data;\n'
iop = InstObjParams(name, Name, 'MTOp', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = ThreadRegisterExecute.subst(iop)
}};
def format MT_MTTR(code, *flags) {{
flags += ('IsNonSpeculative', )
# code = 'std::cerr << curTick << \": T\" << xc->tcBase()->getThreadNum() << \": Executing MT INST: ' + name + '\" << endl;\n' + code
iop = InstObjParams(name, Name, 'MTOp', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = ThreadRegisterExecute.subst(iop)
}};

View file

@ -70,7 +70,9 @@ def template TlbOpExecute {{
// Primary format for integer operate instructions:
def format TlbOp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'MipsStaticInst', code, opt_flags)
orig_code = code
cblk = code
iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecodeWithMnemonic.subst(iop)

View file

@ -88,7 +88,6 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ completeAccTemplate.subst(iop))
}};
output header {{
std::string inst2string(MachInst machInst);
}};
@ -97,7 +96,7 @@ output decoder {{
std::string inst2string(MachInst machInst)
{
std::string str = "";
string str = "";
uint32_t mask = 0x80000000;
for(int i=0; i < 32; i++) {
@ -114,40 +113,3 @@ std::string inst2string(MachInst machInst)
}
}};
output exec {{
using namespace MipsISA;
/// CLEAR ALL CPU INST/EXE HAZARDS
inline void
clear_exe_inst_hazards()
{
//CODE HERE
}
/// Check "FP enabled" machine status bit. Called when executing any FP
/// instruction in full-system mode.
/// @retval Full-system mode: NoFault if FP is enabled, FenFault
/// if not. Non-full-system mode: always returns NoFault.
#if FULL_SYSTEM
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
{
Fault fault = NoFault; // dummy... this ipr access should not fault
if (!Mips34k::ICSR_FPE(xc->readIpr(MipsISA::IPR_ICSR, fault))) {
fault = FloatEnableFault;
}
return fault;
}
#else
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
{
return NoFault;
}
#endif
}};

View file

@ -44,19 +44,23 @@ output header {{
}};
output decoder {{
#include <cmath>
#if defined(linux)
#include <fenv.h>
#endif
#include "arch/mips/faults.hh"
#include "arch/mips/isa_traits.hh"
#include "arch/mips/isa_traits.hh"
#include "arch/mips/isa_traits.hh"
#include "arch/mips/utility.hh"
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
#include "cpu/thread_context.hh"
#include "arch/mips/faults.hh"
#include "arch/mips/isa_traits.hh"
#include "arch/mips/pra_constants.hh"
#include "arch/mips/dt_constants.hh"
#include "arch/mips/mt_constants.hh"
#include "arch/mips/utility.hh"
#include "arch/mips/dsp.hh"
#include "mem/packet.hh"
#include <math.h>
#if defined(linux)
#include <fenv.h>
#endif
using namespace MipsISA;
}};
@ -65,20 +69,25 @@ output exec {{
#include "arch/mips/faults.hh"
#include "arch/mips/isa_traits.hh"
#include "arch/mips/utility.hh"
#include "arch/mips/dsp.hh"
#include "arch/mips/pra_constants.hh"
#include "arch/mips/dt_constants.hh"
#include "arch/mips/mt_constants.hh"
#include <math.h>
#if defined(linux)
#include <fenv.h>
#endif
#ifdef FULL_SYSTEM
//#include "arch/alpha/pseudo_inst.hh"
#endif
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "sim/sim_exit.hh"
#include "sim/eventq.hh"
#include "sim/sim_events.hh"
using namespace MipsISA;
}};

View file

@ -48,16 +48,37 @@ def operands {{
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 2),
'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 3),
#Immediate Value operand
'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3),
#Operands used for Link or Syscall Insts
'R31': ('IntReg', 'uw','31','IsInteger', 4),
'R2': ('IntReg', 'uw','2', 'IsInteger', 5),
#Special Integer Reg operands
'HI': ('IntReg', 'uw','MipsISA::HI', 'IsInteger', 6),
'LO': ('IntReg', 'uw','MipsISA::LO', 'IsInteger', 7),
'LO0': ('IntReg', 'uw','MipsISA::LO', 'IsInteger', 6),
'HI0': ('IntReg', 'uw','MipsISA::HI', 'IsInteger', 7),
#Immediate Value operand
'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3),
#Bitfield-dependent HI/LO Register Access
'LO_RD_SEL': ('IntReg','uw','MipsISA::DSPLo0 + ACDST*3', None, 6),
'HI_RD_SEL': ('IntReg','uw','MipsISA::DSPHi0 + ACDST*3', None, 7),
'LO_RS_SEL': ('IntReg','uw','MipsISA::DSPLo0 + ACSRC*3', None, 6),
'HI_RS_SEL': ('IntReg','uw','MipsISA::DSPHi0 + ACSRC*3', None, 7),
#DSP Special Purpose Integer Operands
'DSPControl': ('IntReg', 'uw', 'MipsISA::DSPControl', None, 8),
'DSPLo0': ('IntReg', 'uw', 'MipsISA::LO', None, 1),
'DSPHi0': ('IntReg', 'uw', 'MipsISA::HI', None, 1),
'DSPACX0': ('IntReg', 'uw', 'MipsISA::DSPACX0', None, 1),
'DSPLo1': ('IntReg', 'uw', 'MipsISA::DSPLo1', None, 1),
'DSPHi1': ('IntReg', 'uw', 'MipsISA::DSPHi1', None, 1),
'DSPACX1': ('IntReg', 'uw', 'MipsISA::DSPACX1', None, 1),
'DSPLo2': ('IntReg', 'uw', 'MipsISA::DSPLo2', None, 1),
'DSPHi2': ('IntReg', 'uw', 'MipsISA::DSPHi2', None, 1),
'DSPACX2': ('IntReg', 'uw', 'MipsISA::DSPACX2', None, 1),
'DSPLo3': ('IntReg', 'uw', 'MipsISA::DSPLo3', None, 1),
'DSPHi3': ('IntReg', 'uw', 'MipsISA::DSPHi3', None, 1),
'DSPACX3': ('IntReg', 'uw', 'MipsISA::DSPACX3', None, 1),
#Floating Point Reg Operands
'Fd': ('FloatReg', 'sf', 'FD', 'IsFloating', 1),
@ -65,14 +86,14 @@ def operands {{
'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3),
'Fr': ('FloatReg', 'sf', 'FR', 'IsFloating', 3),
#Special Floating Point Control Reg Operands
#Special Purpose Floating Point Control Reg Operands
'FIR': ('FloatReg', 'uw', 'MipsISA::FIR', 'IsFloating', 1),
'FCCR': ('FloatReg', 'uw', 'MipsISA::FCCR', 'IsFloating', 2),
'FEXR': ('FloatReg', 'uw', 'MipsISA::FEXR', 'IsFloating', 3),
'FENR': ('FloatReg', 'uw', 'MipsISA::FENR', 'IsFloating', 3),
'FCSR': ('FloatReg', 'uw', 'MipsISA::FCSR', 'IsFloating', 3),
#Operands For Paired Singles FP Operations
#Operands For Paired Singles FP Operations
'Fd1': ('FloatReg', 'sf', 'FD', 'IsFloating', 4),
'Fd2': ('FloatReg', 'sf', 'FD+1', 'IsFloating', 4),
'Fs1': ('FloatReg', 'sf', 'FS', 'IsFloating', 5),
@ -82,10 +103,44 @@ def operands {{
'Fr1': ('FloatReg', 'sf', 'FR', 'IsFloating', 7),
'Fr2': ('FloatReg', 'sf', 'FR+1', 'IsFloating', 7),
#Status Control Reg
'Status': ('ControlReg', 'uw', 'MipsISA::Status', None, 1),
#Special cases for when a Control Register Access is dependent on
#a combination of bitfield indices (handles MTCO & MFCO)
'CP0_RD_SEL': ('ControlReg', 'uw', 'RD << 3 | SEL', None, 1),
#MT Control Regs
'MVPConf0': ('ControlReg', 'uw', 'MipsISA::MVPConf0', None, 1),
'MVPControl': ('ControlReg', 'uw', 'MipsISA::MVPControl', None, 1),
'TCBind': ('ControlReg', 'uw', 'MipsISA::TCBind', None, 1),
'TCStatus': ('ControlReg', 'uw', 'MipsISA::TCStatus', None, 1),
'TCRestart': ('ControlReg', 'uw', 'MipsISA::TCRestart', None, 1),
'VPEConf0': ('ControlReg', 'uw', 'MipsISA::VPEConf0', None, 1),
'VPEControl': ('ControlReg', 'uw', 'MipsISA::VPEControl', None, 1),
'YQMask': ('ControlReg', 'uw', 'MipsISA::YQMask', None, 1),
# named bitfields of Control Regs
'Status_IE': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
'Status_ERL': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
'Status_EXL': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
'Status_CU3': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
'Status_CU2': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
'Status_CU1': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
'Status_CU0': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
'SRSCtl_HSS': ('ControlBitfield', 'uw', 'MipsISA::SRSCtl', None, 4),
'SRSCtl_PSS': ('ControlBitfield', 'uw', 'MipsISA::SRSCtl', None, 4),
'SRSCtl_CSS': ('ControlBitfield', 'uw', 'MipsISA::SRSCtl', None, 4),
'Config_AR': ('ControlBitfield', 'uw', 'MipsISA::Config', None, 3),
# named bitfields of Debug Regs
'Debug_DM': ('ControlBitfield', 'uw', 'MipsISA::Debug', None, 1),
'Debug_IEXI': ('ControlBitfield', 'uw', 'MipsISA::Debug', None, 1),
#Memory Operand
'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
#Program Counter Operands
'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4),
'NNPC':('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4)
'NPC': ('NPC', 'uw', None, 'IsControl', 4),
'NNPC':('NNPC', 'uw', None, 'IsControl', 4)
}};

View file

@ -96,3 +96,5 @@ RegFile::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(nnpc);
}

View file

@ -60,24 +60,13 @@ namespace MipsISA
// Constants Related to the number of registers
const int NumIntArchRegs = 32;
const int NumIntSpecialRegs = 2;
const int NumIntSpecialRegs = 9;
const int NumFloatArchRegs = 32;
const int NumFloatSpecialRegs = 5;
const int NumControlRegs = 265;
const int NumInternalProcRegs = 0;
const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs; //HI & LO Regs
const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;//
const int NumMiscRegs = NumControlRegs;
const int TotalNumRegs = NumIntRegs + NumFloatRegs +
NumMiscRegs + 0/*NumInternalProcRegs*/;
const int TotalDataRegs = NumIntRegs + NumFloatRegs;
// Static instruction parameters
const int MaxInstSrcRegs = 3;
const int MaxInstDestRegs = 2;
const int MaxInstSrcRegs = 5;
const int MaxInstDestRegs = 4;
// semantically meaningful register indices
const int ZeroReg = 0;
@ -97,7 +86,7 @@ namespace MipsISA
const int ReturnAddressReg = 31;
const int SyscallNumReg = ReturnValueReg1;
const int SyscallPseudoReturnReg = ReturnValueReg1;
const int SyscallPseudoReturnReg = ReturnValueReg2;
const int SyscallSuccessReg = ArgumentReg3;
const int LogVMPageSize = 13; // 8K bytes
@ -110,13 +99,176 @@ namespace MipsISA
const int HalfwordBytes = 2;
const int ByteBytes = 1;
// These help enumerate all the registers for dependence tracking.
const int FP_Base_DepTag = 34;
const int Ctrl_Base_DepTag = 257;
const int ANNOTE_NONE = 0;
const uint32_t ITOUCH_ANNOTE = 0xffffffff;
// Enumerate names for 'Control' Registers in the CPU
// Reference MIPS32 Arch. for Programmers, Vol. III, Ch.8
// (Register Number-Register Select) Summary of Register
//------------------------------------------------------
// The first set of names classify the CP0 names as Register Banks
// for easy indexing when using the 'RD + SEL' index combination
// in CP0 instructions.
enum MiscRegTags {
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-63
BadVAddr = 64, //Bank 8: 64-71
Count = 72, //Bank 9: 72-79
EntryHi = 80, //Bank 10: 80-87
Compare = 88, //Bank 11: 88-95
Status = 96, //Bank 12: 96-103
IntCtl,
SRSCtl,
SRSMap,
Cause = 104, //Bank 13: 104-111
EPC = 112, //Bank 14: 112-119
PRId = 120, //Bank 15: 120-127,
EBase,
Config = 128, //Bank 16: 128-135
Config1,
Config2,
Config3,
Config4,
Config5,
Config6,
Config7,
LLAddr = 136, //Bank 17: 136-143
WatchLo0 = 144, //Bank 18: 144-151
WatchLo1,
WatchLo2,
WatchLo3,
WatchLo4,
WatchLo5,
WatchLo6,
WatchLo7,
WatchHi0 = 152, //Bank 19: 152-159
WatchHi1,
WatchHi2,
WatchHi3,
WatchHi4,
WatchHi5,
WatchHi6,
WatchHi7,
XCContext64 = 160, //Bank 20: 160-167
//Bank 21: 168-175
//Bank 22: 176-183
Debug = 184, //Bank 23: 184-191
TraceControl1,
TraceControl2,
UserTraceData,
TraceBPC,
DEPC = 192, //Bank 24: 192-199
PerfCnt0 = 200, //Bank 25: 200-207
PerfCnt1,
PerfCnt2,
PerfCnt3,
PerfCnt4,
PerfCnt5,
PerfCnt6,
PerfCnt7,
ErrCtl = 208, //Bank 26: 208-215
CacheErr0 = 216, //Bank 27: 216-223
CacheErr1,
CacheErr2,
CacheErr3,
TagLo0 = 224, //Bank 28: 224-231
DataLo1,
TagLo2,
DataLo3,
TagLo4,
DataLo5,
TagLo6,
DataLo7,
TagHi0 = 232, //Bank 29: 232-239
DataHi1,
TagHi2,
DataHi3,
TagHi4,
DataHi5,
TagHi6,
DataHi7,
ErrorEPC = 240, //Bank 30: 240-247
DESAVE = 248, //Bank 31: 248-256
LLFlag = 257,
NumControlRegs
};
const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs; //HI & LO Regs
const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;//
const int NumMiscRegs = NumControlRegs;
const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
const int TotalDataRegs = NumIntRegs + NumFloatRegs;
// These help enumerate all the registers for dependence tracking.
const int FP_Base_DepTag = NumIntRegs;
const int Ctrl_Base_DepTag = FP_Base_DepTag + NumFloatRegs;
};
using namespace MipsISA;

View file

@ -72,3 +72,4 @@ const int MipsLinux::NUM_OPEN_FLAGS =

View file

@ -32,6 +32,9 @@
#define __ARCH_MIPS_LINUX_LINUX_HH__
#include "kern/linux/linux.hh"
#include <string>
using std::string;
class MipsLinux : public Linux
{
@ -91,21 +94,21 @@ class MipsLinux : public Linux
//@{
/// ioctl() command codes.
static const unsigned TIOCGETP_ = 0x7408;
static const unsigned TIOCSETP_ = 0x7409;
static const unsigned TIOCSETN_ = 0x740a;
static const unsigned TIOCSETC_ = 0x7411;
static const unsigned TIOCGETC_ = 0x7412;
static const unsigned FIONREAD_ = 0x467f;
static const unsigned TIOCISATTY_ = 0x5480;
static const unsigned TIOCGETS_ = 0x7413;
static const unsigned TIOCGETA_ = 0x7417;
static const unsigned TIOCGETP = 0x7408;
static const unsigned TIOCSETP = 0x7409;
static const unsigned TIOCSETN = 0x740a;
static const unsigned TIOCSETC = 0x7411;
static const unsigned TIOCGETC = 0x7412;
static const unsigned FIONREAD = 0x467f;
static const unsigned TIOCISATTY = 0x5480;
static const unsigned TIOCGETS = 0x540d;
static const unsigned TIOCGETA = 0x7417;
//@}
/// For table().
static const int TBL_SYSINFO = 12;
/// Resource enumeration for getrlimit().
/// Resource enumeration for getrlimit()/setrlimit().
enum rlimit_resources {
TGT_RLIMIT_CPU = 0,
TGT_RLIMIT_FSIZE = 1,
@ -118,9 +121,14 @@ class MipsLinux : public Linux
TGT_RLIMIT_VMEM = 7,
TGT_RLIMIT_NPROC = 8,
TGT_RLIMIT_MEMLOCK = 9,
TGT_RLIMIT_LOCKS = 10
TGT_RLIMIT_LOCKS = 10,
NUM_RLIMIT_RESOURCES
};
/// Offset used to make sure that processes don't
/// assign themselves to process IDs reserved for
/// the root users.
static const int NUM_ROOT_PROCS = 2;
};
#endif

View file

@ -37,7 +37,9 @@
#include "kern/linux/linux.hh"
#include "sim/process.hh"
#include "sim/system.hh"
#include "sim/syscall_emul.hh"
#include "sim/eventq.hh"
using namespace std;
using namespace MipsISA;
@ -50,7 +52,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
strcpy(name->nodename,"m5.eecs.umich.edu");
strcpy(name->release, "2.4.20");
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "mips");
@ -116,7 +118,6 @@ sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
return 1;
}
SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 0 */ SyscallDesc("syscall", unimplementedFunc),
/* 1 */ SyscallDesc("exit", exitFunc),
@ -155,12 +156,12 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 34 */ SyscallDesc("nice", unimplementedFunc),
/* 35 */ SyscallDesc("ftime", unimplementedFunc),
/* 36 */ SyscallDesc("sync", unimplementedFunc),
/* 37 */ SyscallDesc("kill", ignoreFunc),
/* 37 */ SyscallDesc("kill", unimplementedFunc),
/* 38 */ SyscallDesc("rename", unimplementedFunc),
/* 39 */ SyscallDesc("mkdir", unimplementedFunc),
/* 40 */ SyscallDesc("rmdir", unimplementedFunc),
/* 41 */ SyscallDesc("dup", unimplementedFunc),
/* 42 */ SyscallDesc("pipe", unimplementedFunc),
/* 42 */ SyscallDesc("pipe", pipePseudoFunc),
/* 43 */ SyscallDesc("times", unimplementedFunc),
/* 44 */ SyscallDesc("prof", unimplementedFunc),
/* 45 */ SyscallDesc("brk", obreakFunc),
@ -172,7 +173,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 51 */ SyscallDesc("acct", unimplementedFunc),
/* 52 */ SyscallDesc("umount2", unimplementedFunc),
/* 53 */ SyscallDesc("lock", unimplementedFunc),
/* 54 */ SyscallDesc("ioctl", ioctlFunc<MipsLinux>),
/* 54 */ SyscallDesc("ioctl", unimplementedFunc/*ioctlFunc<MipsLinux>*/),
/* 55 */ SyscallDesc("fcntl", fcntlFunc),
/* 56 */ SyscallDesc("mpx", unimplementedFunc),
/* 57 */ SyscallDesc("setpgid", unimplementedFunc),
@ -193,9 +194,9 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 72 */ SyscallDesc("sigsuspend", unimplementedFunc),
/* 73 */ SyscallDesc("sigpending", unimplementedFunc),
/* 74 */ SyscallDesc("sethostname", ignoreFunc),
/* 75 */ SyscallDesc("setrlimit", unimplementedFunc),
/* 76 */ SyscallDesc("getrlimit", unimplementedFunc),
/* 77 */ SyscallDesc("getrusage", unimplementedFunc),
/* 75 */ SyscallDesc("setrlimit", unimplementedFunc/*setrlimitFunc<MipsLinux>*/),
/* 76 */ SyscallDesc("getrlimit", unimplementedFunc/*getrlimitFunc<MipsLinux>*/),
/* 77 */ SyscallDesc("getrusage", getrusageFunc<MipsLinux>),
/* 78 */ SyscallDesc("gettimeofday", unimplementedFunc),
/* 79 */ SyscallDesc("settimeofday", unimplementedFunc),
/* 80 */ SyscallDesc("getgroups", unimplementedFunc),
@ -212,8 +213,8 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 91 */ SyscallDesc("munmap",munmapFunc),
/* 92 */ SyscallDesc("truncate", truncateFunc),
/* 93 */ SyscallDesc("ftruncate", ftruncateFunc),
/* 94 */ SyscallDesc("fchmod", unimplementedFunc),
/* 95 */ SyscallDesc("fchown", unimplementedFunc),
/* 94 */ SyscallDesc("fchmod", fchmodFunc<MipsLinux>),
/* 95 */ SyscallDesc("fchown", fchownFunc),
/* 96 */ SyscallDesc("getpriority", unimplementedFunc),
/* 97 */ SyscallDesc("setpriority", unimplementedFunc),
/* 98 */ SyscallDesc("profil", unimplementedFunc),
@ -238,7 +239,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 117 */ SyscallDesc("ipc", unimplementedFunc),
/* 118 */ SyscallDesc("fsync", unimplementedFunc),
/* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
/* 120 */ SyscallDesc("clone", unimplementedFunc),
/* 120 */ SyscallDesc("clone", unimplementedFunc/*cloneFunc<MipsLinux>*/),
/* 121 */ SyscallDesc("setdomainname", unimplementedFunc),
/* 122 */ SyscallDesc("uname", unameFunc),
/* 123 */ SyscallDesc("modify_ldt", unimplementedFunc),
@ -271,7 +272,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 150 */ SyscallDesc("unused#150", unimplementedFunc),
/* 151 */ SyscallDesc("getsid", unimplementedFunc),
/* 152 */ SyscallDesc("fdatasync", unimplementedFunc),
/* 153 */ SyscallDesc("sysctl", unimplementedFunc),
/* 153 */ SyscallDesc("sysctl", ignoreFunc),
/* 154 */ SyscallDesc("mlock", unimplementedFunc),
/* 155 */ SyscallDesc("munlock", unimplementedFunc),
/* 156 */ SyscallDesc("mlockall", unimplementedFunc),
@ -312,12 +313,12 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 191 */ SyscallDesc("getresgid", unimplementedFunc),
/* 192 */ SyscallDesc("prctl", unimplementedFunc),
/* 193 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
/* 194 */ SyscallDesc("rt_sigaction", ignoreFunc),
/* 195 */ SyscallDesc("rt_sigprocmask", ignoreFunc),
/* 194 */ SyscallDesc("rt_sigaction", unimplementedFunc/*rt_sigactionFunc<MipsLinux>*/),
/* 195 */ SyscallDesc("rt_sigprocmask", unimplementedFunc/*rt_sigprocmaskFunc<MipsLinux>*/),
/* 196 */ SyscallDesc("rt_sigpending", unimplementedFunc),
/* 197 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
/* 198 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc),
/* 199 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
/* 199 */ SyscallDesc("rt_sigsuspend", unimplementedFunc/*rt_sigsuspendFunc<MipsLinux>*/),
/* 200 */ SyscallDesc("pread64", unimplementedFunc),
/* 201 */ SyscallDesc("pwrite64", unimplementedFunc),
/* 202 */ SyscallDesc("chown", unimplementedFunc),
@ -400,9 +401,10 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 279 */ SyscallDesc("unknown #279", unimplementedFunc),
/* 280 */ SyscallDesc("add_key", unimplementedFunc),
/* 281 */ SyscallDesc("request_key", unimplementedFunc),
/* 282 */ SyscallDesc("keyctl", unimplementedFunc),
/* 282 */ SyscallDesc("keyctl", unimplementedFunc)
};
MipsLinuxProcess::MipsLinuxProcess(const std::string &name,
ObjectFile *objFile,
System *system,
@ -421,7 +423,13 @@ MipsLinuxProcess::MipsLinuxProcess(const std::string &name,
: MipsLiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd,
argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid),
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
{ }
{ }
void
MipsLinuxProcess::startup()
{
MipsLiveProcess::argsInit(MachineBytes, VMPageSize);
}
SyscallDesc*
MipsLinuxProcess::getDesc(int callnum)
@ -434,3 +442,8 @@ MipsLinuxProcess::getDesc(int callnum)
return &syscallDescs[m5_sys_idx];
}

View file

@ -30,7 +30,8 @@
#define __MIPS_LINUX_PROCESS_HH__
#include "arch/mips/process.hh"
#include "arch/mips/linux/linux.hh"
#include "sim/eventq.hh"
/// A process with emulated Mips/Linux syscalls.
class MipsLinuxProcess : public MipsLiveProcess
@ -48,16 +49,19 @@ class MipsLinuxProcess : public MipsLiveProcess
uint64_t _gid, uint64_t _egid,
uint64_t _pid, uint64_t _ppid);
void startup();
virtual SyscallDesc* getDesc(int callnum);
/// The target system's hostname.
static const char *hostname;
/// Array of syscall descriptors, indexed by call number.
static SyscallDesc syscallDescs[];
/// ID of the thread group leader for the process
uint64_t __tgid;
/// Array of syscall descriptors, indexed by call number.
static SyscallDesc syscallDescs[];
const int Num_Syscall_Descs;
};
#endif // __MIPS_LINUX_PROCESS_HH__

View file

@ -37,6 +37,9 @@
* ISA-specific helper functions for locked memory accesses.
*/
#include "arch/isa_traits.hh"
#include "base/misc.hh"
#include "base/trace.hh"
#include "mem/request.hh"
@ -46,6 +49,11 @@ template <class XC>
inline void
handleLockedRead(XC *xc, Request *req)
{
unsigned tid = req->getThreadNum();
xc->setMiscReg(LLAddr, req->getPaddr() & ~0xf, tid);
xc->setMiscReg(LLFlag, true, tid);
DPRINTF(LLSC, "[tid:%i]: Load-Link Flag Set & Load-Link Address set to %x.\n",
tid, req->getPaddr() & ~0xf);
}
@ -53,6 +61,52 @@ template <class XC>
inline bool
handleLockedWrite(XC *xc, Request *req)
{
unsigned tid = req->getThreadNum();
if (req->isUncacheable()) {
// Funky Turbolaser mailbox access...don't update
// result register (see stq_c in decoder.isa)
req->setExtraData(2);
} else {
// standard store conditional
bool lock_flag = xc->readMiscReg(LLFlag, tid);
Addr lock_addr = xc->readMiscReg(LLAddr, tid);
if (!lock_flag || (req->getPaddr() & ~0xf) != lock_addr) {
// Lock flag not set or addr mismatch in CPU;
// don't even bother sending to memory system
req->setExtraData(0);
xc->setMiscReg(LLFlag, false, tid);
// the rest of this code is not architectural;
// it's just a debugging aid to help detect
// livelock by warning on long sequences of failed
// store conditionals
int stCondFailures = xc->readStCondFailures();
stCondFailures++;
xc->setStCondFailures(stCondFailures);
if (stCondFailures % 10 == 0) {
warn("%i: cpu %d: %d consecutive "
"store conditional failures\n",
curTick, xc->readCpuId(), stCondFailures);
}
if (stCondFailures == 5000) {
panic("Max (5000) Store Conditional Fails Reached. Check Code For Deadlock.\n");
}
if (!lock_flag){
DPRINTF(LLSC, "[tid:%i]: Lock Flag Set, Store Conditional Failed.\n",
tid);
} else if ((req->getPaddr() & ~0xf) != lock_addr) {
DPRINTF(LLSC, "[tid:%i]: Load-Link Address Mismatch, Store Conditional Failed.\n",
tid);
}
// store conditional failed already, so don't issue it to mem
return false;
}
}
return true;
}

302
src/arch/mips/mt.hh Executable file
View file

@ -0,0 +1,302 @@
/*
* 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_MT_HH__
#define __ARCH_MIPS_MT_HH__
/**
* @file
*
* ISA-specific helper functions for multithreaded execution.
*/
#include "arch/isa_traits.hh"
#include "arch/mips/faults.hh"
#include "arch/mips/mt_constants.hh"
#include "base/bitfield.hh"
#include "base/trace.hh"
#include "base/misc.hh"
#include <iostream>
using namespace std;
namespace MipsISA
{
template <class TC>
inline unsigned
getVirtProcNum(TC *tc)
{
MiscReg tcbind = tc->readMiscRegNoEffect(TCBind);
return bits(tcbind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO);
}
template <class TC>
inline unsigned
getTargetThread(TC *tc)
{
MiscReg vpec_ctrl = tc->readMiscRegNoEffect(VPEControl);
return bits(vpec_ctrl, VPEC_TARG_TC_HI, VPEC_TARG_TC_LO);
}
template <class TC>
inline void
haltThread(TC *tc)
{
if (tc->status() == TC::Active) {
tc->halt();
// Save last known PC in TCRestart
// @TODO: Needs to check if this is a branch and if so, take previous instruction
tc->setMiscReg(TCRestart, tc->readNextPC());
warn("%i: Halting thread %i in %s @ PC %x, setting restart PC to %x", curTick, tc->getThreadNum(), tc->getCpuPtr()->name(),
tc->readPC(), tc->readNextPC());
}
}
template <class TC>
inline void
restoreThread(TC *tc)
{
if (tc->status() != TC::Active) {
// Restore PC from TCRestart
IntReg pc = tc->readMiscRegNoEffect(TCRestart);
// TODO: SET PC WITH AN EVENT INSTEAD OF INSTANTANEOUSLY
// tc->setPCEvent(pc, pc + 4, pc + 8);
tc->setPC(pc);
tc->setNextPC(pc + 4);
tc->setNextNPC(pc + 8);
tc->activate(0);
warn("%i: Restoring thread %i in %s @ PC %x", curTick, tc->getThreadNum(), tc->getCpuPtr()->name(),
tc->readPC());
}
}
template <class TC>
void
forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
{
int num_threads = bits(tc->readMiscRegNoEffect(MVPConf0), MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
int success = 0;
for (int tid = 0; tid < num_threads && success == 0; tid++) {
unsigned tid_TCBind = tc->readRegOtherThread(MipsISA::TCBind + Ctrl_Base_DepTag,
tid);
unsigned tc_bind = tc->readMiscRegNoEffect(MipsISA::TCBind);
if (bits(tid_TCBind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO) ==
bits(tc_bind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO)) {
unsigned tid_TCStatus = tc->readRegOtherThread(MipsISA::TCStatus + Ctrl_Base_DepTag,
tid);
unsigned tid_TCHalt = tc->readRegOtherThread(MipsISA::TCHalt + Ctrl_Base_DepTag,
tid);
if (bits(tid_TCStatus, TCS_DA) == 1 &&
bits(tid_TCHalt, TCH_H) == 0 &&
bits(tid_TCStatus, TCS_A) == 0 &&
success == 0) {
tc->setRegOtherThread(MipsISA::TCRestart + Ctrl_Base_DepTag, Rs, tid);
tc->setRegOtherThread(Rd_bits, Rt, tid);
unsigned status_ksu = bits(tc->readMiscReg(MipsISA::Status),
S_KSU_HI, S_KSU_LO);
unsigned tc_status_asid = bits(tc->readMiscReg(MipsISA::TCStatus),
TCS_ASID_HI, TCS_ASID_LO);
// Set Run-State to Running
replaceBits(tid_TCStatus, TCSTATUS_RNST_HI, TCSTATUS_RNST_LO, 0);
// Set Delay-Slot to 0
replaceBits(tid_TCStatus, TCSTATUS_TDS, 0);
// Set Dirty TC to 1
replaceBits(tid_TCStatus, TCSTATUS_DT, 1);
// Set Activated to 1
replaceBits(tid_TCStatus, TCSTATUS_A, 1);
// Set status to previous thread's status
replaceBits(tid_TCStatus, TCSTATUS_TKSU_HI, TCSTATUS_TKSU_LO, status_ksu);
// Set ASID to previous thread's state
replaceBits(tid_TCStatus, TCSTATUS_ASID_HI, TCSTATUS_ASID_LO, tc_status_asid);
// Write Status Register
tc->setRegOtherThread(MipsISA::TCStatus + Ctrl_Base_DepTag,
tid_TCStatus, tid);
// Mark As Successful Fork
success = 1;
}
} else {
std::cerr << "Bad VPEs" << endl;
}
}
if (success == 0) {
unsigned vpe_control = tc->readMiscRegNoEffect(MipsISA::VPEControl);
tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 1));
fault = new ThreadFault();
}
}
template <class TC>
int
yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask)
{
if (src_reg == 0) {
unsigned mvpconf0 = tc->readMiscRegNoEffect(MVPConf0);
int num_threads = bits(mvpconf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
int ok = 0;
// Get Current VPE & TC numbers from calling thread
unsigned tcbind = tc->readMiscRegNoEffect(TCBind);
unsigned cur_vpe = bits(tcbind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO);
unsigned cur_tc = bits(tcbind, TCB_CUR_TC_HI, TCB_CUR_TC_LO);
for (int tid = 0; tid < num_threads; tid++) {
unsigned tid_TCStatus = tc->readRegOtherThread(MipsISA::TCStatus + Ctrl_Base_DepTag,
tid);
unsigned tid_TCHalt = tc->readRegOtherThread(MipsISA::TCHalt + Ctrl_Base_DepTag,
tid);
unsigned tid_TCBind = tc->readRegOtherThread(MipsISA::TCBind + Ctrl_Base_DepTag,
tid);
unsigned tid_vpe = bits(tid_TCBind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO);
unsigned tid_tc = bits(tid_TCBind, TCB_CUR_TC_HI, TCB_CUR_TC_LO);
unsigned tid_tcstatus_da = bits(tid_TCStatus, TCS_DA);
unsigned tid_tcstatus_a = bits(tid_TCStatus, TCS_A);
unsigned tid_tchalt_h = bits(tid_TCHalt, TCH_H);
if (tid_vpe == cur_vpe &&
tid_tc == cur_tc &&
tid_tcstatus_da == 1 &&
tid_tchalt_h == 0 &&
tid_tcstatus_a == 1) {
ok = 1;
}
}
if (ok == 1) {
unsigned tcstatus = tc->readMiscRegNoEffect(TCStatus);
tc->setMiscReg(TCStatus, insertBits(tcstatus, TCS_A, TCS_A, 0));
warn("%i: Deactivating Hardware Thread Context #%i", curTick, tc->getThreadNum());
}
} else if (src_reg > 0) {
if (src_reg & !yield_mask != 0) {
unsigned vpe_control = tc->readMiscReg(VPEControl);
tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 2));
fault = new ThreadFault();
} else {
//tc->setThreadRescheduleCondition(src_reg & yield_mask);
}
} else if (src_reg != -2) {
unsigned tcstatus = tc->readMiscRegNoEffect(TCStatus);
unsigned vpe_control = tc->readMiscRegNoEffect(VPEControl);
unsigned tcstatus_dt = bits(tcstatus, TCS_DT);
unsigned vpe_control_ysi = bits(vpe_control, VPEC_YSI);
if (vpe_control_ysi == 1 && tcstatus_dt == 1 ) {
tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 4));
fault = new ThreadFault();
} else {
//tc->ScheduleOtherThreads();
//std::cerr << "T" << tc->getThreadNum() << "YIELD: Schedule Other Threads.\n" << std::endl;
//tc->suspend();
// Save last known PC in TCRestart
// @TODO: Needs to check if this is a branch and if so, take previous instruction
//tc->setMiscRegWithEffect(TCRestart, tc->readNextPC());
}
}
return src_reg & yield_mask;
}
// TC will usually be a object derived from ThreadContext
// (src/cpu/thread_context.hh)
template <class TC>
inline void
updateStatusView(TC *tc)
{
// TCStatus' register view must be the same as
// Status register view for CU, MX, KSU bits
MiscReg tc_status = tc->readMiscRegNoEffect(TCStatus);
MiscReg status = tc->readMiscRegNoEffect(Status);
unsigned cu_bits = bits(tc_status, TCS_TCU_HI, TCS_TCU_LO);
replaceBits(status, S_CU_HI, S_CU_LO, cu_bits);
unsigned mx_bits = bits(tc_status, TCS_TMX);
replaceBits(status, S_MX, S_MX, mx_bits);
unsigned ksu_bits = bits(tc_status, TCS_TKSU_HI, TCS_TKSU_LO);
replaceBits(status, S_KSU_HI, S_KSU_LO, ksu_bits);
tc->setMiscRegNoEffect(Status, status);
}
// TC will usually be a object derived from ThreadContext
// (src/cpu/thread_context.hh)
template <class TC>
inline void
updateTCStatusView(TC *tc)
{
// TCStatus' register view must be the same as
// Status register view for CU, MX, KSU bits
MiscReg tc_status = tc->readMiscRegNoEffect(TCStatus);
MiscReg status = tc->readMiscRegNoEffect(Status);
unsigned cu_bits = bits(status, S_CU_HI, S_CU_LO);
replaceBits(tc_status, TCS_TCU_HI, TCS_TCU_LO, cu_bits);
unsigned mx_bits = bits(status, S_MX, S_MX);
replaceBits(tc_status, TCS_TMX, mx_bits);
unsigned ksu_bits = bits(status, S_KSU_HI, S_KSU_LO);
replaceBits(tc_status, TCS_TKSU_HI, TCS_TKSU_LO, ksu_bits);
tc->setMiscRegNoEffect(TCStatus, tc_status);
}
} // namespace MipsISA
#endif

122
src/arch/mips/mt_constants.hh Executable file
View file

@ -0,0 +1,122 @@
/*
* 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_MT_CONSTANTS_HH__
#define __ARCH_MIPS_MT_CONSTANTS_HH__
#include "arch/mips/types.hh"
//#include "config/full_system.hh"
namespace MipsISA
{
// MVPControl
const unsigned MVPC_EVP = 0;
const unsigned MVPC_CUR_VPE_HI = 3;
const unsigned MVPC_CUR_VPE_LO = 0;
// MVPConf0
const unsigned MVPC0_TCA = 15;
const unsigned MVPC0_PVPE_HI = 13;
const unsigned MVPC0_PVPE_LO = 10;
const unsigned MVPC0_PTC_HI = 7;
const unsigned MVPC0_PTC_LO = 0;
//VPEControl
const unsigned VPEC_YSI = 21;
const unsigned VPEC_EXCPT_HI = 18;
const unsigned VPEC_EXCPT_LO = 16;
const unsigned VPEC_TE = 15;
const unsigned VPEC_TARG_TC_HI = 7;
const unsigned VPEC_TARG_TC_LO = 0;
//VPEConf0
const unsigned VPEC0_MVP = 1;
//TCBind
const unsigned TCB_CUR_VPE_HI = 3;
const unsigned TCB_CUR_VPE_LO = 0;
const unsigned TCB_CUR_TC_HI = 28;
const unsigned TCB_CUR_TC_LO = 21;
//TCStatus
const unsigned TCS_TCU_HI = 31;
const unsigned TCS_TCU_LO = 28;
const unsigned TCS_TMX = 27;
const unsigned TCS_DT = 20;
const unsigned TCS_DA = 15;
const unsigned TCS_A = 13;
const unsigned TCS_TKSU_HI = 12;
const unsigned TCS_TKSU_LO = 11;
const unsigned TCS_IXMT = 7;
const unsigned TCS_ASID_HI = 7;
const unsigned TCS_ASID_LO = 7;
const unsigned TCSTATUS_TCU_HI = 31;
const unsigned TCSTATUS_TCU_LO = 28;
const unsigned TCSTATUS_TMX = 27;
const unsigned TCSTATUS_RNST_HI = 24;
const unsigned TCSTATUS_RNST_LO = 23;
const unsigned TCSTATUS_TDS = 21;
const unsigned TCSTATUS_DT = 20;
const unsigned TCSTATUS_DA = 15;
const unsigned TCSTATUS_A = 13;
const unsigned TCSTATUS_TKSU_HI = 12;
const unsigned TCSTATUS_TKSU_LO = 11;
const unsigned TCSTATUS_IXMT = 7;
const unsigned TCSTATUS_ASID_HI = 7;
const unsigned TCSTATUS_ASID_LO = 7;
//TCHalt
const unsigned TCH_H = 0;
//Status
const unsigned S_CU_HI = 31;
const unsigned S_CU_LO = 28;
const unsigned S_MX = 24;
const unsigned S_KSU_HI = 4;
const unsigned S_KSU_LO = 3;
// Config0
const unsigned CFG_M = 31;
// Config1
const unsigned CFG1_M = 31;
// Config2
const unsigned CFG2_M = 31;
// Config3
const unsigned CFG3_M = 31;
const unsigned CFG3_MT = 2;
} // namespace MipsISA
#endif

464
src/arch/mips/pra_constants.hh Executable file
View file

@ -0,0 +1,464 @@
/*
* 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: Jaidev Patwardhan
*/
#ifndef __ARCH_MIPS_PRA_CONSTANTS_HH__
#define __ARCH_MIPS_PRA_CONSTANTS_HH__
#include "arch/mips/types.hh"
//#include "config/full_system.hh"
namespace MipsISA
{
// See MIPS32(R) Architecture Reference Manual Volume - III
// This header file uses definitions from Revision 2.50
// Index Status Register - CP0 Reg 0, Sel 0
const unsigned Index_P_HI = 31;
const unsigned Index_P_LO = 31;
// Need to figure out how to put in the TLB specific bits here
// For now, we assume that the entire length is used by the index field
// In reality, Index_HI = N-1, where Ceiling(log2(TLB Entries))=N
const unsigned Index_HI = 30;
const unsigned Index_LO = 0;
// CP0 Reg 0, Sel 1-3 are MT registers, see mt_constants.hh
// Random Register - CP0 Reg 1, Sel 0
// This has a problem similar to the Index_HI fields. We'll keep both consistent at 30 for now
const unsigned Random_HI = 30;
const unsigned Random_LO = 0;
// EntryLo0 - CP0 Reg2, Sel 0 - Table 8-6, ARM Vol-3
const unsigned EntryLo0_Fill_HI = 31; // See Table 8-8, ARM Vol III
const unsigned EntryLo0_Fill_LO = 30;
const unsigned EntryLo0_PFN_HI = 29; //PFN defines the Page Frame Number (see Table 8-7, ARM Vol III)
const unsigned EntryLo0_PFN_LO = 6;
const unsigned EntryLo0_C_HI = 5; // Coherency attribute of a Page (see Table 8-8, ARM Vol III)
const unsigned EntryLo0_C_LO = 3;
const unsigned EntryLo0_D = 2; // Dirty Bit, if D=1, page is writable. If D=0, a write causes a TLB Modified Exception
const unsigned EntryLo0_V = 1; // Valid Bit
const unsigned EntryLo0_G = 0; // Global Bit. From the ARM Vol-III, Table 8-5:
// On a TLB write, the logical AND of the G bits from EntryLo0 and EntryLo1
// becomes the G bit in the TLB entry. If the TLB entry G bit is 1, ASID comparisons are
// ignored during TLB matches. On a read from a TLB entry, the G bits of both Lo0 and Lo1
// reflect the state of the TLB G bit.
// EntryLo1 - CP0 Reg3, Sel 0
const unsigned EntryLo1_G = 0;
const unsigned EntryLo1_V = 1; // Valid Bit
const unsigned EntryLo1_D = 2; // Dirty Bit, if D=1, page is writable. If D=0, a write causes a TLB Modified Exception
const unsigned EntryLo1_C_HI = 5; // Coherency attribute of a Page (see Table 8-8, ARM Vol III)
const unsigned EntryLo1_C_LO = 3;
const unsigned EntryLo1_PFN_HI = 29; //PFN defines the Page Frame Number (see Table 8-7, ARM Vol III)
const unsigned EntryLo1_PFN_LO = 6;
const unsigned EntryLo1_Fill_LO = 30;
const unsigned EntryLo1_Fill_HI = 31; // See Table 8-8, ARM Vol III
// Context Register - CP0 Reg 4, Sel 0
const unsigned Context_PTEBase_HI = 31; // Used by the OS to point into current PTE array
const unsigned Context_PTEBase_LO = 23;
const unsigned Context_BadVPN2_HI = 22; // This is written by hardware on a TLB exception. Contains bits 31-13 of the
const unsigned Context_BadVPN2_LO = 4; // virtual address
// Bits 3-0 are zeros
// PageMask Register - CP0 Reg 5, Sel 0
// Bits 31-29 are 0
const unsigned PageMask_Mask_HI = 28; // (Table 8-10, ARM Vol-III) The Mask field is a bit mask in which a "1" indicates that
const unsigned PageMask_Mask_LO = 13; // the corresponding bit of the virtual address should not participate in the TLB match
const unsigned PageMask_MaskX_HI = 12; // See Table 8-10, ARM Vol-III
const unsigned PageMask_MaskX_LO = 11;
// Bits 10-0 are zero
// PageGrain Register - CP0 Reg 5, Sel 1
const unsigned PageGrain_ASE_UP_HI = 31; // ASE specific bits (SmartMIPS)
const unsigned PageGrain_ASE_UP_LO = 30; //
const unsigned PageGrain_ELPA = 29; // Used to enable support for large physical addresses in MIPS64 processors, unused in MIPS32
const unsigned PageGrain_ESP = 28; // Enables support for 1KB pages (1==enabled,0==disabled), See ARM Vol-III, Table 8-12
const unsigned PageGrain_ASE_DN_HI = 12;
const unsigned PageGrain_ASE_DN_LO = 8;
// Bits 27-13, 7-0 are zeros
// Wired Register - CPO Reg 6, Sel 0
// See note on Index register (CP0, Sel0) above
const unsigned Wired_HI = 30;
const unsigned Wired_LO = 0;
// HWREna Register - CP0 Reg 7, Sel 0
const unsigned HWREna_IMPL_HI = 31; // These bits enable access to implementation dependent hardware registers 31
const unsigned HWREna_IMPL_LO = 30; // and 30
const unsigned HWREna_Mask_HI = 3; // Each bit enables access to a particular hardware register. If bit 'n' is 1, HW Reg n is accessible
const unsigned HWREna_Mask_LO = 0; // See the RDHWR instruction for more details
// BadVAddr Register - CP0 Reg 8, Sel 0
const unsigned BadVAddr_HI = 31;
const unsigned BadVAddr_LO = 0;
// Count Register - CP0 Reg 9, Sel 0
const unsigned Count_HI = 31;
const unsigned Count_LO = 0;
// EntryHI Register - CP0 Reg 10, Sel 0
const unsigned Entry_HI_VPN2_HI = 31; // This field is written by hardware on a TLB exception or on a TLB read
const unsigned Entry_HI_VPN2_LO = 13; // and is written by software before a TLB write
const unsigned Entry_HI_VPN2X_HI = 12; // Extension to support 1KB pages
const unsigned Entry_HI_VPN2X_LO = 11;
const unsigned Entry_HI_ASID_HI = 7; // Address space identifier
const unsigned Entry_HI_ASID_LO = 0;
// Compare Register - CP0 Reg 11, Sel 0
const unsigned Compare_HI = 31; // Used in conjunction with Count
const unsigned Compare_LO = 0;
// Status Register - CP Reg 12, Sel 0
const unsigned Status_IE_HI = 0;
const unsigned Status_IE_LO = 0;
const unsigned Status_EXL_HI = 1;
const unsigned Status_EXL_LO = 1;
const unsigned Status_ERL_HI = 2;
const unsigned Status_ERL_LO = 2;
const unsigned Status_R0 = 3;
const unsigned Status_UM = 4;
const unsigned Status_KSU_HI = 4; // R0 and UM are also aliased as KSU
const unsigned Status_KSU_LO = 3;
const unsigned Status_UX = 5;
const unsigned Status_SX = 6;
const unsigned Status_KX = 7;
const unsigned Status_IM0 = 8;
const unsigned Status_IM1 = 9;
const unsigned Status_IM2 = 10;
const unsigned Status_IM3 = 11;
const unsigned Status_IM4 = 12;
const unsigned Status_IM5 = 13;
const unsigned Status_IM6 = 14;
const unsigned Status_IM7 = 15;
const unsigned Status_IPL_HI = 15; // IM7..IM2 are also aliased as IPL
const unsigned Status_IPL_LO = 10;
const unsigned Status_IMPL_HI = 17;
const unsigned Status_IMPL_LO = 16;
const unsigned Status_NMI = 19;
const unsigned Status_SR = 20;
const unsigned Status_TS = 21;
const unsigned Status_BEV = 22;
const unsigned Status_PX = 23;
const unsigned Status_MX = 24;
const unsigned Status_RE = 25;
const unsigned Status_FR = 26;
const unsigned Status_RP = 27;
const unsigned Status_CU3_HI = 31;
const unsigned Status_CU3_LO = 31;
const unsigned Status_CU2_HI = 30;
const unsigned Status_CU2_LO = 30;
const unsigned Status_CU1_HI = 29;
const unsigned Status_CU1_LO = 29;
const unsigned Status_CU0_HI = 28;
const unsigned Status_CU0_LO = 28;
// IntCtl Register - CP0 Reg 12, Sel 1
// Interrupt System status and control
const unsigned IntCtl_IPTI_HI = 31;
const unsigned IntCtl_IPTI_LO = 29;
const unsigned IntCtl_IPPCI_HI = 28;
const unsigned IntCtl_IPPCI_LO = 26;
const unsigned IntCtl_VS_HI = 9;
const unsigned IntCtl_VS_LO = 5;
// Bits 26-10, 4-0 are zeros
// SRSCtl Register - CP0 Reg 12, Sel 2
// Shadow Register Set Status and Control
const unsigned SRSCtl_HSS_HI=29; // Highest Shadow Set
const unsigned SRSCtl_HSS_LO=26;
const unsigned SRSCtl_EICSS_HI=21; //EIC interrupt mode shadow set
const unsigned SRSCtl_EICSS_LO=18;
const unsigned SRSCtl_ESS_HI=15; // Exception Shadow Set
const unsigned SRSCtl_ESS_LO=12;
const unsigned SRSCtl_PSS_HI=9; // Previous Shadow Set
const unsigned SRSCtl_PSS_LO=6;
const unsigned SRSCtl_CSS_HI=3; // Current Shadow Set
const unsigned SRSCtl_CSS_LO=0;
// SRSMap Register - CP0 Reg 12, Sel 3
// Shadow Set IPL mapping
const unsigned SRSMap_SSV7_HI = 31; // Shadow sets for particular vector numbers (7..0)
const unsigned SRSMap_SSV7_LO = 28;
const unsigned SRSMap_SSV6_HI = 27;
const unsigned SRSMap_SSV6_LO = 24;
const unsigned SRSMap_SSV5_HI = 23;
const unsigned SRSMap_SSV5_LO = 20;
const unsigned SRSMap_SSV4_HI = 19;
const unsigned SRSMap_SSV4_LO = 16;
const unsigned SRSMap_SSV3_HI = 15;
const unsigned SRSMap_SSV3_LO = 12;
const unsigned SRSMap_SSV2_HI = 11;
const unsigned SRSMap_SSV2_LO = 8;
const unsigned SRSMap_SSV1_HI = 7;
const unsigned SRSMap_SSV1_LO = 4;
const unsigned SRSMap_SSV0_HI = 3;
const unsigned SRSMap_SSV0_LO = 20;
// Cause Register - CP0 Reg 13, Sel 0
const unsigned Cause_BD = 31;
const unsigned Cause_TI = 30;
const unsigned Cause_CE_HI = 29;
const unsigned Cause_CE_LO = 28;
const unsigned Cause_DC = 27;
const unsigned Cause_PCI = 26;
const unsigned Cause_IV = 24;
const unsigned Cause_WP = 23;
const unsigned Cause_RIPL_HI = 15; // The individual bits of RIPL are also available as IP7..IP5
const unsigned Cause_RIPL_LO = 10;
const unsigned Cause_IP7 = 15;
const unsigned Cause_IP6 = 14;
const unsigned Cause_IP5 = 13;
const unsigned Cause_IP4 = 12;
const unsigned Cause_IP3 = 11;
const unsigned Cause_IP2 = 10;
const unsigned Cause_IP1 = 9;
const unsigned Cause_IP0 = 8;
const unsigned Cause_EXCCODE_HI = 6;
const unsigned Cause_EXCCODE_LO = 2;
// All intermediate undefined bits must be ZERO
// EPC Register - CP0 Reg 14, Sel 0
// Exception Program Counter
const unsigned EPC_HI = 31;
const unsigned EPC_LO = 0;
// PRId Register - CP0 Reg 15, Sel 0
// Processor Identification register
const unsigned PRIdCoOp_HI = 31;
const unsigned PRIdCoOp_LO = 24;
const unsigned PRIdCoID_HI = 23;
const unsigned PRIdCoID_LO = 16;
const unsigned PRIdProc_ID_HI = 15;
const unsigned PRIdProc_ID_LO = 8;
const unsigned PRIdRev_HI = 7;
const unsigned PRIdRev_LO = 0;
// EBase Register - CP0 Reg 15, Sel 1
// Exception Base Register
const unsigned EBase_MSB = 31; // MUST BE = 1
const unsigned EBase_EXCEPTION_Base_HI = 29;
const unsigned EBase_EXCEPTION_Base_LO = 12;
const unsigned EBase_CPUNum_HI = 9;
const unsigned EBase_CPUNum_LO = 0;
// Undefined bits must be zero
// Config Register - CP0 Reg 16, Sel 0
const unsigned Config_M = 31;
const unsigned Config_K23_HI = 30;
const unsigned Config_K23_LO = 28;
const unsigned Config_KU_HI = 27;
const unsigned Config_KU_LO = 25;
const unsigned Config_IMPL_HI = 24;
const unsigned Config_IMPL_LO = 16;
const unsigned Config_BE = 15;
const unsigned Config_AT_HI = 14;
const unsigned Config_AT_LO = 13;
const unsigned Config_AR_HI = 12;
const unsigned Config_AR_LO = 10;
const unsigned Config_MT_HI = 9;
const unsigned Config_MT_LO = 7;
const unsigned Config_VI = 3;
const unsigned Config_K0_HI = 2;
const unsigned Config_K0_LO = 0;
// Config1 Register - CP0 Reg 16, Sel 1
const unsigned Config1_M = 31;
const unsigned Config1_MMUSize_HI = 30;
const unsigned Config1_MMUSize_LO = 25;
const unsigned Config1_IS_HI = 24;
const unsigned Config1_IS_LO = 22;
const unsigned Config1_IL_HI = 21;
const unsigned Config1_IL_LO = 19;
const unsigned Config1_IA_HI = 18;
const unsigned Config1_IA_LO = 16;
const unsigned Config1_DS_HI = 15;
const unsigned Config1_DS_LO = 13;
const unsigned Config1_DL_HI = 12;
const unsigned Config1_DL_LO = 10;
const unsigned Config1_DA_HI = 9;
const unsigned Config1_DA_LO = 7;
const unsigned Config1_C2 = 6;
const unsigned Config1_MD = 5;
const unsigned Config1_PC = 4;
const unsigned Config1_WR = 3;
const unsigned Config1_CA = 2;
const unsigned Config1_EP = 1;
const unsigned Config1_FP = 0;
// Config2 Register - CP0 Reg 16, Sel 2
const unsigned Config2_M = 31;
const unsigned Config2_TU_HI = 30;
const unsigned Config2_TU_LO = 28;
const unsigned Config2_TS_HI = 27;
const unsigned Config2_TS_LO = 24;
const unsigned Config2_TL_HI = 23;
const unsigned Config2_TL_LO = 20;
const unsigned Config2_TA_HI = 19;
const unsigned Config2_TA_LO = 16;
const unsigned Config2_SU_HI = 15;
const unsigned Config2_SU_LO = 12;
const unsigned Config2_SS_HI = 11;
const unsigned Config2_SS_LO = 8;
const unsigned Config2_SL_HI = 7;
const unsigned Config2_SL_LO = 4;
const unsigned Config2_SA_HI = 3;
const unsigned Config2_SA_LO = 0;
// Config3 Register - CP0 Reg 16, Sel 3
const unsigned Config3_M = 31;
const unsigned Config3_DSPP = 10;
const unsigned Config3_LPA=7;
const unsigned Config3_VEIC=6;
const unsigned Config3_VINT=5;
const unsigned Config3_SP=4;
const unsigned Config3_MT=2;
const unsigned Config3_SM=1;
const unsigned Config3_TL=0;
// LLAddr Register - CP0 Reg 17, Sel 0
// Load Linked Address (Physical)
const unsigned LLAddr_PAddr_HI = 31;
const unsigned LLAddr_PAddr_LO = 0;
// WatchLo Register - CP0 Reg 18, Sel 0-n
// See WatchHi to determine how many pairs of these registers are available
const unsigned WatchLo_VAddr_HI = 31;
const unsigned WatchLo_VAddr_LO = 3;
const unsigned WatchLo_I = 2;
const unsigned WatchLo_R = 1;
const unsigned WatchLo_W = 0;
// WatchHi Register - CP0 Reg 19, Sel 0-n
const unsigned WatchHi_M = 31; // If M = 1, another pair of WatchHi/Lo registers exist
const unsigned WatchHi_G = 30;
const unsigned WatchHi_ASID_HI = 23;
const unsigned WatchHi_ASID_LO = 16;
const unsigned WatchHi_Mask_HI = 11;
const unsigned WatchHi_Mask_LO = 3;
const unsigned WatchHi_I = 2;
const unsigned WatchHi_R = 1;
const unsigned WatchHi_W = 0;
// Debug Register - CP0 Reg 23, Sel 0
// TraceControl Register - CP0 Reg 23, Sel 1
// TraceControl2 Register - CP0 Reg 23, Sel 2
// UserTraceData Register - CP0 Reg 23, Sel 3
// TraceBPC Register - CP0 Reg 23, Sel 4
// DEPC Register - CP0 Reg 24, Sel 0
// PerfCnt Register - CP0 Reg 25, Sel 0-n
// Each Perf. counter that exists is mapped onto even-odd select pairs of Reg 25
// Even values are control registers, odd values are the actual counter
// The format for the control reg is:
const unsigned PerfCntCtl_M = 31; // Is there another pair of perf counter registers?
const unsigned PerfCntCtl_W = 30;
const unsigned PerfCntCtl_Event_HI = 10;
const unsigned PerfCntCtl_Event_LO = 5;
const unsigned PerfCntCtl_IE = 4;
const unsigned PerfCntCtl_U = 3;
const unsigned PerfCntCtl_S = 2;
const unsigned PerfCntCtl_K = 1;
const unsigned PerfCntCtl_EXL = 0;
// The format for the counter is a 32-bit value (or 64-bit for MIPS64)
const unsigned PerfCnt_Count_HI = 31;
const unsigned PerfCnt_Count_LO = 0;
// ErrCtl Register - CP0 Reg 26, Sel 0
// This is implementation dependent, not defined by the ISA
// CacheErr Register - CP0 Reg 27, Sel 0
// NOTE: Page 65 of the ARM, Volume-III indicates that there are four sel. values (0-3)
// used by the CacheErr registers. However, on page 134, only one sel value is shown
const unsigned Cache_Err_ER = 31;
const unsigned Cache_Err_EC = 30;
const unsigned Cache_Err_ED = 29;
const unsigned Cache_Err_ET = 28;
const unsigned Cache_Err_ES = 27;
const unsigned Cache_Err_EE = 26;
const unsigned Cache_Err_EB = 25;
const unsigned Cache_Err_IMPL_HI = 24;
const unsigned Cache_Err_IMPL_LO = 22;
const unsigned Cache_Err_Index_HI = 21;
const unsigned Cache_Err_Index_LO = 0;
// TagLo Register - CP0 Reg 28 - Even Selects (0,2)
const unsigned TagLo_PTagLo_HI = 31;
const unsigned TagLo_PTagLo_LO = 8;
const unsigned TagLo_PState_HI = 7;
const unsigned TagLo_PState_LO = 6;
const unsigned TagLo_L = 5;
const unsigned TagLo_IMPL_HI = 4;
const unsigned TagLo_IMPL_LO = 3;
const unsigned TagLo_P = 0;
// undefined bits must be written 0
// DataLo Register - CP0 Reg 28 - Odd Selects (1,3)
const unsigned DataLo_HI = 31;
const unsigned DataLo_LO = 0;
// TagHi Register - CP0 Reg 29 - Even Selects (0,2)
// Not defined by the architecture
// DataHi Register - CP0 Reg 29 - Odd Selects (1,3)
const unsigned DataHi_HI = 31;
const unsigned DataHi_LO = 0;
// ErrorEPC - CP0 Reg 30, Sel 0
const unsigned ErrorPC_HI = 31;
const unsigned ErrorPC_LO = 0;
// DESAVE - CP0 Reg 31, Sel 0
} // namespace MipsISA
#endif

View file

@ -48,12 +48,12 @@ class MipsLiveProcess : public LiveProcess
System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
std::vector<std::string> &argv,
std::vector<std::string> &envp,
const std::string &cwd,
const std::string &cwd,
uint64_t _uid, uint64_t _euid,
uint64_t _gid, uint64_t _egid,
uint64_t _pid, uint64_t _ppid);
void startup();
virtual void startup();
};

View file

@ -88,12 +88,9 @@ namespace MipsISA
public:
void clear()
{
bzero(regs, sizeof(regs));
}
void clear() { bzero(&regs, sizeof(regs)); }
double readReg(int floatReg, int width)
double readReg(int floatReg, int width, unsigned tid = 0)
{
switch(width)
{
@ -115,7 +112,7 @@ namespace MipsISA
}
}
FloatRegBits readRegBits(int floatReg, int width)
FloatRegBits readRegBits(int floatReg, int width, unsigned tid = 0)
{
if (floatReg < NumFloatArchRegs - 1) {
switch(width)
@ -137,8 +134,9 @@ namespace MipsISA
}
}
Fault setReg(int floatReg, const FloatRegVal &val, int width)
Fault setReg(int floatReg, const FloatRegVal &val, int width, unsigned tid = 0)
{
using namespace std;
switch(width)
{
case SingleWidth:
@ -165,8 +163,9 @@ namespace MipsISA
return NoFault;
}
Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
Fault setRegBits(int floatReg, const FloatRegBits &val, int width, unsigned tid = 0)
{
using namespace std;
switch(width)
{

View file

@ -47,8 +47,21 @@ namespace MipsISA
}
enum MiscIntRegNums {
HI = NumIntArchRegs,
LO
LO = NumIntArchRegs,
HI,
DSPACX0,
DSPLo1,
DSPHi1,
DSPACX1,
DSPLo2,
DSPHi2,
DSPACX2,
DSPLo3,
DSPHi3,
DSPACX3,
DSPControl,
DSPLo0 = LO,
DSPHi0 = HI
};
class IntRegFile
@ -57,6 +70,8 @@ namespace MipsISA
IntReg regs[NumIntRegs];
public:
void clear() { bzero(&regs, sizeof(regs)); }
IntReg readReg(int intReg)
{
return regs[intReg];
@ -64,7 +79,10 @@ namespace MipsISA
Fault setReg(int intReg, const IntReg &val)
{
regs[intReg] = val;
if (intReg != ZeroReg) {
regs[intReg] = val;
}
return NoFault;
}

View file

@ -0,0 +1,377 @@
/*
* 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
*/
#include "base/bitfield.hh"
#include "arch/mips/regfile/misc_regfile.hh"
#include "arch/mips/mt_constants.hh"
#include "arch/mips/faults.hh"
#include "cpu/thread_context.hh"
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
//#include "cpu/mixie/cpu.hh"
using namespace std;
std::string MiscRegFile::miscRegNames[NumMiscRegs] =
{"Index", "MVPControl", "MVPConf0", "MVPConf1", "", "", "", "",
"Random", "VPEControl", "VPEConf0", "VPEConf1", "YQMask", "VPESchedule", "VPEScheFBack", "VPEOpt",
"EntryLo0", "TCStatus", "TCBind", "TCRestart", "TCHalt", "TCContext", "TCSchedule", "TCScheFBack",
"EntryLo1", "", "", "", "", "", "", "",
"Context", "ContextConfig", "", "", "", "", "", "",
"PageMask", "PageGrain", "", "", "", "", "", "",
"Wired", "SRSConf0", "SRCConf1", "SRSConf2", "SRSConf3", "SRSConf4", "", "",
"HWREna", "", "", "", "", "", "", "",
"BadVAddr", "", "", "", "", "", "", "",
"Count", "", "", "", "", "", "", "",
"EntryHi", "", "", "", "", "", "", "",
"Compare", "", "", "", "", "", "", "",
"Status", "IntCtl", "SRSCtl", "SRSMap", "", "", "", "",
"Cause", "", "", "", "", "", "", "",
"EPC", "", "", "", "", "", "", "",
"PRId", "EBase", "", "", "", "", "", "",
"Config", "Config1", "Config2", "Config3", "", "", "", "",
"LLAddr", "", "", "", "", "", "", "",
"WatchLo0", "WatchLo1", "WatchLo2", "WatchLo3", "WatchLo4", "WatchLo5", "WatchLo6", "WatchLo7",
"WatchHi0", "WatchHi1", "WatchHi2", "WatchHi3", "WatchHi4", "WatchHi5", "WatchHi6", "WatchHi7",
"XCContext64", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"Debug", "TraceControl1", "TraceControl2", "UserTraceData", "TraceBPC", "", "", "",
"DEPC", "", "", "", "", "", "", "",
"PerfCnt0", "PerfCnt1", "PerfCnt2", "PerfCnt3", "PerfCnt4", "PerfCnt5", "PerfCnt6", "PerfCnt7",
"ErrCtl", "", "", "", "", "", "", "",
"CacheErr0", "CacheErr1", "CacheErr2", "CacheErr3", "", "", "", "",
"TagLo0", "DataLo1", "TagLo2", "DataLo3", "TagLo4", "DataLo5", "TagLo6", "DataLo7",
"TagHi0", "DataHi1", "TagHi2", "DataHi3", "TagHi4", "DataHi5", "TagHi6", "DataHi7",
"ErrorEPC", "", "", "", "", "", "", "",
"DESAVE", "", "", "", "", "", "", "",
"LLFlag"
};
MiscRegFile::MiscRegFile()
{
init();
}
MiscRegFile::MiscRegFile(BaseCPU *_cpu)
{
cpu = _cpu;
init();
}
void
MiscRegFile::init()
{
miscRegFile.resize(NumMiscRegs);
bankType.resize(NumMiscRegs);
for (int i=0; i < NumMiscRegs; i++) {
miscRegFile[i].resize(1);
bankType[i] = perProcessor;
}
clear(0);
}
void
MiscRegFile::clear(unsigned tid_or_vpn)
{
for(int i = 0; i < NumMiscRegs; i++) {
miscRegFile[i][tid_or_vpn] = 0;
}
}
void
MiscRegFile::expandForMultithreading(unsigned num_threads, unsigned num_vpes)
{
// Initialize all Per-VPE regs
uint32_t per_vpe_regs[] = { VPEControl, VPEConf0, VPEConf1, YQMask,
VPESchedule, VPEScheFBack, VPEOpt, SRSConf0,
SRSConf1, SRSConf2, SRSConf3, SRSConf4,
EBase
};
uint32_t num_vpe_regs = sizeof(per_vpe_regs) / 4;
for (int i = 0; i < num_vpe_regs; i++) {
if (num_vpes > 1) {
miscRegFile[per_vpe_regs[i]].resize(num_vpes);
}
bankType[per_vpe_regs[i]] = perVirtProcessor;
}
// Initialize all Per-TC regs
uint32_t per_tc_regs[] = { Status, TCStatus, TCBind, TCRestart, TCHalt,
TCContext, TCSchedule, TCScheFBack, Debug,
LLAddr
};
uint32_t num_tc_regs = sizeof(per_tc_regs) / 4;
for (int i = 0; i < num_tc_regs; i++) {
miscRegFile[per_tc_regs[i]].resize(num_threads);
bankType[per_tc_regs[i]] = perThreadContext;
}
if (num_vpes > 1) {
for (int i=1; i < num_vpes; i++) {
clear(i);
}
}
}
//@TODO: Use MIPS STYLE CONSTANTS (e.g. TCHALT_H instead of TCH_H)
void
MiscRegFile::reset(std::string core_name, unsigned num_threads,
unsigned num_vpes)
{
DPRINTF(MipsPRA, "Resetting CP0 State with %i TCs and %i VPEs\n",
num_threads, num_vpes);
// Do Default CP0 initialization HERE
// Do Initialization for MT cores here (eventually use
// core_name parameter to toggle this initialization)
// ===================================================
// Config
MiscReg cfg = readRegNoEffect(Config);
replaceBits(cfg, CFG_M, 1);
setRegNoEffect(Config, cfg);
// Config1
MiscReg cfg1 = readRegNoEffect(Config1);
replaceBits(cfg1, CFG1_M, 1);
setRegNoEffect(Config1, cfg1);
// Config2
MiscReg cfg2 = readRegNoEffect(Config2);
replaceBits(cfg2, CFG2_M, 1);
setRegNoEffect(Config2, cfg2);
// Config3
MiscReg cfg3 = readRegNoEffect(Config3);
replaceBits(cfg3, CFG3_MT, 1);
setRegNoEffect(Config3, cfg3);
// MVPConf0
MiscReg mvp_conf0 = readRegNoEffect(MVPConf0);
replaceBits(mvp_conf0, MVPC0_TCA, 1);
replaceBits(mvp_conf0, MVPC0_PVPE_HI, MVPC0_PVPE_LO, num_vpes - 1);
replaceBits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO, num_threads - 1);
setRegNoEffect(MVPConf0, mvp_conf0);
// VPEConf0
MiscReg vpe_conf0 = readRegNoEffect(VPEConf0);
replaceBits(vpe_conf0, VPEC0_MVP, 1);
setRegNoEffect(VPEConf0, vpe_conf0);
// TCBind
for (int tid = 0; tid < num_threads; tid++) {
MiscReg tc_bind = readRegNoEffect(TCBind, tid);
replaceBits(tc_bind, TCB_CUR_TC_HI, TCB_CUR_TC_LO, tid);
setRegNoEffect(TCBind, tc_bind, tid);
}
// TCHalt
MiscReg tc_halt = readRegNoEffect(TCHalt);
replaceBits(tc_halt, TCH_H, 0);
setRegNoEffect(TCHalt, tc_halt);
/*for (int tid = 1; tid < num_threads; tid++) {
// Set TCHalt Halt bit to 1 for all other threads
tc_halt = readRegNoEffect(TCHalt, tid);
replaceBits(tc_halt, TCH_H, 1);
setReg(TCHalt, tc_halt, tid);
}*/
// TCStatus
// Set TCStatus Activated to 1 for the initial thread that is running
MiscReg tc_status = readRegNoEffect(TCStatus);
replaceBits(tc_status, TCS_A, 1);
setRegNoEffect(TCStatus, tc_status);
// Set Dynamically Allocatable bit to 1 for all other threads
for (int tid = 0; tid < num_threads; tid++) {
tc_status = readRegNoEffect(TCStatus, tid);
replaceBits(tc_status, TCSTATUS_DA, 1);
setRegNoEffect(TCStatus, tc_status, tid);
}
}
inline std::string
MipsISA::getMiscRegName(unsigned reg_idx)
{
return MiscRegFile::miscRegNames[reg_idx];
}
inline unsigned
MiscRegFile::getVPENum(unsigned tid)
{
unsigned tc_bind = miscRegFile[TCBind][tid];
return bits(tc_bind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO);
}
MiscReg
MiscRegFile::readRegNoEffect(int misc_reg, unsigned tid)
{
unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
? tid : getVPENum(tid);
return miscRegFile[misc_reg][reg_sel];
}
//@TODO: MIPS MT's register view automatically connects
// Status to TCStatus depending on current thread
MiscReg
MiscRegFile::readReg(int misc_reg,
ThreadContext *tc, unsigned tid)
{
DPRINTF(MipsPRA, "Reading CP0 Register:%u Select:%u (%s) with effect.\n",
misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg));
unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
? tid : getVPENum(tid);
switch (misc_reg)
{
default:
return miscRegFile[misc_reg][reg_sel];
}
}
void
MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid)
{
unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
? tid : getVPENum(tid);
miscRegFile[misc_reg][reg_sel] = val;
}
// PROGRAMMER'S NOTES:
// (1) Some CP0 Registers have fields that cannot
// be overwritten. Make sure to handle those particular registers
// with care!
void
MiscRegFile::setReg(int misc_reg, const MiscReg &val,
ThreadContext *tc, unsigned tid)
{
unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
? tid : getVPENum(tid);
DPRINTF(MipsPRA, "[tid:%i]: Setting CP0 Register:%u Select:%u (%s) to %#x, with effect.\n",
tid, misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), val);
MiscReg cp0_val = filterCP0Write(misc_reg, val);
miscRegFile[misc_reg][reg_sel] = cp0_val;
scheduleCP0Update();
}
void
MiscRegFile::scheduleCP0Update(int delay)
{
if (!cp0Updated) {
cp0Updated = true;
//schedule UPDATE
CP0Event *cp0_event = new CP0Event(this, cpu, UpdateCP0);
cp0_event->schedule(curTick + cpu->cycles(delay));
}
}
void
MiscRegFile::updateCPU()
{
///////////////////////////////////////////////////////////////////
//
// EVALUATE CP0 STATE FOR MIPS MT
//
///////////////////////////////////////////////////////////////////
unsigned mvp_conf0 = readRegNoEffect(MVPConf0);
unsigned num_threads = bits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
for (int tid = 0; tid < num_threads; tid++) {
MiscReg tc_status = readRegNoEffect(TCStatus, tid);
MiscReg tc_halt = readRegNoEffect(TCHalt, tid);
//@todo: add vpe/mt check here thru mvpcontrol & vpecontrol regs
if (bits(tc_halt, TCH_H) == 1 || bits(tc_status, TCS_A) == 0) {
haltThread(cpu->getContext(tid));
} else if (bits(tc_halt, TCH_H) == 0 && bits(tc_status, TCS_A) == 1) {
restoreThread(cpu->getContext(tid));
}
}
num_threads = bits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
// Toggle update flag after we finished updating
cp0Updated = false;
}
MiscRegFile::CP0Event::CP0Event(CP0 *_cp0, BaseCPU *_cpu, CP0EventType e_type)
: Event(&mainEventQueue, CPU_Tick_Pri), cp0(_cp0), cpu(_cpu), cp0EventType(e_type)
{ }
void
MiscRegFile::CP0Event::process()
{
switch (cp0EventType)
{
case UpdateCP0:
cp0->updateCPU();
break;
}
//cp0EventRemoveList.push(this);
}
const char *
MiscRegFile::CP0Event::description()
{
return "Coprocessor-0 event";
}
void
MiscRegFile::CP0Event::scheduleEvent(int delay)
{
if (squashed())
reschedule(curTick + cpu->cycles(delay));
else if (!scheduled())
schedule(curTick + cpu->cycles(delay));
}
void
MiscRegFile::CP0Event::unscheduleEvent()
{
if (scheduled())
squash();
}

View file

@ -31,213 +31,128 @@
#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/mt.hh"
#include "arch/mips/mt_constants.hh"
#include "base/bitfield.hh"
#include "cpu/base.hh"
#include "sim/faults.hh"
#include <queue>
class ThreadContext;
namespace MipsISA
{
static inline std::string getMiscRegName(RegIndex)
{
return "";
}
//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 {
public:
// Give RegFile object, private access
friend class RegFile;
// The MIPS name for this file is CP0 or Coprocessor 0
typedef MiscRegFile CP0;
protected:
uint64_t fpcr; // floating point condition codes
// FPCR is not used in MIPS. Condition
// codes are kept as part of the FloatRegFile
enum BankType {
perProcessor,
perThreadContext,
perVirtProcessor
};
bool lock_flag; // lock flag for LL/SC
// use LL reg. in the future
std::vector<std::vector<MiscReg> > miscRegFile;
std::vector<BankType> bankType;
Addr lock_addr; // lock address for LL/SC
// use LLAddr reg. in the future
MiscReg miscRegFile[NumMiscRegs];
BaseCPU *cpu;
public:
void clear()
{
fpcr = 0;
lock_flag = 0;
lock_addr = 0;
}
MiscRegFile();
MiscRegFile(BaseCPU *cpu);
void init();
void clear(unsigned tid_or_vpn = 0);
void reset(std::string core_name, unsigned num_threads, unsigned num_vpes);
void expandForMultithreading(unsigned num_threads, unsigned num_vpes);
void copyMiscRegs(ThreadContext *tc);
MiscReg readRegNoEffect(int misc_reg)
{
return miscRegFile[misc_reg];
}
inline unsigned getVPENum(unsigned tid);
MiscReg readReg(int misc_reg, ThreadContext *tc)
{
return miscRegFile[misc_reg];
}
void setRegNoEffect(int misc_reg, const MiscReg &val)
{
miscRegFile[misc_reg] = val;
}
//////////////////////////////////////////////////////////
//
// READ/WRITE CP0 STATE
//
//
//////////////////////////////////////////////////////////
//@TODO: MIPS MT's register view automatically connects
// Status to TCStatus depending on current thread
void updateCP0ReadView(int misc_reg, unsigned tid) { }
MiscReg readRegNoEffect(int misc_reg, unsigned tid = 0);
MiscReg readReg(int misc_reg,
ThreadContext *tc, unsigned tid = 0);
MiscReg filterCP0Write(int misc_reg, MiscReg val) { return val; }
void setRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid = 0);
void setReg(int misc_reg, const MiscReg &val,
ThreadContext *tc)
{
miscRegFile[misc_reg] = val;
}
ThreadContext *tc, unsigned tid = 0);
friend class RegFile;
//////////////////////////////////////////////////////////
//
// DECLARE INTERFACE THAT WILL ALLOW A MiscRegFile (Cop0)
// TO SCHEDULE EVENTS
//
//////////////////////////////////////////////////////////
// Flag that is set when CP0 state has been written to.
bool cp0Updated;
// Enumerated List of CP0 Event Types
enum CP0EventType {
UpdateCP0
};
// Declare A CP0Event Class for scheduling
class CP0Event : public Event
{
protected:
MiscRegFile::CP0 *cp0;
BaseCPU *cpu;
CP0EventType cp0EventType;
Fault fault;
public:
/** Constructs a CP0 event. */
CP0Event(CP0 *_cp0, BaseCPU *_cpu, CP0EventType e_type);
/** Process this event. */
virtual void process();
/** Returns the description of this event. */
const char *description();
/** Schedule This Event */
void scheduleEvent(int delay);
/** Unschedule This Event */
void unscheduleEvent();
};
// Schedule a CP0 Update Event
void scheduleCP0Update(int delay = 0);
// If any changes have been made, then check the state for changes
// and if necessary alert the CPU
void updateCPU();
// Keep a List of CPU Events that need to be deallocated
std::queue<CP0Event*> cp0EventRemoveList;
static std::string miscRegNames[NumMiscRegs];
};
inline std::string getMiscRegName(unsigned reg_idx);
} // namespace MipsISA
#endif

View file

@ -32,6 +32,8 @@
#define __ARCH_MIPS_REGFILE_REGFILE_HH__
#include "arch/mips/types.hh"
#include "arch/mips/isa_traits.hh"
#include "arch/mips/mt.hh"
#include "arch/mips/regfile/int_regfile.hh"
#include "arch/mips/regfile/float_regfile.hh"
#include "arch/mips/regfile/misc_regfile.hh"
@ -49,33 +51,50 @@ namespace MipsISA
MiscRegFile miscRegFile; // control register file
public:
void clear()
{
intRegFile.clear();
floatRegFile.clear();
miscRegFile.clear();
}
void reset(std::string core_name, unsigned num_threads, unsigned num_vpes)
{
bzero(&intRegFile, sizeof(intRegFile));
bzero(&floatRegFile, sizeof(floatRegFile));
bzero(&miscRegFile, sizeof(miscRegFile));
miscRegFile.reset(core_name, num_threads, num_vpes);
}
MiscReg readMiscRegNoEffect(int miscReg)
IntReg readIntReg(int intReg)
{
return miscRegFile.readRegNoEffect(miscReg);
return intRegFile.readReg(intReg);
}
MiscReg readMiscReg(int miscReg, ThreadContext *tc)
Fault setIntReg(int intReg, const IntReg &val)
{
return miscRegFile.readReg(miscReg, tc);
return intRegFile.setReg(intReg, val);
}
void setMiscRegNoEffect(int miscReg, const MiscReg &val)
MiscReg readMiscRegNoEffect(int miscReg, unsigned tid = 0)
{
miscRegFile.setRegNoEffect(miscReg, val);
return miscRegFile.readRegNoEffect(miscReg, tid);
}
MiscReg readMiscReg(int miscReg, ThreadContext *tc,
unsigned tid = 0)
{
return miscRegFile.readReg(miscReg, tc, tid);
}
void setMiscRegNoEffect(int miscReg, const MiscReg &val, unsigned tid = 0)
{
miscRegFile.setRegNoEffect(miscReg, val, tid);
}
void setMiscReg(int miscReg, const MiscReg &val,
ThreadContext * tc)
ThreadContext * tc, unsigned tid = 0)
{
miscRegFile.setReg(miscReg, val, tc);
miscRegFile.setReg(miscReg, val, tc, tid);
}
FloatRegVal readFloatReg(int floatReg)
@ -98,35 +117,26 @@ namespace MipsISA
return floatRegFile.readRegBits(floatReg,width);
}
void setFloatReg(int floatReg, const FloatRegVal &val)
Fault setFloatReg(int floatReg, const FloatRegVal &val)
{
floatRegFile.setReg(floatReg, val, SingleWidth);
return floatRegFile.setReg(floatReg, val, SingleWidth);
}
void setFloatReg(int floatReg, const FloatRegVal &val, int width)
Fault setFloatReg(int floatReg, const FloatRegVal &val, int width)
{
floatRegFile.setReg(floatReg, val, width);
return floatRegFile.setReg(floatReg, val, width);
}
void setFloatRegBits(int floatReg, const FloatRegBits &val)
Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
{
floatRegFile.setRegBits(floatReg, val, SingleWidth);
return floatRegFile.setRegBits(floatReg, val, SingleWidth);
}
void setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
{
floatRegFile.setRegBits(floatReg, val, width);
return floatRegFile.setRegBits(floatReg, val, width);
}
IntReg readIntReg(int intReg)
{
return intRegFile.readReg(intReg);
}
void setIntReg(int intReg, const IntReg &val)
{
intRegFile.setReg(intReg, val);
}
protected:
Addr pc; // program counter
@ -134,6 +144,7 @@ namespace MipsISA
Addr nnpc; // next-next-cycle program counter
// used to implement branch delay slot
// not real register
public:
Addr readPC()
{

View file

@ -28,12 +28,18 @@
* Authors: Korey Sewell
*/
#include "arch/mips/regfile.hh"
#include "arch/mips/isa_traits.hh"
#include "arch/mips/utility.hh"
#include "base/misc.hh"
#include "arch/mips/constants.hh"
#include "config/full_system.hh"
#include "cpu/thread_context.hh"
#include "cpu/static_inst.hh"
#include "sim/serialize.hh"
#include "base/bitfield.hh"
#include "base/misc.hh"
using namespace MipsISA;
using namespace std;
uint64_t
MipsISA::fpConvert(ConvertType cvt_type, double fp_val)
@ -197,3 +203,9 @@ MipsISA::isSnan(void *val_ptr, int size)
panic("Type unsupported. Size mismatch\n");
}
}
void
MipsISA::startupCPU(ThreadContext *tc, int cpuId)
{
tc->activate(0);
}

View file

@ -35,13 +35,15 @@
#define __ARCH_MIPS_UTILITY_HH__
#include "arch/mips/types.hh"
#include "arch/mips/isa_traits.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
#include "cpu/thread_context.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"
#include "cpu/thread_context.hh"
class ThreadContext;
namespace MipsISA {
@ -66,6 +68,8 @@ namespace MipsISA {
template <class TC>
void zeroRegisters(TC *tc);
void startupCPU(ThreadContext *tc, int cpuId);
void copyRegs(ThreadContext *src, ThreadContext *dest);
// Instruction address compression hooks
@ -88,9 +92,17 @@ namespace MipsISA {
return 0;
}
inline void startupCPU(ThreadContext *tc, int cpuId)
{
tc->activate(0);
static inline ExtMachInst
makeExtMI(MachInst inst, ThreadContext * xc) {
#if FULL_SYSTEM
ExtMachInst ext_inst = inst;
if (xc->readPC() && 0x1)
return ext_inst|=(static_cast<ExtMachInst>(xc->readPC() & 0x1) << 32);
else
return ext_inst;
#else
return ExtMachInst(inst);
#endif
}
};

View file

@ -58,6 +58,17 @@ bits(T val, int first, int last)
return (val >> last) & mask(nbits);
}
/**
* Extract the bit from this position from 'val' and right justify it.
*/
template <class T>
inline
T
bits(T val, int bit)
{
return bits(val, bit, bit);
}
/**
* Mask off the given bits in place like bits() but without shifting.
* msb = 63, lsb = 0
@ -101,6 +112,17 @@ insertBits(T val, int first, int last, B bit_val)
return ((t_bit_val << last) & bmask) | (val & ~bmask);
}
/**
* Overloaded for access to only one bit in value
*/
template <class T, class B>
inline
T
insertBits(T val, int bit, B bit_val)
{
return insertBits(val, bit, bit, bit_val);
}
/**
* A convenience function to replace bits first to last of val with bit_val
* in place.
@ -113,6 +135,14 @@ replaceBits(T& val, int first, int last, B bit_val)
val = insertBits(val, first, last, bit_val);
}
/** Overloaded function to allow to access only 1 bit*/
template <class T, class B>
inline
void
replaceBits(T& val, int bit, B bit_val)
{
val = insertBits(val, bit, bit, bit_val);
}
/**
* Returns the bit position of the MSB that is set in the input
*/

View file

@ -128,6 +128,7 @@ baseFlags = [
'Mbox',
'MemDepUnit',
'MemoryAccess',
'MipsPRA',
'O3CPU',
'OzoneCPU',
'OzoneLSQ',

View file

@ -215,6 +215,7 @@ class BaseSimpleCPU : public BaseCPU
// need to do this...
}
Fault copySrcTranslate(Addr src);
Fault copy(Addr dest);
@ -353,6 +354,18 @@ class BaseSimpleCPU : public BaseCPU
thread->setStCondFailures(sc_failures);
}
MiscReg readRegOtherThread(int regIdx, int tid = -1)
{
panic("Simple CPU models do not support multithreaded "
"register access.\n");
}
void setRegOtherThread(int regIdx, const MiscReg &val, int tid = -1)
{
panic("Simple CPU models do not support multithreaded "
"register access.\n");
}
#if FULL_SYSTEM
Fault hwrei() { return thread->hwrei(); }
void ev5_trap(Fault fault) { fault->invoke(tc); }

View file

@ -349,22 +349,22 @@ class SimpleThread : public ThreadState
regs.setNextNPC(val);
}
MiscReg readMiscRegNoEffect(int misc_reg)
MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid = 0)
{
return regs.readMiscRegNoEffect(misc_reg);
}
MiscReg readMiscReg(int misc_reg)
MiscReg readMiscReg(int misc_reg, unsigned tid = 0)
{
return regs.readMiscReg(misc_reg, tc);
}
void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
void setMiscRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid = 0)
{
return regs.setMiscRegNoEffect(misc_reg, val);
}
void setMiscReg(int misc_reg, const MiscReg &val)
void setMiscReg(int misc_reg, const MiscReg &val, unsigned tid = 0)
{
return regs.setMiscReg(misc_reg, val, tc);
}

View file

@ -234,6 +234,10 @@ class ThreadContext
virtual void setMiscReg(int misc_reg, const MiscReg &val) = 0;
virtual uint64_t readRegOtherThread(int misc_reg, unsigned tid) { return 0; }
virtual void setRegOtherThread(int misc_reg, const MiscReg &val, unsigned tid) { };
// Also not necessarily the best location for these two. Hopefully will go
// away once we decide upon where st cond failures goes.
virtual unsigned readStCondFailures() = 0;