1// Copyright (c) 2006-2007 The Regents of The University of Michigan 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer; 8// redistributions in binary form must reproduce the above copyright 9// notice, this list of conditions and the following disclaimer in the 10// documentation and/or other materials provided with the distribution; 11// neither the name of the copyright holders nor the names of its 12// contributors may be used to endorse or promote products derived from 13// this software without specific prior written permission. 14// 15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26// 27// Authors: Ali Saidi 28// Gabe Black 29// Steve Reinhardt 30 31//////////////////////////////////////////////////////////////////// 32// 33// Privilege mode instructions 34// 35 36def template ControlRegConstructor {{ 37%(class_name)s::%(class_name)s(ExtMachInst machInst) : 38 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, "%(reg_name)s") 39{ 40 %(constructor)s; 41} 42}}; 43 44def template PrivExecute {{ 45Fault 46%(class_name)s::execute(ExecContext *xc, Trace::InstRecord *traceData) const 47{ 48 %(op_decl)s; 49 %(op_rd)s; 50 51 // If the processor isn't in privileged mode, fault out right away 52 if (%(check)s) 53 return std::make_shared<PrivilegedAction>(); 54 55 %(tl_check)s 56 57 Fault fault = NoFault; 58 %(code)s; 59 %(op_wb)s; 60 return fault; 61} 62}}; 63 64let {{ 65 tl_check_code = ''' 66 if (Tl == 0) 67 return std::make_shared<IllegalInstruction>(); 68''' 69 70 def doPrivFormat(code, check_code, name, Name, opt_flags, check_tl=False): 71 (uses_imm, code, imm_code, r_string, i_string) = splitOutImm(code) 72 tl_check = tl_check_code if check_tl else '' 73 # If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions, 74 # cut any other info out of the mnemonic. Also pick a different 75 # base class. 76 reg_base = 'Priv' 77 reg_name = '' 78 for mnem in ["rdhpr", "rdpr", "rd"]: 79 if name.startswith(mnem): 80 reg_name = name[len(mnem):] 81 name = mnem 82 reg_base = 'RdPriv' 83 break 84 for mnem in ["wrhpr", "wrpr", "wr"]: 85 if name.startswith(mnem): 86 reg_name = name[len(mnem):] 87 name = mnem 88 reg_base = 'WrPriv' 89 break 90 iop = InstObjParams(name, Name, reg_base, 91 {"code": code, "check": check_code, 92 "tl_check": tl_check, "reg_name": reg_name}, 93 opt_flags) 94 header_output = BasicDeclare.subst(iop) 95 if reg_name == '': 96 decoder_output = BasicConstructor.subst(iop) 97 else: 98 decoder_output = ControlRegConstructor.subst(iop) 99 exec_output = PrivExecute.subst(iop) 100 if uses_imm: 101 imm_iop = InstObjParams(name, Name + 'Imm', reg_base + 'Imm', 102 {"code": imm_code, "check": check_code, 103 "tl_check": tl_check, "reg_name": reg_name}, 104 opt_flags) 105 header_output += BasicDeclare.subst(imm_iop) 106 if reg_name == '': 107 decoder_output += BasicConstructor.subst(imm_iop) 108 else: 109 decoder_output += ControlRegConstructor.subst(imm_iop) 110 exec_output += PrivExecute.subst(imm_iop) 111 decode_block = ROrImmDecode.subst(iop) 112 else: 113 decode_block = BasicDecode.subst(iop) 114 return (header_output, decoder_output, exec_output, decode_block) 115}}; 116 117def format Priv(code, extraCond=true, check_tl=false, *opt_flags) {{ 118 check_code = "(%s) && !(Pstate.priv || Hpstate.hpriv)" % extraCond 119 (header_output, decoder_output, exec_output, decode_block) = \ 120 doPrivFormat(code, check_code, name, Name, opt_flags, 121 check_tl=(check_tl != 'false')) 122}}; 123 124def format NoPriv(code, *opt_flags) {{ 125 # Instructions which use this format don't really check for any 126 # particular mode, but the disassembly is performed using the control 127 # register's actual name 128 check_code = "false" 129 (header_output, decoder_output, exec_output, decode_block) = \ 130 doPrivFormat(code, check_code, name, Name, opt_flags) 131}}; 132 133def format HPriv(code, check_tl=false, *opt_flags) {{ 134 check_code = "!Hpstate.hpriv" 135 (header_output, decoder_output, exec_output, decode_block) = \ 136 doPrivFormat(code, check_code, name, Name, opt_flags, 137 check_tl=(check_tl != 'false')) 138}}; 139 140