From 3aa64284b14c5ed34c0146c77d6b232127057781 Mon Sep 17 00:00:00 2001 From: Yu-hsin Wang Date: Mon, 10 May 2021 15:06:53 +0800 Subject: [PATCH] dev-arm: add ArmSigInterruptPin ArmSigInterruptPin helps connecting ArmInterruptPin with general interrupt pin. Change-Id: I4235fa0714054079a111163caca8dd3985999095 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/45266 Reviewed-by: Giacomo Travaglini Maintainer: Giacomo Travaglini Tested-by: kokoro --- src/dev/arm/Gic.py | 8 +++++++ src/dev/arm/base_gic.cc | 50 +++++++++++++++++++++++++++++++++++++++++ src/dev/arm/base_gic.hh | 31 +++++++++++++++++++++++++ 3 files changed, 89 insertions(+) diff --git a/src/dev/arm/Gic.py b/src/dev/arm/Gic.py index a24256c272..8531aaa5a1 100644 --- a/src/dev/arm/Gic.py +++ b/src/dev/arm/Gic.py @@ -40,6 +40,7 @@ from m5.SimObject import SimObject from m5.objects.Device import PioDevice, BasicPioDevice from m5.objects.Platform import Platform +from m5.objects.IntPin import IntSourcePin class BaseGic(PioDevice): type = 'BaseGic' @@ -137,6 +138,13 @@ class ArmPPI(ArmInterruptPin): return gic.interruptCells( self._LINUX_ID, self.num - 16, int(self.int_type.getValue())) +class ArmSigInterruptPin(ArmInterruptPin): + type = 'ArmSigInterruptPin' + cxx_header = "dev/arm/base_gic.hh" + cxx_class = "ArmSigInterruptPinGen" + + irq = IntSourcePin('Interrupt pin') + class GicV2(BaseGic): type = 'GicV2' cxx_header = "dev/arm/gic_v2.hh" diff --git a/src/dev/arm/base_gic.cc b/src/dev/arm/base_gic.cc index f94cb9735b..27bf2660ca 100644 --- a/src/dev/arm/base_gic.cc +++ b/src/dev/arm/base_gic.cc @@ -41,6 +41,7 @@ #include "dev/arm/realview.hh" #include "params/ArmInterruptPin.hh" #include "params/ArmPPI.hh" +#include "params/ArmSigInterruptPin.hh" #include "params/ArmSPI.hh" #include "params/BaseGic.hh" @@ -117,6 +118,33 @@ ArmPPIGen::get(ThreadContext* tc) } } +ArmSigInterruptPinGen::ArmSigInterruptPinGen(const ArmSigInterruptPinParams &p) + : ArmInterruptPinGen(p), pin(new ArmSigInterruptPin(p)) +{} + +ArmInterruptPin* +ArmSigInterruptPinGen::get(ThreadContext* tc) +{ + return pin; +} + +Port & +ArmSigInterruptPinGen::getPort(const std::string &if_name, PortID idx) +{ + if (if_name == "irq") { + assert(idx != InvalidPortID); + if (idx >= pin->sigPin.size()) + pin->sigPin.resize(idx + 1); + if (!pin->sigPin.at(idx)) + pin->sigPin.at(idx).reset( + new IntSourcePin( + csprintf("%s.irq[%d]", name(), idx), idx, this)); + return *pin->sigPin.at(idx); + } + + return ArmInterruptPinGen::getPort(if_name, idx); +} + ArmInterruptPin::ArmInterruptPin( const ArmInterruptPinParams &p, ThreadContext *tc) : threadContext(tc), platform(dynamic_cast(p.platform)), @@ -193,3 +221,25 @@ ArmPPI::clear() _active = false; platform->gic->clearPPInt(intNum, targetContext()); } + +ArmSigInterruptPin::ArmSigInterruptPin(const ArmSigInterruptPinParams &p) + : ArmInterruptPin(p, nullptr) +{} + +void +ArmSigInterruptPin::raise() +{ + _active = true; + for (auto &pin : sigPin) + if (pin) + pin->raise(); +} + +void +ArmSigInterruptPin::clear() +{ + _active = false; + for (auto &pin : sigPin) + if (pin) + pin->lower(); +} diff --git a/src/dev/arm/base_gic.hh b/src/dev/arm/base_gic.hh index 058f2bb2a9..d6d856e1ca 100644 --- a/src/dev/arm/base_gic.hh +++ b/src/dev/arm/base_gic.hh @@ -42,9 +42,12 @@ #ifndef __DEV_ARM_BASE_GIC_H__ #define __DEV_ARM_BASE_GIC_H__ +#include #include +#include #include "arch/arm/system.hh" +#include "dev/intpin.hh" #include "dev/io_device.hh" #include "enums/ArmInterruptType.hh" @@ -55,10 +58,12 @@ class ThreadContext; class ArmInterruptPin; class ArmSPI; class ArmPPI; +class ArmSigInterruptPin; struct ArmInterruptPinParams; struct ArmPPIParams; struct ArmSPIParams; +struct ArmSigInterruptPinParams; struct BaseGicParams; class BaseGic : public PioDevice @@ -173,6 +178,19 @@ class ArmPPIGen : public ArmInterruptPinGen std::unordered_map pins; }; +class ArmSigInterruptPinGen : public ArmInterruptPinGen +{ + public: + ArmSigInterruptPinGen(const ArmSigInterruptPinParams &p); + + ArmInterruptPin* get(ThreadContext* tc = nullptr) override; + Port &getPort(const std::string &if_name, + PortID idx = InvalidPortID) override; + + protected: + ArmSigInterruptPin* pin; +}; + /** * Generic representation of an Arm interrupt pin. */ @@ -257,4 +275,17 @@ class ArmPPI : public ArmInterruptPin void clear() override; }; +class ArmSigInterruptPin : public ArmInterruptPin +{ + friend class ArmSigInterruptPinGen; + private: + ArmSigInterruptPin(const ArmSigInterruptPinParams &p); + + std::vector>> sigPin; + + public: + void raise() override; + void clear() override; +}; + #endif