priv.isa revision 12106:7784fac1b159
12929Sktlim@umich.edu// Copyright (c) 2006-2007 The Regents of The University of Michigan 22929Sktlim@umich.edu// All rights reserved. 32932Sktlim@umich.edu// 42929Sktlim@umich.edu// Redistribution and use in source and binary forms, with or without 52929Sktlim@umich.edu// modification, are permitted provided that the following conditions are 62929Sktlim@umich.edu// met: redistributions of source code must retain the above copyright 72929Sktlim@umich.edu// notice, this list of conditions and the following disclaimer; 82929Sktlim@umich.edu// redistributions in binary form must reproduce the above copyright 92929Sktlim@umich.edu// notice, this list of conditions and the following disclaimer in the 102929Sktlim@umich.edu// documentation and/or other materials provided with the distribution; 112929Sktlim@umich.edu// neither the name of the copyright holders nor the names of its 122929Sktlim@umich.edu// contributors may be used to endorse or promote products derived from 132929Sktlim@umich.edu// this software without specific prior written permission. 142929Sktlim@umich.edu// 152929Sktlim@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 162929Sktlim@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 172929Sktlim@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 182929Sktlim@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 192929Sktlim@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 202929Sktlim@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 212929Sktlim@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 222929Sktlim@umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 232929Sktlim@umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 242929Sktlim@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 252929Sktlim@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262929Sktlim@umich.edu// 272929Sktlim@umich.edu// Authors: Ali Saidi 282932Sktlim@umich.edu// Gabe Black 292932Sktlim@umich.edu// Steve Reinhardt 302932Sktlim@umich.edu 312929Sktlim@umich.edu//////////////////////////////////////////////////////////////////// 322929Sktlim@umich.edu// 332929Sktlim@umich.edu// Privilege mode instructions 342929Sktlim@umich.edu// 352929Sktlim@umich.edu 362929Sktlim@umich.eduoutput header {{ 372929Sktlim@umich.edu /** 382929Sktlim@umich.edu * Base class for privelege mode operations. 392929Sktlim@umich.edu */ 402929Sktlim@umich.edu class Priv : public SparcStaticInst 412929Sktlim@umich.edu { 422929Sktlim@umich.edu protected: 432929Sktlim@umich.edu // Constructor 442929Sktlim@umich.edu Priv(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : 452929Sktlim@umich.edu SparcStaticInst(mnem, _machInst, __opClass) 462929Sktlim@umich.edu { 472929Sktlim@umich.edu } 482929Sktlim@umich.edu 492929Sktlim@umich.edu std::string generateDisassembly(Addr pc, 502929Sktlim@umich.edu const SymbolTable *symtab) const; 512929Sktlim@umich.edu }; 522929Sktlim@umich.edu 532929Sktlim@umich.edu // This class is for instructions that explicitly read control 542929Sktlim@umich.edu // registers. It provides a special generateDisassembly function. 552929Sktlim@umich.edu class RdPriv : public Priv 562929Sktlim@umich.edu { 572929Sktlim@umich.edu protected: 582929Sktlim@umich.edu // Constructor 592929Sktlim@umich.edu RdPriv(const char *mnem, ExtMachInst _machInst, 602929Sktlim@umich.edu OpClass __opClass, char const * _regName) : 612929Sktlim@umich.edu Priv(mnem, _machInst, __opClass), regName(_regName) 622929Sktlim@umich.edu { 632929Sktlim@umich.edu } 642929Sktlim@umich.edu 652929Sktlim@umich.edu std::string generateDisassembly(Addr pc, 662929Sktlim@umich.edu const SymbolTable *symtab) const; 672929Sktlim@umich.edu 682929Sktlim@umich.edu char const * regName; 692929Sktlim@umich.edu }; 702929Sktlim@umich.edu 712929Sktlim@umich.edu // This class is for instructions that explicitly write control 722929Sktlim@umich.edu // registers. It provides a special generateDisassembly function. 732929Sktlim@umich.edu class WrPriv : public Priv 742929Sktlim@umich.edu { 752929Sktlim@umich.edu protected: 762929Sktlim@umich.edu // Constructor 772929Sktlim@umich.edu WrPriv(const char *mnem, ExtMachInst _machInst, 782929Sktlim@umich.edu OpClass __opClass, char const * _regName) : 792929Sktlim@umich.edu Priv(mnem, _machInst, __opClass), regName(_regName) 802929Sktlim@umich.edu { 812929Sktlim@umich.edu } 822929Sktlim@umich.edu 832929Sktlim@umich.edu std::string generateDisassembly(Addr pc, 842929Sktlim@umich.edu const SymbolTable *symtab) const; 852929Sktlim@umich.edu 862929Sktlim@umich.edu char const * regName; 872929Sktlim@umich.edu }; 882929Sktlim@umich.edu 892929Sktlim@umich.edu /** 902929Sktlim@umich.edu * Base class for privelege mode operations with immediates. 912929Sktlim@umich.edu */ 922929Sktlim@umich.edu class PrivImm : public Priv 932929Sktlim@umich.edu { 942929Sktlim@umich.edu protected: 952929Sktlim@umich.edu // Constructor 962929Sktlim@umich.edu PrivImm(const char *mnem, ExtMachInst _machInst, 972929Sktlim@umich.edu OpClass __opClass) : 982929Sktlim@umich.edu Priv(mnem, _machInst, __opClass), imm(SIMM13) 992929Sktlim@umich.edu { 1002929Sktlim@umich.edu } 1012929Sktlim@umich.edu 1022929Sktlim@umich.edu int32_t imm; 1032929Sktlim@umich.edu }; 1042929Sktlim@umich.edu 1052929Sktlim@umich.edu // This class is for instructions that explicitly write control 1062929Sktlim@umich.edu // registers. It provides a special generateDisassembly function. 1072929Sktlim@umich.edu class WrPrivImm : public PrivImm 1082929Sktlim@umich.edu { 1092929Sktlim@umich.edu protected: 1102929Sktlim@umich.edu // Constructor 1112929Sktlim@umich.edu WrPrivImm(const char *mnem, ExtMachInst _machInst, 1122929Sktlim@umich.edu OpClass __opClass, char const * _regName) : 1132929Sktlim@umich.edu PrivImm(mnem, _machInst, __opClass), regName(_regName) 1142929Sktlim@umich.edu { 1152929Sktlim@umich.edu } 1162929Sktlim@umich.edu 1172929Sktlim@umich.edu std::string generateDisassembly(Addr pc, 1182929Sktlim@umich.edu const SymbolTable *symtab) const; 1192929Sktlim@umich.edu 1202929Sktlim@umich.edu char const * regName; 1212929Sktlim@umich.edu }; 1222929Sktlim@umich.edu}}; 1232929Sktlim@umich.edu 1242929Sktlim@umich.eduoutput decoder {{ 1252929Sktlim@umich.edu std::string 1262929Sktlim@umich.edu Priv::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1272929Sktlim@umich.edu { 1282929Sktlim@umich.edu std::stringstream response; 1292929Sktlim@umich.edu 1302929Sktlim@umich.edu printMnemonic(response, mnemonic); 1312929Sktlim@umich.edu 1322929Sktlim@umich.edu return response.str(); 1332929Sktlim@umich.edu } 1342929Sktlim@umich.edu 1352929Sktlim@umich.edu std::string 1362929Sktlim@umich.edu RdPriv::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1372929Sktlim@umich.edu { 1382929Sktlim@umich.edu std::stringstream response; 1392929Sktlim@umich.edu 1402929Sktlim@umich.edu printMnemonic(response, mnemonic); 1412929Sktlim@umich.edu 1422932Sktlim@umich.edu ccprintf(response, " %%%s, ", regName); 1432932Sktlim@umich.edu printDestReg(response, 0); 1442929Sktlim@umich.edu 1452929Sktlim@umich.edu return response.str(); 1462929Sktlim@umich.edu } 1472929Sktlim@umich.edu 1482929Sktlim@umich.edu std::string 1492929Sktlim@umich.edu WrPriv::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1502929Sktlim@umich.edu { 1512929Sktlim@umich.edu std::stringstream response; 1522929Sktlim@umich.edu 1532929Sktlim@umich.edu printMnemonic(response, mnemonic); 1542929Sktlim@umich.edu 1552929Sktlim@umich.edu ccprintf(response, " "); 1562929Sktlim@umich.edu // If the first reg is %g0, don't print it. 1572929Sktlim@umich.edu // This improves readability 1582929Sktlim@umich.edu if (_srcRegIdx[0].index() != 0) { 1592929Sktlim@umich.edu printSrcReg(response, 0); 1602932Sktlim@umich.edu ccprintf(response, ", "); 1612932Sktlim@umich.edu } 1622932Sktlim@umich.edu printSrcReg(response, 1); 1632932Sktlim@umich.edu ccprintf(response, ", %%%s", regName); 1642932Sktlim@umich.edu 1652932Sktlim@umich.edu return response.str(); 1662932Sktlim@umich.edu } 1672932Sktlim@umich.edu 1682929Sktlim@umich.edu std::string WrPrivImm::generateDisassembly(Addr pc, 1692932Sktlim@umich.edu const SymbolTable *symtab) const 1702932Sktlim@umich.edu { 1712929Sktlim@umich.edu std::stringstream response; 1722929Sktlim@umich.edu 1732932Sktlim@umich.edu printMnemonic(response, mnemonic); 1742932Sktlim@umich.edu 1752932Sktlim@umich.edu ccprintf(response, " "); 1762932Sktlim@umich.edu // If the first reg is %g0, don't print it. 1772929Sktlim@umich.edu // This improves readability 1782929Sktlim@umich.edu if (_srcRegIdx[0].index() != 0) { 1792929Sktlim@umich.edu printSrcReg(response, 0); 1802929Sktlim@umich.edu ccprintf(response, ", "); 1812929Sktlim@umich.edu } 1822929Sktlim@umich.edu ccprintf(response, "0x%x, %%%s", imm, regName); 1832929Sktlim@umich.edu 1842929Sktlim@umich.edu return response.str(); 1852929Sktlim@umich.edu } 1862929Sktlim@umich.edu}}; 1872929Sktlim@umich.edu 1882929Sktlim@umich.edudef template ControlRegConstructor {{ 1892932Sktlim@umich.edu %(class_name)s::%(class_name)s(ExtMachInst machInst) 1902932Sktlim@umich.edu : %(base_class)s("%(mnemonic)s", machInst, 1912929Sktlim@umich.edu %(op_class)s, "%(reg_name)s") 1922929Sktlim@umich.edu { 1932929Sktlim@umich.edu %(constructor)s; 1942929Sktlim@umich.edu } 1952929Sktlim@umich.edu}}; 1962929Sktlim@umich.edu 1972929Sktlim@umich.edudef template PrivExecute {{ 1982929Sktlim@umich.edu Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 1992929Sktlim@umich.edu Trace::InstRecord *traceData) const 2002929Sktlim@umich.edu { 2012929Sktlim@umich.edu %(op_decl)s; 2022929Sktlim@umich.edu %(op_rd)s; 2032929Sktlim@umich.edu 2042929Sktlim@umich.edu // If the processor isn't in privileged mode, fault out right away 2052929Sktlim@umich.edu if (%(check)s) 2062929Sktlim@umich.edu return std::make_shared<PrivilegedAction>(); 2072929Sktlim@umich.edu 2082929Sktlim@umich.edu if (%(tlCheck)s) 2092929Sktlim@umich.edu return std::make_shared<IllegalInstruction>(); 2102929Sktlim@umich.edu 2112929Sktlim@umich.edu Fault fault = NoFault; 2122929Sktlim@umich.edu %(code)s; 2132929Sktlim@umich.edu %(op_wb)s; 2142929Sktlim@umich.edu return fault; 2152929Sktlim@umich.edu } 2162929Sktlim@umich.edu}}; 2172929Sktlim@umich.edu 2182929Sktlim@umich.edulet {{ 2192929Sktlim@umich.edu def doPrivFormat(code, checkCode, name, Name, tlCheck, opt_flags): 2202929Sktlim@umich.edu (usesImm, code, immCode, 2212932Sktlim@umich.edu rString, iString) = splitOutImm(code) 2222932Sktlim@umich.edu #If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions, 2232929Sktlim@umich.edu #cut any other info out of the mnemonic. Also pick a different 2242929Sktlim@umich.edu #base class. 2252929Sktlim@umich.edu regBase = 'Priv' 2262929Sktlim@umich.edu regName = '' 2272929Sktlim@umich.edu for mnem in ["rdhpr", "rdpr", "rd"]: 2282929Sktlim@umich.edu if name.startswith(mnem): 2292929Sktlim@umich.edu regName = name[len(mnem):] 2302929Sktlim@umich.edu name = mnem 2312932Sktlim@umich.edu regBase = 'RdPriv' 2322932Sktlim@umich.edu break 2332929Sktlim@umich.edu for mnem in ["wrhpr", "wrpr", "wr"]: 2342929Sktlim@umich.edu if name.startswith(mnem): 2352932Sktlim@umich.edu regName = name[len(mnem):] 2362932Sktlim@umich.edu name = mnem 2372929Sktlim@umich.edu regBase = 'WrPriv' 2382929Sktlim@umich.edu break 2392929Sktlim@umich.edu iop = InstObjParams(name, Name, regBase, 2402929Sktlim@umich.edu {"code": code, "check": checkCode, 2412929Sktlim@umich.edu "tlCheck": tlCheck, "reg_name": regName}, 2422929Sktlim@umich.edu opt_flags) 2432929Sktlim@umich.edu header_output = BasicDeclare.subst(iop) 2442929Sktlim@umich.edu if regName == '': 2452929Sktlim@umich.edu decoder_output = BasicConstructor.subst(iop) 2462929Sktlim@umich.edu else: 2472929Sktlim@umich.edu decoder_output = ControlRegConstructor.subst(iop) 2482929Sktlim@umich.edu exec_output = PrivExecute.subst(iop) 2492929Sktlim@umich.edu if usesImm: 2502929Sktlim@umich.edu imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm', 2512929Sktlim@umich.edu {"code": immCode, "check": checkCode, 2522929Sktlim@umich.edu "tlCheck": tlCheck, "reg_name": regName}, 2532929Sktlim@umich.edu opt_flags) 2542929Sktlim@umich.edu header_output += BasicDeclare.subst(imm_iop) 2552929Sktlim@umich.edu if regName == '': 2562929Sktlim@umich.edu decoder_output += BasicConstructor.subst(imm_iop) 2572929Sktlim@umich.edu else: 2582929Sktlim@umich.edu decoder_output += ControlRegConstructor.subst(imm_iop) 2592929Sktlim@umich.edu exec_output += PrivExecute.subst(imm_iop) 2602929Sktlim@umich.edu decode_block = ROrImmDecode.subst(iop) 2612929Sktlim@umich.edu else: 2622929Sktlim@umich.edu decode_block = BasicDecode.subst(iop) 263 return (header_output, decoder_output, exec_output, decode_block) 264}}; 265 266def format Priv(code, extraCond=true, checkTl=false, *opt_flags) {{ 267 checkCode = "(%s) && !(Pstate.priv || Hpstate.hpriv)" % extraCond 268 if checkTl != "false": 269 tlCheck = "Tl == 0" 270 else: 271 tlCheck = "false" 272 (header_output, decoder_output, 273 exec_output, decode_block) = doPrivFormat(code, 274 checkCode, name, Name, tlCheck, opt_flags) 275}}; 276 277def format NoPriv(code, checkTl=false, *opt_flags) {{ 278 #Instructions which use this format don't really check for 279 #any particular mode, but the disassembly is performed 280 #using the control registers actual name 281 checkCode = "false" 282 if checkTl != "false": 283 tlCheck = "Tl == 0" 284 else: 285 tlCheck = "false" 286 (header_output, decoder_output, 287 exec_output, decode_block) = doPrivFormat(code, 288 checkCode, name, Name, tlCheck, opt_flags) 289}}; 290 291def format HPriv(code, checkTl=false, *opt_flags) {{ 292 checkCode = "!Hpstate.hpriv" 293 if checkTl != "false": 294 tlCheck = "Tl == 0" 295 else: 296 tlCheck = "false" 297 (header_output, decoder_output, 298 exec_output, decode_block) = doPrivFormat(code, 299 checkCode, name, Name, tlCheck, opt_flags) 300}}; 301 302