dev-arm: Define ArmInterruptType
This is a scoped enum meant to be used mainly in the python world for DTB autogeneration. By making an ArmInterruptPin self aware of its own type, we can use it in the C++ world when modelling devices. For example if a device spec is enforcing a specific triggering behaviour, its gem5 implementation can query the interrupt type and panic if its expectations are not met. In this way we are sure what the Linux kernel sees in the DTB is in sync with how the model really behaves Change-Id: I66ae3cfbc7b1ed94804f1f882c12eb31f70840da Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35395 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2012-2013, 2017-2019 ARM Limited
|
||||
# Copyright (c) 2012-2013, 2017-2020 ARM Limited
|
||||
# All rights reserved.
|
||||
#
|
||||
# The license below extends only to copyright in the software and shall
|
||||
@@ -70,6 +70,19 @@ class BaseGic(PioDevice):
|
||||
assert self._state.interrupt_cells == 3
|
||||
return [ int_type, int_num, int_flag ]
|
||||
|
||||
class ArmInterruptType(ScopedEnum):
|
||||
"""
|
||||
The values of the scoped enum are matching Linux macroes
|
||||
defined in include/linux/irq.h. They are mainly meant
|
||||
to be used for DTB autogen
|
||||
"""
|
||||
map = {
|
||||
'IRQ_TYPE_EDGE_RISING' : 0x1,
|
||||
'IRQ_TYPE_EDGE_FALLING' : 0x2,
|
||||
'IRQ_TYPE_LEVEL_HIGH' : 0x4,
|
||||
'IRQ_TYPE_LEVEL_LOW' : 0x8
|
||||
}
|
||||
|
||||
class ArmInterruptPin(SimObject):
|
||||
type = 'ArmInterruptPin'
|
||||
cxx_header = "dev/arm/base_gic.hh"
|
||||
@@ -78,6 +91,8 @@ class ArmInterruptPin(SimObject):
|
||||
|
||||
platform = Param.Platform(Parent.any, "Platform with interrupt controller")
|
||||
num = Param.UInt32("Interrupt number in GIC")
|
||||
int_type = Param.ArmInterruptType('IRQ_TYPE_LEVEL_HIGH',
|
||||
"Interrupt type (level/edge triggered)")
|
||||
|
||||
class ArmSPI(ArmInterruptPin):
|
||||
type = 'ArmSPI'
|
||||
|
||||
@@ -81,7 +81,7 @@ ArmInterruptPinGen::ArmInterruptPinGen(const ArmInterruptPinParams &p)
|
||||
}
|
||||
|
||||
ArmSPIGen::ArmSPIGen(const ArmSPIParams &p)
|
||||
: ArmInterruptPinGen(p), pin(new ArmSPI(p.platform, p.num))
|
||||
: ArmInterruptPinGen(p), pin(new ArmSPI(p))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ ArmPPIGen::get(ThreadContext* tc)
|
||||
} else {
|
||||
// Generate PPI Pin
|
||||
auto &p = static_cast<const ArmPPIParams &>(_params);
|
||||
ArmPPI *pin = new ArmPPI(p.platform, tc, p.num);
|
||||
ArmPPI *pin = new ArmPPI(p, tc);
|
||||
|
||||
pins.insert({cid, pin});
|
||||
|
||||
@@ -119,9 +119,9 @@ ArmPPIGen::get(ThreadContext* tc)
|
||||
}
|
||||
|
||||
ArmInterruptPin::ArmInterruptPin(
|
||||
Platform *_platform, ThreadContext *tc, uint32_t int_num)
|
||||
: threadContext(tc), platform(dynamic_cast<RealView*>(_platform)),
|
||||
intNum(int_num), _active(false)
|
||||
const ArmInterruptPinParams &p, ThreadContext *tc)
|
||||
: threadContext(tc), platform(dynamic_cast<RealView*>(p.platform)),
|
||||
intNum(p.num), triggerType(p.int_type), _active(false)
|
||||
{
|
||||
fatal_if(!platform, "Interrupt not connected to a RealView platform");
|
||||
}
|
||||
@@ -156,8 +156,8 @@ ArmInterruptPin::unserialize(CheckpointIn &cp)
|
||||
}
|
||||
|
||||
ArmSPI::ArmSPI(
|
||||
Platform *_platform, uint32_t int_num)
|
||||
: ArmInterruptPin(_platform, nullptr, int_num)
|
||||
const ArmSPIParams &p)
|
||||
: ArmInterruptPin(p, nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -176,8 +176,8 @@ ArmSPI::clear()
|
||||
}
|
||||
|
||||
ArmPPI::ArmPPI(
|
||||
Platform *_platform, ThreadContext *tc, uint32_t int_num)
|
||||
: ArmInterruptPin(_platform, tc, int_num)
|
||||
const ArmPPIParams &p, ThreadContext *tc)
|
||||
: ArmInterruptPin(p, tc)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
#include "arch/arm/system.hh"
|
||||
#include "dev/io_device.hh"
|
||||
|
||||
#include "enums/ArmInterruptType.hh"
|
||||
|
||||
class Platform;
|
||||
class RealView;
|
||||
class ThreadContext;
|
||||
@@ -177,8 +179,7 @@ class ArmInterruptPin : public Serializable
|
||||
{
|
||||
friend class ArmInterruptPinGen;
|
||||
protected:
|
||||
ArmInterruptPin(Platform *platform, ThreadContext *tc,
|
||||
uint32_t int_num);
|
||||
ArmInterruptPin(const ArmInterruptPinParams &p, ThreadContext *tc);
|
||||
|
||||
public: /* Public interface */
|
||||
/**
|
||||
@@ -226,6 +227,9 @@ class ArmInterruptPin : public Serializable
|
||||
/** Interrupt number to generate */
|
||||
const uint32_t intNum;
|
||||
|
||||
/** Interrupt triggering type */
|
||||
const ArmInterruptType triggerType;
|
||||
|
||||
/** True if interrupt pin is active, false otherwise */
|
||||
bool _active;
|
||||
};
|
||||
@@ -234,7 +238,7 @@ class ArmSPI : public ArmInterruptPin
|
||||
{
|
||||
friend class ArmSPIGen;
|
||||
private:
|
||||
ArmSPI(Platform *platform, uint32_t int_num);
|
||||
ArmSPI(const ArmSPIParams &p);
|
||||
|
||||
public:
|
||||
void raise() override;
|
||||
@@ -245,7 +249,7 @@ class ArmPPI : public ArmInterruptPin
|
||||
{
|
||||
friend class ArmPPIGen;
|
||||
private:
|
||||
ArmPPI(Platform *platform, ThreadContext *tc, uint32_t int_num);
|
||||
ArmPPI(const ArmPPIParams &p, ThreadContext *tc);
|
||||
|
||||
public:
|
||||
void raise() override;
|
||||
|
||||
Reference in New Issue
Block a user