mips import pt. 1
src/arch/mips/SConscript: "mips import pt.1". --HG-- extra : convert_revision : 2e393341938bebf32fb638a209262d074fad4cc1
This commit is contained in:
parent
16c1b5484f
commit
753adb38d5
44 changed files with 5277 additions and 631 deletions
|
@ -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
41
src/arch/mips/constants.hh
Executable 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
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
171
src/arch/mips/dsp.hh
Executable 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
216
src/arch/mips/dt_constants.hh
Executable 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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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
218
src/arch/mips/isa/formats/dsp.isa
Executable 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)
|
||||
|
||||
}};
|
||||
|
||||
|
||||
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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) = \
|
||||
|
|
|
@ -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)
|
||||
}};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
}};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}};
|
||||
|
|
|
@ -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)
|
||||
}};
|
||||
|
|
|
@ -96,3 +96,5 @@ RegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
|||
UNSERIALIZE_SCALAR(nnpc);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -72,3 +72,4 @@ const int MipsLinux::NUM_OPEN_FLAGS =
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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
302
src/arch/mips/mt.hh
Executable 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
122
src/arch/mips/mt_constants.hh
Executable 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
464
src/arch/mips/pra_constants.hh
Executable 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
|
|
@ -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();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -88,12 +88,9 @@ namespace MipsISA
|
|||
|
||||
public:
|
||||
|
||||
void clear()
|
||||
{
|
||||
bzero(regs, sizeof(regs));
|
||||
}
|
||||
void clear() { bzero(®s, 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)
|
||||
{
|
||||
|
|
|
@ -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(®s, 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;
|
||||
}
|
||||
|
||||
|
|
377
src/arch/mips/regfile/misc_regfile.cc
Executable file
377
src/arch/mips/regfile/misc_regfile.cc
Executable 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();
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -128,6 +128,7 @@ baseFlags = [
|
|||
'Mbox',
|
||||
'MemDepUnit',
|
||||
'MemoryAccess',
|
||||
'MipsPRA',
|
||||
'O3CPU',
|
||||
'OzoneCPU',
|
||||
'OzoneLSQ',
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue