control.isa revision 13615:5cc9363f5ab7
12810SN/A// -*- mode:c++ -*-
22810SN/A
32810SN/A// Copyright (c) 2007 MIPS Technologies, Inc.
42810SN/A// All rights reserved.
52810SN/A//
62810SN/A// Redistribution and use in source and binary forms, with or without
72810SN/A// modification, are permitted provided that the following conditions are
82810SN/A// met: redistributions of source code must retain the above copyright
92810SN/A// notice, this list of conditions and the following disclaimer;
102810SN/A// redistributions in binary form must reproduce the above copyright
112810SN/A// notice, this list of conditions and the following disclaimer in the
122810SN/A// documentation and/or other materials provided with the distribution;
132810SN/A// neither the name of the copyright holders nor the names of its
142810SN/A// contributors may be used to endorse or promote products derived from
152810SN/A// this software without specific prior written permission.
162810SN/A//
172810SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182810SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192810SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202810SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212810SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222810SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232810SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242810SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252810SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262810SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272810SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282810SN/A//
292810SN/A// Authors: Korey Sewell
302810SN/A//          Jaidev Patwardhan
312810SN/A
322810SN/A////////////////////////////////////////////////////////////////////
332810SN/A//
342810SN/A// Coprocessor instructions
352810SN/A//
362810SN/A
372810SN/A//Outputs to decoder.hh
382810SN/Aoutput header {{
392810SN/A
402810SN/A        class CP0Control : public MipsStaticInst
418229Snate@binkert.org        {
428229Snate@binkert.org                protected:
432810SN/A
442810SN/A                /// Constructor
452810SN/A                CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
462810SN/A                           MipsStaticInst(mnem, _machInst, __opClass)
472810SN/A                {
482810SN/A                }
492810SN/A
502810SN/A                std::string generateDisassembly(
512810SN/A                        Addr pc, const SymbolTable *symtab) const override;
522810SN/A        };
532810SN/A        class CP0TLB : public MipsStaticInst
542810SN/A        {
552810SN/A                protected:
562810SN/A
572810SN/A                /// Constructor
582810SN/A                CP0TLB(const char *mnem, MachInst _machInst, OpClass __opClass) :
592810SN/A                           MipsStaticInst(mnem, _machInst, __opClass)
602810SN/A                {
612810SN/A                }
622810SN/A
632810SN/A                std::string generateDisassembly(
642810SN/A                        Addr pc, const SymbolTable *symtab) const override;
652810SN/A        };
662810SN/A
676978SLisa.Hsu@amd.com
686978SLisa.Hsu@amd.com        class CP1Control : public MipsStaticInst
696978SLisa.Hsu@amd.com        {
702810SN/A                protected:
712810SN/A
722810SN/A                /// Constructor
732810SN/A                CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
742810SN/A                           MipsStaticInst(mnem, _machInst, __opClass)
752810SN/A                {
762810SN/A                }
775999Snate@binkert.org
782810SN/A                std::string generateDisassembly(
795999Snate@binkert.org                        Addr pc, const SymbolTable *symtab) const override;
802810SN/A        };
812810SN/A
825999Snate@binkert.org}};
832810SN/A
842810SN/A// Basic instruction class execute method template.
852810SN/Adef template CP0Execute {{
862810SN/A        Fault %(class_name)s::execute(
872810SN/A            ExecContext *xc, Trace::InstRecord *traceData) const
882810SN/A        {
895999Snate@binkert.org                Fault fault = NoFault;
902810SN/A                %(op_decl)s;
912810SN/A                %(op_rd)s;
922810SN/A
932810SN/A                if (isCoprocessorEnabled(xc, 0)) {
942810SN/A                    %(code)s;
952810SN/A
962810SN/A                    if(fault == NoFault)
972810SN/A                    {
985999Snate@binkert.org                        %(op_wb)s;
996978SLisa.Hsu@amd.com                    }
1008833Sdam.sunwoo@arm.com                } else {
1016978SLisa.Hsu@amd.com                    fault = std::make_shared<CoprocessorUnusableFault>(0);
1026978SLisa.Hsu@amd.com                }
1038833Sdam.sunwoo@arm.com                return fault;
1046978SLisa.Hsu@amd.com        }
1056978SLisa.Hsu@amd.com}};
1062810SN/A
1072810SN/Adef template CP1Execute {{
1082810SN/A        Fault %(class_name)s::execute(
1092810SN/A            ExecContext *xc, Trace::InstRecord *traceData) const
1102810SN/A        {
1112810SN/A                Fault fault = NoFault;
1122810SN/A                %(op_decl)s;
1132810SN/A                %(op_rd)s;
1142810SN/A
1152810SN/A                if (isCoprocessorEnabled(xc, 1)) {
1162810SN/A                    %(code)s;
1172810SN/A                } else {
1182810SN/A                    fault = std::make_shared<CoprocessorUnusableFault>(1);
1192810SN/A                }
1202810SN/A
1212810SN/A                if(fault == NoFault)
1222810SN/A                {
1232810SN/A                    %(op_wb)s;
1242810SN/A                }
1252810SN/A                return fault;
1262810SN/A        }
1272810SN/A}};
1282810SN/A// Basic instruction class execute method template.
1292810SN/Adef template ControlTLBExecute {{
1302810SN/A        Fault %(class_name)s::execute(
1312810SN/A            ExecContext *xc, Trace::InstRecord *traceData) const
1322810SN/A        {
1332810SN/A            Fault fault = NoFault;
1342810SN/A            %(op_decl)s;
1352810SN/A            %(op_rd)s;
1362810SN/A
1372810SN/A            if (FullSystem) {
1382810SN/A                if (isCoprocessor0Enabled(xc)) {
1392810SN/A                    if(isMMUTLB(xc)){
1402810SN/A                        %(code)s;
1412810SN/A                    } else {
1422810SN/A                        fault = std::make_shared<ReservedInstructionFault>();
1432810SN/A                    }
1447612SGene.Wu@arm.com                } else {
1457612SGene.Wu@arm.com                    fault = std::make_shared<CoprocessorUnusableFault>(0);
1467612SGene.Wu@arm.com                }
1477612SGene.Wu@arm.com            } else { // Syscall Emulation Mode - No TLB Instructions
1487612SGene.Wu@arm.com                fault = std::make_shared<ReservedInstructionFault>();
1497612SGene.Wu@arm.com            }
1502810SN/A
1512810SN/A            if (fault == NoFault) {
1522810SN/A                %(op_wb)s;
1532810SN/A            }
1542810SN/A            return fault;
1552810SN/A        }
1562810SN/A}};
1572810SN/A
1582810SN/A//Outputs to decoder.cc
1592810SN/Aoutput decoder {{
1602810SN/A        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            RegVal Stat = xc->readMiscReg(MISCREG_STATUS);
196            if (cop_num == 0) {
197                RegVal 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                RegVal Stat = xc->readMiscReg(MISCREG_STATUS);
216                RegVal 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            RegVal 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
261