1671b9ad71a8276a2a4a53733989c187c0062298
[gem5.git] / src / arch / mips / isa / formats / control.isa
1 // -*- mode:c++ -*-
2
3 // Copyright \eN) 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 \eN) <Publication Year> Copyright Owner), and (3)
18 // the name of MIPS Technologies, Inc. (\e$(B!H\e(BMIPS\e$(B!I\e(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 \e$(B!H\e(BAS IS.\e$(B!I\e(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
44 output 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.
88 def 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
109 def 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.
130 def 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
161 output 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
183 output 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
248 def 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 }};
256 def 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 }};
264 def 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