control.isa revision 5268:5bfc53fe60e7
15323Sgblack@eecs.umich.edu// -*- mode:c++ -*-
22934Sktlim@umich.edu
32934Sktlim@umich.edu// Copyright (c) 2007 MIPS Technologies, Inc.
42934Sktlim@umich.edu// All rights reserved.
52934Sktlim@umich.edu//
62934Sktlim@umich.edu// Redistribution and use in source and binary forms, with or without
72934Sktlim@umich.edu// modification, are permitted provided that the following conditions are
82934Sktlim@umich.edu// met: redistributions of source code must retain the above copyright
92934Sktlim@umich.edu// notice, this list of conditions and the following disclaimer;
102934Sktlim@umich.edu// redistributions in binary form must reproduce the above copyright
112934Sktlim@umich.edu// notice, this list of conditions and the following disclaimer in the
122934Sktlim@umich.edu// documentation and/or other materials provided with the distribution;
132934Sktlim@umich.edu// neither the name of the copyright holders nor the names of its
142934Sktlim@umich.edu// contributors may be used to endorse or promote products derived from
152934Sktlim@umich.edu// this software without specific prior written permission.
162934Sktlim@umich.edu//
172934Sktlim@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182934Sktlim@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192934Sktlim@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202934Sktlim@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212934Sktlim@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222934Sktlim@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232934Sktlim@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242934Sktlim@umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252934Sktlim@umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262934Sktlim@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272934Sktlim@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282934Sktlim@umich.edu//
292934Sktlim@umich.edu// Authors: Korey Sewell
302969Sktlim@umich.edu//          Jaidev Patwardhan
312934Sktlim@umich.edu
322995Ssaidi@eecs.umich.edu////////////////////////////////////////////////////////////////////
332934Sktlim@umich.edu//
342934Sktlim@umich.edu// Coprocessor instructions
352934Sktlim@umich.edu//
362934Sktlim@umich.edu
372934Sktlim@umich.edu//Outputs to decoder.hh
382934Sktlim@umich.eduoutput header {{
392934Sktlim@umich.edu
402934Sktlim@umich.edu        class CP0Control : public MipsStaticInst
414520Ssaidi@eecs.umich.edu        {
424520Ssaidi@eecs.umich.edu                protected:
434982Ssaidi@eecs.umich.edu
444520Ssaidi@eecs.umich.edu                /// Constructor
454520Ssaidi@eecs.umich.edu                CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
462934Sktlim@umich.edu                           MipsStaticInst(mnem, _machInst, __opClass)
472934Sktlim@umich.edu                {
483005Sstever@eecs.umich.edu                }
493005Sstever@eecs.umich.edu
503304Sstever@eecs.umich.edu                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
512995Ssaidi@eecs.umich.edu        };
522934Sktlim@umich.edu        class CP0TLB : public MipsStaticInst
532934Sktlim@umich.edu        {
544965Ssaidi@eecs.umich.edu                protected:
555266Sksewell@umich.edu
562934Sktlim@umich.edu                /// Constructor
572934Sktlim@umich.edu                CP0TLB(const char *mnem, MachInst _machInst, OpClass __opClass) :
582934Sktlim@umich.edu                           MipsStaticInst(mnem, _machInst, __opClass)
592934Sktlim@umich.edu                {
602934Sktlim@umich.edu                }
612995Ssaidi@eecs.umich.edu
622934Sktlim@umich.edu                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
632934Sktlim@umich.edu        };
642934Sktlim@umich.edu
652934Sktlim@umich.edu
662934Sktlim@umich.edu        class CP1Control : public MipsStaticInst
672995Ssaidi@eecs.umich.edu        {
682934Sktlim@umich.edu                protected:
692934Sktlim@umich.edu
702953Sktlim@umich.edu                /// Constructor
715478Snate@binkert.org                CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
722934Sktlim@umich.edu                           MipsStaticInst(mnem, _machInst, __opClass)
733449Shsul@eecs.umich.edu                {
742934Sktlim@umich.edu                }
752934Sktlim@umich.edu
762934Sktlim@umich.edu                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
772934Sktlim@umich.edu        };
782934Sktlim@umich.edu
793584Ssaidi@eecs.umich.edu}};
804486Sbinkertn@umich.edu
814486Sbinkertn@umich.edu// Basic instruction class execute method template.
824486Sbinkertn@umich.edudef template CP0Execute {{
834486Sbinkertn@umich.edu        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
844486Sbinkertn@umich.edu        {
854486Sbinkertn@umich.edu                Fault fault = NoFault;
864486Sbinkertn@umich.edu                %(op_decl)s;
873584Ssaidi@eecs.umich.edu                %(op_rd)s;
883584Ssaidi@eecs.umich.edu
893584Ssaidi@eecs.umich.edu                if (isCoprocessorEnabled(xc, 0)) {
903584Ssaidi@eecs.umich.edu                    %(code)s;
913584Ssaidi@eecs.umich.edu                } else {
923743Sgblack@eecs.umich.edu                    fault = new CoprocessorUnusableFault(0);
933584Ssaidi@eecs.umich.edu                }
944972Ssaidi@eecs.umich.edu
953743Sgblack@eecs.umich.edu                if(fault == NoFault)
964104Ssaidi@eecs.umich.edu                {
973743Sgblack@eecs.umich.edu                    %(op_wb)s;
983823Ssaidi@eecs.umich.edu                }
993814Ssaidi@eecs.umich.edu                return fault;
1003743Sgblack@eecs.umich.edu        }
1013743Sgblack@eecs.umich.edu}};
1023584Ssaidi@eecs.umich.edu
1033814Ssaidi@eecs.umich.edudef template CP1Execute {{
1043584Ssaidi@eecs.umich.edu        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
1053745Sgblack@eecs.umich.edu        {
1063745Sgblack@eecs.umich.edu                Fault fault = NoFault;
1073745Sgblack@eecs.umich.edu                %(op_decl)s;
1083584Ssaidi@eecs.umich.edu                %(op_rd)s;
1093898Ssaidi@eecs.umich.edu
1103898Ssaidi@eecs.umich.edu                if (isCoprocessorEnabled(xc, 1)) {
1113898Ssaidi@eecs.umich.edu                    %(code)s;
1124103Ssaidi@eecs.umich.edu                } else {
1134103Ssaidi@eecs.umich.edu                    fault = new CoprocessorUnusableFault(1);
1144103Ssaidi@eecs.umich.edu                }
1153745Sgblack@eecs.umich.edu
1163745Sgblack@eecs.umich.edu                if(fault == NoFault)
1173745Sgblack@eecs.umich.edu                {
1183584Ssaidi@eecs.umich.edu                    %(op_wb)s;
1193584Ssaidi@eecs.umich.edu                }
1203584Ssaidi@eecs.umich.edu                return fault;
1215222Sksewell@umich.edu        }
1225222Sksewell@umich.edu}};
1235222Sksewell@umich.edu// Basic instruction class execute method template.
1245222Sksewell@umich.edudef template ControlTLBExecute {{
1255222Sksewell@umich.edu        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
1265222Sksewell@umich.edu        {
1275222Sksewell@umich.edu                Fault fault = NoFault;
1285222Sksewell@umich.edu                %(op_decl)s;
1295222Sksewell@umich.edu                %(op_rd)s;
1305222Sksewell@umich.edu
1315222Sksewell@umich.edu#if FULL_SYSTEM
1325222Sksewell@umich.edu                if (isCoprocessor0Enabled(xc)) {
1335222Sksewell@umich.edu                  if(isMMUTLB(xc)){
1345222Sksewell@umich.edu                      %(code)s;
1355222Sksewell@umich.edu                  } else {
1365222Sksewell@umich.edu                    fault = new ReservedInstructionFault();
1375222Sksewell@umich.edu                  }
1385222Sksewell@umich.edu                } else {
1395222Sksewell@umich.edu                  fault = new CoprocessorUnusableFault(0);
1405222Sksewell@umich.edu                }
1415222Sksewell@umich.edu#else // Syscall Emulation Mode - No TLB Instructions
1425222Sksewell@umich.edu                fault = new ReservedInstructionFault();
1435222Sksewell@umich.edu#endif
1445222Sksewell@umich.edu
1455222Sksewell@umich.edu                if(fault == NoFault)
1465222Sksewell@umich.edu                {
1475222Sksewell@umich.edu                    %(op_wb)s;
1485222Sksewell@umich.edu                }
1495222Sksewell@umich.edu                return fault;
1505222Sksewell@umich.edu
1515478Snate@binkert.org        }
1525222Sksewell@umich.edu}};
1535222Sksewell@umich.edu
1545222Sksewell@umich.edu//Outputs to decoder.cc
1555222Sksewell@umich.eduoutput decoder {{
1565222Sksewell@umich.edu        std::string CP0Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1575222Sksewell@umich.edu        {
1585323Sgblack@eecs.umich.edu            std::stringstream ss;
1595357Sgblack@eecs.umich.edu            ccprintf(ss, "%-10s r%d, %d, %d", mnemonic, RT, RD, SEL);
1605323Sgblack@eecs.umich.edu            return ss.str();
1615323Sgblack@eecs.umich.edu        }
1625613Sgblack@eecs.umich.edu        std::string CP0TLB::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1635613Sgblack@eecs.umich.edu        {
1645613Sgblack@eecs.umich.edu            std::stringstream ss;
1655613Sgblack@eecs.umich.edu            ccprintf(ss, "%-10s r%d, %d, %d", mnemonic, RT, RD, SEL);
1665133Sgblack@eecs.umich.edu            return ss.str();
1675133Sgblack@eecs.umich.edu        }
1685133Sgblack@eecs.umich.edu        std::string CP1Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1695133Sgblack@eecs.umich.edu        {
1705133Sgblack@eecs.umich.edu            std::stringstream ss;
1715133Sgblack@eecs.umich.edu            ccprintf(ss, "%-10s r%d, f%d", mnemonic, RT, FS);
1725323Sgblack@eecs.umich.edu            return ss.str();
1735450Sgblack@eecs.umich.edu        }
1745133Sgblack@eecs.umich.edu
1755133Sgblack@eecs.umich.edu}};
1765613Sgblack@eecs.umich.edu
1775613Sgblack@eecs.umich.eduoutput exec {{
1785613Sgblack@eecs.umich.edu        bool isCoprocessorEnabled(%(CPU_exec_context)s *xc, unsigned cop_num)
1795613Sgblack@eecs.umich.edu        {
1805613Sgblack@eecs.umich.edu#if !FULL_SYSTEM
1815613Sgblack@eecs.umich.edu            return true;
1825613Sgblack@eecs.umich.edu#else
1835638Sgblack@eecs.umich.edu          MiscReg Stat = xc->readMiscReg(MipsISA::Status);
1845613Sgblack@eecs.umich.edu          switch(cop_num)
1855613Sgblack@eecs.umich.edu            {
1865613Sgblack@eecs.umich.edu            case 0:
1875613Sgblack@eecs.umich.edu              {
1885615Sgblack@eecs.umich.edu                  MiscReg Dbg = xc->readMiscReg(MipsISA::Debug);
1895615Sgblack@eecs.umich.edu                  if((Stat & 0x10000006) == 0  // EXL, ERL or CU0 set, CP0 accessible
1905615Sgblack@eecs.umich.edu                     && (Dbg & 0x40000000) == 0 // DM bit set, CP0 accessible
1915615Sgblack@eecs.umich.edu                     && (Stat & 0x00000018) != 0) {  // KSU = 0, kernel mode is base mode
1925613Sgblack@eecs.umich.edu                      // Unable to use Status_CU0, etc directly, using bitfields & masks
1935613Sgblack@eecs.umich.edu                      return false;
1945613Sgblack@eecs.umich.edu                  }
1955613Sgblack@eecs.umich.edu
1965613Sgblack@eecs.umich.edu              }
1975613Sgblack@eecs.umich.edu              break;
1985613Sgblack@eecs.umich.edu            case 1:
1995450Sgblack@eecs.umich.edu              if((Stat & 0x20000000) == 0) // CU1 is reset
2005450Sgblack@eecs.umich.edu                return false;
2015450Sgblack@eecs.umich.edu              break;
2025450Sgblack@eecs.umich.edu            case 2:
2035450Sgblack@eecs.umich.edu              if((Stat & 0x40000000) == 0) // CU2 is reset
2045450Sgblack@eecs.umich.edu                return false;
2055450Sgblack@eecs.umich.edu              break;
2065450Sgblack@eecs.umich.edu            case 3:
2075450Sgblack@eecs.umich.edu              if((Stat & 0x80000000) == 0) // CU3 is reset
2085450Sgblack@eecs.umich.edu                return false;
2095450Sgblack@eecs.umich.edu              break;
2105450Sgblack@eecs.umich.edu            default: panic("Invalid Coprocessor Number Specified");
2115450Sgblack@eecs.umich.edu              break;
2125450Sgblack@eecs.umich.edu            }
2135450Sgblack@eecs.umich.edu            return true;
2145450Sgblack@eecs.umich.edu#endif
2155330Sgblack@eecs.umich.edu        }
2165416Sgblack@eecs.umich.edu        bool inline isCoprocessor0Enabled(%(CPU_exec_context)s *xc)
2175330Sgblack@eecs.umich.edu        {
2185133Sgblack@eecs.umich.edu#if FULL_SYSTEM
2195133Sgblack@eecs.umich.edu          MiscReg Stat = xc->readMiscRegNoEffect(MipsISA::Status);
2203584Ssaidi@eecs.umich.edu          MiscReg Dbg = xc->readMiscRegNoEffect(MipsISA::Debug);
2213025Ssaidi@eecs.umich.edu          if((Stat & 0x10000006) == 0  // EXL, ERL or CU0 set, CP0 accessible
2222934Sktlim@umich.edu                 && (Dbg & 0x40000000) == 0 // DM bit set, CP0 accessible
2232995Ssaidi@eecs.umich.edu                 && (Stat & 0x00000018) != 0) {  // KSU = 0, kernel mode is base mode
2242995Ssaidi@eecs.umich.edu                // Unable to use Status_CU0, etc directly, using bitfields & masks
2254981Ssaidi@eecs.umich.edu                  return false;
2264981Ssaidi@eecs.umich.edu              }
2274981Ssaidi@eecs.umich.edu#else
2284981Ssaidi@eecs.umich.edu              //printf("Syscall Emulation Mode: CP0 Enable Check defaults to TRUE\n");
2293025Ssaidi@eecs.umich.edu#endif
2303025Ssaidi@eecs.umich.edu            return true;
2313025Ssaidi@eecs.umich.edu        }
2322934Sktlim@umich.edu        bool isMMUTLB(%(CPU_exec_context)s *xc)
2332934Sktlim@umich.edu        {
2345253Sksewell@umich.edu#if FULL_SYSTEM
2355263Sksewell@umich.edu          if((xc->readMiscRegNoEffect(MipsISA::Config) & 0x00000380)==0x80)
2365253Sksewell@umich.edu            return true;
2375253Sksewell@umich.edu#endif
2385253Sksewell@umich.edu          return false;
2395253Sksewell@umich.edu        }
2405253Sksewell@umich.edu}};
2415253Sksewell@umich.edu
2425253Sksewell@umich.edudef format CP0Control(code, *flags) {{
2435253Sksewell@umich.edu    flags += ('IsNonSpeculative', )
2445253Sksewell@umich.edu    iop = InstObjParams(name, Name, 'CP0Control', code, flags)
2455253Sksewell@umich.edu    header_output = BasicDeclare.subst(iop)
2465253Sksewell@umich.edu    decoder_output = BasicConstructor.subst(iop)
2475253Sksewell@umich.edu    decode_block = BasicDecode.subst(iop)
2485253Sksewell@umich.edu    exec_output = CP0Execute.subst(iop)
2495253Sksewell@umich.edu}};
2505253Sksewell@umich.edudef format CP0TLB(code, *flags) {{
2515253Sksewell@umich.edu    flags += ('IsNonSpeculative', )
2525253Sksewell@umich.edu    iop = InstObjParams(name, Name, 'CP0Control', code, flags)
2535253Sksewell@umich.edu    header_output = BasicDeclare.subst(iop)
2545253Sksewell@umich.edu    decoder_output = BasicConstructor.subst(iop)
2555253Sksewell@umich.edu    decode_block = BasicDecode.subst(iop)
2565253Sksewell@umich.edu    exec_output = ControlTLBExecute.subst(iop)
2575253Sksewell@umich.edu}};
2585253Sksewell@umich.edudef format CP1Control(code, *flags) {{
2595253Sksewell@umich.edu    flags += ('IsNonSpeculative', )
2605253Sksewell@umich.edu    iop = InstObjParams(name, Name, 'CP1Control', code, flags)
2615253Sksewell@umich.edu    header_output = BasicDeclare.subst(iop)
2625253Sksewell@umich.edu    decoder_output = BasicConstructor.subst(iop)
2635253Sksewell@umich.edu    decode_block = BasicDecode.subst(iop)
2645253Sksewell@umich.edu    exec_output = CP1Execute.subst(iop)
2655253Sksewell@umich.edu}};
2665253Sksewell@umich.edu
2675253Sksewell@umich.edu
2685253Sksewell@umich.edu