control.isa (12234:78ece221f9f5) control.isa (12616:4b463b4dc098)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2007 MIPS Technologies, Inc.
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Korey Sewell
30// Jaidev Patwardhan
31
32////////////////////////////////////////////////////////////////////
33//
34// Coprocessor instructions
35//
36
37//Outputs to decoder.hh
38output header {{
39
40 class CP0Control : public MipsStaticInst
41 {
42 protected:
43
44 /// Constructor
45 CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
46 MipsStaticInst(mnem, _machInst, __opClass)
47 {
48 }
49
1// -*- mode:c++ -*-
2
3// Copyright (c) 2007 MIPS Technologies, Inc.
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Korey Sewell
30// Jaidev Patwardhan
31
32////////////////////////////////////////////////////////////////////
33//
34// Coprocessor instructions
35//
36
37//Outputs to decoder.hh
38output header {{
39
40 class CP0Control : public MipsStaticInst
41 {
42 protected:
43
44 /// Constructor
45 CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
46 MipsStaticInst(mnem, _machInst, __opClass)
47 {
48 }
49
50 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
50 std::string generateDisassembly(
51 Addr pc, const SymbolTable *symtab) const override;
51 };
52 class CP0TLB : public MipsStaticInst
53 {
54 protected:
55
56 /// Constructor
57 CP0TLB(const char *mnem, MachInst _machInst, OpClass __opClass) :
58 MipsStaticInst(mnem, _machInst, __opClass)
59 {
60 }
61
52 };
53 class CP0TLB : public MipsStaticInst
54 {
55 protected:
56
57 /// Constructor
58 CP0TLB(const char *mnem, MachInst _machInst, OpClass __opClass) :
59 MipsStaticInst(mnem, _machInst, __opClass)
60 {
61 }
62
62 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
63 std::string generateDisassembly(
64 Addr pc, const SymbolTable *symtab) const override;
63 };
64
65
66 class CP1Control : public MipsStaticInst
67 {
68 protected:
69
70 /// Constructor
71 CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
72 MipsStaticInst(mnem, _machInst, __opClass)
73 {
74 }
75
65 };
66
67
68 class CP1Control : public MipsStaticInst
69 {
70 protected:
71
72 /// Constructor
73 CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
74 MipsStaticInst(mnem, _machInst, __opClass)
75 {
76 }
77
76 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
78 std::string generateDisassembly(
79 Addr pc, const SymbolTable *symtab) const override;
77 };
78
79}};
80
81// Basic instruction class execute method template.
82def template CP0Execute {{
83 Fault %(class_name)s::execute(
84 ExecContext *xc, Trace::InstRecord *traceData) const
85 {
86 Fault fault = NoFault;
87 %(op_decl)s;
88 %(op_rd)s;
89
90 if (isCoprocessorEnabled(xc, 0)) {
91 %(code)s;
92
93 if(fault == NoFault)
94 {
95 %(op_wb)s;
96 }
97 } else {
98 fault = std::make_shared<CoprocessorUnusableFault>(0);
99 }
100 return fault;
101 }
102}};
103
104def template CP1Execute {{
105 Fault %(class_name)s::execute(
106 ExecContext *xc, Trace::InstRecord *traceData) const
107 {
108 Fault fault = NoFault;
109 %(op_decl)s;
110 %(op_rd)s;
111
112 if (isCoprocessorEnabled(xc, 1)) {
113 %(code)s;
114 } else {
115 fault = std::make_shared<CoprocessorUnusableFault>(1);
116 }
117
118 if(fault == NoFault)
119 {
120 %(op_wb)s;
121 }
122 return fault;
123 }
124}};
125// Basic instruction class execute method template.
126def template ControlTLBExecute {{
127 Fault %(class_name)s::execute(
128 ExecContext *xc, Trace::InstRecord *traceData) const
129 {
130 Fault fault = NoFault;
131 %(op_decl)s;
132 %(op_rd)s;
133
134 if (FullSystem) {
135 if (isCoprocessor0Enabled(xc)) {
136 if(isMMUTLB(xc)){
137 %(code)s;
138 } else {
139 fault = std::make_shared<ReservedInstructionFault>();
140 }
141 } else {
142 fault = std::make_shared<CoprocessorUnusableFault>(0);
143 }
144 } else { // Syscall Emulation Mode - No TLB Instructions
145 fault = std::make_shared<ReservedInstructionFault>();
146 }
147
148 if (fault == NoFault) {
149 %(op_wb)s;
150 }
151 return fault;
152 }
153}};
154
155//Outputs to decoder.cc
156output decoder {{
157 std::string CP0Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
158 {
159 std::stringstream ss;
160 ccprintf(ss, "%-10s r%d, %d, %d", mnemonic, RT, RD, SEL);
161 return ss.str();
162 }
163 std::string CP0TLB::generateDisassembly(Addr pc, const SymbolTable *symtab) const
164 {
165 std::stringstream ss;
166 ccprintf(ss, "%-10s r%d, %d, %d", mnemonic, RT, RD, SEL);
167 return ss.str();
168 }
169 std::string CP1Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
170 {
171 std::stringstream ss;
172 ccprintf(ss, "%-10s r%d, f%d", mnemonic, RT, FS);
173 return ss.str();
174 }
175
176}};
177
178output header {{
179 bool isCoprocessorEnabled(ExecContext *xc, unsigned cop_num);
180
181 bool isMMUTLB(ExecContext *xc);
182
183}};
184
185output exec {{
186 bool
187 isCoprocessorEnabled(ExecContext *xc, unsigned cop_num)
188 {
189 if (!FullSystem)
190 return true;
191
192 MiscReg Stat = xc->readMiscReg(MISCREG_STATUS);
193 if (cop_num == 0) {
194 MiscReg Dbg = xc->readMiscReg(MISCREG_DEBUG);
195 // In Stat, EXL, ERL or CU0 set, CP0 accessible
196 // In Dbg, DM bit set, CP0 accessible
197 // In Stat, KSU = 0, kernel mode is base mode
198 return (Stat & 0x10000006) ||
199 (Dbg & 0x40000000) ||
200 !(Stat & 0x00000018);
201 } else if (cop_num < 4) {
202 return Stat & (0x10000000 << cop_num); // CU is reset
203 } else {
204 panic("Invalid Coprocessor Number Specified");
205 }
206 }
207
208 bool inline
209 isCoprocessor0Enabled(ExecContext *xc)
210 {
211 if (FullSystem) {
212 MiscReg Stat = xc->readMiscReg(MISCREG_STATUS);
213 MiscReg Dbg = xc->readMiscReg(MISCREG_DEBUG);
214 // In Stat, EXL, ERL or CU0 set, CP0 accessible
215 // In Dbg, DM bit set, CP0 accessible
216 // In Stat KSU = 0, kernel mode is base mode
217 return (Stat & 0x10000006) || (Dbg & 0x40000000) ||
218 !(Stat & 0x00000018);
219 } else {
220 return true;
221 }
222 }
223
224 bool
225 isMMUTLB(ExecContext *xc)
226 {
227 MiscReg Config = xc->readMiscReg(MISCREG_CONFIG);
228 return FullSystem && (Config & 0x380) == 0x80;
229 }
230}};
231
232def format CP0Control(code, *flags) {{
233 flags += ('IsNonSpeculative', )
234 iop = InstObjParams(name, Name, 'CP0Control', code, flags)
235 header_output = BasicDeclare.subst(iop)
236 decoder_output = BasicConstructor.subst(iop)
237 decode_block = BasicDecode.subst(iop)
238 exec_output = CP0Execute.subst(iop)
239}};
240def format CP0TLB(code, *flags) {{
241 flags += ('IsNonSpeculative', )
242 iop = InstObjParams(name, Name, 'CP0Control', code, flags)
243 header_output = BasicDeclare.subst(iop)
244 decoder_output = BasicConstructor.subst(iop)
245 decode_block = BasicDecode.subst(iop)
246 exec_output = ControlTLBExecute.subst(iop)
247}};
248def format CP1Control(code, *flags) {{
249 flags += ('IsNonSpeculative', )
250 iop = InstObjParams(name, Name, 'CP1Control', code, flags)
251 header_output = BasicDeclare.subst(iop)
252 decoder_output = BasicConstructor.subst(iop)
253 decode_block = BasicDecode.subst(iop)
254 exec_output = CP1Execute.subst(iop)
255}};
256
257
80 };
81
82}};
83
84// Basic instruction class execute method template.
85def template CP0Execute {{
86 Fault %(class_name)s::execute(
87 ExecContext *xc, Trace::InstRecord *traceData) const
88 {
89 Fault fault = NoFault;
90 %(op_decl)s;
91 %(op_rd)s;
92
93 if (isCoprocessorEnabled(xc, 0)) {
94 %(code)s;
95
96 if(fault == NoFault)
97 {
98 %(op_wb)s;
99 }
100 } else {
101 fault = std::make_shared<CoprocessorUnusableFault>(0);
102 }
103 return fault;
104 }
105}};
106
107def template CP1Execute {{
108 Fault %(class_name)s::execute(
109 ExecContext *xc, Trace::InstRecord *traceData) const
110 {
111 Fault fault = NoFault;
112 %(op_decl)s;
113 %(op_rd)s;
114
115 if (isCoprocessorEnabled(xc, 1)) {
116 %(code)s;
117 } else {
118 fault = std::make_shared<CoprocessorUnusableFault>(1);
119 }
120
121 if(fault == NoFault)
122 {
123 %(op_wb)s;
124 }
125 return fault;
126 }
127}};
128// Basic instruction class execute method template.
129def template ControlTLBExecute {{
130 Fault %(class_name)s::execute(
131 ExecContext *xc, Trace::InstRecord *traceData) const
132 {
133 Fault fault = NoFault;
134 %(op_decl)s;
135 %(op_rd)s;
136
137 if (FullSystem) {
138 if (isCoprocessor0Enabled(xc)) {
139 if(isMMUTLB(xc)){
140 %(code)s;
141 } else {
142 fault = std::make_shared<ReservedInstructionFault>();
143 }
144 } else {
145 fault = std::make_shared<CoprocessorUnusableFault>(0);
146 }
147 } else { // Syscall Emulation Mode - No TLB Instructions
148 fault = std::make_shared<ReservedInstructionFault>();
149 }
150
151 if (fault == NoFault) {
152 %(op_wb)s;
153 }
154 return fault;
155 }
156}};
157
158//Outputs to decoder.cc
159output decoder {{
160 std::string CP0Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
161 {
162 std::stringstream ss;
163 ccprintf(ss, "%-10s r%d, %d, %d", mnemonic, RT, RD, SEL);
164 return ss.str();
165 }
166 std::string CP0TLB::generateDisassembly(Addr pc, const SymbolTable *symtab) const
167 {
168 std::stringstream ss;
169 ccprintf(ss, "%-10s r%d, %d, %d", mnemonic, RT, RD, SEL);
170 return ss.str();
171 }
172 std::string CP1Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
173 {
174 std::stringstream ss;
175 ccprintf(ss, "%-10s r%d, f%d", mnemonic, RT, FS);
176 return ss.str();
177 }
178
179}};
180
181output header {{
182 bool isCoprocessorEnabled(ExecContext *xc, unsigned cop_num);
183
184 bool isMMUTLB(ExecContext *xc);
185
186}};
187
188output exec {{
189 bool
190 isCoprocessorEnabled(ExecContext *xc, unsigned cop_num)
191 {
192 if (!FullSystem)
193 return true;
194
195 MiscReg Stat = xc->readMiscReg(MISCREG_STATUS);
196 if (cop_num == 0) {
197 MiscReg Dbg = xc->readMiscReg(MISCREG_DEBUG);
198 // In Stat, EXL, ERL or CU0 set, CP0 accessible
199 // In Dbg, DM bit set, CP0 accessible
200 // In Stat, KSU = 0, kernel mode is base mode
201 return (Stat & 0x10000006) ||
202 (Dbg & 0x40000000) ||
203 !(Stat & 0x00000018);
204 } else if (cop_num < 4) {
205 return Stat & (0x10000000 << cop_num); // CU is reset
206 } else {
207 panic("Invalid Coprocessor Number Specified");
208 }
209 }
210
211 bool inline
212 isCoprocessor0Enabled(ExecContext *xc)
213 {
214 if (FullSystem) {
215 MiscReg Stat = xc->readMiscReg(MISCREG_STATUS);
216 MiscReg Dbg = xc->readMiscReg(MISCREG_DEBUG);
217 // In Stat, EXL, ERL or CU0 set, CP0 accessible
218 // In Dbg, DM bit set, CP0 accessible
219 // In Stat KSU = 0, kernel mode is base mode
220 return (Stat & 0x10000006) || (Dbg & 0x40000000) ||
221 !(Stat & 0x00000018);
222 } else {
223 return true;
224 }
225 }
226
227 bool
228 isMMUTLB(ExecContext *xc)
229 {
230 MiscReg Config = xc->readMiscReg(MISCREG_CONFIG);
231 return FullSystem && (Config & 0x380) == 0x80;
232 }
233}};
234
235def format CP0Control(code, *flags) {{
236 flags += ('IsNonSpeculative', )
237 iop = InstObjParams(name, Name, 'CP0Control', code, flags)
238 header_output = BasicDeclare.subst(iop)
239 decoder_output = BasicConstructor.subst(iop)
240 decode_block = BasicDecode.subst(iop)
241 exec_output = CP0Execute.subst(iop)
242}};
243def format CP0TLB(code, *flags) {{
244 flags += ('IsNonSpeculative', )
245 iop = InstObjParams(name, Name, 'CP0Control', code, flags)
246 header_output = BasicDeclare.subst(iop)
247 decoder_output = BasicConstructor.subst(iop)
248 decode_block = BasicDecode.subst(iop)
249 exec_output = ControlTLBExecute.subst(iop)
250}};
251def format CP1Control(code, *flags) {{
252 flags += ('IsNonSpeculative', )
253 iop = InstObjParams(name, Name, 'CP1Control', code, flags)
254 header_output = BasicDeclare.subst(iop)
255 decoder_output = BasicConstructor.subst(iop)
256 decode_block = BasicDecode.subst(iop)
257 exec_output = CP1Execute.subst(iop)
258}};
259
260