From f289f9e8b5f53585a7f870377898cd4b27f8fd6d Mon Sep 17 00:00:00 2001 From: Robert Hauser <85344819+robhau@users.noreply.github.com> Date: Tue, 6 Feb 2024 18:38:50 +0100 Subject: [PATCH] arch-riscv: adding support for local interrupts (#813) Besides the standard RISC-V interrupts software, timer, and external interrupt, the RISC-V specification also offers the possibility to implement local interrupts. With this patch, we contribute an extension of RiscvInterrupts that enables connecting interrupt sources to the local interrupt controller. We assigned the local interrupts to machine-level and gave them the highest priority. If two local interrupts are pending, there exception code will be the tie-breaker (higher ID > lower ID). 32 Bit systems only recognize the local interrupts 16 to 31, 64 Bit systems 16 to 63. Change-Id: Iff8d34e740b925dce351c0c6f54f4bd37a647e0c --------- Co-authored-by: Robert Hauser --- src/arch/riscv/RiscvInterrupts.py | 26 ++++ src/arch/riscv/SConscript | 2 + src/arch/riscv/faults.hh | 49 ++++++ src/arch/riscv/interrupts.cc | 248 ++++++++++++++++++++++++++++++ src/arch/riscv/interrupts.hh | 140 ++--------------- src/arch/riscv/regs/misc.hh | 13 +- 6 files changed, 350 insertions(+), 128 deletions(-) create mode 100644 src/arch/riscv/interrupts.cc diff --git a/src/arch/riscv/RiscvInterrupts.py b/src/arch/riscv/RiscvInterrupts.py index ad64013a2e..7cb0412a69 100644 --- a/src/arch/riscv/RiscvInterrupts.py +++ b/src/arch/riscv/RiscvInterrupts.py @@ -2,6 +2,7 @@ # Copyright (c) 2014 Sven Karlsson # Copyright (c) 2016 RISC-V Foundation # Copyright (c) 2016 The University of Virginia +# Copyright (c) 2024 University of Rostock # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -27,10 +28,35 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +from m5.citations import add_citation from m5.objects.BaseInterrupts import BaseInterrupts +from m5.objects.IntPin import VectorIntSinkPin +from m5.params import VectorParam class RiscvInterrupts(BaseInterrupts): type = "RiscvInterrupts" cxx_class = "gem5::RiscvISA::Interrupts" cxx_header = "arch/riscv/interrupts.hh" + + local_interrupt_pins = VectorIntSinkPin("Pins for local interrupts") + local_interrupt_ids = VectorParam.Unsigned( + [], "list of local interrupt ids" + ) + + +add_citation( + RiscvInterrupts, + r"""@inproceedings{Hauser:2024:LocalRiscvInterrupts, + author = {Robert Hauser and + Lukas Steffen and + Florian Grützmacher and + Christian Haubelt}, + title = {Analyzing Local RISC-V Interrupt Latencies with Virtual Prototyping}, + booktitle = {Workshop Methoden und Beschreibungssprachen zur Modellierung und Verifikation von Schaltungen und Systemen (MBMV24)}, + pages = {1-7}, + year = {2024}, + month = {2} + } + """, +) diff --git a/src/arch/riscv/SConscript b/src/arch/riscv/SConscript index d183314af0..78864523c7 100644 --- a/src/arch/riscv/SConscript +++ b/src/arch/riscv/SConscript @@ -4,6 +4,7 @@ # Copyright (c) 2014 Sven Karlsson # Copyright (c) 2020 Barkhausen Institut # Copyright (c) 2021 Huawei International +# Copyright (c) 2024 University of Rostock # All rights reserved # # The license below extends only to copyright in the software and shall @@ -48,6 +49,7 @@ if env['CONF']['USE_RISCV_ISA']: Source('decoder.cc', tags='riscv isa') Source('faults.cc', tags='riscv isa') +Source('interrupts.cc', tags='riscv isa') Source('isa.cc', tags='riscv isa') Source('process.cc', tags='riscv isa') Source('pagetable.cc', tags='riscv isa') diff --git a/src/arch/riscv/faults.hh b/src/arch/riscv/faults.hh index fa67e3b34c..36fec182e7 100644 --- a/src/arch/riscv/faults.hh +++ b/src/arch/riscv/faults.hh @@ -2,6 +2,7 @@ * Copyright (c) 2016 RISC-V Foundation * Copyright (c) 2016 The University of Virginia * Copyright (c) 2018 TU Dresden + * Copyright (c) 2024 University of Rostock * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -93,6 +94,54 @@ enum ExceptionCode : uint64_t INT_EXT_USER = 8, INT_EXT_SUPER = 9, INT_EXT_MACHINE = 11, + INT_LOCAL_0 = 16, + INT_LOCAL_1 = 17, + INT_LOCAL_2 = 18, + INT_LOCAL_3 = 19, + INT_LOCAL_4 = 20, + INT_LOCAL_5 = 21, + INT_LOCAL_6 = 22, + INT_LOCAL_7 = 23, + INT_LOCAL_8 = 24, + INT_LOCAL_9 = 25, + INT_LOCAL_10 = 26, + INT_LOCAL_11 = 27, + INT_LOCAL_12 = 28, + INT_LOCAL_13 = 29, + INT_LOCAL_14 = 30, + INT_LOCAL_15 = 31, + INT_LOCAL_16 = 32, + INT_LOCAL_17 = 33, + INT_LOCAL_18 = 34, + INT_LOCAL_19 = 35, + INT_LOCAL_20 = 36, + INT_LOCAL_21 = 37, + INT_LOCAL_22 = 38, + INT_LOCAL_23 = 39, + INT_LOCAL_24 = 40, + INT_LOCAL_25 = 41, + INT_LOCAL_26 = 42, + INT_LOCAL_27 = 43, + INT_LOCAL_28 = 44, + INT_LOCAL_29 = 45, + INT_LOCAL_30 = 46, + INT_LOCAL_31 = 47, + INT_LOCAL_32 = 48, + INT_LOCAL_33 = 49, + INT_LOCAL_34 = 50, + INT_LOCAL_35 = 51, + INT_LOCAL_36 = 52, + INT_LOCAL_37 = 53, + INT_LOCAL_38 = 54, + INT_LOCAL_39 = 55, + INT_LOCAL_40 = 56, + INT_LOCAL_41 = 57, + INT_LOCAL_42 = 58, + INT_LOCAL_43 = 59, + INT_LOCAL_44 = 60, + INT_LOCAL_45 = 61, + INT_LOCAL_46 = 62, + INT_LOCAL_47 = 63, NumInterruptTypes, // INT_NMI does not exist in the spec, it's a modeling artifact for NMI. We // intentionally set it to be NumInterruptTypes so it can never conflict diff --git a/src/arch/riscv/interrupts.cc b/src/arch/riscv/interrupts.cc new file mode 100644 index 0000000000..29770781ef --- /dev/null +++ b/src/arch/riscv/interrupts.cc @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2011 Google + * Copyright (c) 2024 University of Rostock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "arch/riscv/interrupts.hh" + +namespace gem5 +{ + +namespace RiscvISA +{ + +Interrupts::Interrupts(const Params &p) : BaseInterrupts(p), + ip(0), + ie(0) +{ + for (uint8_t i = 0; + i < p.port_local_interrupt_pins_connection_count; + ++i) { + uint8_t interruptID = p.local_interrupt_ids[i]; + assert(interruptID >= 0); + assert(interruptID <= 47); + std::string pinName = + csprintf("%s.local_interrupt_pins[%d]", p.name, i); + IntSinkPin* pin = + new IntSinkPin(pinName,i, this, interruptID); + localInterruptPins.push_back(pin); + } +} + + +std::bitset +Interrupts::globalMask() const +{ + INTERRUPT mask = 0; + STATUS status = tc->readMiscReg(MISCREG_STATUS); + MISA misa = tc->readMiscRegNoEffect(MISCREG_ISA); + INTERRUPT mideleg = 0; + if (misa.rvs || misa.rvn) { + mideleg = tc->readMiscReg(MISCREG_MIDELEG); + } + INTERRUPT sideleg = 0; + if (misa.rvs && misa.rvn) { + sideleg = tc->readMiscReg(MISCREG_SIDELEG); + } + PrivilegeMode prv = (PrivilegeMode)tc->readMiscReg(MISCREG_PRV); + switch (prv) { + case PRV_U: + // status.uie is always 0 if misa.rvn is disabled + if (misa.rvs) { + mask.local = ~sideleg.local; + if (status.uie) + mask.local = mask.local | sideleg.local; + mask.mei = (!sideleg.mei) | (sideleg.mei & status.uie); + mask.mti = (!sideleg.mti) | (sideleg.mti & status.uie); + mask.msi = (!sideleg.msi) | (sideleg.msi & status.uie); + mask.sei = (!sideleg.sei) | (sideleg.sei & status.uie); + mask.sti = (!sideleg.sti) | (sideleg.sti & status.uie); + mask.ssi = (!sideleg.ssi) | (sideleg.ssi & status.uie); + } else { + // According to the RISC-V privilege spec v1.10, if the + // S privilege mode is not implemented and user-trap + // support, setting mideleg/medeleg bits will delegate the + // trap to U-mode trap handler + mask.local = ~mideleg.local; + if (status.uie) + mask.local = mask.local | mideleg.local; + mask.mei = (!mideleg.mei) | (mideleg.mei & status.uie); + mask.mti = (!mideleg.mti) | (mideleg.mti & status.uie); + mask.msi = (!mideleg.msi) | (mideleg.msi & status.uie); + mask.sei = mask.sti = mask.ssi = 0; + } + if (status.uie) + mask.uei = mask.uti = mask.usi = 1; + break; + case PRV_S: + mask.local = ~mideleg.local; + mask.mei = (!mideleg.mei) | (mideleg.mei & status.sie); + mask.mti = (!mideleg.mti) | (mideleg.mti & status.sie); + mask.msi = (!mideleg.msi) | (mideleg.msi & status.sie); + if (status.sie) { + mask.sei = mask.sti = mask.ssi = 1; + mask.local = mask.local | mideleg.local; + } + mask.uei = mask.uti = mask.usi = 0; + break; + case PRV_M: + + if (status.mie) { + mask.local = gem5::mask(48); + mask.mei = mask.mti = mask.msi = 1; + } + mask.sei = mask.sti = mask.ssi = 0; + mask.uei = mask.uti = mask.usi = 0; + break; + default: + panic("Unknown privilege mode %d.", prv); + break; + } + + return std::bitset(mask); +} + +Fault +Interrupts::getInterrupt() +{ + assert(checkInterrupts()); + if (checkNonMaskableInterrupt()) + return std::make_shared(); + std::bitset mask = globalMask(); + if (((ISA*) tc->getIsaPtr())->rvType() == RV64) { + const std::vector interrupt_order { + INT_LOCAL_47, INT_LOCAL_46, INT_LOCAL_45, INT_LOCAL_44, + INT_LOCAL_43, INT_LOCAL_42, INT_LOCAL_41, INT_LOCAL_40, + INT_LOCAL_39, INT_LOCAL_38, INT_LOCAL_37, INT_LOCAL_36, + INT_LOCAL_35, INT_LOCAL_34, INT_LOCAL_33, INT_LOCAL_32, + INT_LOCAL_31, INT_LOCAL_30, INT_LOCAL_29, INT_LOCAL_28, + INT_LOCAL_27, INT_LOCAL_26, INT_LOCAL_25, INT_LOCAL_24, + INT_LOCAL_23, INT_LOCAL_22, INT_LOCAL_21, INT_LOCAL_20, + INT_LOCAL_19, INT_LOCAL_18, INT_LOCAL_17, INT_LOCAL_16, + INT_LOCAL_15, INT_LOCAL_14, INT_LOCAL_13, INT_LOCAL_12, + INT_LOCAL_11, INT_LOCAL_10, INT_LOCAL_9, INT_LOCAL_8, + INT_LOCAL_7, INT_LOCAL_6, INT_LOCAL_5, INT_LOCAL_4, + INT_LOCAL_3, INT_LOCAL_2, INT_LOCAL_1, INT_LOCAL_0, + INT_EXT_MACHINE, INT_SOFTWARE_MACHINE, INT_TIMER_MACHINE, + INT_EXT_SUPER, INT_SOFTWARE_SUPER, INT_TIMER_SUPER, + INT_EXT_USER, INT_SOFTWARE_USER, INT_TIMER_USER + }; + for (const int &id : interrupt_order) { + if (checkInterrupt(id) && mask[id]) { + return std::make_shared(id); + } + } + } else if (((ISA*) tc->getIsaPtr())->rvType() == RV32) { + const std::vector interrupt_order { + INT_LOCAL_15, INT_LOCAL_14, INT_LOCAL_13, INT_LOCAL_12, + INT_LOCAL_11, INT_LOCAL_10, INT_LOCAL_9, INT_LOCAL_8, + INT_LOCAL_7, INT_LOCAL_6, INT_LOCAL_5, INT_LOCAL_4, + INT_LOCAL_3, INT_LOCAL_2, INT_LOCAL_1, INT_LOCAL_0, + INT_EXT_MACHINE, INT_SOFTWARE_MACHINE, INT_TIMER_MACHINE, + INT_EXT_SUPER, INT_SOFTWARE_SUPER, INT_TIMER_SUPER, + INT_EXT_USER, INT_SOFTWARE_USER, INT_TIMER_USER + }; + for (const int &id : interrupt_order) { + if (checkInterrupt(id) && mask[id]) { + return std::make_shared(id); + } + } + } + return NoFault; +} + +void +Interrupts::post(int int_num, int index) +{ + DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); + if (int_num != INT_NMI) { + ip[int_num] = true; + } else { + postNMI(); + } +} + +void +Interrupts::clear(int int_num, int index) +{ + DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); + if (int_num != INT_NMI) { + ip[int_num] = false; + } else { + clearNMI(); + } +} + +void +Interrupts::clearAll() +{ + DPRINTF(Interrupt, "All interrupts cleared\n"); + ip = 0; + clearNMI(); +} + +void +Interrupts::raiseInterruptPin(uint32_t num) +{ + tc->getCpuPtr()->postInterrupt(tc->threadId(), num + 16, 0); +} + +void +Interrupts::serialize(CheckpointOut &cp) const +{ + unsigned long ip_ulong = ip.to_ulong(); + unsigned long ie_ulong = ie.to_ulong(); + SERIALIZE_SCALAR(ip_ulong); + SERIALIZE_SCALAR(ie_ulong); +} + +void +Interrupts::unserialize(CheckpointIn &cp) +{ + unsigned long ip_ulong; + unsigned long ie_ulong; + UNSERIALIZE_SCALAR(ip_ulong); + ip = ip_ulong; + UNSERIALIZE_SCALAR(ie_ulong); + ie = ie_ulong; +} + +Port & +Interrupts::getPort(const std::string &if_name, PortID idx) +{ + + if (if_name == "local_interrupt_pins" && idx < localInterruptPins.size()) { + return *localInterruptPins[idx]; + } else { + return BaseInterrupts::getPort(if_name, idx); + } +} + +} // namespace RiscvISA + +} // namespace gem5 diff --git a/src/arch/riscv/interrupts.hh b/src/arch/riscv/interrupts.hh index b003b59426..a10479fb65 100644 --- a/src/arch/riscv/interrupts.hh +++ b/src/arch/riscv/interrupts.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2011 Google + * Copyright (c) 2024 University of Rostock * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,8 +37,10 @@ #include "arch/riscv/faults.hh" #include "arch/riscv/regs/misc.hh" #include "base/logging.hh" +#include "cpu/base.hh" #include "cpu/thread_context.hh" #include "debug/Interrupt.hh" +#include "dev/intpin.hh" #include "params/RiscvInterrupts.hh" #include "sim/sim_object.hh" @@ -59,71 +62,13 @@ class Interrupts : public BaseInterrupts std::bitset ip; std::bitset ie; + std::vector*> localInterruptPins; public: using Params = RiscvInterruptsParams; - Interrupts(const Params &p) : BaseInterrupts(p), ip(0), ie(0) {} + Interrupts(const Params &p); - std::bitset - globalMask() const - { - INTERRUPT mask = 0; - STATUS status = tc->readMiscReg(MISCREG_STATUS); - MISA misa = tc->readMiscRegNoEffect(MISCREG_ISA); - INTERRUPT mideleg = 0; - if (misa.rvs || misa.rvn) { - mideleg = tc->readMiscReg(MISCREG_MIDELEG); - } - INTERRUPT sideleg = 0; - if (misa.rvs && misa.rvn) { - sideleg = tc->readMiscReg(MISCREG_SIDELEG); - } - PrivilegeMode prv = (PrivilegeMode)tc->readMiscReg(MISCREG_PRV); - switch (prv) { - case PRV_U: - // status.uie is always 0 if misa.rvn is disabled - if (misa.rvs) { - mask.mei = (!sideleg.mei) | (sideleg.mei & status.uie); - mask.mti = (!sideleg.mti) | (sideleg.mti & status.uie); - mask.msi = (!sideleg.msi) | (sideleg.msi & status.uie); - mask.sei = (!sideleg.sei) | (sideleg.sei & status.uie); - mask.sti = (!sideleg.sti) | (sideleg.sti & status.uie); - mask.ssi = (!sideleg.ssi) | (sideleg.ssi & status.uie); - } else { - // According to the RISC-V privilege spec v1.10, if the - // S privilege mode is not implemented and user-trap - // support, setting mideleg/medeleg bits will delegate the - // trap to U-mode trap handler - mask.mei = (!mideleg.mei) | (mideleg.mei & status.uie); - mask.mti = (!mideleg.mti) | (mideleg.mti & status.uie); - mask.msi = (!mideleg.msi) | (mideleg.msi & status.uie); - mask.sei = mask.sti = mask.ssi = 0; - } - if (status.uie) - mask.uei = mask.uti = mask.usi = 1; - break; - case PRV_S: - // status.sie is always 0 if misa.rvn is disabled - mask.mei = (!mideleg.mei) | (mideleg.mei & status.sie); - mask.mti = (!mideleg.mti) | (mideleg.mti & status.sie); - mask.msi = (!mideleg.msi) | (mideleg.msi & status.sie); - if (status.sie) - mask.sei = mask.sti = mask.ssi = 1; - mask.uei = mask.uti = mask.usi = 0; - break; - case PRV_M: - if (status.mie) - mask.mei = mask.mti = mask.msi = 1; - mask.sei = mask.sti = mask.ssi = 0; - mask.uei = mask.uti = mask.usi = 0; - break; - default: - panic("Unknown privilege mode %d.", prv); - break; - } - - return std::bitset(mask); - } + std::bitset globalMask() const; bool checkNonMaskableInterrupt() const @@ -137,83 +82,32 @@ class Interrupts : public BaseInterrupts return checkNonMaskableInterrupt() || (ip & ie & globalMask()).any(); } - Fault - getInterrupt() override - { - assert(checkInterrupts()); - if (checkNonMaskableInterrupt()) - return std::make_shared(); - std::bitset mask = globalMask(); - const std::vector interrupt_order { - INT_EXT_MACHINE, INT_SOFTWARE_MACHINE, INT_TIMER_MACHINE, - INT_EXT_SUPER, INT_SOFTWARE_SUPER, INT_TIMER_SUPER, - INT_EXT_USER, INT_SOFTWARE_USER, INT_TIMER_USER - }; - for (const int &id : interrupt_order) - if (checkInterrupt(id) && mask[id]) - return std::make_shared(id); - return NoFault; - } + Fault getInterrupt() override; void updateIntrInfo() override {} - void - post(int int_num, int index) override - { - DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); - if (int_num != INT_NMI) { - ip[int_num] = true; - } else { - postNMI(); - } - } + void post(int int_num, int index) override; - void - clear(int int_num, int index) override - { - DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); - if (int_num != INT_NMI) { - ip[int_num] = false; - } else { - clearNMI(); - } - } + void clear(int int_num, int index) override; void postNMI() { tc->setMiscReg(MISCREG_NMIP, 1); } void clearNMI() { tc->setMiscReg(MISCREG_NMIP, 0); } - void - clearAll() override - { - DPRINTF(Interrupt, "All interrupts cleared\n"); - ip = 0; - clearNMI(); - } + void clearAll() override; uint64_t readIP() const { return (uint64_t)ip.to_ulong(); } uint64_t readIE() const { return (uint64_t)ie.to_ulong(); } void setIP(const uint64_t& val) { ip = val; } void setIE(const uint64_t& val) { ie = val; } - void - serialize(CheckpointOut &cp) const override - { - unsigned long ip_ulong = ip.to_ulong(); - unsigned long ie_ulong = ie.to_ulong(); - SERIALIZE_SCALAR(ip_ulong); - SERIALIZE_SCALAR(ie_ulong); - } + void serialize(CheckpointOut &cp) const override; - void - unserialize(CheckpointIn &cp) override - { - unsigned long ip_ulong; - unsigned long ie_ulong; - UNSERIALIZE_SCALAR(ip_ulong); - ip = ip_ulong; - UNSERIALIZE_SCALAR(ie_ulong); - ie = ie_ulong; - } + void unserialize(CheckpointIn &cp) override; + + Port &getPort(const std::string &if_name, PortID idx) override; + + void raiseInterruptPin(uint32_t num); + void lowerInterruptPin(uint32_t num) {}; }; } // namespace RiscvISA diff --git a/src/arch/riscv/regs/misc.hh b/src/arch/riscv/regs/misc.hh index 96e88c7438..837cbfacbd 100644 --- a/src/arch/riscv/regs/misc.hh +++ b/src/arch/riscv/regs/misc.hh @@ -17,6 +17,7 @@ * * Copyright (c) 2016 RISC-V Foundation * Copyright (c) 2016 The University of Virginia + * Copyright (c) 2024 University of Rostock * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -1233,6 +1234,7 @@ EndBitUnion(MISA) * this bit union. */ BitUnion64(INTERRUPT) + Bitfield<63,16> local; Bitfield<11> mei; Bitfield<9> sei; Bitfield<8> uei; @@ -1438,6 +1440,7 @@ USTATUS_MASKS[enums::Num_RiscvType][enums::Num_PrivilegeModeSet] = { }, }; +const RegVal LOCAL_MASK = mask(63,16); const RegVal MEI_MASK = 1ULL << 11; const RegVal SEI_MASK = 1ULL << 9; const RegVal UEI_MASK = 1ULL << 8; @@ -1448,13 +1451,13 @@ const RegVal MSI_MASK = 1ULL << 3; const RegVal SSI_MASK = 1ULL << 1; const RegVal USI_MASK = 1ULL << 0; const RegVal MI_MASK[enums::Num_PrivilegeModeSet] = { - [enums::M] = MEI_MASK| MTI_MASK | MSI_MASK, - [enums::MU] = MEI_MASK| MTI_MASK | MSI_MASK, - [enums::MNU] = MEI_MASK | UEI_MASK | MTI_MASK | UTI_MASK | + [enums::M] = LOCAL_MASK | MEI_MASK| MTI_MASK | MSI_MASK, + [enums::MU] = LOCAL_MASK | MEI_MASK| MTI_MASK | MSI_MASK, + [enums::MNU] = LOCAL_MASK | MEI_MASK | UEI_MASK | MTI_MASK | UTI_MASK | MSI_MASK | USI_MASK, - [enums::MSU] = MEI_MASK | SEI_MASK | MTI_MASK | STI_MASK | + [enums::MSU] = LOCAL_MASK | MEI_MASK | SEI_MASK | MTI_MASK | STI_MASK | MSI_MASK | SSI_MASK, - [enums::MNSU] = MEI_MASK | SEI_MASK | UEI_MASK | + [enums::MNSU] = LOCAL_MASK | MEI_MASK | SEI_MASK | UEI_MASK | MTI_MASK | STI_MASK | UTI_MASK | MSI_MASK | SSI_MASK | USI_MASK, };