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 <giacomo.travaglini@arm.com> Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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<ArmSigInterruptPinGen>(
|
||||
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<RealView*>(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();
|
||||
}
|
||||
|
||||
@@ -42,9 +42,12 @@
|
||||
#ifndef __DEV_ARM_BASE_GIC_H__
|
||||
#define __DEV_ARM_BASE_GIC_H__
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#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<ContextID, ArmPPI*> 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<std::unique_ptr<IntSourcePin<ArmSigInterruptPinGen>>> sigPin;
|
||||
|
||||
public:
|
||||
void raise() override;
|
||||
void clear() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user