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