46 #include "debug/GIC.hh" 82 irqAffinityRouting(it_lines, 0),
116 int max_spi_int_id =
itLines - 1;
117 int it_lines_number =
divCeil(max_spi_int_id + 1, 32) - 1;
119 (1 << 17) | (1 << 16) |
121 (it_lines_number << 0);
141 if (!
DS && !is_secure_access) {
152 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
167 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
188 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
209 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
233 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
258 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
283 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
306 for (
int i = 0, int_id = first_intid;
i < size && int_id <
itLines;
311 if (!
DS && !is_secure_access) {
317 prio = (prio << 1) & 0xff;
321 val |= prio << (
i * 8);
328 warn(
"Gicv3Distributor::read(): " 329 "GICD_ITARGETSR is RAZ/WI, legacy not supported!\n");
341 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
342 i =
i + 2, int_id++) {
361 if (!is_secure_access) {
373 for (
int i = 0, int_id = first_intid;
374 i < 8 * size && int_id <
itLines;
i++, int_id++) {
390 if (
DS || (!
DS && !is_secure_access)) {
396 for (
int i = 0, int_id = first_intid;
397 i < 8 * size && int_id <
itLines;
i =
i + 2, int_id++) {
404 warn(
"Gicv3Distributor::read(): " 405 "GICD_CPENDSGIR is RAZ/WI, legacy not supported!\n");
409 warn(
"Gicv3Distributor::read(): " 410 "GICD_SPENDSGIR is RAZ/WI, legacy not supported!\n");
441 if (is_secure_access) {
463 return (
DS << 6) | (
ARE << 4) |
499 panic(
"Gicv3Distributor::read(): invalid offset %#x\n", addr);
506 bool is_secure_access)
509 if (!
DS && !is_secure_access) {
520 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
522 irqGroup[int_id] = data & (1 <<
i) ? 1 : 0;
523 DPRINTF(GIC,
"Gicv3Distributor::write(): int_id %d group %d\n",
536 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
544 bool enable = data & (1 <<
i) ? 1 : 0;
548 DPRINTF(GIC,
"Gicv3Distributor::write(): " 549 "int_id %d enabled\n", int_id);
565 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
573 bool disable = data & (1 <<
i) ? 1 : 0;
577 DPRINTF(GIC,
"Gicv3Distributor::write(): " 578 "int_id %d disabled\n", int_id);
594 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
605 bool pending = data & (1 <<
i) ? 1 : 0;
608 DPRINTF(GIC,
"Gicv3Distributor::write() (GICD_ISPENDR): " 609 "int_id %d (SPI) pending bit set\n", int_id);
624 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
635 bool clear = data & (1 <<
i) ? 1 : 0;
653 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
661 bool active = data & (1 <<
i) ? 1 : 0;
677 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
685 bool clear = data & (1 <<
i) ? 1 : 0;
689 DPRINTF(GIC,
"Gicv3Distributor::write(): " 690 "int_id %d active cleared\n", int_id);
706 for (
int i = 0, int_id = first_intid;
i < size && int_id <
itLines;
708 uint8_t prio =
bits(data, (
i + 1) * 8 - 1, (
i * 8));
710 if (!
DS && !is_secure_access) {
715 prio = 0x80 | (prio >> 1);
720 DPRINTF(GIC,
"Gicv3Distributor::write(): int_id %d priority %d\n",
728 warn(
"Gicv3Distributor::write(): " 729 "GICD_ITARGETSR is RAZ/WI, legacy not supported!\n");
744 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
745 i =
i + 2, int_id++) {
749 DPRINTF(GIC,
"Gicv3Distributor::write(): int_id %d config %d\n",
759 if (!is_secure_access) {
769 for (
int i = 0, int_id = first_intid;
770 i < 8 * size && int_id <
itLines;
i++, int_id++) {
787 if (
DS || (!
DS && !is_secure_access)) {
791 for (
int i = 0, int_id = first_intid;
792 i < 8 * size && int_id <
itLines;
i =
i + 2, int_id++) {
793 irqNsacr[int_id] = (data >> (2 * int_id)) & 0x3;
826 DPRINTF(GIC,
"Gicv3Distributor::write(): " 827 "int_id %d GICD_IROUTER %#llx\n",
844 if ((data & (1 << 4)) == 0) {
845 warn(
"Gicv3Distributor::write(): " 846 "setting ARE to 0 is not supported!\n");
851 DPRINTF(GIC,
"Gicv3Distributor::write(): (DS 1)" 852 "EnableGrp1NS %d EnableGrp0 %d\n",
855 if (is_secure_access) {
868 if ((data & (1 << 5)) == 0) {
869 warn(
"Gicv3Distributor::write(): " 870 "setting ARE_NS to 0 is not supported!\n");
873 if ((data & (1 << 4)) == 0) {
874 warn(
"Gicv3Distributor::write(): " 875 "setting ARE_S to 0 is not supported!\n");
882 DPRINTF(GIC,
"Gicv3Distributor::write(): (DS 0 secure)" 884 "EnableGrp1S %d EnableGrp1NS %d EnableGrp0 %d\n",
887 if (data & GICD_CTLR_DS) {
897 if ((data & (1 << 4)) == 0) {
898 warn(
"Gicv3Distributor::write(): " 899 "setting ARE_NS to 0 is not supported!\n");
903 DPRINTF(GIC,
"Gicv3Distributor::write(): (DS 0 non-secure)" 923 const uint32_t intid =
bits(data, 9, 0);
942 const uint32_t intid =
bits(data, 9, 0);
960 const uint32_t intid =
bits(data, 9, 0);
976 const uint32_t intid =
bits(data, 9, 0);
987 panic(
"Gicv3Distributor::write(): invalid offset %#x\n", addr);
998 DPRINTF(GIC,
"Gicv3Distributor::sendInt(): " 999 "int_id %d (SPI) pending bit set\n", int_id);
1022 if (affinity_routing.IRM) {
1028 if (redistributor_i->
1030 target_redistributor = redistributor_i;
1035 uint32_t affinity = (affinity_routing.Aff3 << 24) |
1036 (affinity_routing.Aff2 << 16) |
1037 (affinity_routing.Aff1 << 8) |
1038 (affinity_routing.Aff0 << 0);
1039 target_redistributor =
1043 if (!target_redistributor) {
1054 auto cpu_interface =
route(int_id);
1056 cpu_interface->resetHppi(int_id);
1075 if (!target_cpu_interface)
continue;
1079 int_id < target_cpu_interface->hppi.intid)) {
1081 target_cpu_interface->
hppi.
intid = int_id;
1083 target_cpu_interface->
hppi.
group = int_group;
#define panic(...)
This implements a cprintf based panic() function.
static const AddrRange GICD_SPENDSGIR
#define UNSERIALIZE_CONTAINER(member)
std::vector< uint8_t > irqGrpmod
bool haveSecurity() const
Returns true if this system implements the Security Extensions.
bool contains(const Addr &a) const
Determine if the range contains an address.
static const AddrRange GICD_ISENABLER
uint64_t read(Addr addr, size_t size, bool is_secure_access)
std::vector< Gicv3::IntTriggerType > irqConfig
std::vector< uint8_t > irqPriority
std::vector< uint8_t > irqPriority
bool nsAccessToSecInt(uint32_t int_id, bool is_secure_access) const
std::vector< uint8_t > irqNsacr
void write(Addr addr, uint64_t data, size_t size, bool is_secure_access)
std::vector< IROUTER > irqAffinityRouting
bool canBeSelectedFor1toNInterrupt(Gicv3::GroupId group) const
void sendInt(uint32_t int_id)
static const AddrRange GICD_CPENDSGIR
static const AddrRange GICD_IGROUPR
std::vector< bool > irqEnabled
static const AddrRange GICD_ITARGETSR
void deassertSPI(uint32_t int_id)
void clearIrqCpuInterface(uint32_t int_id)
Gicv3Redistributor * getRedistributorByAffinity(uint32_t affinity) const
static const AddrRange GICD_ICENABLER
std::vector< bool > irqPending
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
#define UNSERIALIZE_SCALAR(scalar)
static const AddrRange GICD_ICFGR
static const AddrRange GICD_ISACTIVER
Gicv3CPUInterface * getCPUInterface() const
std::vector< bool > irqActive
static const uint32_t IDBITS
static const AddrRange GICD_ISPENDR
std::vector< uint8_t > irqGroup
std::vector< bool > irqPending
bool isNotSPI(uint32_t int_id) const
unsigned numContexts() const
Gicv3Distributor(Gicv3 *gic, uint32_t it_lines)
void activateIRQ(uint32_t int_id)
std::vector< bool > irqEnabled
static const AddrRange GICD_ICACTIVER
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Gicv3Redistributor * getRedistributor(ContextID context_id) const
static const AddrRange GICD_NSACR
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Gicv3::IntStatus intStatus(uint32_t int_id) const
std::vector< uint8_t > irqGrpmod
std::vector< bool > irqActive
#define SERIALIZE_SCALAR(scalar)
Gicv3::GroupId getIntGroup(int int_id) const
#define SERIALIZE_CONTAINER(member)
std::ostream CheckpointOut
static const AddrRange GICD_IPRIORITYR
static const uint32_t GICD_CTLR_ENABLEGRP1S
Gicv3CPUInterface * route(uint32_t int_id)
T divCeil(const T &a, const U &b)
std::vector< Gicv3::IntTriggerType > irqConfig
static const uint32_t GICD_CTLR_ENABLEGRP1NS
static const uint32_t GICD_CTLR_DS
std::vector< uint8_t > irqNsacr
bool groupEnabled(Gicv3::GroupId group) const
Addr start() const
Get the start address of the range.
void serialize(CheckpointOut &cp) const override
Serialize an object.
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
ArmSystem * getSystem() const
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
static const AddrRange GICD_IGRPMODR
static const uint32_t GICD_CTLR_ENABLEGRP1A
static const AddrRange GICD_IROUTER
static const AddrRange GICD_ICPENDR
std::vector< uint8_t > irqGroup
void deactivateIRQ(uint32_t int_id)
static const int INTID_SECURE