From: kajoljain379 Date: Wed, 20 Mar 2019 09:45:37 +0000 (+0530) Subject: arch-power: Modify Interrupt handler for DSI and ISI X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ef28584eb9d1c5d63883aad309b6c93785b427da;p=gem5.git arch-power: Modify Interrupt handler for DSI and ISI * Modify Interrupt handler for Data storage (DSI) and Instruction Storage Interrupt (ISI). * Added function to check mode of instruction. * Added function to prepare registers for DSI. * Added function to prepare registers for ISI. Change-Id: I62ee5116c2acdbad225f7dc7fe72bb95d9462dc4 Signed-off-by: kajoljain379 --- diff --git a/src/arch/power/faults.hh b/src/arch/power/faults.hh index 81ea3480b..48f149fb9 100644 --- a/src/arch/power/faults.hh +++ b/src/arch/power/faults.hh @@ -136,6 +136,10 @@ class PowerInterrupt : public PowerFaultBase } }; +//SRR1 value is correctly set by the entity raising +//Instruction Storage Interrupt. So, no need to +//Update here. + class InstrStorageInterrupt : public PowerInterrupt { public: @@ -143,41 +147,14 @@ public: { } virtual void invoke(ThreadContext * tc, const StaticInstPtr &inst = - StaticInst::nullStaticInstPtr , uint64_t bitSet = 0) + StaticInst::nullStaticInstPtr) { tc->setIntReg(INTREG_SRR0 , tc->instAddr()); - PowerInterrupt::updateSRR1(tc, bitSet); PowerInterrupt::updateMsr(tc); tc->pcState(InstrStoragePCSet); } }; -class InstrInvalidInterrupt : public InstrStorageInterrupt -{ -public: - InstrInvalidInterrupt() - { - } - virtual void invoke(ThreadContext * tc, const StaticInstPtr &inst = - StaticInst::nullStaticInstPtr) - { - InstrStorageInterrupt::invoke(tc, inst ,setBitMask(INVALID_SET_BIT)); - } -}; - -//When permissions or privilege violates -class InstrPriStorageInterrupt : public InstrStorageInterrupt -{ -public: - InstrPriStorageInterrupt() - { - } - virtual void invoke(ThreadContext * tc, const StaticInstPtr &inst = - StaticInst::nullStaticInstPtr) - { - InstrStorageInterrupt::invoke(tc, inst ,setBitMask(PERMISSION_BIT)); - } -}; class DataStorageInterrupt :public PowerInterrupt { @@ -186,47 +163,15 @@ public: { } virtual void invoke(ThreadContext * tc, const StaticInstPtr &inst = - StaticInst::nullStaticInstPtr ,uint64_t bitSet = 0) + StaticInst::nullStaticInstPtr) { - Msr msr = tc->readIntReg(INTREG_MSR); tc->setIntReg(INTREG_SRR0 , tc->instAddr()); - PowerInterrupt::updateSRR1(tc, 0); - uint64_t dsisr = tc->readIntReg(INTREG_DSISR); - dsisr = (dsisr & DSISR_MASK) | bitSet; - if (msr.dr) - dsisr = setbit(33, dsisr); - tc->setIntReg(INTREG_DSISR, dsisr); + PowerInterrupt::updateSRR1(tc); PowerInterrupt::updateMsr(tc); tc->pcState(DataStoragePCSet); } }; -class DataInvalidInterrupt : public DataStorageInterrupt -{ -public: - DataInvalidInterrupt() - { - } - virtual void invoke(ThreadContext * tc, const StaticInstPtr &inst = - StaticInst::nullStaticInstPtr) - { - DataStorageInterrupt::invoke(tc, inst ,setBitMask(INVALID_SET_BIT)); - } -}; - -//When permissions or privilege violates -class DataPriStorageInterrupt : public DataStorageInterrupt -{ -public: - DataPriStorageInterrupt() - { - } - virtual void invoke(ThreadContext * tc, const StaticInstPtr &inst = - StaticInst::nullStaticInstPtr) - { - DataStorageInterrupt::invoke(tc, inst ,setBitMask(PERMISSION_BIT)); - } -}; //TODO: Need to add Floating point and TM Bad thing fault handler class ProgramInterrupt : public PowerInterrupt diff --git a/src/arch/power/radixwalk.cc b/src/arch/power/radixwalk.cc index efa3422e4..a293c595a 100644 --- a/src/arch/power/radixwalk.cc +++ b/src/arch/power/radixwalk.cc @@ -15,6 +15,7 @@ #define PRTB_MASK 0x0ffffffffffff #define PRTB_ALIGN 4 #define TABLE_BASE_ALIGN PRTB_SHIFT +#define DSISR_MASK 0x00000000ffffffff #define RPDB_SHIFT 8 #define RPDB_MASK 0x0fffffffffffff @@ -88,6 +89,40 @@ RadixWalk::writePhysMem(uint64_t addr, uint64_t dataSize) return ret; } +Fault +RadixWalk::prepareDSI(ThreadContext * tc, RequestPtr req, + BaseTLB::Mode mode, uint64_t BitMask) +{ + uint64_t dsisr = tc->readIntReg(INTREG_DSISR); + dsisr = (dsisr & (~(DSISR_MASK))) | BitMask; + if (mode == BaseTLB::Write) + dsisr = dsisr | ISSTORE; + tc->setIntReg(INTREG_DSISR, dsisr); + tc->setIntReg(INTREG_DAR, req->getVaddr()); + return std::make_shared(); +} + +Fault +RadixWalk::prepareISI(ThreadContext * tc, RequestPtr req, + uint64_t BitMask) +{ + Msr msr = tc->readIntReg(INTREG_MSR); + //here unsetting SRR1 bits 33-36 and 42-47 according to ISA + uint64_t srr1 = ((msr & unsetMask(31, 27)) & unsetMask(22,16)) | BitMask; + tc->setIntReg(INTREG_SRR1, srr1); + return std::make_shared(); +} + +Fault +RadixWalk::prepareSI(ThreadContext * tc, RequestPtr req, + BaseTLB::Mode mode, uint64_t BitMask) +{ + if (mode != BaseTLB::Execute) + return prepareDSI(tc, req, mode, BitMask); + else + return prepareISI(tc, req, BitMask); +} + uint32_t geteffLPID(ThreadContext *tc) { Msr msr = tc->readIntReg(INTREG_MSR); diff --git a/src/arch/power/radixwalk.hh b/src/arch/power/radixwalk.hh index dae379bff..850c952e8 100644 --- a/src/arch/power/radixwalk.hh +++ b/src/arch/power/radixwalk.hh @@ -70,6 +70,14 @@ namespace PowerISA std::pair walkTree(Addr vaddr ,uint64_t curBase , ThreadContext * tc ,BaseTLB::Mode mode , uint64_t curSize ,uint64_t usefulBits); + Fault prepareSI(ThreadContext * tc, + RequestPtr req, BaseTLB::Mode mode, uint64_t BitMask); + + Fault prepareISI(ThreadContext * tc, + RequestPtr req, uint64_t BitMask); + + Fault prepareDSI(ThreadContext * tc, RequestPtr req, + BaseTLB::Mode mode,uint64_t BitMask); typedef PowerRadixWalkParams Params;