control.isa revision 5224:0e354459fb8a
1// -*- mode:c++ -*-
2
3// Copyright N) 2007 MIPS Technologies, Inc.  All Rights Reserved
4
5//  This software is part of the M5 simulator.
6
7//  THIS IS A LEGAL AGREEMENT.  BY DOWNLOADING, USING, COPYING, CREATING
8//  DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING
9//  TO THESE TERMS AND CONDITIONS.
10
11//  Permission is granted to use, copy, create derivative works and
12//  distribute this software and such derivative works for any purpose,
13//  so long as (1) the copyright notice above, this grant of permission,
14//  and the disclaimer below appear in all copies and derivative works
15//  made, (2) the copyright notice above is augmented as appropriate to
16//  reflect the addition of any new copyrightable work in a derivative
17//  work (e.g., Copyright N) <Publication Year> Copyright Owner), and (3)
18//  the name of MIPS Technologies, Inc. ($(B!H(BMIPS$(B!I(B) is not used in any
19//  advertising or publicity pertaining to the use or distribution of
20//  this software without specific, written prior authorization.
21
22//  THIS SOFTWARE IS PROVIDED $(B!H(BAS IS.$(B!I(B  MIPS MAKES NO WARRANTIES AND
23//  DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR
24//  OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25//  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
26//  NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE.
27//  IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT,
28//  INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF
29//  ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT,
30//  THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY
31//  IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR
32//  STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE
33//  POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE.
34
35//Authors: Korey L. Sewell
36//         Jaidev Patwardhan
37
38////////////////////////////////////////////////////////////////////
39//
40// Coprocessor instructions
41//
42
43//Outputs to decoder.hh
44output header {{
45
46        class CP0Control : public MipsStaticInst
47        {
48                protected:
49
50                /// Constructor
51                CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
52                           MipsStaticInst(mnem, _machInst, __opClass)
53                {
54                }
55
56                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
57        };
58        class CP0TLB : public MipsStaticInst
59        {
60                protected:
61
62                /// Constructor
63                CP0TLB(const char *mnem, MachInst _machInst, OpClass __opClass) :
64                           MipsStaticInst(mnem, _machInst, __opClass)
65                {
66                }
67
68                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
69        };
70
71
72        class CP1Control : public MipsStaticInst
73        {
74                protected:
75
76                /// Constructor
77                CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
78                           MipsStaticInst(mnem, _machInst, __opClass)
79                {
80                }
81
82                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
83        };
84
85}};
86
87// Basic instruction class execute method template.
88def template CP0Execute {{
89        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
90        {
91                Fault fault = NoFault;
92                %(op_decl)s;
93                %(op_rd)s;
94
95                if (isCoprocessorEnabled(xc, 0)) {
96                    %(code)s;
97                } else {
98                    fault = new CoprocessorUnusableFault(0);
99                }
100
101                if(fault == NoFault)
102                {
103                    %(op_wb)s;
104                }
105                return fault;
106        }
107}};
108
109def template CP1Execute {{
110        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
111        {
112                Fault fault = NoFault;
113                %(op_decl)s;
114                %(op_rd)s;
115
116                if (isCoprocessorEnabled(xc, 1)) {
117                    %(code)s;
118                } else {
119                    fault = new CoprocessorUnusableFault(1);
120                }
121
122                if(fault == NoFault)
123                {
124                    %(op_wb)s;
125                }
126                return fault;
127        }
128}};
129// Basic instruction class execute method template.
130def template ControlTLBExecute {{
131        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
132        {
133                Fault fault = NoFault;
134                %(op_decl)s;
135                %(op_rd)s;
136
137#if FULL_SYSTEM
138                if (isCoprocessor0Enabled(xc)) {
139                  if(isMMUTLB(xc)){
140                      %(code)s;
141                  } else {
142                    fault = new ReservedInstructionFault();
143                  }
144                } else {
145                  fault = new CoprocessorUnusableFault(0);
146                }
147#else // Syscall Emulation Mode - No TLB Instructions
148                fault = new ReservedInstructionFault();
149#endif
150
151                if(fault == NoFault)
152                {
153                    %(op_wb)s;
154                }
155                return fault;
156
157        }
158}};
159
160//Outputs to decoder.cc
161output decoder {{
162        std::string CP0Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
163        {
164            std::stringstream ss;
165            ccprintf(ss, "%-10s r%d, %d, %d", mnemonic, RT, RD, SEL);
166            return ss.str();
167        }
168        std::string CP0TLB::generateDisassembly(Addr pc, const SymbolTable *symtab) const
169        {
170            std::stringstream ss;
171            ccprintf(ss, "%-10s r%d, %d, %d", mnemonic, RT, RD, SEL);
172            return ss.str();
173        }
174        std::string CP1Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
175        {
176            std::stringstream ss;
177            ccprintf(ss, "%-10s r%d, f%d", mnemonic, RT, FS);
178            return ss.str();
179        }
180
181}};
182
183output exec {{
184        bool isCoprocessorEnabled(%(CPU_exec_context)s *xc, unsigned cop_num)
185        {
186#if !FULL_SYSTEM
187            return true;
188#else
189          MiscReg Stat = xc->readMiscReg(MipsISA::Status);
190          switch(cop_num)
191            {
192            case 0:
193              {
194                  MiscReg Dbg = xc->readMiscReg(MipsISA::Debug);
195                  if((Stat & 0x10000006) == 0  // EXL, ERL or CU0 set, CP0 accessible
196                     && (Dbg & 0x40000000) == 0 // DM bit set, CP0 accessible
197                     && (Stat & 0x00000018) != 0) {  // KSU = 0, kernel mode is base mode
198                      // Unable to use Status_CU0, etc directly, using bitfields & masks
199                      return false;
200                  }
201
202              }
203              break;
204            case 1:
205              if((Stat & 0x20000000) == 0) // CU1 is reset
206                return false;
207              break;
208            case 2:
209              if((Stat & 0x40000000) == 0) // CU2 is reset
210                return false;
211              break;
212            case 3:
213              if((Stat & 0x80000000) == 0) // CU3 is reset
214                return false;
215              break;
216            default: panic("Invalid Coprocessor Number Specified");
217              break;
218            }
219            return true;
220#endif
221        }
222        bool inline isCoprocessor0Enabled(%(CPU_exec_context)s *xc)
223        {
224#if FULL_SYSTEM
225          MiscReg Stat = xc->readMiscRegNoEffect(MipsISA::Status);
226          MiscReg Dbg = xc->readMiscRegNoEffect(MipsISA::Debug);
227          if((Stat & 0x10000006) == 0  // EXL, ERL or CU0 set, CP0 accessible
228                 && (Dbg & 0x40000000) == 0 // DM bit set, CP0 accessible
229                 && (Stat & 0x00000018) != 0) {  // KSU = 0, kernel mode is base mode
230                // Unable to use Status_CU0, etc directly, using bitfields & masks
231                  return false;
232              }
233#else
234              //printf("Syscall Emulation Mode: CP0 Enable Check defaults to TRUE\n");
235#endif
236            return true;
237        }
238        bool isMMUTLB(%(CPU_exec_context)s *xc)
239        {
240#if FULL_SYSTEM
241          if((xc->readMiscRegNoEffect(MipsISA::Config) & 0x00000380)==0x80)
242            return true;
243#endif
244          return false;
245        }
246}};
247
248def format CP0Control(code, *flags) {{
249    flags += ('IsNonSpeculative', )
250    iop = InstObjParams(name, Name, 'CP0Control', code, flags)
251    header_output = BasicDeclare.subst(iop)
252    decoder_output = BasicConstructor.subst(iop)
253    decode_block = BasicDecode.subst(iop)
254    exec_output = CP0Execute.subst(iop)
255}};
256def format CP0TLB(code, *flags) {{
257    flags += ('IsNonSpeculative', )
258    iop = InstObjParams(name, Name, 'CP0Control', code, flags)
259    header_output = BasicDeclare.subst(iop)
260    decoder_output = BasicConstructor.subst(iop)
261    decode_block = BasicDecode.subst(iop)
262    exec_output = ControlTLBExecute.subst(iop)
263}};
264def format CP1Control(code, *flags) {{
265    flags += ('IsNonSpeculative', )
266    iop = InstObjParams(name, Name, 'CP1Control', code, flags)
267    header_output = BasicDeclare.subst(iop)
268    decoder_output = BasicConstructor.subst(iop)
269    decode_block = BasicDecode.subst(iop)
270    exec_output = CP1Execute.subst(iop)
271}};
272
273
274