13931Ssaidi@eecs.umich.edu// Copyright (c) 2006-2007 The Regents of The University of Michigan 23388Sgblack@eecs.umich.edu// All rights reserved. 33388Sgblack@eecs.umich.edu// 43388Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 53388Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are 63388Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright 73388Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 83388Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 93388Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 103388Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution; 113388Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its 123388Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from 133388Sgblack@eecs.umich.edu// this software without specific prior written permission. 143388Sgblack@eecs.umich.edu// 153388Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 163388Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 173388Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 183388Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 193388Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 203388Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 213388Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 223388Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 233388Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 243388Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 253388Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 263388Sgblack@eecs.umich.edu// 273388Sgblack@eecs.umich.edu// Authors: Ali Saidi 283388Sgblack@eecs.umich.edu// Gabe Black 293388Sgblack@eecs.umich.edu// Steve Reinhardt 303388Sgblack@eecs.umich.edu 313388Sgblack@eecs.umich.edu//////////////////////////////////////////////////////////////////// 323388Sgblack@eecs.umich.edu// 333388Sgblack@eecs.umich.edu// Mem utility templates and functions 343388Sgblack@eecs.umich.edu// 353388Sgblack@eecs.umich.edu 367741Sgblack@eecs.umich.edu// This template provides the execute functions for a load 373388Sgblack@eecs.umich.edudef template LoadExecute {{ 3812234Sgabeblack@google.com Fault %(class_name)s::execute(ExecContext *xc, 393388Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 403388Sgblack@eecs.umich.edu { 413388Sgblack@eecs.umich.edu Fault fault = NoFault; 423388Sgblack@eecs.umich.edu Addr EA; 433931Ssaidi@eecs.umich.edu %(fp_enable_check)s; 443388Sgblack@eecs.umich.edu %(op_decl)s; 453388Sgblack@eecs.umich.edu %(op_rd)s; 463388Sgblack@eecs.umich.edu %(ea_code)s; 473766Sgblack@eecs.umich.edu DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); 483391Sgblack@eecs.umich.edu %(fault_check)s; 497741Sgblack@eecs.umich.edu if (fault == NoFault) { 504648Sgblack@eecs.umich.edu %(EA_trunc)s 518442Sgblack@eecs.umich.edu fault = readMemAtomic(xc, traceData, EA, Mem, %(asi_val)s); 523391Sgblack@eecs.umich.edu } 537741Sgblack@eecs.umich.edu if (fault == NoFault) { 543391Sgblack@eecs.umich.edu %(code)s; 553391Sgblack@eecs.umich.edu } 567741Sgblack@eecs.umich.edu if (fault == NoFault) { 577741Sgblack@eecs.umich.edu // Write the resulting state to the execution context 587741Sgblack@eecs.umich.edu %(op_wb)s; 593388Sgblack@eecs.umich.edu } 603388Sgblack@eecs.umich.edu 613388Sgblack@eecs.umich.edu return fault; 623388Sgblack@eecs.umich.edu } 633792Sgblack@eecs.umich.edu}}; 643388Sgblack@eecs.umich.edu 653792Sgblack@eecs.umich.edudef template LoadInitiateAcc {{ 6612234Sgabeblack@google.com Fault %(class_name)s::initiateAcc(ExecContext * xc, 673388Sgblack@eecs.umich.edu Trace::InstRecord * traceData) const 683388Sgblack@eecs.umich.edu { 693388Sgblack@eecs.umich.edu Fault fault = NoFault; 703388Sgblack@eecs.umich.edu Addr EA; 713931Ssaidi@eecs.umich.edu %(fp_enable_check)s; 723792Sgblack@eecs.umich.edu %(op_decl)s; 733792Sgblack@eecs.umich.edu %(op_rd)s; 743388Sgblack@eecs.umich.edu %(ea_code)s; 753766Sgblack@eecs.umich.edu DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); 763391Sgblack@eecs.umich.edu %(fault_check)s; 777741Sgblack@eecs.umich.edu if (fault == NoFault) { 784648Sgblack@eecs.umich.edu %(EA_trunc)s 7911303Ssteve.reinhardt@amd.com fault = initiateMemRead(xc, traceData, EA, Mem, %(asi_val)s); 803391Sgblack@eecs.umich.edu } 813388Sgblack@eecs.umich.edu return fault; 823388Sgblack@eecs.umich.edu } 833792Sgblack@eecs.umich.edu}}; 843388Sgblack@eecs.umich.edu 853792Sgblack@eecs.umich.edudef template LoadCompleteAcc {{ 8612234Sgabeblack@google.com Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext * xc, 873388Sgblack@eecs.umich.edu Trace::InstRecord * traceData) const 883388Sgblack@eecs.umich.edu { 893388Sgblack@eecs.umich.edu Fault fault = NoFault; 903792Sgblack@eecs.umich.edu %(op_decl)s; 913792Sgblack@eecs.umich.edu %(op_rd)s; 928442Sgblack@eecs.umich.edu getMem(pkt, Mem, traceData); 933388Sgblack@eecs.umich.edu %(code)s; 947741Sgblack@eecs.umich.edu if (fault == NoFault) { 953792Sgblack@eecs.umich.edu %(op_wb)s; 963388Sgblack@eecs.umich.edu } 973388Sgblack@eecs.umich.edu return fault; 983388Sgblack@eecs.umich.edu } 993388Sgblack@eecs.umich.edu}}; 1003388Sgblack@eecs.umich.edu 1017741Sgblack@eecs.umich.edu// This template provides the execute functions for a store 1023388Sgblack@eecs.umich.edudef template StoreExecute {{ 10312234Sgabeblack@google.com Fault %(class_name)s::execute(ExecContext *xc, 1043388Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 1053388Sgblack@eecs.umich.edu { 1063388Sgblack@eecs.umich.edu Fault fault = NoFault; 1077741Sgblack@eecs.umich.edu // This is to support the conditional store in cas instructions. 1087741Sgblack@eecs.umich.edu // It should be optomized out in all the others 1093439Sgblack@eecs.umich.edu bool storeCond = true; 1103388Sgblack@eecs.umich.edu Addr EA; 1113931Ssaidi@eecs.umich.edu %(fp_enable_check)s; 1123388Sgblack@eecs.umich.edu %(op_decl)s; 1133388Sgblack@eecs.umich.edu %(op_rd)s; 1143388Sgblack@eecs.umich.edu %(ea_code)s; 1153766Sgblack@eecs.umich.edu DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); 1163391Sgblack@eecs.umich.edu %(fault_check)s; 1177741Sgblack@eecs.umich.edu if (fault == NoFault) { 1183391Sgblack@eecs.umich.edu %(code)s; 1193391Sgblack@eecs.umich.edu } 1207741Sgblack@eecs.umich.edu if (storeCond && fault == NoFault) { 1214648Sgblack@eecs.umich.edu %(EA_trunc)s 1228442Sgblack@eecs.umich.edu fault = writeMemAtomic(xc, traceData, Mem, EA, %(asi_val)s, 0); 1233388Sgblack@eecs.umich.edu } 1247741Sgblack@eecs.umich.edu if (fault == NoFault) { 1257741Sgblack@eecs.umich.edu // Write the resulting state to the execution context 1267741Sgblack@eecs.umich.edu %(op_wb)s; 1273388Sgblack@eecs.umich.edu } 1283388Sgblack@eecs.umich.edu 1293388Sgblack@eecs.umich.edu return fault; 1303388Sgblack@eecs.umich.edu } 1313792Sgblack@eecs.umich.edu}}; 1323388Sgblack@eecs.umich.edu 1333792Sgblack@eecs.umich.edudef template StoreInitiateAcc {{ 13412234Sgabeblack@google.com Fault %(class_name)s::initiateAcc(ExecContext * xc, 1353388Sgblack@eecs.umich.edu Trace::InstRecord * traceData) const 1363388Sgblack@eecs.umich.edu { 1373388Sgblack@eecs.umich.edu Fault fault = NoFault; 1383439Sgblack@eecs.umich.edu bool storeCond = true; 1393388Sgblack@eecs.umich.edu Addr EA; 1403931Ssaidi@eecs.umich.edu %(fp_enable_check)s; 1413388Sgblack@eecs.umich.edu %(op_decl)s; 1424040Ssaidi@eecs.umich.edu 1433388Sgblack@eecs.umich.edu %(op_rd)s; 1443388Sgblack@eecs.umich.edu %(ea_code)s; 1453766Sgblack@eecs.umich.edu DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); 1463391Sgblack@eecs.umich.edu %(fault_check)s; 1477741Sgblack@eecs.umich.edu if (fault == NoFault) { 1483391Sgblack@eecs.umich.edu %(code)s; 1493391Sgblack@eecs.umich.edu } 1507741Sgblack@eecs.umich.edu if (storeCond && fault == NoFault) { 1514648Sgblack@eecs.umich.edu %(EA_trunc)s 1528442Sgblack@eecs.umich.edu fault = writeMemTiming(xc, traceData, Mem, EA, %(asi_val)s, 0); 1533388Sgblack@eecs.umich.edu } 1543388Sgblack@eecs.umich.edu return fault; 1553388Sgblack@eecs.umich.edu } 1563792Sgblack@eecs.umich.edu}}; 1573388Sgblack@eecs.umich.edu 1583792Sgblack@eecs.umich.edudef template StoreCompleteAcc {{ 15912234Sgabeblack@google.com Fault %(class_name)s::completeAcc(PacketPtr, ExecContext * xc, 1603388Sgblack@eecs.umich.edu Trace::InstRecord * traceData) const 1613388Sgblack@eecs.umich.edu { 1623388Sgblack@eecs.umich.edu return NoFault; 1633388Sgblack@eecs.umich.edu } 1643388Sgblack@eecs.umich.edu}}; 1653388Sgblack@eecs.umich.edu 1667741Sgblack@eecs.umich.edu// Here are some code snippets which check for various fault conditions 1673391Sgblack@eecs.umich.edulet {{ 1683792Sgblack@eecs.umich.edu LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc] 1693792Sgblack@eecs.umich.edu StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc] 1704040Ssaidi@eecs.umich.edu 1713391Sgblack@eecs.umich.edu # The LSB can be zero, since it's really the MSB in doubles and quads 1723391Sgblack@eecs.umich.edu # and we're dealing with doubles 1733391Sgblack@eecs.umich.edu BlockAlignmentFaultCheck = ''' 1747741Sgblack@eecs.umich.edu if (RD & 0xe) 17510474Sandreas.hansson@arm.com fault = std::make_shared<IllegalInstruction>(); 1767741Sgblack@eecs.umich.edu else if (EA & 0x3f) 17710474Sandreas.hansson@arm.com fault = std::make_shared<MemAddressNotAligned>(); 1783391Sgblack@eecs.umich.edu ''' 1793835Sgblack@eecs.umich.edu TwinAlignmentFaultCheck = ''' 1807741Sgblack@eecs.umich.edu if (RD & 0x1) 18110474Sandreas.hansson@arm.com fault = std::make_shared<IllegalInstruction>(); 1827741Sgblack@eecs.umich.edu else if (EA & 0xf) 18310474Sandreas.hansson@arm.com fault = std::make_shared<MemAddressNotAligned>(); 1843835Sgblack@eecs.umich.edu ''' 1853391Sgblack@eecs.umich.edu # XXX Need to take care of pstate.hpriv as well. The lower ASIs 1863391Sgblack@eecs.umich.edu # are split into ones that are available in priv and hpriv, and 1873391Sgblack@eecs.umich.edu # those that are only available in hpriv 1883391Sgblack@eecs.umich.edu AlternateASIPrivFaultCheck = ''' 1898829Sgblack@eecs.umich.edu if ((!Pstate.priv && !Hpstate.hpriv && 1907741Sgblack@eecs.umich.edu !asiIsUnPriv((ASI)EXT_ASI)) || 1918829Sgblack@eecs.umich.edu (!Hpstate.hpriv && asiIsHPriv((ASI)EXT_ASI))) 19210474Sandreas.hansson@arm.com fault = std::make_shared<PrivilegedAction>(); 1938829Sgblack@eecs.umich.edu else if (asiIsAsIfUser((ASI)EXT_ASI) && !Pstate.priv) 19410474Sandreas.hansson@arm.com fault = std::make_shared<PrivilegedAction>(); 1953391Sgblack@eecs.umich.edu ''' 1963391Sgblack@eecs.umich.edu 1974648Sgblack@eecs.umich.edu TruncateEA = ''' 19811981Snikos.nikoleris@arm.com if (!FullSystem) { 1998829Sgblack@eecs.umich.edu EA = Pstate.am ? EA<31:0> : EA; 20011981Snikos.nikoleris@arm.com } 2014648Sgblack@eecs.umich.edu ''' 2023391Sgblack@eecs.umich.edu}}; 2033391Sgblack@eecs.umich.edu 2047741Sgblack@eecs.umich.edu// A simple function to generate the name of the macro op of a certain 2057741Sgblack@eecs.umich.edu// instruction at a certain micropc 2063391Sgblack@eecs.umich.edulet {{ 2073391Sgblack@eecs.umich.edu def makeMicroName(name, microPc): 2083616Sgblack@eecs.umich.edu return name + "::" + name + "_" + str(microPc) 2093391Sgblack@eecs.umich.edu}}; 2103391Sgblack@eecs.umich.edu 2117741Sgblack@eecs.umich.edu// This function properly generates the execute functions for one of the 2127741Sgblack@eecs.umich.edu// templates above. This is needed because in one case, ea computation, 2137741Sgblack@eecs.umich.edu// fault checks and the actual code all occur in the same function, 2147741Sgblack@eecs.umich.edu// and in the other they're distributed across two. Also note that for 2157741Sgblack@eecs.umich.edu// execute functions, the name of the base class doesn't matter. 2163388Sgblack@eecs.umich.edulet {{ 2173949Sgblack@eecs.umich.edu def doSplitExecute(execute, name, Name, asi, opt_flags, microParam): 2183810Sgblack@eecs.umich.edu microParam["asi_val"] = asi; 2193792Sgblack@eecs.umich.edu iop = InstObjParams(name, Name, '', microParam, opt_flags) 2203792Sgblack@eecs.umich.edu (execf, initf, compf) = execute 2213792Sgblack@eecs.umich.edu return execf.subst(iop) + initf.subst(iop) + compf.subst(iop) 2223439Sgblack@eecs.umich.edu 2233439Sgblack@eecs.umich.edu 2244040Ssaidi@eecs.umich.edu def doDualSplitExecute(code, postacc_code, eaRegCode, eaImmCode, execute, 2253810Sgblack@eecs.umich.edu faultCode, nameReg, nameImm, NameReg, NameImm, asi, opt_flags): 2263388Sgblack@eecs.umich.edu executeCode = '' 2273388Sgblack@eecs.umich.edu for (eaCode, name, Name) in ( 2283388Sgblack@eecs.umich.edu (eaRegCode, nameReg, NameReg), 2293388Sgblack@eecs.umich.edu (eaImmCode, nameImm, NameImm)): 2304040Ssaidi@eecs.umich.edu microParams = {"code": code, "postacc_code" : postacc_code, 2314648Sgblack@eecs.umich.edu "ea_code": eaCode, "fault_check": faultCode, 2324648Sgblack@eecs.umich.edu "EA_trunc" : TruncateEA} 2333792Sgblack@eecs.umich.edu executeCode += doSplitExecute(execute, name, Name, 2343810Sgblack@eecs.umich.edu asi, opt_flags, microParams) 2353388Sgblack@eecs.umich.edu return executeCode 2363388Sgblack@eecs.umich.edu}}; 237