110037SARM gem5 Developers// -*- mode:c++ -*- 210037SARM gem5 Developers 312531Sandreas.sandberg@arm.com// Copyright (c) 2011-2013, 2016-2018 ARM Limited 410037SARM gem5 Developers// All rights reserved 510037SARM gem5 Developers// 610037SARM gem5 Developers// The license below extends only to copyright in the software and shall 710037SARM gem5 Developers// not be construed as granting a license to any other intellectual 810037SARM gem5 Developers// property including but not limited to intellectual property relating 910037SARM gem5 Developers// to a hardware implementation of the functionality of the software 1010037SARM gem5 Developers// licensed hereunder. You may use the software subject to the license 1110037SARM gem5 Developers// terms below provided that you ensure that this notice is replicated 1210037SARM gem5 Developers// unmodified and in its entirety in all distributions of the software, 1310037SARM gem5 Developers// modified or unmodified, in source code or in binary form. 1410037SARM gem5 Developers// 1510037SARM gem5 Developers// Redistribution and use in source and binary forms, with or without 1610037SARM gem5 Developers// modification, are permitted provided that the following conditions are 1710037SARM gem5 Developers// met: redistributions of source code must retain the above copyright 1810037SARM gem5 Developers// notice, this list of conditions and the following disclaimer; 1910037SARM gem5 Developers// redistributions in binary form must reproduce the above copyright 2010037SARM gem5 Developers// notice, this list of conditions and the following disclaimer in the 2110037SARM gem5 Developers// documentation and/or other materials provided with the distribution; 2210037SARM gem5 Developers// neither the name of the copyright holders nor the names of its 2310037SARM gem5 Developers// contributors may be used to endorse or promote products derived from 2410037SARM gem5 Developers// this software without specific prior written permission. 2510037SARM gem5 Developers// 2610037SARM gem5 Developers// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2710037SARM gem5 Developers// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2810037SARM gem5 Developers// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2910037SARM gem5 Developers// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3010037SARM gem5 Developers// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3110037SARM gem5 Developers// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3210037SARM gem5 Developers// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3310037SARM gem5 Developers// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3410037SARM gem5 Developers// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3510037SARM gem5 Developers// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3610037SARM gem5 Developers// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3710037SARM gem5 Developers// 3810037SARM gem5 Developers// Authors: Gabe Black 3910037SARM gem5 Developers 4010037SARM gem5 Developerslet {{ 4110037SARM gem5 Developers svcCode = ''' 4210474Sandreas.hansson@arm.com fault = std::make_shared<SupervisorCall>(machInst, bits(machInst, 20, 5)); 4310037SARM gem5 Developers ''' 4410037SARM gem5 Developers 4512538Sgiacomo.travaglini@arm.com svcIop = InstObjParams("svc", "Svc64", "ImmOp64", 4610037SARM gem5 Developers svcCode, ["IsSyscall", "IsNonSpeculative", 4710037SARM gem5 Developers "IsSerializeAfter"]) 4812538Sgiacomo.travaglini@arm.com header_output = ImmOp64Declare.subst(svcIop) 4912538Sgiacomo.travaglini@arm.com decoder_output = ImmOp64Constructor.subst(svcIop) 5010037SARM gem5 Developers exec_output = BasicExecute.subst(svcIop) 5110037SARM gem5 Developers 5211576SDylan.Johnson@ARM.com hvcCode = ''' 5311576SDylan.Johnson@ARM.com SCR scr = Scr64; 5413362Sgiacomo.travaglini@arm.com HCR hcr = Hcr64; 5513362Sgiacomo.travaglini@arm.com CPSR cpsr = Cpsr; 5611576SDylan.Johnson@ARM.com 5713362Sgiacomo.travaglini@arm.com auto tc = xc->tcBase(); 5813362Sgiacomo.travaglini@arm.com ExceptionLevel pstate_EL = (ExceptionLevel)(uint8_t)(cpsr.el); 5913362Sgiacomo.travaglini@arm.com 6013362Sgiacomo.travaglini@arm.com bool unalloc_encod = !ArmSystem::haveEL(tc, EL2) || pstate_EL == EL0 || 6113362Sgiacomo.travaglini@arm.com (pstate_EL == EL1 && inSecureState(tc)); 6213362Sgiacomo.travaglini@arm.com 6313362Sgiacomo.travaglini@arm.com bool hvc_enable = ArmSystem::haveEL(tc, EL3) ? 6413362Sgiacomo.travaglini@arm.com scr.hce : !hcr.hcd; 6513362Sgiacomo.travaglini@arm.com 6613362Sgiacomo.travaglini@arm.com if (unalloc_encod || !hvc_enable) { 6713362Sgiacomo.travaglini@arm.com fault = undefinedFault64(tc, pstate_EL); 6811576SDylan.Johnson@ARM.com } else { 6911576SDylan.Johnson@ARM.com fault = std::make_shared<HypervisorCall>(machInst, bits(machInst, 20, 5)); 7011576SDylan.Johnson@ARM.com } 7111576SDylan.Johnson@ARM.com ''' 7211576SDylan.Johnson@ARM.com 7312538Sgiacomo.travaglini@arm.com hvcIop = InstObjParams("hvc", "Hvc64", "ImmOp64", 7411576SDylan.Johnson@ARM.com hvcCode, ["IsSyscall", "IsNonSpeculative", 7511576SDylan.Johnson@ARM.com "IsSerializeAfter"]) 7612538Sgiacomo.travaglini@arm.com header_output += ImmOp64Declare.subst(hvcIop) 7712538Sgiacomo.travaglini@arm.com decoder_output += ImmOp64Constructor.subst(hvcIop) 7811576SDylan.Johnson@ARM.com exec_output += BasicExecute.subst(hvcIop) 7911576SDylan.Johnson@ARM.com 8010037SARM gem5 Developers # @todo: extend to take into account Virtualization. 8110037SARM gem5 Developers smcCode = ''' 8210037SARM gem5 Developers SCR scr = Scr64; 8310037SARM gem5 Developers CPSR cpsr = Cpsr; 8410037SARM gem5 Developers 8510037SARM gem5 Developers if (!ArmSystem::haveSecurity(xc->tcBase()) || inUserMode(cpsr) || scr.smd) { 8610037SARM gem5 Developers fault = disabledFault(); 8710037SARM gem5 Developers } else { 8810474Sandreas.hansson@arm.com fault = std::make_shared<SecureMonitorCall>(machInst); 8910037SARM gem5 Developers } 9010037SARM gem5 Developers ''' 9110037SARM gem5 Developers 9212538Sgiacomo.travaglini@arm.com smcIop = InstObjParams("smc", "Smc64", "ImmOp64", 9310037SARM gem5 Developers smcCode, ["IsNonSpeculative", "IsSerializeAfter"]) 9412538Sgiacomo.travaglini@arm.com header_output += ImmOp64Declare.subst(smcIop) 9512538Sgiacomo.travaglini@arm.com decoder_output += ImmOp64Constructor.subst(smcIop) 9610037SARM gem5 Developers exec_output += BasicExecute.subst(smcIop) 9710037SARM gem5 Developers 9810037SARM gem5 Developers def subst(templateBase, iop): 9910037SARM gem5 Developers global header_output, decoder_output, exec_output 10010037SARM gem5 Developers header_output += eval(templateBase + "Declare").subst(iop) 10110037SARM gem5 Developers decoder_output += eval(templateBase + "Constructor").subst(iop) 10210037SARM gem5 Developers exec_output += BasicExecute.subst(iop) 10310037SARM gem5 Developers 10410037SARM gem5 Developers bfmMaskCode = ''' 10510037SARM gem5 Developers uint64_t bitMask; 10610037SARM gem5 Developers int diff = imm2 - imm1; 10710037SARM gem5 Developers if (imm1 <= imm2) { 10810037SARM gem5 Developers bitMask = mask(diff + 1); 10910037SARM gem5 Developers } else { 11010037SARM gem5 Developers bitMask = mask(imm2 + 1); 11110037SARM gem5 Developers bitMask = (bitMask >> imm1) | (bitMask << (intWidth - imm1)); 11210037SARM gem5 Developers diff += intWidth; 11310037SARM gem5 Developers } 11410037SARM gem5 Developers uint64_t topBits M5_VAR_USED = ~mask(diff+1); 11510537Sandreas.hansson@arm.com uint64_t result = imm1 == 0 ? Op164 : 11610537Sandreas.hansson@arm.com (Op164 >> imm1) | (Op164 << (intWidth - imm1)); 11710037SARM gem5 Developers result &= bitMask; 11810037SARM gem5 Developers ''' 11910037SARM gem5 Developers 12010037SARM gem5 Developers bfmCode = bfmMaskCode + 'Dest64 = result | (Dest64 & ~bitMask);' 12110037SARM gem5 Developers bfmIop = InstObjParams("bfm", "Bfm64", "RegRegImmImmOp64", bfmCode); 12210037SARM gem5 Developers subst("RegRegImmImmOp64", bfmIop) 12310037SARM gem5 Developers 12410037SARM gem5 Developers ubfmCode = bfmMaskCode + 'Dest64 = result;' 12510037SARM gem5 Developers ubfmIop = InstObjParams("ubfm", "Ubfm64", "RegRegImmImmOp64", ubfmCode); 12610037SARM gem5 Developers subst("RegRegImmImmOp64", ubfmIop) 12710037SARM gem5 Developers 12810037SARM gem5 Developers sbfmCode = bfmMaskCode + \ 12910037SARM gem5 Developers 'Dest64 = result | (bits(Op164, imm2) ? topBits : 0);' 13010037SARM gem5 Developers sbfmIop = InstObjParams("sbfm", "Sbfm64", "RegRegImmImmOp64", sbfmCode); 13110037SARM gem5 Developers subst("RegRegImmImmOp64", sbfmIop) 13210037SARM gem5 Developers 13310037SARM gem5 Developers extrCode = ''' 13410037SARM gem5 Developers if (imm == 0) { 13510037SARM gem5 Developers Dest64 = Op264; 13610037SARM gem5 Developers } else { 13710037SARM gem5 Developers Dest64 = (Op164 << (intWidth - imm)) | (Op264 >> imm); 13810037SARM gem5 Developers } 13910037SARM gem5 Developers ''' 14010037SARM gem5 Developers extrIop = InstObjParams("extr", "Extr64", "RegRegRegImmOp64", extrCode); 14110037SARM gem5 Developers subst("RegRegRegImmOp64", extrIop); 14210037SARM gem5 Developers 14310037SARM gem5 Developers unknownCode = ''' 14410474Sandreas.hansson@arm.com return std::make_shared<UndefinedInstruction>(machInst, true); 14510037SARM gem5 Developers ''' 14610037SARM gem5 Developers unknown64Iop = InstObjParams("unknown", "Unknown64", "UnknownOp64", 14710037SARM gem5 Developers unknownCode) 14810037SARM gem5 Developers header_output += BasicDeclare.subst(unknown64Iop) 14910037SARM gem5 Developers decoder_output += BasicConstructor64.subst(unknown64Iop) 15010037SARM gem5 Developers exec_output += BasicExecute.subst(unknown64Iop) 15110037SARM gem5 Developers 15212259Sgiacomo.travaglini@arm.com isbIop = InstObjParams("isb", "Isb64", "ArmStaticInst", "", 15312488Sgiacomo.travaglini@arm.com ['IsSquashAfter']) 15410037SARM gem5 Developers header_output += BasicDeclare.subst(isbIop) 15510037SARM gem5 Developers decoder_output += BasicConstructor64.subst(isbIop) 15610037SARM gem5 Developers exec_output += BasicExecute.subst(isbIop) 15710037SARM gem5 Developers 15812259Sgiacomo.travaglini@arm.com dsbIop = InstObjParams("dsb", "Dsb64", "ArmStaticInst", "", 15912261Sgiacomo.travaglini@arm.com ['IsMemBarrier', 'IsSerializeAfter']) 16010037SARM gem5 Developers header_output += BasicDeclare.subst(dsbIop) 16110037SARM gem5 Developers decoder_output += BasicConstructor64.subst(dsbIop) 16210037SARM gem5 Developers exec_output += BasicExecute.subst(dsbIop) 16310037SARM gem5 Developers 16410037SARM gem5 Developers dmbIop = InstObjParams("dmb", "Dmb64", "ArmStaticInst", "", 16510037SARM gem5 Developers ['IsMemBarrier']) 16610037SARM gem5 Developers header_output += BasicDeclare.subst(dmbIop) 16710037SARM gem5 Developers decoder_output += BasicConstructor64.subst(dmbIop) 16810037SARM gem5 Developers exec_output += BasicExecute.subst(dmbIop) 16910037SARM gem5 Developers 17010037SARM gem5 Developers clrexIop = InstObjParams("clrex", "Clrex64", "ArmStaticInst", 17110037SARM gem5 Developers "LLSCLock = 0;") 17210037SARM gem5 Developers header_output += BasicDeclare.subst(clrexIop) 17310037SARM gem5 Developers decoder_output += BasicConstructor64.subst(clrexIop) 17410037SARM gem5 Developers exec_output += BasicExecute.subst(clrexIop) 17512299Sandreas.sandberg@arm.com 17612299Sandreas.sandberg@arm.com 17712299Sandreas.sandberg@arm.com brkCode = ''' 17812299Sandreas.sandberg@arm.com fault = std::make_shared<SoftwareBreakpoint>(machInst, 17912299Sandreas.sandberg@arm.com bits(machInst, 20, 5)); 18012299Sandreas.sandberg@arm.com ''' 18112299Sandreas.sandberg@arm.com 18212538Sgiacomo.travaglini@arm.com brkIop = InstObjParams("brk", "Brk64", "ImmOp64", 18312299Sandreas.sandberg@arm.com brkCode, ["IsSerializeAfter"]) 18412538Sgiacomo.travaglini@arm.com header_output += ImmOp64Declare.subst(brkIop) 18512538Sgiacomo.travaglini@arm.com decoder_output += ImmOp64Constructor.subst(brkIop) 18612299Sandreas.sandberg@arm.com exec_output += BasicExecute.subst(brkIop) 18712531Sandreas.sandberg@arm.com 18812531Sandreas.sandberg@arm.com hltCode = ''' 18912531Sandreas.sandberg@arm.com ThreadContext *tc = xc->tcBase(); 19012539Sgiacomo.travaglini@arm.com if (ArmSystem::haveSemihosting(tc) && imm == 0xF000) { 19112531Sandreas.sandberg@arm.com X0 = ArmSystem::callSemihosting64(tc, X0 & mask(32), X1); 19212531Sandreas.sandberg@arm.com } else { 19312531Sandreas.sandberg@arm.com // HLT instructions aren't implemented, so treat them as undefined 19412531Sandreas.sandberg@arm.com // instructions. 19512531Sandreas.sandberg@arm.com fault = std::make_shared<UndefinedInstruction>( 19612531Sandreas.sandberg@arm.com machInst, false, mnemonic); 19712531Sandreas.sandberg@arm.com } 19812531Sandreas.sandberg@arm.com 19912531Sandreas.sandberg@arm.com ''' 20012531Sandreas.sandberg@arm.com 20112538Sgiacomo.travaglini@arm.com hltIop = InstObjParams("hlt", "Hlt64", "ImmOp64", 20212531Sandreas.sandberg@arm.com hltCode, ["IsNonSpeculative"]) 20312538Sgiacomo.travaglini@arm.com header_output += ImmOp64Declare.subst(hltIop) 20412543Sgiacomo.travaglini@arm.com decoder_output += SemihostConstructor64.subst(hltIop) 20512531Sandreas.sandberg@arm.com exec_output += BasicExecute.subst(hltIop) 20610037SARM gem5 Developers}}; 207