From: Kajol Jain Date: Wed, 12 Jun 2019 06:35:17 +0000 (+0530) Subject: arch-power: Added support for Program Interrupt X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a1610c78ece6579ce51ecfb58ad56fb093aa1f96;p=gem5.git arch-power: Added support for Program Interrupt Added supoort for program interrupt for Privileged type instruction. * Added flag IsPrivileged to check wheather instruction is privileged or not. * Define bit number to be set in MSR for corresponding interrupt. * Added Program interrupt handler with privileged type interrupt handler. * Add IsPrivileged flag in all privileged instructions * Add checker for PR bit inorder to verify mode for privilege instructions and raise interrupt if needed. Change-Id: I2aeb1a603568a6f80cd074bf67d4a528ebb6a5bd Signed-off-by: Kajol Jain --- diff --git a/src/arch/power/faults.hh b/src/arch/power/faults.hh index 47b46cb8b..8139e203e 100644 --- a/src/arch/power/faults.hh +++ b/src/arch/power/faults.hh @@ -36,6 +36,8 @@ #include "cpu/thread_context.hh" #include "sim/faults.hh" +#define SRR1_PRI_BIT 17 + #define setbit(shift, mask) ( (uint64_t)1 << shift | mask) #define unsetbit(shift,mask) ( ~((uint64_t)1 << shift) & mask) #define setBitMask(shift) ( (uint64_t)1 << shift) @@ -138,6 +140,35 @@ class PowerInterrupt : public PowerFaultBase }; +//TODO: Need to add Floating point and TM Bad thing fault handler +class ProgramInterrupt : public PowerInterrupt +{ + public: + ProgramInterrupt() + { + } + virtual void invoke(ThreadContext * tc, const StaticInstPtr &inst = + StaticInst::nullStaticInstPtr ,uint64_t bitSet = 0) + { + tc->setIntReg(INTREG_SRR0, tc->instAddr() + 4); + PowerInterrupt::updateSRR1(tc, bitSet); + PowerInterrupt::updateMsr(tc); + tc->pcState(ProgramPCSet); + } +}; + +class ProgramPriInterrupt : public ProgramInterrupt +{ + public: + ProgramPriInterrupt() + { + } + virtual void invoke(ThreadContext * tc, const StaticInstPtr &inst = + StaticInst::nullStaticInstPtr) + { + ProgramInterrupt::invoke(tc, inst, setBitMask(SRR1_PRI_BIT)); + } +}; class SystemCallInterrupt : public PowerInterrupt { diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa index 97ade360b..7b858d247 100644 --- a/src/arch/power/isa/decoder.isa +++ b/src/arch/power/isa/decoder.isa @@ -141,7 +141,7 @@ decode PO default Unknown::unknown() { MSR = insertBits(MSR,11,6,bits(SRR1,11,6)); MSR = insertBits(MSR,3,0,bits(SRR1,3,0)); NIA = SRR0 & -4ULL; - }}); + }}, [ IsPrivileged ]); 274: hrfid({{ if((bits(MSR,34,32)!=0x02)|(bits(HSRR1,34,32)!=0x00)) MSR = insertBits(MSR,34,32,bits(HSRR1,34,32)); @@ -627,7 +627,9 @@ decode PO default Unknown::unknown() { 0x2c9: mthdec({{HDEC = Rs;}}); 0x24a: mtpcr({{PCR = Rs;}}); } - 83: mfmsr({{ Rt = MSR }}); + + 83: mfmsr({{ Rt = MSR; }}, [ IsPrivileged ]); + 178: mtmsrd({{ if (L == 0 ) { uint64_t val = bits(Rs, 34, 32); @@ -667,7 +669,7 @@ decode PO default Unknown::unknown() { MSR = insertBits(MSR,15,bits(Rs,15)); MSR = insertBits(MSR,1,bits(Rs,1)); } - }}); + }}, [ IsPrivileged ]); } // Integer logic instructions use source registers Rs and Rb, @@ -888,9 +890,9 @@ decode PO default Unknown::unknown() { 54: dcbst({{ }}); 982: icbi({{ }}); 306: tlbie({{ }}); - 274: tlbiel({{ }}); + 274: tlbiel({{ }}, [ IsPrivileged ]); 566: tlbsync({{ }}); - 498: slbia({{ }}); + 498: slbia({{ }}, [ IsPrivileged ]); } // These instructions are of XO form with bit 21 as the OE bit. diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa index 8f23084f1..d3c94a0a1 100644 --- a/src/arch/power/isa/formats/integer.isa +++ b/src/arch/power/isa/formats/integer.isa @@ -129,9 +129,25 @@ setOVCode = ''' }}; +// Check the PR bit in MSR (which is bit number 14 of MSR) +// to see if Program interrupt is there. + +let {{ + +def GetPriCode(code): + cond_code = 'if (bits(MSR,14)==1) {\n' + cond_code += 'fault=std::make_shared();\n' + cond_code += '} else {\n' + cond_code += code + '\n' + cond_code += '}\n' + return cond_code + +}}; // A basic integer instruction. -def format IntOp(code, inst_flags = []) {{ +def format IntOp(code,inst_flags = []) {{ + if 'IsPrivileged' in inst_flags: + code = GetPriCode(code) (header_output, decoder_output, decode_block, exec_output) = \ GenAluOp(name, Name, 'IntOp', code, inst_flags, BasicDecode, BasicConstructor) diff --git a/src/arch/power/isa/formats/misc.isa b/src/arch/power/isa/formats/misc.isa index af2c2de64..11ee04156 100644 --- a/src/arch/power/isa/formats/misc.isa +++ b/src/arch/power/isa/formats/misc.isa @@ -51,7 +51,23 @@ def template MiscOpExecute {{ } }}; +// Check the PR bit in MSR (which is bit number 14 of MSR) +// to see if Program interrupt is there. + +let {{ + +def GetPriCode(code): + cond_code = 'if (bits(MSR,14)==1) {\n' + cond_code += 'fault=std::make_shared();\n' + cond_code += '} else {\n' + cond_code += code + '\n' + cond_code += '}\n' + return cond_code + +}}; def format MiscOp(code, opt_flags = []) {{ + if 'IsPrivileged' in opt_flags: + code = GetPriCode(code) iop = InstObjParams(name, Name, 'IntOp', {"code": code}, opt_flags) diff --git a/src/cpu/StaticInstFlags.py b/src/cpu/StaticInstFlags.py index 55ef456ce..f9eafa32f 100644 --- a/src/cpu/StaticInstFlags.py +++ b/src/cpu/StaticInstFlags.py @@ -99,6 +99,7 @@ class StaticInstFlags(Enum): 'IsSyscall', # Causes a system call to be emulated in syscall # emulation mode. + 'IsPrivileged', # Is flag to check instruction is privileged or not # Flags for microcode 'IsMacroop', # Is a macroop containing microops diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh index 84b352502..8fbb099d8 100644 --- a/src/cpu/static_inst.hh +++ b/src/cpu/static_inst.hh @@ -178,6 +178,7 @@ class StaticInst : public RefCounted, public StaticInstFlags bool isIprAccess() const { return flags[IsIprAccess]; } bool isUnverifiable() const { return flags[IsUnverifiable]; } bool isSyscall() const { return flags[IsSyscall]; } + bool isPrivileged() const { return flags[IsPrivileged]; } bool isMacroop() const { return flags[IsMacroop]; } bool isMicroop() const { return flags[IsMicroop]; } bool isDelayedCommit() const { return flags[IsDelayedCommit]; }