48 #include "debug/GIC.hh" 84 irqAffinityRouting(it_lines, 0),
118 int max_spi_int_id =
itLines - 1;
119 int it_lines_number =
divCeil(max_spi_int_id + 1, 32) - 1;
121 (1 << 17) | (1 << 16) |
123 (it_lines_number << 0);
143 if (!
DS && !is_secure_access) {
154 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
169 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
190 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
211 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
235 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
260 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
285 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
308 for (
int i = 0, int_id = first_intid;
i < size && int_id <
itLines;
313 if (!
DS && !is_secure_access) {
319 prio = (prio << 1) & 0xff;
323 val |= prio << (
i * 8);
330 warn(
"Gicv3Distributor::read(): " 331 "GICD_ITARGETSR is RAZ/WI, legacy not supported!\n");
343 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
344 i =
i + 2, int_id++) {
363 if (!is_secure_access) {
375 for (
int i = 0, int_id = first_intid;
376 i < 8 * size && int_id <
itLines;
i++, int_id++) {
392 if (
DS || (!
DS && !is_secure_access)) {
398 for (
int i = 0, int_id = first_intid;
399 i < 8 * size && int_id <
itLines;
i =
i + 2, int_id++) {
406 warn(
"Gicv3Distributor::read(): " 407 "GICD_CPENDSGIR is RAZ/WI, legacy not supported!\n");
411 warn(
"Gicv3Distributor::read(): " 412 "GICD_SPENDSGIR is RAZ/WI, legacy not supported!\n");
443 if (is_secure_access) {
465 return (
DS << 6) | (
ARE << 4) |
501 panic(
"Gicv3Distributor::read(): invalid offset %#x\n", addr);
508 bool is_secure_access)
511 if (!
DS && !is_secure_access) {
522 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
524 irqGroup[int_id] = data & (1 <<
i) ? 1 : 0;
525 DPRINTF(GIC,
"Gicv3Distributor::write(): int_id %d group %d\n",
538 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
546 bool enable = data & (1 <<
i) ? 1 : 0;
550 DPRINTF(GIC,
"Gicv3Distributor::write(): " 551 "int_id %d enabled\n", int_id);
567 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
575 bool disable = data & (1 <<
i) ? 1 : 0;
579 DPRINTF(GIC,
"Gicv3Distributor::write(): " 580 "int_id %d disabled\n", int_id);
596 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
607 bool pending = data & (1 <<
i) ? 1 : 0;
610 DPRINTF(GIC,
"Gicv3Distributor::write() (GICD_ISPENDR): " 611 "int_id %d (SPI) pending bit set\n", int_id);
626 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
637 bool clear = data & (1 <<
i) ? 1 : 0;
655 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
663 bool active = data & (1 <<
i) ? 1 : 0;
679 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
687 bool clear = data & (1 <<
i) ? 1 : 0;
691 DPRINTF(GIC,
"Gicv3Distributor::write(): " 692 "int_id %d active cleared\n", int_id);
708 for (
int i = 0, int_id = first_intid;
i < size && int_id <
itLines;
710 uint8_t prio =
bits(data, (
i + 1) * 8 - 1, (
i * 8));
712 if (!
DS && !is_secure_access) {
717 prio = 0x80 | (prio >> 1);
722 DPRINTF(GIC,
"Gicv3Distributor::write(): int_id %d priority %d\n",
730 warn(
"Gicv3Distributor::write(): " 731 "GICD_ITARGETSR is RAZ/WI, legacy not supported!\n");
746 for (
int i = 0, int_id = first_intid;
i < 8 * size && int_id <
itLines;
747 i =
i + 2, int_id++) {
751 DPRINTF(GIC,
"Gicv3Distributor::write(): int_id %d config %d\n",
761 if (!is_secure_access) {
771 for (
int i = 0, int_id = first_intid;
772 i < 8 * size && int_id <
itLines;
i++, int_id++) {
789 if (
DS || (!
DS && !is_secure_access)) {
793 for (
int i = 0, int_id = first_intid;
794 i < 8 * size && int_id <
itLines;
i =
i + 2, int_id++) {
795 irqNsacr[int_id] = (data >> (2 * int_id)) & 0x3;
828 DPRINTF(GIC,
"Gicv3Distributor::write(): " 829 "int_id %d GICD_IROUTER %#llx\n",
846 if ((data & (1 << 4)) == 0) {
847 warn(
"Gicv3Distributor::write(): " 848 "setting ARE to 0 is not supported!\n");
853 DPRINTF(GIC,
"Gicv3Distributor::write(): (DS 1)" 854 "EnableGrp1NS %d EnableGrp0 %d\n",
857 if (is_secure_access) {
870 if ((data & (1 << 5)) == 0) {
871 warn(
"Gicv3Distributor::write(): " 872 "setting ARE_NS to 0 is not supported!\n");
875 if ((data & (1 << 4)) == 0) {
876 warn(
"Gicv3Distributor::write(): " 877 "setting ARE_S to 0 is not supported!\n");
884 DPRINTF(GIC,
"Gicv3Distributor::write(): (DS 0 secure)" 886 "EnableGrp1S %d EnableGrp1NS %d EnableGrp0 %d\n",
889 if (data & GICD_CTLR_DS) {
899 if ((data & (1 << 4)) == 0) {
900 warn(
"Gicv3Distributor::write(): " 901 "setting ARE_NS to 0 is not supported!\n");
905 DPRINTF(GIC,
"Gicv3Distributor::write(): (DS 0 non-secure)" 925 const uint32_t intid =
bits(data, 9, 0);
944 const uint32_t intid =
bits(data, 9, 0);
962 const uint32_t intid =
bits(data, 9, 0);
978 const uint32_t intid =
bits(data, 9, 0);
989 panic(
"Gicv3Distributor::write(): invalid offset %#x\n", addr);
1000 DPRINTF(GIC,
"Gicv3Distributor::sendInt(): " 1001 "int_id %d (SPI) pending bit set\n", int_id);
1024 if (affinity_routing.IRM) {
1030 if (redistributor_i->
1032 target_redistributor = redistributor_i;
1037 uint32_t affinity = (affinity_routing.Aff3 << 24) |
1038 (affinity_routing.Aff2 << 16) |
1039 (affinity_routing.Aff1 << 8) |
1040 (affinity_routing.Aff0 << 0);
1041 target_redistributor =
1045 if (!target_redistributor) {
1056 auto cpu_interface =
route(int_id);
1058 cpu_interface->resetHppi(int_id);
1077 if (!target_cpu_interface)
continue;
1081 int_id < target_cpu_interface->hppi.intid)) {
1083 target_cpu_interface->
hppi.
intid = int_id;
1085 target_cpu_interface->
hppi.
group = int_group;
#define panic(...)
This implements a cprintf based panic() function.
static const AddrRange GICD_SPENDSGIR
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
#define SERIALIZE_CONTAINER(member)
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.
#define UNSERIALIZE_CONTAINER(member)
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
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