summaryrefslogtreecommitdiff
path: root/src/dev/arm/base_gic.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/dev/arm/base_gic.hh')
-rw-r--r--src/dev/arm/base_gic.hh72
1 files changed, 64 insertions, 8 deletions
diff --git a/src/dev/arm/base_gic.hh b/src/dev/arm/base_gic.hh
index c5dfa3e82..f18539fe8 100644
--- a/src/dev/arm/base_gic.hh
+++ b/src/dev/arm/base_gic.hh
@@ -44,11 +44,16 @@
#ifndef __DEV_ARM_BASE_GIC_H__
#define __DEV_ARM_BASE_GIC_H__
+#include <unordered_map>
+
#include "dev/io_device.hh"
class Platform;
class RealView;
class ThreadContext;
+class ArmInterruptPin;
+class ArmSPI;
+class ArmPPI;
struct ArmInterruptPinParams;
struct ArmPPIParams;
@@ -111,12 +116,59 @@ class BaseGicRegisters
};
/**
- * Generic representation of an Arm interrupt pin.
+ * This SimObject is instantiated in the python world and
+ * serves as an ArmInterruptPin generator. In this way it
+ * is possible to instantiate a single generator per component
+ * during configuration, and to dynamically spawn ArmInterruptPins.
+ * See ArmPPIGen for more info on how this is used.
+ */
+class ArmInterruptPinGen : public SimObject
+{
+ public:
+ ArmInterruptPinGen(const ArmInterruptPinParams *p);
+
+ virtual ArmInterruptPin* get(ThreadContext *tc = nullptr) = 0;
+};
+
+/**
+ * Shared Peripheral Interrupt Generator
+ * It is capable of generating one interrupt only: it maintains a pointer
+ * to it and returns it every time it is asked for it (via the get metod)
+ */
+class ArmSPIGen : public ArmInterruptPinGen
+{
+ public:
+ ArmSPIGen(const ArmSPIParams *p);
+
+ ArmInterruptPin* get(ThreadContext *tc = nullptr) override;
+ protected:
+ ArmSPI* pin;
+};
+
+/**
+ * Private Peripheral Interrupt Generator
+ * Since PPIs are banked in the GIC, this class is capable of generating
+ * more than one interrupt (one per ContextID).
*/
-class ArmInterruptPin : public SimObject
+class ArmPPIGen : public ArmInterruptPinGen
{
public:
- ArmInterruptPin(const ArmInterruptPinParams *p);
+ ArmPPIGen(const ArmPPIParams *p);
+
+ ArmInterruptPin* get(ThreadContext* tc = nullptr) override;
+ protected:
+ std::unordered_map<ContextID, ArmPPI*> pins;
+};
+
+/**
+ * Generic representation of an Arm interrupt pin.
+ */
+class ArmInterruptPin
+{
+ friend class ArmInterruptPinGen;
+ protected:
+ ArmInterruptPin(Platform *platform, ThreadContext *tc,
+ uint32_t int_num);
public: /* Public interface */
/**
@@ -153,27 +205,31 @@ class ArmInterruptPin : public SimObject
/** Arm platform to use for interrupt generation */
RealView *const platform;
+
/** Interrupt number to generate */
const uint32_t intNum;
};
class ArmSPI : public ArmInterruptPin
{
- public:
- ArmSPI(const ArmSPIParams *p);
+ friend class ArmSPIGen;
+ private:
+ ArmSPI(Platform *platform, uint32_t int_num);
+ public:
void raise() override;
void clear() override;
};
class ArmPPI : public ArmInterruptPin
{
- public:
- ArmPPI(const ArmPPIParams *p);
+ friend class ArmPPIGen;
+ private:
+ ArmPPI(Platform *platform, ThreadContext *tc, uint32_t int_num);
+ public:
void raise() override;
void clear() override;
};
-
#endif