45 #include "debug/GIC.hh"
52 using namespace ArmISA;
60 cpuInterface(nullptr),
63 peInLowPowerState(true),
65 irqEnabled(
Gicv3::SGI_MAX +
Gicv3::PPI_MAX, false),
66 irqPending(
Gicv3::SGI_MAX +
Gicv3::PPI_MAX, false),
67 irqPendingIspendr(
Gicv3::SGI_MAX +
Gicv3::PPI_MAX, false),
68 irqActive(
Gicv3::SGI_MAX +
Gicv3::PPI_MAX, false),
69 irqPriority(
Gicv3::SGI_MAX +
Gicv3::PPI_MAX, 0),
77 lpiConfigurationTablePtr(0),
79 lpiPendingTablePtr(0),
80 addrRangeSize(
gic->params().gicv4 ? 0x40000 : 0x20000)
100 for (
int i = 0, int_id = first_intid;
i < size;
i++, int_id++) {
109 prio = (prio << 1) & 0xff;
113 value |= prio << (
i * 8);
136 value |= GICR_CTLR_ENABLE_LPIS;
169 return (affinity << 32) | (1 << 24) | (
cpuId << 8) |
170 (1 << 5) | (last << 4) | (1 << 3) | (1 << 0);
191 uint8_t part_1 = 0x4;
192 return (des_0 << 4) | (part_1 << 0);
196 uint8_t arch_rev = 0x3;
199 return (arch_rev << 4) | (jedec << 3) | (des_1 << 0);
208 return (size << 4) | (des_2 << 0);
224 for (
int int_id = 0; int_id < 8 * size; int_id++) {
225 value |= (
irqGroup[int_id] << int_id);
235 for (
int int_id = 0; int_id < 8 * size; int_id++) {
244 value |= (1 << int_id);
255 for (
int int_id = 0; int_id < 8 * size; int_id++) {
273 for (
int int_id = 0; int_id < 8 * size; int_id++) {
292 for (
int i = 0, int_id = first_int_id;
i < 32;
293 i =
i + 2, int_id++) {
315 if (!is_secure_access) {
319 for (
int int_id = 0; int_id < 8 * size; int_id++) {
335 if (!is_secure_access) {
339 for (
int i = 0, int_id = 0;
i < 8 * size;
340 i =
i + 2, int_id++) {
383 panic(
"Gicv3Redistributor::read(): invalid offset %#x\n",
addr);
390 bool is_secure_access)
395 for (
int i = 0, int_id = first_intid;
i < size;
i++, int_id++) {
396 uint8_t prio =
bits(
data, (
i + 1) * 8 - 1, (
i * 8));
404 prio = 0x80 | (prio >> 1);
409 DPRINTF(GIC,
"Gicv3Redistributor::write(): "
410 "int_id %d priority %d\n", int_id,
irqPriority[int_id]);
436 DPRINTF(GIC,
"Gicv3Redistributor::write(): "
437 "PE entering in low power state\n");
440 DPRINTF(GIC,
"Gicv3Redistributor::write(): powering up PE\n");
453 for (
int int_id = 0; int_id < 8 * size; int_id++) {
455 DPRINTF(GIC,
"Gicv3Redistributor::write(): "
456 "int_id %d group %d\n", int_id,
irqGroup[int_id]);
462 for (
int int_id = 0; int_id < 8 * size; int_id++) {
476 DPRINTF(GIC,
"Gicv3Redistributor::write(): "
477 "int_id %d enable %i\n", int_id,
irqEnabled[int_id]);
483 for (
int int_id = 0; int_id < 8 * size; int_id++) {
497 DPRINTF(GIC,
"Gicv3Redistributor::write(): "
498 "int_id %d enable %i\n", int_id,
irqEnabled[int_id]);
504 for (
int int_id = 0; int_id < 8 * size; int_id++) {
512 bool pending =
data & (1 << int_id) ? 1 : 0;
515 DPRINTF(GIC,
"Gicv3Redistributor::write() "
516 "(GICR_ISPENDR0): int_id %d (PPI) "
517 "pending bit set\n", int_id);
527 for (
int int_id = 0; int_id < 8 * size; int_id++) {
535 bool clear =
data & (1 << int_id) ? 1 : 0;
545 for (
int int_id = 0; int_id < 8 * size; int_id++) {
553 bool activate =
data & (1 << int_id) ? 1 : 0;
557 DPRINTF(GIC,
"Gicv3Redistributor::write(): "
558 "int_id %d active set\n", int_id);
568 for (
int int_id = 0; int_id < 8 * size; int_id++) {
576 bool clear =
data & (1 << int_id) ? 1 : 0;
580 DPRINTF(GIC,
"Gicv3Redistributor::write(): "
581 "int_id %d active cleared\n", int_id);
596 for (
int i = 0, int_id = first_intid;
i < 8 * size;
597 i =
i + 2, int_id++) {
608 DPRINTF(GIC,
"Gicv3Redistributor::write(): "
609 "int_id %d (PPI) config %d\n",
620 for (
int int_id = 0; int_id < 8 * size; int_id++) {
621 if (!is_secure_access) {
637 if (!is_secure_access) {
640 for (
int i = 0, int_id = 0;
i < 8 * size;
641 i =
i + 2, int_id++) {
710 panic(
"Gicv3Redistributor::write(): invalid offset %#x\n",
addr);
722 DPRINTF(GIC,
"Gicv3Redistributor::sendPPInt(): "
723 "int_id %d (PPI) pending bit set\n", int_id);
744 bool forward =
false;
762 forward = (group == int_group) ||
767 if (!forward)
return;
771 DPRINTF(GIC,
"Gicv3ReDistributor::sendSGI(): "
772 "int_id %d (SGI) pending bit set\n", int_id);
820 int_id < cpuInterface->hppi.intid)) {
831 const uint32_t largest_lpi_id = 1 << (
lpiIDBits + 1);
834 uint8_t lpi_pending_table[largest_lpi_id / 8];
835 uint8_t lpi_config_table[number_lpis];
839 sizeof(lpi_pending_table));
843 sizeof(lpi_config_table));
847 uint32_t lpi_pending_entry_byte = lpi_id / 8;
848 uint8_t lpi_pending_entry_bit_position = lpi_id % 8;
849 bool lpi_is_pending = lpi_pending_table[lpi_pending_entry_byte] &
850 1 << lpi_pending_entry_bit_position;
853 LPIConfigurationTableEntry config_entry =
854 lpi_config_table[lpi_configuration_entry_index];
856 bool lpi_is_enable = config_entry.enable;
863 if (lpi_is_pending && lpi_is_enable && group_enabled) {
864 uint8_t lpi_priority = config_entry.priority << 2;
866 if ((lpi_priority < cpuInterface->hppi.prio) ||
892 uint8_t lpi_pending_entry;
895 sizeof(lpi_pending_entry));
897 return lpi_pending_entry;
907 sizeof(lpi_pending_entry));
916 uint8_t lpi_pending_entry_bit_position = lpi_id % 8;
917 bool is_set = lpi_pending_entry & (1 << lpi_pending_entry_bit_position);
931 uint32_t lpi_id =
data & 0xffffffff;
932 uint32_t largest_lpi_id = 1 << (
lpiIDBits + 1);
934 if (lpi_id > largest_lpi_id) {
943 uint8_t lpi_pending_entry_bit_position = lpi_id % 8;
944 bool is_set = lpi_pending_entry & (1 << lpi_pending_entry_bit_position);
953 lpi_pending_entry |= 1 << (lpi_pending_entry_bit_position);
961 lpi_pending_entry &= ~(1 << (lpi_pending_entry_bit_position));
1026 uint64_t affinity = ((mpidr & 0xff00000000) >> 8) | (mpidr & (0xffffff));