12686Sksewell@umich.edu// -*- mode:c++ -*- 22686Sksewell@umich.edu 35268Sksewell@umich.edu// Copyright (c) 2007 MIPS Technologies, Inc. 45268Sksewell@umich.edu// All rights reserved. 55268Sksewell@umich.edu// 65268Sksewell@umich.edu// Redistribution and use in source and binary forms, with or without 75268Sksewell@umich.edu// modification, are permitted provided that the following conditions are 85268Sksewell@umich.edu// met: redistributions of source code must retain the above copyright 95268Sksewell@umich.edu// notice, this list of conditions and the following disclaimer; 105268Sksewell@umich.edu// redistributions in binary form must reproduce the above copyright 115268Sksewell@umich.edu// notice, this list of conditions and the following disclaimer in the 125268Sksewell@umich.edu// documentation and/or other materials provided with the distribution; 135268Sksewell@umich.edu// neither the name of the copyright holders nor the names of its 145268Sksewell@umich.edu// contributors may be used to endorse or promote products derived from 155268Sksewell@umich.edu// this software without specific prior written permission. 165268Sksewell@umich.edu// 175268Sksewell@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 185268Sksewell@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 195268Sksewell@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 205268Sksewell@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 215268Sksewell@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 225268Sksewell@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 235268Sksewell@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 245268Sksewell@umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 255268Sksewell@umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 265268Sksewell@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 275268Sksewell@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 285268Sksewell@umich.edu// 295268Sksewell@umich.edu// Authors: Korey Sewell 305268Sksewell@umich.edu// Jaidev Patwardhan 312706Sksewell@umich.edu 322686Sksewell@umich.edu//////////////////////////////////////////////////////////////////// 332686Sksewell@umich.edu// 344661Sksewell@umich.edu// Coprocessor instructions 352686Sksewell@umich.edu// 362686Sksewell@umich.edu 372686Sksewell@umich.edu//Outputs to decoder.hh 382686Sksewell@umich.eduoutput header {{ 392686Sksewell@umich.edu 404661Sksewell@umich.edu class CP0Control : public MipsStaticInst 412686Sksewell@umich.edu { 422686Sksewell@umich.edu protected: 432686Sksewell@umich.edu 442686Sksewell@umich.edu /// Constructor 454661Sksewell@umich.edu CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) : 462686Sksewell@umich.edu MipsStaticInst(mnem, _machInst, __opClass) 472686Sksewell@umich.edu { 482686Sksewell@umich.edu } 492686Sksewell@umich.edu 5012616Sgabeblack@google.com std::string generateDisassembly( 5112616Sgabeblack@google.com Addr pc, const SymbolTable *symtab) const override; 522686Sksewell@umich.edu }; 535222Sksewell@umich.edu class CP0TLB : public MipsStaticInst 545222Sksewell@umich.edu { 555222Sksewell@umich.edu protected: 565222Sksewell@umich.edu 575222Sksewell@umich.edu /// Constructor 585222Sksewell@umich.edu CP0TLB(const char *mnem, MachInst _machInst, OpClass __opClass) : 595222Sksewell@umich.edu MipsStaticInst(mnem, _machInst, __opClass) 605222Sksewell@umich.edu { 615222Sksewell@umich.edu } 625222Sksewell@umich.edu 6312616Sgabeblack@google.com std::string generateDisassembly( 6412616Sgabeblack@google.com Addr pc, const SymbolTable *symtab) const override; 655222Sksewell@umich.edu }; 665222Sksewell@umich.edu 672686Sksewell@umich.edu 684661Sksewell@umich.edu class CP1Control : public MipsStaticInst 692686Sksewell@umich.edu { 702686Sksewell@umich.edu protected: 712686Sksewell@umich.edu 722686Sksewell@umich.edu /// Constructor 732686Sksewell@umich.edu CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) : 744661Sksewell@umich.edu MipsStaticInst(mnem, _machInst, __opClass) 752686Sksewell@umich.edu { 762686Sksewell@umich.edu } 772686Sksewell@umich.edu 7812616Sgabeblack@google.com std::string generateDisassembly( 7912616Sgabeblack@google.com Addr pc, const SymbolTable *symtab) const override; 802686Sksewell@umich.edu }; 812686Sksewell@umich.edu 822686Sksewell@umich.edu}}; 832686Sksewell@umich.edu 844661Sksewell@umich.edu// Basic instruction class execute method template. 855222Sksewell@umich.edudef template CP0Execute {{ 8612234Sgabeblack@google.com Fault %(class_name)s::execute( 8712234Sgabeblack@google.com ExecContext *xc, Trace::InstRecord *traceData) const 884661Sksewell@umich.edu { 894661Sksewell@umich.edu Fault fault = NoFault; 904661Sksewell@umich.edu %(op_decl)s; 914661Sksewell@umich.edu %(op_rd)s; 924661Sksewell@umich.edu 934661Sksewell@umich.edu if (isCoprocessorEnabled(xc, 0)) { 944661Sksewell@umich.edu %(code)s; 958800Sgblack@eecs.umich.edu 968800Sgblack@eecs.umich.edu if(fault == NoFault) 978800Sgblack@eecs.umich.edu { 988800Sgblack@eecs.umich.edu %(op_wb)s; 998800Sgblack@eecs.umich.edu } 1004661Sksewell@umich.edu } else { 10110474Sandreas.hansson@arm.com fault = std::make_shared<CoprocessorUnusableFault>(0); 1024661Sksewell@umich.edu } 1034661Sksewell@umich.edu return fault; 1044661Sksewell@umich.edu } 1054661Sksewell@umich.edu}}; 1064661Sksewell@umich.edu 1075222Sksewell@umich.edudef template CP1Execute {{ 10812234Sgabeblack@google.com Fault %(class_name)s::execute( 10912234Sgabeblack@google.com ExecContext *xc, Trace::InstRecord *traceData) const 1105222Sksewell@umich.edu { 1115222Sksewell@umich.edu Fault fault = NoFault; 1125222Sksewell@umich.edu %(op_decl)s; 1135222Sksewell@umich.edu %(op_rd)s; 1145222Sksewell@umich.edu 1155222Sksewell@umich.edu if (isCoprocessorEnabled(xc, 1)) { 1165222Sksewell@umich.edu %(code)s; 1175222Sksewell@umich.edu } else { 11810474Sandreas.hansson@arm.com fault = std::make_shared<CoprocessorUnusableFault>(1); 1195222Sksewell@umich.edu } 1205222Sksewell@umich.edu 1215222Sksewell@umich.edu if(fault == NoFault) 1225222Sksewell@umich.edu { 1235222Sksewell@umich.edu %(op_wb)s; 1245222Sksewell@umich.edu } 1255222Sksewell@umich.edu return fault; 1265222Sksewell@umich.edu } 1275222Sksewell@umich.edu}}; 1285222Sksewell@umich.edu// Basic instruction class execute method template. 1295222Sksewell@umich.edudef template ControlTLBExecute {{ 13012234Sgabeblack@google.com Fault %(class_name)s::execute( 13112234Sgabeblack@google.com ExecContext *xc, Trace::InstRecord *traceData) const 1325222Sksewell@umich.edu { 1338564Sgblack@eecs.umich.edu Fault fault = NoFault; 1348564Sgblack@eecs.umich.edu %(op_decl)s; 1358564Sgblack@eecs.umich.edu %(op_rd)s; 1365222Sksewell@umich.edu 1378738Sgblack@eecs.umich.edu if (FullSystem) { 1385222Sksewell@umich.edu if (isCoprocessor0Enabled(xc)) { 1398564Sgblack@eecs.umich.edu if(isMMUTLB(xc)){ 1408564Sgblack@eecs.umich.edu %(code)s; 1418564Sgblack@eecs.umich.edu } else { 14210474Sandreas.hansson@arm.com fault = std::make_shared<ReservedInstructionFault>(); 1438564Sgblack@eecs.umich.edu } 1445222Sksewell@umich.edu } else { 14510474Sandreas.hansson@arm.com fault = std::make_shared<CoprocessorUnusableFault>(0); 1465222Sksewell@umich.edu } 1478564Sgblack@eecs.umich.edu } else { // Syscall Emulation Mode - No TLB Instructions 14810474Sandreas.hansson@arm.com fault = std::make_shared<ReservedInstructionFault>(); 1498564Sgblack@eecs.umich.edu } 1505222Sksewell@umich.edu 1518564Sgblack@eecs.umich.edu if (fault == NoFault) { 1528564Sgblack@eecs.umich.edu %(op_wb)s; 1538564Sgblack@eecs.umich.edu } 1548564Sgblack@eecs.umich.edu return fault; 1555222Sksewell@umich.edu } 1565222Sksewell@umich.edu}}; 1575222Sksewell@umich.edu 1582686Sksewell@umich.edu//Outputs to decoder.cc 1592686Sksewell@umich.eduoutput decoder {{ 1602686Sksewell@umich.edu std::string CP0Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1612686Sksewell@umich.edu { 1622686Sksewell@umich.edu std::stringstream ss; 1634661Sksewell@umich.edu ccprintf(ss, "%-10s r%d, %d, %d", mnemonic, RT, RD, SEL); 1642686Sksewell@umich.edu return ss.str(); 1652686Sksewell@umich.edu } 1665222Sksewell@umich.edu std::string CP0TLB::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1675222Sksewell@umich.edu { 1685222Sksewell@umich.edu std::stringstream ss; 1695222Sksewell@umich.edu ccprintf(ss, "%-10s r%d, %d, %d", mnemonic, RT, RD, SEL); 1705222Sksewell@umich.edu return ss.str(); 1715222Sksewell@umich.edu } 1722686Sksewell@umich.edu std::string CP1Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1732686Sksewell@umich.edu { 1742686Sksewell@umich.edu std::stringstream ss; 1752686Sksewell@umich.edu ccprintf(ss, "%-10s r%d, f%d", mnemonic, RT, FS); 1762686Sksewell@umich.edu return ss.str(); 1772686Sksewell@umich.edu } 1782686Sksewell@umich.edu 1792686Sksewell@umich.edu}}; 1802686Sksewell@umich.edu 1819554Sandreas.hansson@arm.comoutput header {{ 18212234Sgabeblack@google.com bool isCoprocessorEnabled(ExecContext *xc, unsigned cop_num); 1839554Sandreas.hansson@arm.com 18412234Sgabeblack@google.com bool isMMUTLB(ExecContext *xc); 1859554Sandreas.hansson@arm.com 1869554Sandreas.hansson@arm.com}}; 1879554Sandreas.hansson@arm.com 1884661Sksewell@umich.eduoutput exec {{ 1898564Sgblack@eecs.umich.edu bool 19012234Sgabeblack@google.com isCoprocessorEnabled(ExecContext *xc, unsigned cop_num) 1914661Sksewell@umich.edu { 1928738Sgblack@eecs.umich.edu if (!FullSystem) 1938564Sgblack@eecs.umich.edu return true; 1945224Sksewell@umich.edu 19513615Sgabeblack@google.com RegVal Stat = xc->readMiscReg(MISCREG_STATUS); 1968564Sgblack@eecs.umich.edu if (cop_num == 0) { 19713615Sgabeblack@google.com RegVal Dbg = xc->readMiscReg(MISCREG_DEBUG); 1988564Sgblack@eecs.umich.edu // In Stat, EXL, ERL or CU0 set, CP0 accessible 1998564Sgblack@eecs.umich.edu // In Dbg, DM bit set, CP0 accessible 2008564Sgblack@eecs.umich.edu // In Stat, KSU = 0, kernel mode is base mode 2018564Sgblack@eecs.umich.edu return (Stat & 0x10000006) || 2028564Sgblack@eecs.umich.edu (Dbg & 0x40000000) || 2038564Sgblack@eecs.umich.edu !(Stat & 0x00000018); 2048564Sgblack@eecs.umich.edu } else if (cop_num < 4) { 2058564Sgblack@eecs.umich.edu return Stat & (0x10000000 << cop_num); // CU is reset 2068564Sgblack@eecs.umich.edu } else { 2078564Sgblack@eecs.umich.edu panic("Invalid Coprocessor Number Specified"); 2084661Sksewell@umich.edu } 2094661Sksewell@umich.edu } 2108564Sgblack@eecs.umich.edu 2118564Sgblack@eecs.umich.edu bool inline 21212234Sgabeblack@google.com isCoprocessor0Enabled(ExecContext *xc) 2135222Sksewell@umich.edu { 2148738Sgblack@eecs.umich.edu if (FullSystem) { 21513615Sgabeblack@google.com RegVal Stat = xc->readMiscReg(MISCREG_STATUS); 21613615Sgabeblack@google.com RegVal Dbg = xc->readMiscReg(MISCREG_DEBUG); 2178564Sgblack@eecs.umich.edu // In Stat, EXL, ERL or CU0 set, CP0 accessible 2188564Sgblack@eecs.umich.edu // In Dbg, DM bit set, CP0 accessible 2198564Sgblack@eecs.umich.edu // In Stat KSU = 0, kernel mode is base mode 2208564Sgblack@eecs.umich.edu return (Stat & 0x10000006) || (Dbg & 0x40000000) || 2218564Sgblack@eecs.umich.edu !(Stat & 0x00000018); 2228564Sgblack@eecs.umich.edu } else { 2238564Sgblack@eecs.umich.edu return true; 2248564Sgblack@eecs.umich.edu } 2255222Sksewell@umich.edu } 2268564Sgblack@eecs.umich.edu 2278564Sgblack@eecs.umich.edu bool 22812234Sgabeblack@google.com isMMUTLB(ExecContext *xc) 2295222Sksewell@umich.edu { 23013615Sgabeblack@google.com RegVal Config = xc->readMiscReg(MISCREG_CONFIG); 2318738Sgblack@eecs.umich.edu return FullSystem && (Config & 0x380) == 0x80; 2325222Sksewell@umich.edu } 2332686Sksewell@umich.edu}}; 2342686Sksewell@umich.edu 2352686Sksewell@umich.edudef format CP0Control(code, *flags) {{ 2364661Sksewell@umich.edu flags += ('IsNonSpeculative', ) 2374661Sksewell@umich.edu iop = InstObjParams(name, Name, 'CP0Control', code, flags) 2384661Sksewell@umich.edu header_output = BasicDeclare.subst(iop) 2394661Sksewell@umich.edu decoder_output = BasicConstructor.subst(iop) 2404661Sksewell@umich.edu decode_block = BasicDecode.subst(iop) 2415222Sksewell@umich.edu exec_output = CP0Execute.subst(iop) 2422686Sksewell@umich.edu}}; 2435222Sksewell@umich.edudef format CP0TLB(code, *flags) {{ 2445222Sksewell@umich.edu flags += ('IsNonSpeculative', ) 2455222Sksewell@umich.edu iop = InstObjParams(name, Name, 'CP0Control', code, flags) 2465222Sksewell@umich.edu header_output = BasicDeclare.subst(iop) 2475222Sksewell@umich.edu decoder_output = BasicConstructor.subst(iop) 2485222Sksewell@umich.edu decode_block = BasicDecode.subst(iop) 2495222Sksewell@umich.edu exec_output = ControlTLBExecute.subst(iop) 2505222Sksewell@umich.edu}}; 2512686Sksewell@umich.edudef format CP1Control(code, *flags) {{ 2524661Sksewell@umich.edu flags += ('IsNonSpeculative', ) 2534661Sksewell@umich.edu iop = InstObjParams(name, Name, 'CP1Control', code, flags) 2544661Sksewell@umich.edu header_output = BasicDeclare.subst(iop) 2554661Sksewell@umich.edu decoder_output = BasicConstructor.subst(iop) 2564661Sksewell@umich.edu decode_block = BasicDecode.subst(iop) 2575222Sksewell@umich.edu exec_output = CP1Execute.subst(iop) 2582686Sksewell@umich.edu}}; 2592686Sksewell@umich.edu 2602686Sksewell@umich.edu 261