Merge vm1.(none):/home/stever/bk/newmem-head
into vm1.(none):/home/stever/bk/newmem-cache2 src/base/traceflags.py: Hand merge. --HG-- extra : convert_revision : 9e7539eeab4220ed7a7237457a8f336f79216924
This commit is contained in:
commit
245b0bd9b9
45 changed files with 5299 additions and 631 deletions
|
@ -1414,6 +1414,28 @@ class ControlRegOperand(Operand):
|
||||||
self.base_name
|
self.base_name
|
||||||
return wb
|
return wb
|
||||||
|
|
||||||
|
class ControlBitfieldOperand(ControlRegOperand):
|
||||||
|
def makeRead(self):
|
||||||
|
bit_select = 0
|
||||||
|
if (self.ctype == 'float' or self.ctype == 'double'):
|
||||||
|
error(0, 'Attempt to read control register as FP')
|
||||||
|
base = 'xc->readMiscReg(%s)' % self.reg_spec
|
||||||
|
name = self.base_name
|
||||||
|
return '%s = bits(%s, %s_HI, %s_LO);' % \
|
||||||
|
(name, base, name, name)
|
||||||
|
|
||||||
|
def makeWrite(self):
|
||||||
|
if (self.ctype == 'float' or self.ctype == 'double'):
|
||||||
|
error(0, 'Attempt to write control register as FP')
|
||||||
|
base = 'xc->readMiscReg(%s)' % self.reg_spec
|
||||||
|
name = self.base_name
|
||||||
|
wb_val = 'insertBits(%s, %s_HI, %s_LO, %s)' % \
|
||||||
|
(base, name, name, self.base_name)
|
||||||
|
wb = 'xc->setMiscRegOperand(this, %s, %s );\n' % (self.dest_reg_idx, wb_val)
|
||||||
|
wb += 'if (traceData) { traceData->setData(%s); }' % \
|
||||||
|
self.base_name
|
||||||
|
return wb
|
||||||
|
|
||||||
class MemOperand(Operand):
|
class MemOperand(Operand):
|
||||||
def isMem(self):
|
def isMem(self):
|
||||||
return 1
|
return 1
|
||||||
|
|
|
@ -35,7 +35,9 @@ Import('*')
|
||||||
if env['TARGET_ISA'] == 'mips':
|
if env['TARGET_ISA'] == 'mips':
|
||||||
Source('faults.cc')
|
Source('faults.cc')
|
||||||
Source('isa_traits.cc')
|
Source('isa_traits.cc')
|
||||||
|
Source('regfile/misc_regfile.cc')
|
||||||
Source('utility.cc')
|
Source('utility.cc')
|
||||||
|
Source('dsp.cc')
|
||||||
|
|
||||||
if env['FULL_SYSTEM']:
|
if env['FULL_SYSTEM']:
|
||||||
#Insert Full-System Files Here
|
#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;
|
FaultVect ResetFault::_vect = 0x0001;
|
||||||
FaultStat ResetFault::_count;
|
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";
|
FaultName ArithmeticFault::_name = "arith";
|
||||||
FaultVect ArithmeticFault::_vect = 0x0501;
|
FaultVect ArithmeticFault::_vect = 0x0501;
|
||||||
FaultStat ArithmeticFault::_count;
|
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";
|
FaultName InterruptFault::_name = "interrupt";
|
||||||
FaultVect InterruptFault::_vect = 0x0101;
|
FaultVect InterruptFault::_vect = 0x0101;
|
||||||
FaultStat InterruptFault::_count;
|
FaultStat InterruptFault::_count;
|
||||||
|
@ -90,21 +113,77 @@ FaultName ItbAcvFault::_name = "iaccvio";
|
||||||
FaultVect ItbAcvFault::_vect = 0x0081;
|
FaultVect ItbAcvFault::_vect = 0x0081;
|
||||||
FaultStat ItbAcvFault::_count;
|
FaultStat ItbAcvFault::_count;
|
||||||
|
|
||||||
FaultName UnimplementedOpcodeFault::_name = "opdec";
|
|
||||||
FaultVect UnimplementedOpcodeFault::_vect = 0x0481;
|
|
||||||
FaultStat UnimplementedOpcodeFault::_count;
|
|
||||||
|
|
||||||
FaultName FloatEnableFault::_name = "fen";
|
FaultName FloatEnableFault::_name = "fen";
|
||||||
FaultVect FloatEnableFault::_vect = 0x0581;
|
FaultVect FloatEnableFault::_vect = 0x0581;
|
||||||
FaultStat FloatEnableFault::_count;
|
FaultStat FloatEnableFault::_count;
|
||||||
|
|
||||||
FaultName PalFault::_name = "pal";
|
|
||||||
FaultVect PalFault::_vect = 0x2001;
|
|
||||||
FaultStat PalFault::_count;
|
|
||||||
|
|
||||||
FaultName IntegerOverflowFault::_name = "intover";
|
FaultName IntegerOverflowFault::_name = "intover";
|
||||||
FaultVect IntegerOverflowFault::_vect = 0x0501;
|
FaultVect IntegerOverflowFault::_vect = 0x0501;
|
||||||
FaultStat IntegerOverflowFault::_count;
|
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
|
} // namespace MipsISA
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,42 @@ class AlignmentFault : public MipsFault
|
||||||
bool isAlignmentFault() {return true;}
|
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()
|
static inline Fault genMachineCheckFault()
|
||||||
{
|
{
|
||||||
return new MachineCheckFault;
|
return new MachineCheckFault;
|
||||||
|
@ -100,8 +136,49 @@ class ResetFault : public MipsFault
|
||||||
FaultName name() {return _name;}
|
FaultName name() {return _name;}
|
||||||
FaultVect vect() {return _vect;}
|
FaultVect vect() {return _vect;}
|
||||||
FaultStat & countStat() {return _count;}
|
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
|
class ArithmeticFault : public MipsFault
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -217,18 +294,6 @@ class ItbAcvFault : public MipsFault
|
||||||
FaultStat & countStat() {return _count;}
|
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
|
class FloatEnableFault : public MipsFault
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -241,20 +306,6 @@ class FloatEnableFault : public MipsFault
|
||||||
FaultStat & countStat() {return _count;}
|
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
|
class IntegerOverflowFault : public MipsFault
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -267,6 +318,19 @@ class IntegerOverflowFault : public MipsFault
|
||||||
FaultStat & countStat() {return _count;}
|
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
|
} // MipsISA namespace
|
||||||
|
|
||||||
#endif // __FAULTS_HH__
|
#endif // __FAULTS_HH__
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
//
|
//
|
||||||
// Authors: Korey Sewell
|
// Authors: Korey Sewell
|
||||||
|
|
||||||
|
//@TODO: Make sure the naming convention is consistent here.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Bitfield definitions.
|
// Bitfield definitions.
|
||||||
|
@ -58,6 +59,7 @@ def bitfield RT_RD <20:11>;
|
||||||
def bitfield RD <15:11>;
|
def bitfield RD <15:11>;
|
||||||
|
|
||||||
def bitfield INTIMM <15: 0>;
|
def bitfield INTIMM <15: 0>;
|
||||||
|
def bitfield RS_RT_INTIMM <25: 0>;
|
||||||
|
|
||||||
// Floating-point operate format
|
// Floating-point operate format
|
||||||
def bitfield FMT <25:21>;
|
def bitfield FMT <25:21>;
|
||||||
|
@ -81,7 +83,7 @@ def bitfield BRANCH_CC <20:18>;
|
||||||
// CP0 Register Select
|
// CP0 Register Select
|
||||||
def bitfield SEL < 2: 0>;
|
def bitfield SEL < 2: 0>;
|
||||||
|
|
||||||
// Interrupts
|
// INTERRUPTS
|
||||||
def bitfield SC < 5: 5>;
|
def bitfield SC < 5: 5>;
|
||||||
|
|
||||||
// Branch format
|
// Branch format
|
||||||
|
@ -100,3 +102,20 @@ def bitfield LSB <10: 6>;
|
||||||
|
|
||||||
// M5 instructions
|
// M5 instructions
|
||||||
def bitfield M5FUNC <7:0>;
|
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 {{
|
output header {{
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for instructions whose disassembly is not purely a
|
* 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 = ' NNPC = NNPC;\n'
|
||||||
not_taken_code += '} \n'
|
not_taken_code += '} \n'
|
||||||
|
|
||||||
|
@ -230,13 +231,13 @@ def format Branch(code,*opt_flags) {{
|
||||||
not_taken_code = ' NPC = NNPC;\n'
|
not_taken_code = ' NPC = NNPC;\n'
|
||||||
not_taken_code += ' NNPC = NNPC + 4;\n'
|
not_taken_code += ' NNPC = NNPC + 4;\n'
|
||||||
not_taken_code += '} \n'
|
not_taken_code += '} \n'
|
||||||
inst_flags = ('IsCondDelaySlot', )
|
inst_flags += ('IsCondDelaySlot', )
|
||||||
else:
|
else:
|
||||||
inst_flags += (x, )
|
inst_flags += (x, )
|
||||||
|
|
||||||
#Take into account uncond. branch instruction
|
#Take into account uncond. branch instruction
|
||||||
if 'cond == 1' in code:
|
if 'cond = 1' in code:
|
||||||
inst_flags += ('IsUnCondControl', )
|
inst_flags += ('IsUncondControl', )
|
||||||
else:
|
else:
|
||||||
inst_flags += ('IsCondControl', )
|
inst_flags += ('IsCondControl', )
|
||||||
|
|
||||||
|
@ -254,6 +255,51 @@ def format Branch(code,*opt_flags) {{
|
||||||
exec_output = BasicExecute.subst(iop)
|
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) {{
|
def format Jump(code, *opt_flags) {{
|
||||||
#Build Instruction Flags
|
#Build Instruction Flags
|
||||||
#Use Link Flag to Add Link Code
|
#Use Link Flag to Add Link Code
|
||||||
|
|
|
@ -30,18 +30,18 @@
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Integer operate instructions
|
// Coprocessor instructions
|
||||||
//
|
//
|
||||||
|
|
||||||
//Outputs to decoder.hh
|
//Outputs to decoder.hh
|
||||||
output header {{
|
output header {{
|
||||||
|
|
||||||
class Control : public MipsStaticInst
|
class CP0Control : public MipsStaticInst
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
|
CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
|
||||||
MipsStaticInst(mnem, _machInst, __opClass)
|
MipsStaticInst(mnem, _machInst, __opClass)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -49,26 +49,13 @@ output header {{
|
||||||
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CP0Control : public Control
|
class CP1Control : public MipsStaticInst
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
|
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
|
//Outputs to decoder.cc
|
||||||
output decoder {{
|
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::string CP0Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
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();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,28 +104,50 @@ output decoder {{
|
||||||
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def format System(code, *flags) {{
|
output exec {{
|
||||||
iop = InstObjParams(name, Name, 'Control', code, flags)
|
bool isCoprocessorEnabled(%(CPU_exec_context)s *xc, unsigned cop_num)
|
||||||
header_output = BasicDeclare.subst(iop)
|
{
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
switch(cop_num)
|
||||||
decode_block = BasicDecode.subst(iop)
|
{
|
||||||
exec_output = BasicExecute.subst(iop)
|
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) {{
|
def format CP0Control(code, *flags) {{
|
||||||
iop = InstObjParams(name, Name, 'CP0Control', code, flags)
|
flags += ('IsNonSpeculative', )
|
||||||
header_output = BasicDeclare.subst(iop)
|
iop = InstObjParams(name, Name, 'CP0Control', code, flags)
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
header_output = BasicDeclare.subst(iop)
|
||||||
decode_block = BasicDecode.subst(iop)
|
decoder_output = BasicConstructor.subst(iop)
|
||||||
exec_output = BasicExecute.subst(iop)
|
decode_block = BasicDecode.subst(iop)
|
||||||
|
exec_output = ControlExecute.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def format CP1Control(code, *flags) {{
|
def format CP1Control(code, *flags) {{
|
||||||
iop = InstObjParams(name, Name, 'CP1Control', code, flags)
|
flags += ('IsNonSpeculative', )
|
||||||
header_output = BasicDeclare.subst(iop)
|
iop = InstObjParams(name, Name, 'CP1Control', code, flags)
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
header_output = BasicDeclare.subst(iop)
|
||||||
decode_block = BasicDecode.subst(iop)
|
decoder_output = BasicConstructor.subst(iop)
|
||||||
exec_output = BasicExecute.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 the integer formats
|
||||||
##include "int.isa"
|
##include "int.isa"
|
||||||
|
|
||||||
|
//Include the DSP integer format
|
||||||
|
##include "dsp.isa"
|
||||||
|
|
||||||
//Include the floatOp format
|
//Include the floatOp format
|
||||||
##include "fp.isa"
|
##include "fp.isa"
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,12 @@ output decoder {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
output exec {{
|
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
|
//If any operand is Nan return the appropriate QNaN
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -145,7 +151,7 @@ output exec {{
|
||||||
uint32_t fcsr_bits = cpu->tcBase()->readFloatRegBits(FCSR);
|
uint32_t fcsr_bits = cpu->tcBase()->readFloatRegBits(FCSR);
|
||||||
|
|
||||||
//Write FCSR from FloatRegFile
|
//Write FCSR from FloatRegFile
|
||||||
cpu->tcBase()->setFloatRegBits(FCSR, genInvalidVector(fcsr_bits));
|
cpu->tcBase()->setFloatRegOperandBits(FCSR, genInvalidVector(fcsr_bits));
|
||||||
|
|
||||||
if (traceData) { traceData->setData(mips_nan); }
|
if (traceData) { traceData->setData(mips_nan); }
|
||||||
return true;
|
return true;
|
||||||
|
@ -160,6 +166,7 @@ output exec {{
|
||||||
//Read FCSR from FloatRegFile
|
//Read FCSR from FloatRegFile
|
||||||
uint32_t fcsr = cpu->tcBase()->readFloatRegBits(FCSR);
|
uint32_t fcsr = cpu->tcBase()->readFloatRegBits(FCSR);
|
||||||
|
|
||||||
|
// TODO: Use utility function here
|
||||||
fcsr = bits(fcsr, 31, 18) << 18 | bits(fcsr, 11, 0);
|
fcsr = bits(fcsr, 31, 18) << 18 | bits(fcsr, 11, 0);
|
||||||
|
|
||||||
//Write FCSR from FloatRegFile
|
//Write FCSR from FloatRegFile
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
//
|
//
|
||||||
output header {{
|
output header {{
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
/**
|
/**
|
||||||
* Base class for integer operations.
|
* Base class for integer operations.
|
||||||
*/
|
*/
|
||||||
|
@ -64,12 +65,12 @@ output header {{
|
||||||
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HiLoMiscOp: public HiLoOp
|
class HiLoRsSelOp: public HiLoOp
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
HiLoMiscOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
|
HiLoRsSelOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
|
||||||
HiLoOp(mnem, _machInst, __opClass)
|
HiLoOp(mnem, _machInst, __opClass)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -77,6 +78,31 @@ output header {{
|
||||||
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
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
|
class IntImmOp : public MipsStaticInst
|
||||||
{
|
{
|
||||||
|
@ -105,9 +131,7 @@ output header {{
|
||||||
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
// HiLo<Misc> instruction class execute method template.
|
// HiLo instruction class execute method template.
|
||||||
// Mainly to get instruction trace data to print out
|
|
||||||
// correctly
|
|
||||||
def template HiLoExecute {{
|
def template HiLoExecute {{
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
|
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
|
@ -121,12 +145,58 @@ def template HiLoExecute {{
|
||||||
if(fault == NoFault)
|
if(fault == NoFault)
|
||||||
{
|
{
|
||||||
%(op_wb)s;
|
%(op_wb)s;
|
||||||
//If there are 2 Destination Registers then
|
}
|
||||||
//concatenate the values for the traceData
|
return fault;
|
||||||
if(traceData && _numDestRegs == 2) {
|
}
|
||||||
uint64_t hilo_final_val = (uint64_t)HI << 32 | LO;
|
}};
|
||||||
traceData->setData(hilo_final_val);
|
|
||||||
}
|
// 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;
|
return fault;
|
||||||
}
|
}
|
||||||
|
@ -181,7 +251,37 @@ output decoder {{
|
||||||
return ss.str();
|
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;
|
std::stringstream ss;
|
||||||
|
|
||||||
|
@ -239,26 +339,43 @@ def format IntImmOp(code, *opt_flags) {{
|
||||||
exec_output = BasicExecute.subst(iop)
|
exec_output = BasicExecute.subst(iop)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def format HiLoOp(code, *opt_flags) {{
|
def format HiLoRsSelOp(code, *opt_flags) {{
|
||||||
code += 'HI = val<63:32>;\n'
|
iop = InstObjParams(name, Name, 'HiLoRsSelOp', code, opt_flags)
|
||||||
code += 'LO = val<31:0>;\n'
|
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)
|
iop = InstObjParams(name, Name, 'HiLoOp', code, opt_flags)
|
||||||
header_output = BasicDeclare.subst(iop)
|
header_output = BasicDeclare.subst(iop)
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
decoder_output = BasicConstructor.subst(iop)
|
||||||
decode_block = BasicDecode.subst(iop)
|
decode_block = BasicDecode.subst(iop)
|
||||||
exec_output = HiLoExecute.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 &eaCompInst() const { return eaCompPtr; }
|
||||||
const StaticInstPtr &memAccInst() const { return memAccPtr; }
|
const StaticInstPtr &memAccInst() const { return memAccPtr; }
|
||||||
|
|
||||||
|
unsigned memAccFlags() { return memAccessFlags; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -108,6 +110,37 @@ output decoder {{
|
||||||
flags[IsFloating] ? FD : RD,
|
flags[IsFloating] ? FD : RD,
|
||||||
RS, RT);
|
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 {{
|
def template LoadStoreDeclare {{
|
||||||
|
@ -125,7 +158,7 @@ def template LoadStoreDeclare {{
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
EAComp(MachInst machInst);
|
EAComp(ExtMachInst machInst);
|
||||||
|
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
};
|
};
|
||||||
|
@ -137,7 +170,7 @@ def template LoadStoreDeclare {{
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
MemAcc(MachInst machInst);
|
MemAcc(ExtMachInst machInst);
|
||||||
|
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
};
|
};
|
||||||
|
@ -145,13 +178,15 @@ def template LoadStoreDeclare {{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
%(class_name)s(MachInst machInst);
|
%(class_name)s(ExtMachInst machInst);
|
||||||
|
|
||||||
%(BasicExecDeclare)s
|
%(BasicExecDeclare)s
|
||||||
|
|
||||||
%(InitiateAccDeclare)s
|
%(InitiateAccDeclare)s
|
||||||
|
|
||||||
%(CompleteAccDeclare)s
|
%(CompleteAccDeclare)s
|
||||||
|
|
||||||
|
%(MemAccSizeDeclare)s
|
||||||
};
|
};
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
@ -162,15 +197,18 @@ def template InitiateAccDeclare {{
|
||||||
|
|
||||||
|
|
||||||
def template CompleteAccDeclare {{
|
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 {{
|
def template EACompConstructor {{
|
||||||
/** TODO: change op_class to AddrGenOp or something (requires
|
/** TODO: change op_class to AddrGenOp or something (requires
|
||||||
* creating new member of OpClass enum in op_class.hh, updating
|
* creating new member of OpClass enum in op_class.hh, updating
|
||||||
* config files, etc.). */
|
* 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)
|
: %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
|
||||||
{
|
{
|
||||||
%(constructor)s;
|
%(constructor)s;
|
||||||
|
@ -179,7 +217,7 @@ def template EACompConstructor {{
|
||||||
|
|
||||||
|
|
||||||
def template MemAccConstructor {{
|
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)
|
: %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
|
||||||
{
|
{
|
||||||
%(constructor)s;
|
%(constructor)s;
|
||||||
|
@ -188,7 +226,7 @@ def template MemAccConstructor {{
|
||||||
|
|
||||||
|
|
||||||
def template LoadStoreConstructor {{
|
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,
|
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
|
||||||
new EAComp(machInst), new MemAcc(machInst))
|
new EAComp(machInst), new MemAcc(machInst))
|
||||||
{
|
{
|
||||||
|
@ -210,8 +248,8 @@ def template EACompExecute {{
|
||||||
%(op_rd)s;
|
%(op_rd)s;
|
||||||
%(ea_code)s;
|
%(ea_code)s;
|
||||||
|
|
||||||
|
// NOTE: Trace Data is written using execute or completeAcc templates
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
%(op_wb)s;
|
|
||||||
xc->setEA(EA);
|
xc->setEA(EA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,19 +265,16 @@ def template LoadMemAccExecute {{
|
||||||
Addr EA;
|
Addr EA;
|
||||||
Fault fault = NoFault;
|
Fault fault = NoFault;
|
||||||
|
|
||||||
%(fp_enable_check)s;
|
|
||||||
%(op_decl)s;
|
%(op_decl)s;
|
||||||
%(op_rd)s;
|
%(op_rd)s;
|
||||||
|
|
||||||
EA = xc->getEA();
|
EA = xc->getEA();
|
||||||
|
|
||||||
if (fault == NoFault) {
|
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
|
||||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
|
|
||||||
%(memacc_code)s;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fault == NoFault) {
|
%(memacc_code)s;
|
||||||
%(op_wb)s;
|
|
||||||
}
|
// NOTE: Write back data using execute or completeAcc templates
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
|
@ -292,9 +327,8 @@ def template LoadInitiateAcc {{
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
def template LoadCompleteAcc {{
|
def template LoadCompleteAcc {{
|
||||||
Fault %(class_name)s::completeAcc(PacketPtr pkt,
|
Fault %(class_name)s::completeAcc(Packet *pkt,
|
||||||
%(CPU_exec_context)s *xc,
|
%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
|
@ -302,6 +336,7 @@ def template LoadCompleteAcc {{
|
||||||
|
|
||||||
%(fp_enable_check)s;
|
%(fp_enable_check)s;
|
||||||
%(op_decl)s;
|
%(op_decl)s;
|
||||||
|
%(op_rd)s;
|
||||||
|
|
||||||
Mem = pkt->get<typeof(Mem)>();
|
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 {{
|
def template StoreMemAccExecute {{
|
||||||
Fault
|
Fault
|
||||||
%(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
|
%(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
|
||||||
|
@ -325,10 +369,12 @@ def template StoreMemAccExecute {{
|
||||||
{
|
{
|
||||||
Addr EA;
|
Addr EA;
|
||||||
Fault fault = NoFault;
|
Fault fault = NoFault;
|
||||||
|
uint64_t write_result = 0;
|
||||||
|
|
||||||
%(fp_enable_check)s;
|
%(fp_enable_check)s;
|
||||||
%(op_decl)s;
|
%(op_decl)s;
|
||||||
%(op_rd)s;
|
%(op_rd)s;
|
||||||
|
|
||||||
EA = xc->getEA();
|
EA = xc->getEA();
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
|
@ -337,16 +383,9 @@ def template StoreMemAccExecute {{
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||||
memAccessFlags, NULL);
|
memAccessFlags, &write_result);
|
||||||
if (traceData) { traceData->setData(Mem); }
|
// @NOTE: Need to Call Complete Access to Set Trace Data
|
||||||
}
|
//if (traceData) { traceData->setData(Mem); }
|
||||||
|
|
||||||
if (fault == NoFault) {
|
|
||||||
%(postacc_code)s;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fault == NoFault) {
|
|
||||||
%(op_wb)s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
|
@ -389,13 +428,13 @@ def template StoreCondMemAccExecute {{
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
def template StoreExecute {{
|
def template StoreExecute {{
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
Addr EA;
|
Addr EA;
|
||||||
Fault fault = NoFault;
|
Fault fault = NoFault;
|
||||||
|
uint64_t write_result = 0;
|
||||||
|
|
||||||
%(fp_enable_check)s;
|
%(fp_enable_check)s;
|
||||||
%(op_decl)s;
|
%(op_decl)s;
|
||||||
|
@ -408,7 +447,7 @@ def template StoreExecute {{
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||||
memAccessFlags, NULL);
|
memAccessFlags, &write_result);
|
||||||
if (traceData) { traceData->setData(Mem); }
|
if (traceData) { traceData->setData(Mem); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,7 +526,7 @@ def template StoreInitiateAcc {{
|
||||||
|
|
||||||
|
|
||||||
def template StoreCompleteAcc {{
|
def template StoreCompleteAcc {{
|
||||||
Fault %(class_name)s::completeAcc(PacketPtr pkt,
|
Fault %(class_name)s::completeAcc(Packet *pkt,
|
||||||
%(CPU_exec_context)s *xc,
|
%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
|
@ -502,6 +541,8 @@ def template StoreCompleteAcc {{
|
||||||
|
|
||||||
if (fault == NoFault) {
|
if (fault == NoFault) {
|
||||||
%(op_wb)s;
|
%(op_wb)s;
|
||||||
|
|
||||||
|
if (traceData) { traceData->setData(getStoreData(pkt)); }
|
||||||
}
|
}
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
|
@ -509,7 +550,7 @@ def template StoreCompleteAcc {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def template StoreCondCompleteAcc {{
|
def template StoreCondCompleteAcc {{
|
||||||
Fault %(class_name)s::completeAcc(PacketPtr pkt,
|
Fault %(class_name)s::completeAcc(Packet *pkt,
|
||||||
%(CPU_exec_context)s *xc,
|
%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
|
@ -584,7 +625,7 @@ def template MiscInitiateAcc {{
|
||||||
|
|
||||||
|
|
||||||
def template MiscCompleteAcc {{
|
def template MiscCompleteAcc {{
|
||||||
Fault %(class_name)s::completeAcc(PacketPtr pkt,
|
Fault %(class_name)s::completeAcc(Packet *pkt,
|
||||||
%(CPU_exec_context)s *xc,
|
%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
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; }},
|
def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
|
||||||
mem_flags = [], inst_flags = []) {{
|
mem_flags = [], inst_flags = []) {{
|
||||||
(header_output, decoder_output, decode_block, exec_output) = \
|
(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 += '\tbyte_offset ^= 3;\n'
|
||||||
decl_code += '#endif\n'
|
decl_code += '#endif\n'
|
||||||
decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\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'
|
memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'
|
||||||
|
|
||||||
(header_output, decoder_output, decode_block, exec_output) = \
|
(header_output, decoder_output, decode_block, exec_output) = \
|
||||||
|
|
|
@ -37,46 +37,185 @@ output header {{
|
||||||
/**
|
/**
|
||||||
* Base class for MIPS MT ASE operations.
|
* Base class for MIPS MT ASE operations.
|
||||||
*/
|
*/
|
||||||
class MT : public MipsStaticInst
|
class MTOp : public MipsStaticInst
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
MT(const char *mnem, MachInst _machInst, OpClass __opClass) :
|
MTOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
|
||||||
MipsStaticInst(mnem, _machInst, __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 {{
|
output decoder {{
|
||||||
//Edit This Template When MT is Implemented
|
std::string MTOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||||
std::string MT::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 {{
|
def template MTExecute{{
|
||||||
//Edit This Template When MT is Implemented
|
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
|
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
//Write the resulting state to the execution context
|
Fault fault = NoFault;
|
||||||
%(op_wb)s;
|
%(op_decl)s;
|
||||||
|
%(op_rd)s;
|
||||||
|
|
||||||
//Call into the trap handler with the appropriate fault
|
unsigned config3;
|
||||||
return No_Fault;
|
|
||||||
|
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:
|
// Primary format for integer operate instructions:
|
||||||
def format MipsMT() {{
|
def format MT_Control(code, *opt_flags) {{
|
||||||
code = 'panic(\"Mips MT Is Currently Unimplemented.\");\n'
|
inst_flags = ('IsNonSpeculative', )
|
||||||
iop = InstObjParams(name, Name, 'MT', code)
|
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)
|
header_output = BasicDeclare.subst(iop)
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
decoder_output = BasicConstructor.subst(iop)
|
||||||
decode_block = BasicDecode.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:
|
// Primary format for integer operate instructions:
|
||||||
def format TlbOp(code, *opt_flags) {{
|
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)
|
header_output = BasicDeclare.subst(iop)
|
||||||
decoder_output = BasicConstructor.subst(iop)
|
decoder_output = BasicConstructor.subst(iop)
|
||||||
decode_block = BasicDecodeWithMnemonic.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))
|
+ completeAccTemplate.subst(iop))
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
output header {{
|
output header {{
|
||||||
std::string inst2string(MachInst machInst);
|
std::string inst2string(MachInst machInst);
|
||||||
}};
|
}};
|
||||||
|
@ -97,7 +96,7 @@ output decoder {{
|
||||||
|
|
||||||
std::string inst2string(MachInst machInst)
|
std::string inst2string(MachInst machInst)
|
||||||
{
|
{
|
||||||
std::string str = "";
|
string str = "";
|
||||||
uint32_t mask = 0x80000000;
|
uint32_t mask = 0x80000000;
|
||||||
|
|
||||||
for(int i=0; i < 32; i++) {
|
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 {{
|
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/isa_traits.hh"
|
|
||||||
#include "arch/mips/utility.hh"
|
|
||||||
#include "base/cprintf.hh"
|
#include "base/cprintf.hh"
|
||||||
#include "base/loader/symtab.hh"
|
#include "base/loader/symtab.hh"
|
||||||
#include "cpu/thread_context.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;
|
using namespace MipsISA;
|
||||||
}};
|
}};
|
||||||
|
@ -65,20 +69,25 @@ output exec {{
|
||||||
#include "arch/mips/faults.hh"
|
#include "arch/mips/faults.hh"
|
||||||
#include "arch/mips/isa_traits.hh"
|
#include "arch/mips/isa_traits.hh"
|
||||||
#include "arch/mips/utility.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>
|
#include <math.h>
|
||||||
#if defined(linux)
|
#if defined(linux)
|
||||||
#include <fenv.h>
|
#include <fenv.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FULL_SYSTEM
|
|
||||||
//#include "arch/alpha/pseudo_inst.hh"
|
|
||||||
#endif
|
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "cpu/exetrace.hh"
|
#include "cpu/exetrace.hh"
|
||||||
|
|
||||||
#include "mem/packet.hh"
|
#include "mem/packet.hh"
|
||||||
#include "mem/packet_access.hh"
|
#include "mem/packet_access.hh"
|
||||||
|
|
||||||
#include "sim/sim_exit.hh"
|
#include "sim/sim_exit.hh"
|
||||||
|
#include "sim/eventq.hh"
|
||||||
|
#include "sim/sim_events.hh"
|
||||||
|
|
||||||
using namespace MipsISA;
|
using namespace MipsISA;
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -48,16 +48,37 @@ def operands {{
|
||||||
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 2),
|
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 2),
|
||||||
'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 3),
|
'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 3),
|
||||||
|
|
||||||
|
#Immediate Value operand
|
||||||
|
'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3),
|
||||||
|
|
||||||
#Operands used for Link or Syscall Insts
|
#Operands used for Link or Syscall Insts
|
||||||
'R31': ('IntReg', 'uw','31','IsInteger', 4),
|
'R31': ('IntReg', 'uw','31','IsInteger', 4),
|
||||||
'R2': ('IntReg', 'uw','2', 'IsInteger', 5),
|
'R2': ('IntReg', 'uw','2', 'IsInteger', 5),
|
||||||
|
|
||||||
#Special Integer Reg operands
|
#Special Integer Reg operands
|
||||||
'HI': ('IntReg', 'uw','MipsISA::HI', 'IsInteger', 6),
|
'LO0': ('IntReg', 'uw','MipsISA::LO', 'IsInteger', 6),
|
||||||
'LO': ('IntReg', 'uw','MipsISA::LO', 'IsInteger', 7),
|
'HI0': ('IntReg', 'uw','MipsISA::HI', 'IsInteger', 7),
|
||||||
|
|
||||||
#Immediate Value operand
|
#Bitfield-dependent HI/LO Register Access
|
||||||
'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3),
|
'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
|
#Floating Point Reg Operands
|
||||||
'Fd': ('FloatReg', 'sf', 'FD', 'IsFloating', 1),
|
'Fd': ('FloatReg', 'sf', 'FD', 'IsFloating', 1),
|
||||||
|
@ -65,14 +86,14 @@ def operands {{
|
||||||
'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3),
|
'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3),
|
||||||
'Fr': ('FloatReg', 'sf', 'FR', '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),
|
'FIR': ('FloatReg', 'uw', 'MipsISA::FIR', 'IsFloating', 1),
|
||||||
'FCCR': ('FloatReg', 'uw', 'MipsISA::FCCR', 'IsFloating', 2),
|
'FCCR': ('FloatReg', 'uw', 'MipsISA::FCCR', 'IsFloating', 2),
|
||||||
'FEXR': ('FloatReg', 'uw', 'MipsISA::FEXR', 'IsFloating', 3),
|
'FEXR': ('FloatReg', 'uw', 'MipsISA::FEXR', 'IsFloating', 3),
|
||||||
'FENR': ('FloatReg', 'uw', 'MipsISA::FENR', 'IsFloating', 3),
|
'FENR': ('FloatReg', 'uw', 'MipsISA::FENR', 'IsFloating', 3),
|
||||||
'FCSR': ('FloatReg', 'uw', 'MipsISA::FCSR', '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),
|
'Fd1': ('FloatReg', 'sf', 'FD', 'IsFloating', 4),
|
||||||
'Fd2': ('FloatReg', 'sf', 'FD+1', 'IsFloating', 4),
|
'Fd2': ('FloatReg', 'sf', 'FD+1', 'IsFloating', 4),
|
||||||
'Fs1': ('FloatReg', 'sf', 'FS', 'IsFloating', 5),
|
'Fs1': ('FloatReg', 'sf', 'FS', 'IsFloating', 5),
|
||||||
|
@ -82,10 +103,44 @@ def operands {{
|
||||||
'Fr1': ('FloatReg', 'sf', 'FR', 'IsFloating', 7),
|
'Fr1': ('FloatReg', 'sf', 'FR', 'IsFloating', 7),
|
||||||
'Fr2': ('FloatReg', 'sf', 'FR+1', '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
|
#Memory Operand
|
||||||
'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
|
'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
|
||||||
|
|
||||||
#Program Counter Operands
|
#Program Counter Operands
|
||||||
'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4),
|
'NPC': ('NPC', 'uw', None, 'IsControl', 4),
|
||||||
'NNPC':('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4)
|
'NNPC':('NNPC', 'uw', None, 'IsControl', 4)
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -96,3 +96,5 @@ RegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
UNSERIALIZE_SCALAR(nnpc);
|
UNSERIALIZE_SCALAR(nnpc);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -60,24 +60,13 @@ namespace MipsISA
|
||||||
|
|
||||||
// Constants Related to the number of registers
|
// Constants Related to the number of registers
|
||||||
const int NumIntArchRegs = 32;
|
const int NumIntArchRegs = 32;
|
||||||
const int NumIntSpecialRegs = 2;
|
const int NumIntSpecialRegs = 9;
|
||||||
const int NumFloatArchRegs = 32;
|
const int NumFloatArchRegs = 32;
|
||||||
const int NumFloatSpecialRegs = 5;
|
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
|
// Static instruction parameters
|
||||||
const int MaxInstSrcRegs = 3;
|
const int MaxInstSrcRegs = 5;
|
||||||
const int MaxInstDestRegs = 2;
|
const int MaxInstDestRegs = 4;
|
||||||
|
|
||||||
// semantically meaningful register indices
|
// semantically meaningful register indices
|
||||||
const int ZeroReg = 0;
|
const int ZeroReg = 0;
|
||||||
|
@ -97,7 +86,7 @@ namespace MipsISA
|
||||||
const int ReturnAddressReg = 31;
|
const int ReturnAddressReg = 31;
|
||||||
|
|
||||||
const int SyscallNumReg = ReturnValueReg1;
|
const int SyscallNumReg = ReturnValueReg1;
|
||||||
const int SyscallPseudoReturnReg = ReturnValueReg1;
|
const int SyscallPseudoReturnReg = ReturnValueReg2;
|
||||||
const int SyscallSuccessReg = ArgumentReg3;
|
const int SyscallSuccessReg = ArgumentReg3;
|
||||||
|
|
||||||
const int LogVMPageSize = 13; // 8K bytes
|
const int LogVMPageSize = 13; // 8K bytes
|
||||||
|
@ -110,13 +99,176 @@ namespace MipsISA
|
||||||
const int HalfwordBytes = 2;
|
const int HalfwordBytes = 2;
|
||||||
const int ByteBytes = 1;
|
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 int ANNOTE_NONE = 0;
|
||||||
const uint32_t ITOUCH_ANNOTE = 0xffffffff;
|
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;
|
using namespace MipsISA;
|
||||||
|
|
|
@ -72,3 +72,4 @@ const int MipsLinux::NUM_OPEN_FLAGS =
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
#define __ARCH_MIPS_LINUX_LINUX_HH__
|
#define __ARCH_MIPS_LINUX_LINUX_HH__
|
||||||
|
|
||||||
#include "kern/linux/linux.hh"
|
#include "kern/linux/linux.hh"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
|
||||||
class MipsLinux : public Linux
|
class MipsLinux : public Linux
|
||||||
{
|
{
|
||||||
|
@ -91,21 +94,21 @@ class MipsLinux : public Linux
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
/// ioctl() command codes.
|
/// ioctl() command codes.
|
||||||
static const unsigned TIOCGETP_ = 0x7408;
|
static const unsigned TIOCGETP = 0x7408;
|
||||||
static const unsigned TIOCSETP_ = 0x7409;
|
static const unsigned TIOCSETP = 0x7409;
|
||||||
static const unsigned TIOCSETN_ = 0x740a;
|
static const unsigned TIOCSETN = 0x740a;
|
||||||
static const unsigned TIOCSETC_ = 0x7411;
|
static const unsigned TIOCSETC = 0x7411;
|
||||||
static const unsigned TIOCGETC_ = 0x7412;
|
static const unsigned TIOCGETC = 0x7412;
|
||||||
static const unsigned FIONREAD_ = 0x467f;
|
static const unsigned FIONREAD = 0x467f;
|
||||||
static const unsigned TIOCISATTY_ = 0x5480;
|
static const unsigned TIOCISATTY = 0x5480;
|
||||||
static const unsigned TIOCGETS_ = 0x7413;
|
static const unsigned TIOCGETS = 0x540d;
|
||||||
static const unsigned TIOCGETA_ = 0x7417;
|
static const unsigned TIOCGETA = 0x7417;
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// For table().
|
/// For table().
|
||||||
static const int TBL_SYSINFO = 12;
|
static const int TBL_SYSINFO = 12;
|
||||||
|
|
||||||
/// Resource enumeration for getrlimit().
|
/// Resource enumeration for getrlimit()/setrlimit().
|
||||||
enum rlimit_resources {
|
enum rlimit_resources {
|
||||||
TGT_RLIMIT_CPU = 0,
|
TGT_RLIMIT_CPU = 0,
|
||||||
TGT_RLIMIT_FSIZE = 1,
|
TGT_RLIMIT_FSIZE = 1,
|
||||||
|
@ -118,9 +121,14 @@ class MipsLinux : public Linux
|
||||||
TGT_RLIMIT_VMEM = 7,
|
TGT_RLIMIT_VMEM = 7,
|
||||||
TGT_RLIMIT_NPROC = 8,
|
TGT_RLIMIT_NPROC = 8,
|
||||||
TGT_RLIMIT_MEMLOCK = 9,
|
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
|
#endif
|
||||||
|
|
|
@ -37,7 +37,9 @@
|
||||||
#include "kern/linux/linux.hh"
|
#include "kern/linux/linux.hh"
|
||||||
|
|
||||||
#include "sim/process.hh"
|
#include "sim/process.hh"
|
||||||
|
#include "sim/system.hh"
|
||||||
#include "sim/syscall_emul.hh"
|
#include "sim/syscall_emul.hh"
|
||||||
|
#include "sim/eventq.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace MipsISA;
|
using namespace MipsISA;
|
||||||
|
@ -50,7 +52,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
|
TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
|
||||||
|
|
||||||
strcpy(name->sysname, "Linux");
|
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->release, "2.4.20");
|
||||||
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
||||||
strcpy(name->machine, "mips");
|
strcpy(name->machine, "mips");
|
||||||
|
@ -116,7 +118,6 @@ sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SyscallDesc MipsLinuxProcess::syscallDescs[] = {
|
SyscallDesc MipsLinuxProcess::syscallDescs[] = {
|
||||||
/* 0 */ SyscallDesc("syscall", unimplementedFunc),
|
/* 0 */ SyscallDesc("syscall", unimplementedFunc),
|
||||||
/* 1 */ SyscallDesc("exit", exitFunc),
|
/* 1 */ SyscallDesc("exit", exitFunc),
|
||||||
|
@ -155,12 +156,12 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
|
||||||
/* 34 */ SyscallDesc("nice", unimplementedFunc),
|
/* 34 */ SyscallDesc("nice", unimplementedFunc),
|
||||||
/* 35 */ SyscallDesc("ftime", unimplementedFunc),
|
/* 35 */ SyscallDesc("ftime", unimplementedFunc),
|
||||||
/* 36 */ SyscallDesc("sync", unimplementedFunc),
|
/* 36 */ SyscallDesc("sync", unimplementedFunc),
|
||||||
/* 37 */ SyscallDesc("kill", ignoreFunc),
|
/* 37 */ SyscallDesc("kill", unimplementedFunc),
|
||||||
/* 38 */ SyscallDesc("rename", unimplementedFunc),
|
/* 38 */ SyscallDesc("rename", unimplementedFunc),
|
||||||
/* 39 */ SyscallDesc("mkdir", unimplementedFunc),
|
/* 39 */ SyscallDesc("mkdir", unimplementedFunc),
|
||||||
/* 40 */ SyscallDesc("rmdir", unimplementedFunc),
|
/* 40 */ SyscallDesc("rmdir", unimplementedFunc),
|
||||||
/* 41 */ SyscallDesc("dup", unimplementedFunc),
|
/* 41 */ SyscallDesc("dup", unimplementedFunc),
|
||||||
/* 42 */ SyscallDesc("pipe", unimplementedFunc),
|
/* 42 */ SyscallDesc("pipe", pipePseudoFunc),
|
||||||
/* 43 */ SyscallDesc("times", unimplementedFunc),
|
/* 43 */ SyscallDesc("times", unimplementedFunc),
|
||||||
/* 44 */ SyscallDesc("prof", unimplementedFunc),
|
/* 44 */ SyscallDesc("prof", unimplementedFunc),
|
||||||
/* 45 */ SyscallDesc("brk", obreakFunc),
|
/* 45 */ SyscallDesc("brk", obreakFunc),
|
||||||
|
@ -172,7 +173,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
|
||||||
/* 51 */ SyscallDesc("acct", unimplementedFunc),
|
/* 51 */ SyscallDesc("acct", unimplementedFunc),
|
||||||
/* 52 */ SyscallDesc("umount2", unimplementedFunc),
|
/* 52 */ SyscallDesc("umount2", unimplementedFunc),
|
||||||
/* 53 */ SyscallDesc("lock", unimplementedFunc),
|
/* 53 */ SyscallDesc("lock", unimplementedFunc),
|
||||||
/* 54 */ SyscallDesc("ioctl", ioctlFunc<MipsLinux>),
|
/* 54 */ SyscallDesc("ioctl", unimplementedFunc/*ioctlFunc<MipsLinux>*/),
|
||||||
/* 55 */ SyscallDesc("fcntl", fcntlFunc),
|
/* 55 */ SyscallDesc("fcntl", fcntlFunc),
|
||||||
/* 56 */ SyscallDesc("mpx", unimplementedFunc),
|
/* 56 */ SyscallDesc("mpx", unimplementedFunc),
|
||||||
/* 57 */ SyscallDesc("setpgid", unimplementedFunc),
|
/* 57 */ SyscallDesc("setpgid", unimplementedFunc),
|
||||||
|
@ -193,9 +194,9 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
|
||||||
/* 72 */ SyscallDesc("sigsuspend", unimplementedFunc),
|
/* 72 */ SyscallDesc("sigsuspend", unimplementedFunc),
|
||||||
/* 73 */ SyscallDesc("sigpending", unimplementedFunc),
|
/* 73 */ SyscallDesc("sigpending", unimplementedFunc),
|
||||||
/* 74 */ SyscallDesc("sethostname", ignoreFunc),
|
/* 74 */ SyscallDesc("sethostname", ignoreFunc),
|
||||||
/* 75 */ SyscallDesc("setrlimit", unimplementedFunc),
|
/* 75 */ SyscallDesc("setrlimit", unimplementedFunc/*setrlimitFunc<MipsLinux>*/),
|
||||||
/* 76 */ SyscallDesc("getrlimit", unimplementedFunc),
|
/* 76 */ SyscallDesc("getrlimit", unimplementedFunc/*getrlimitFunc<MipsLinux>*/),
|
||||||
/* 77 */ SyscallDesc("getrusage", unimplementedFunc),
|
/* 77 */ SyscallDesc("getrusage", getrusageFunc<MipsLinux>),
|
||||||
/* 78 */ SyscallDesc("gettimeofday", unimplementedFunc),
|
/* 78 */ SyscallDesc("gettimeofday", unimplementedFunc),
|
||||||
/* 79 */ SyscallDesc("settimeofday", unimplementedFunc),
|
/* 79 */ SyscallDesc("settimeofday", unimplementedFunc),
|
||||||
/* 80 */ SyscallDesc("getgroups", unimplementedFunc),
|
/* 80 */ SyscallDesc("getgroups", unimplementedFunc),
|
||||||
|
@ -212,8 +213,8 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
|
||||||
/* 91 */ SyscallDesc("munmap",munmapFunc),
|
/* 91 */ SyscallDesc("munmap",munmapFunc),
|
||||||
/* 92 */ SyscallDesc("truncate", truncateFunc),
|
/* 92 */ SyscallDesc("truncate", truncateFunc),
|
||||||
/* 93 */ SyscallDesc("ftruncate", ftruncateFunc),
|
/* 93 */ SyscallDesc("ftruncate", ftruncateFunc),
|
||||||
/* 94 */ SyscallDesc("fchmod", unimplementedFunc),
|
/* 94 */ SyscallDesc("fchmod", fchmodFunc<MipsLinux>),
|
||||||
/* 95 */ SyscallDesc("fchown", unimplementedFunc),
|
/* 95 */ SyscallDesc("fchown", fchownFunc),
|
||||||
/* 96 */ SyscallDesc("getpriority", unimplementedFunc),
|
/* 96 */ SyscallDesc("getpriority", unimplementedFunc),
|
||||||
/* 97 */ SyscallDesc("setpriority", unimplementedFunc),
|
/* 97 */ SyscallDesc("setpriority", unimplementedFunc),
|
||||||
/* 98 */ SyscallDesc("profil", unimplementedFunc),
|
/* 98 */ SyscallDesc("profil", unimplementedFunc),
|
||||||
|
@ -238,7 +239,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
|
||||||
/* 117 */ SyscallDesc("ipc", unimplementedFunc),
|
/* 117 */ SyscallDesc("ipc", unimplementedFunc),
|
||||||
/* 118 */ SyscallDesc("fsync", unimplementedFunc),
|
/* 118 */ SyscallDesc("fsync", unimplementedFunc),
|
||||||
/* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
|
/* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
|
||||||
/* 120 */ SyscallDesc("clone", unimplementedFunc),
|
/* 120 */ SyscallDesc("clone", unimplementedFunc/*cloneFunc<MipsLinux>*/),
|
||||||
/* 121 */ SyscallDesc("setdomainname", unimplementedFunc),
|
/* 121 */ SyscallDesc("setdomainname", unimplementedFunc),
|
||||||
/* 122 */ SyscallDesc("uname", unameFunc),
|
/* 122 */ SyscallDesc("uname", unameFunc),
|
||||||
/* 123 */ SyscallDesc("modify_ldt", unimplementedFunc),
|
/* 123 */ SyscallDesc("modify_ldt", unimplementedFunc),
|
||||||
|
@ -271,7 +272,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
|
||||||
/* 150 */ SyscallDesc("unused#150", unimplementedFunc),
|
/* 150 */ SyscallDesc("unused#150", unimplementedFunc),
|
||||||
/* 151 */ SyscallDesc("getsid", unimplementedFunc),
|
/* 151 */ SyscallDesc("getsid", unimplementedFunc),
|
||||||
/* 152 */ SyscallDesc("fdatasync", unimplementedFunc),
|
/* 152 */ SyscallDesc("fdatasync", unimplementedFunc),
|
||||||
/* 153 */ SyscallDesc("sysctl", unimplementedFunc),
|
/* 153 */ SyscallDesc("sysctl", ignoreFunc),
|
||||||
/* 154 */ SyscallDesc("mlock", unimplementedFunc),
|
/* 154 */ SyscallDesc("mlock", unimplementedFunc),
|
||||||
/* 155 */ SyscallDesc("munlock", unimplementedFunc),
|
/* 155 */ SyscallDesc("munlock", unimplementedFunc),
|
||||||
/* 156 */ SyscallDesc("mlockall", unimplementedFunc),
|
/* 156 */ SyscallDesc("mlockall", unimplementedFunc),
|
||||||
|
@ -312,12 +313,12 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
|
||||||
/* 191 */ SyscallDesc("getresgid", unimplementedFunc),
|
/* 191 */ SyscallDesc("getresgid", unimplementedFunc),
|
||||||
/* 192 */ SyscallDesc("prctl", unimplementedFunc),
|
/* 192 */ SyscallDesc("prctl", unimplementedFunc),
|
||||||
/* 193 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
|
/* 193 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
|
||||||
/* 194 */ SyscallDesc("rt_sigaction", ignoreFunc),
|
/* 194 */ SyscallDesc("rt_sigaction", unimplementedFunc/*rt_sigactionFunc<MipsLinux>*/),
|
||||||
/* 195 */ SyscallDesc("rt_sigprocmask", ignoreFunc),
|
/* 195 */ SyscallDesc("rt_sigprocmask", unimplementedFunc/*rt_sigprocmaskFunc<MipsLinux>*/),
|
||||||
/* 196 */ SyscallDesc("rt_sigpending", unimplementedFunc),
|
/* 196 */ SyscallDesc("rt_sigpending", unimplementedFunc),
|
||||||
/* 197 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
|
/* 197 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
|
||||||
/* 198 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc),
|
/* 198 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc),
|
||||||
/* 199 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
|
/* 199 */ SyscallDesc("rt_sigsuspend", unimplementedFunc/*rt_sigsuspendFunc<MipsLinux>*/),
|
||||||
/* 200 */ SyscallDesc("pread64", unimplementedFunc),
|
/* 200 */ SyscallDesc("pread64", unimplementedFunc),
|
||||||
/* 201 */ SyscallDesc("pwrite64", unimplementedFunc),
|
/* 201 */ SyscallDesc("pwrite64", unimplementedFunc),
|
||||||
/* 202 */ SyscallDesc("chown", unimplementedFunc),
|
/* 202 */ SyscallDesc("chown", unimplementedFunc),
|
||||||
|
@ -400,9 +401,10 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
|
||||||
/* 279 */ SyscallDesc("unknown #279", unimplementedFunc),
|
/* 279 */ SyscallDesc("unknown #279", unimplementedFunc),
|
||||||
/* 280 */ SyscallDesc("add_key", unimplementedFunc),
|
/* 280 */ SyscallDesc("add_key", unimplementedFunc),
|
||||||
/* 281 */ SyscallDesc("request_key", unimplementedFunc),
|
/* 281 */ SyscallDesc("request_key", unimplementedFunc),
|
||||||
/* 282 */ SyscallDesc("keyctl", unimplementedFunc),
|
/* 282 */ SyscallDesc("keyctl", unimplementedFunc)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
MipsLinuxProcess::MipsLinuxProcess(const std::string &name,
|
MipsLinuxProcess::MipsLinuxProcess(const std::string &name,
|
||||||
ObjectFile *objFile,
|
ObjectFile *objFile,
|
||||||
System *system,
|
System *system,
|
||||||
|
@ -421,7 +423,13 @@ MipsLinuxProcess::MipsLinuxProcess(const std::string &name,
|
||||||
: MipsLiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd,
|
: MipsLiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd,
|
||||||
argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid),
|
argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid),
|
||||||
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
|
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
void
|
||||||
|
MipsLinuxProcess::startup()
|
||||||
|
{
|
||||||
|
MipsLiveProcess::argsInit(MachineBytes, VMPageSize);
|
||||||
|
}
|
||||||
|
|
||||||
SyscallDesc*
|
SyscallDesc*
|
||||||
MipsLinuxProcess::getDesc(int callnum)
|
MipsLinuxProcess::getDesc(int callnum)
|
||||||
|
@ -434,3 +442,8 @@ MipsLinuxProcess::getDesc(int callnum)
|
||||||
|
|
||||||
return &syscallDescs[m5_sys_idx];
|
return &syscallDescs[m5_sys_idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,8 @@
|
||||||
#define __MIPS_LINUX_PROCESS_HH__
|
#define __MIPS_LINUX_PROCESS_HH__
|
||||||
|
|
||||||
#include "arch/mips/process.hh"
|
#include "arch/mips/process.hh"
|
||||||
|
#include "arch/mips/linux/linux.hh"
|
||||||
|
#include "sim/eventq.hh"
|
||||||
|
|
||||||
/// A process with emulated Mips/Linux syscalls.
|
/// A process with emulated Mips/Linux syscalls.
|
||||||
class MipsLinuxProcess : public MipsLiveProcess
|
class MipsLinuxProcess : public MipsLiveProcess
|
||||||
|
@ -48,16 +49,19 @@ class MipsLinuxProcess : public MipsLiveProcess
|
||||||
uint64_t _gid, uint64_t _egid,
|
uint64_t _gid, uint64_t _egid,
|
||||||
uint64_t _pid, uint64_t _ppid);
|
uint64_t _pid, uint64_t _ppid);
|
||||||
|
|
||||||
|
void startup();
|
||||||
|
|
||||||
virtual SyscallDesc* getDesc(int callnum);
|
virtual SyscallDesc* getDesc(int callnum);
|
||||||
|
|
||||||
/// The target system's hostname.
|
/// The target system's hostname.
|
||||||
static const char *hostname;
|
static const char *hostname;
|
||||||
|
|
||||||
/// Array of syscall descriptors, indexed by call number.
|
/// ID of the thread group leader for the process
|
||||||
static SyscallDesc syscallDescs[];
|
uint64_t __tgid;
|
||||||
|
|
||||||
|
/// Array of syscall descriptors, indexed by call number.
|
||||||
|
static SyscallDesc syscallDescs[];
|
||||||
const int Num_Syscall_Descs;
|
const int Num_Syscall_Descs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // __MIPS_LINUX_PROCESS_HH__
|
#endif // __MIPS_LINUX_PROCESS_HH__
|
||||||
|
|
|
@ -37,6 +37,9 @@
|
||||||
* ISA-specific helper functions for locked memory accesses.
|
* 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"
|
#include "mem/request.hh"
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,6 +49,11 @@ template <class XC>
|
||||||
inline void
|
inline void
|
||||||
handleLockedRead(XC *xc, Request *req)
|
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
|
inline bool
|
||||||
handleLockedWrite(XC *xc, Request *req)
|
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;
|
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,
|
System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
|
||||||
std::vector<std::string> &argv,
|
std::vector<std::string> &argv,
|
||||||
std::vector<std::string> &envp,
|
std::vector<std::string> &envp,
|
||||||
const std::string &cwd,
|
const std::string &cwd,
|
||||||
uint64_t _uid, uint64_t _euid,
|
uint64_t _uid, uint64_t _euid,
|
||||||
uint64_t _gid, uint64_t _egid,
|
uint64_t _gid, uint64_t _egid,
|
||||||
uint64_t _pid, uint64_t _ppid);
|
uint64_t _pid, uint64_t _ppid);
|
||||||
|
|
||||||
void startup();
|
virtual void startup();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -88,12 +88,9 @@ namespace MipsISA
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void clear()
|
void clear() { bzero(®s, sizeof(regs)); }
|
||||||
{
|
|
||||||
bzero(regs, sizeof(regs));
|
|
||||||
}
|
|
||||||
|
|
||||||
double readReg(int floatReg, int width)
|
double readReg(int floatReg, int width, unsigned tid = 0)
|
||||||
{
|
{
|
||||||
switch(width)
|
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) {
|
if (floatReg < NumFloatArchRegs - 1) {
|
||||||
switch(width)
|
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)
|
switch(width)
|
||||||
{
|
{
|
||||||
case SingleWidth:
|
case SingleWidth:
|
||||||
|
@ -165,8 +163,9 @@ namespace MipsISA
|
||||||
return NoFault;
|
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)
|
switch(width)
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,8 +47,21 @@ namespace MipsISA
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MiscIntRegNums {
|
enum MiscIntRegNums {
|
||||||
HI = NumIntArchRegs,
|
LO = NumIntArchRegs,
|
||||||
LO
|
HI,
|
||||||
|
DSPACX0,
|
||||||
|
DSPLo1,
|
||||||
|
DSPHi1,
|
||||||
|
DSPACX1,
|
||||||
|
DSPLo2,
|
||||||
|
DSPHi2,
|
||||||
|
DSPACX2,
|
||||||
|
DSPLo3,
|
||||||
|
DSPHi3,
|
||||||
|
DSPACX3,
|
||||||
|
DSPControl,
|
||||||
|
DSPLo0 = LO,
|
||||||
|
DSPHi0 = HI
|
||||||
};
|
};
|
||||||
|
|
||||||
class IntRegFile
|
class IntRegFile
|
||||||
|
@ -57,6 +70,8 @@ namespace MipsISA
|
||||||
IntReg regs[NumIntRegs];
|
IntReg regs[NumIntRegs];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void clear() { bzero(®s, sizeof(regs)); }
|
||||||
|
|
||||||
IntReg readReg(int intReg)
|
IntReg readReg(int intReg)
|
||||||
{
|
{
|
||||||
return regs[intReg];
|
return regs[intReg];
|
||||||
|
@ -64,7 +79,10 @@ namespace MipsISA
|
||||||
|
|
||||||
Fault setReg(int intReg, const IntReg &val)
|
Fault setReg(int intReg, const IntReg &val)
|
||||||
{
|
{
|
||||||
regs[intReg] = val;
|
if (intReg != ZeroReg) {
|
||||||
|
regs[intReg] = val;
|
||||||
|
}
|
||||||
|
|
||||||
return NoFault;
|
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__
|
#ifndef __ARCH_MIPS_REGFILE_MISC_REGFILE_HH__
|
||||||
#define __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/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 "sim/faults.hh"
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
class ThreadContext;
|
class ThreadContext;
|
||||||
|
|
||||||
namespace MipsISA
|
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 {
|
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:
|
protected:
|
||||||
uint64_t fpcr; // floating point condition codes
|
enum BankType {
|
||||||
// FPCR is not used in MIPS. Condition
|
perProcessor,
|
||||||
// codes are kept as part of the FloatRegFile
|
perThreadContext,
|
||||||
|
perVirtProcessor
|
||||||
|
};
|
||||||
|
|
||||||
bool lock_flag; // lock flag for LL/SC
|
std::vector<std::vector<MiscReg> > miscRegFile;
|
||||||
// use LL reg. in the future
|
std::vector<BankType> bankType;
|
||||||
|
|
||||||
Addr lock_addr; // lock address for LL/SC
|
BaseCPU *cpu;
|
||||||
// use LLAddr reg. in the future
|
|
||||||
|
|
||||||
MiscReg miscRegFile[NumMiscRegs];
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void clear()
|
MiscRegFile();
|
||||||
{
|
MiscRegFile(BaseCPU *cpu);
|
||||||
fpcr = 0;
|
|
||||||
lock_flag = 0;
|
void init();
|
||||||
lock_addr = 0;
|
|
||||||
}
|
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);
|
void copyMiscRegs(ThreadContext *tc);
|
||||||
|
|
||||||
MiscReg readRegNoEffect(int misc_reg)
|
inline unsigned getVPENum(unsigned tid);
|
||||||
{
|
|
||||||
return miscRegFile[misc_reg];
|
|
||||||
}
|
|
||||||
|
|
||||||
MiscReg readReg(int misc_reg, ThreadContext *tc)
|
//////////////////////////////////////////////////////////
|
||||||
{
|
//
|
||||||
return miscRegFile[misc_reg];
|
// READ/WRITE CP0 STATE
|
||||||
}
|
//
|
||||||
|
//
|
||||||
void setRegNoEffect(int misc_reg, const MiscReg &val)
|
//////////////////////////////////////////////////////////
|
||||||
{
|
//@TODO: MIPS MT's register view automatically connects
|
||||||
miscRegFile[misc_reg] = val;
|
// 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,
|
void setReg(int misc_reg, const MiscReg &val,
|
||||||
ThreadContext *tc)
|
ThreadContext *tc, unsigned tid = 0);
|
||||||
{
|
|
||||||
miscRegFile[misc_reg] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
} // namespace MipsISA
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#define __ARCH_MIPS_REGFILE_REGFILE_HH__
|
#define __ARCH_MIPS_REGFILE_REGFILE_HH__
|
||||||
|
|
||||||
#include "arch/mips/types.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/int_regfile.hh"
|
||||||
#include "arch/mips/regfile/float_regfile.hh"
|
#include "arch/mips/regfile/float_regfile.hh"
|
||||||
#include "arch/mips/regfile/misc_regfile.hh"
|
#include "arch/mips/regfile/misc_regfile.hh"
|
||||||
|
@ -49,33 +51,50 @@ namespace MipsISA
|
||||||
MiscRegFile miscRegFile; // control register file
|
MiscRegFile miscRegFile; // control register file
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void clear()
|
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(&intRegFile, sizeof(intRegFile));
|
||||||
bzero(&floatRegFile, sizeof(floatRegFile));
|
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,
|
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)
|
FloatRegVal readFloatReg(int floatReg)
|
||||||
|
@ -98,35 +117,26 @@ namespace MipsISA
|
||||||
return floatRegFile.readRegBits(floatReg,width);
|
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:
|
protected:
|
||||||
|
|
||||||
Addr pc; // program counter
|
Addr pc; // program counter
|
||||||
|
@ -134,6 +144,7 @@ namespace MipsISA
|
||||||
Addr nnpc; // next-next-cycle program counter
|
Addr nnpc; // next-next-cycle program counter
|
||||||
// used to implement branch delay slot
|
// used to implement branch delay slot
|
||||||
// not real register
|
// not real register
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr readPC()
|
Addr readPC()
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,12 +28,18 @@
|
||||||
* Authors: Korey Sewell
|
* Authors: Korey Sewell
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "arch/mips/regfile.hh"
|
#include "arch/mips/isa_traits.hh"
|
||||||
#include "arch/mips/utility.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/bitfield.hh"
|
||||||
|
#include "base/misc.hh"
|
||||||
|
|
||||||
using namespace MipsISA;
|
using namespace MipsISA;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
MipsISA::fpConvert(ConvertType cvt_type, double fp_val)
|
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");
|
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__
|
#define __ARCH_MIPS_UTILITY_HH__
|
||||||
|
|
||||||
#include "arch/mips/types.hh"
|
#include "arch/mips/types.hh"
|
||||||
|
#include "arch/mips/isa_traits.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
#include "config/full_system.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
|
//XXX This is needed for size_t. We should use something other than size_t
|
||||||
//#include "kern/linux/linux.hh"
|
//#include "kern/linux/linux.hh"
|
||||||
#include "sim/host.hh"
|
#include "sim/host.hh"
|
||||||
|
|
||||||
|
#include "cpu/thread_context.hh"
|
||||||
|
|
||||||
class ThreadContext;
|
class ThreadContext;
|
||||||
|
|
||||||
namespace MipsISA {
|
namespace MipsISA {
|
||||||
|
@ -66,6 +68,8 @@ namespace MipsISA {
|
||||||
template <class TC>
|
template <class TC>
|
||||||
void zeroRegisters(TC *tc);
|
void zeroRegisters(TC *tc);
|
||||||
|
|
||||||
|
void startupCPU(ThreadContext *tc, int cpuId);
|
||||||
|
|
||||||
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
||||||
|
|
||||||
// Instruction address compression hooks
|
// Instruction address compression hooks
|
||||||
|
@ -88,9 +92,17 @@ namespace MipsISA {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void startupCPU(ThreadContext *tc, int cpuId)
|
static inline ExtMachInst
|
||||||
{
|
makeExtMI(MachInst inst, ThreadContext * xc) {
|
||||||
tc->activate(0);
|
#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);
|
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.
|
* Mask off the given bits in place like bits() but without shifting.
|
||||||
* msb = 63, lsb = 0
|
* 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);
|
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
|
* A convenience function to replace bits first to last of val with bit_val
|
||||||
* in place.
|
* in place.
|
||||||
|
@ -113,6 +135,14 @@ replaceBits(T& val, int first, int last, B bit_val)
|
||||||
val = insertBits(val, first, last, 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
|
* Returns the bit position of the MSB that is set in the input
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -129,6 +129,7 @@ baseFlags = [
|
||||||
'MemDepUnit',
|
'MemDepUnit',
|
||||||
'MemoryAccess',
|
'MemoryAccess',
|
||||||
'MemTest',
|
'MemTest',
|
||||||
|
'MipsPRA',
|
||||||
'O3CPU',
|
'O3CPU',
|
||||||
'OzoneCPU',
|
'OzoneCPU',
|
||||||
'OzoneLSQ',
|
'OzoneLSQ',
|
||||||
|
|
|
@ -215,6 +215,7 @@ class BaseSimpleCPU : public BaseCPU
|
||||||
// need to do this...
|
// need to do this...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Fault copySrcTranslate(Addr src);
|
Fault copySrcTranslate(Addr src);
|
||||||
|
|
||||||
Fault copy(Addr dest);
|
Fault copy(Addr dest);
|
||||||
|
@ -353,6 +354,18 @@ class BaseSimpleCPU : public BaseCPU
|
||||||
thread->setStCondFailures(sc_failures);
|
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
|
#if FULL_SYSTEM
|
||||||
Fault hwrei() { return thread->hwrei(); }
|
Fault hwrei() { return thread->hwrei(); }
|
||||||
void ev5_trap(Fault fault) { fault->invoke(tc); }
|
void ev5_trap(Fault fault) { fault->invoke(tc); }
|
||||||
|
|
|
@ -349,22 +349,22 @@ class SimpleThread : public ThreadState
|
||||||
regs.setNextNPC(val);
|
regs.setNextNPC(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
MiscReg readMiscRegNoEffect(int misc_reg)
|
MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid = 0)
|
||||||
{
|
{
|
||||||
return regs.readMiscRegNoEffect(misc_reg);
|
return regs.readMiscRegNoEffect(misc_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
MiscReg readMiscReg(int misc_reg)
|
MiscReg readMiscReg(int misc_reg, unsigned tid = 0)
|
||||||
{
|
{
|
||||||
return regs.readMiscReg(misc_reg, tc);
|
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);
|
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);
|
return regs.setMiscReg(misc_reg, val, tc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,6 +234,10 @@ class ThreadContext
|
||||||
|
|
||||||
virtual void setMiscReg(int misc_reg, const MiscReg &val) = 0;
|
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
|
// Also not necessarily the best location for these two. Hopefully will go
|
||||||
// away once we decide upon where st cond failures goes.
|
// away once we decide upon where st cond failures goes.
|
||||||
virtual unsigned readStCondFailures() = 0;
|
virtual unsigned readStCondFailures() = 0;
|
||||||
|
|
Loading…
Reference in a new issue