gic_v2.cc (13108:8e46a4e10f94) gic_v2.cc (13109:786adb0cefde)
1/*
2 * Copyright (c) 2010, 2013, 2015-2018 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 66 unchanged lines hidden (view full) ---

75 intPriority {}, cpuTarget {}, intConfig {},
76 cpuSgiPending {}, cpuSgiActive {},
77 cpuSgiPendingExt {}, cpuSgiActiveExt {},
78 cpuPpiPending {}, cpuPpiActive {},
79 pendingDelayedInterrupts(0)
80{
81 for (int x = 0; x < CPU_MAX; x++) {
82 iccrpr[x] = 0xff;
1/*
2 * Copyright (c) 2010, 2013, 2015-2018 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 66 unchanged lines hidden (view full) ---

75 intPriority {}, cpuTarget {}, intConfig {},
76 cpuSgiPending {}, cpuSgiActive {},
77 cpuSgiPendingExt {}, cpuSgiActiveExt {},
78 cpuPpiPending {}, cpuPpiActive {},
79 pendingDelayedInterrupts(0)
80{
81 for (int x = 0; x < CPU_MAX; x++) {
82 iccrpr[x] = 0xff;
83 cpuEnabled[x] = false;
83 cpuControl[x] = 0;
84 cpuPriority[x] = 0xff;
85 cpuBpr[x] = GICC_BPR_MINIMUM;
86 // Initialize cpu highest int
87 cpuHighestInt[x] = SPURIOUS_INT;
88 postIntEvent[x] =
89 new EventFunctionWrapper([this, x]{ postDelayedInt(x); },
90 "Post Interrupt to CPU");
91 }
84 cpuPriority[x] = 0xff;
85 cpuBpr[x] = GICC_BPR_MINIMUM;
86 // Initialize cpu highest int
87 cpuHighestInt[x] = SPURIOUS_INT;
88 postIntEvent[x] =
89 new EventFunctionWrapper([this, x]{ postDelayedInt(x); },
90 "Post Interrupt to CPU");
91 }
92 DPRINTF(Interrupt, "cpuEnabled[0]=%d cpuEnabled[1]=%d\n", cpuEnabled[0],
93 cpuEnabled[1]);
92 DPRINTF(Interrupt, "cpuEnabled[0]=%d cpuEnabled[1]=%d\n", cpuEnabled(0),
93 cpuEnabled(1));
94
95 gem5ExtensionsEnabled = false;
96}
97
98GicV2::~GicV2()
99{
100 for (int x = 0; x < CPU_MAX; x++)
101 delete postIntEvent[x];

--- 195 unchanged lines hidden (view full) ---

297
298uint32_t
299GicV2::readCpu(ContextID ctx, Addr daddr)
300{
301 switch(daddr) {
302 case GICC_IIDR:
303 return GICC_400_IIDR_VALUE;
304 case GICC_CTLR:
94
95 gem5ExtensionsEnabled = false;
96}
97
98GicV2::~GicV2()
99{
100 for (int x = 0; x < CPU_MAX; x++)
101 delete postIntEvent[x];

--- 195 unchanged lines hidden (view full) ---

297
298uint32_t
299GicV2::readCpu(ContextID ctx, Addr daddr)
300{
301 switch(daddr) {
302 case GICC_IIDR:
303 return GICC_400_IIDR_VALUE;
304 case GICC_CTLR:
305 return cpuEnabled[ctx];
305 return cpuControl[ctx];
306 case GICC_PMR:
307 return cpuPriority[ctx];
308 case GICC_BPR:
309 return cpuBpr[ctx];
310 case GICC_IAR:
306 case GICC_PMR:
307 return cpuPriority[ctx];
308 case GICC_BPR:
309 return cpuBpr[ctx];
310 case GICC_IAR:
311 if (enabled && cpuEnabled[ctx]) {
311 if (enabled && cpuEnabled(ctx)) {
312 int active_int = cpuHighestInt[ctx];
313 IAR iar = 0;
314 iar.ack_id = active_int;
315 iar.cpu_id = 0;
316 if (active_int < SGI_MAX) {
317 // this is a software interrupt from another CPU
318 if (!gem5ExtensionsEnabled) {
319 panic_if(!cpuSgiPending[active_int],

--- 239 unchanged lines hidden (view full) ---

559 return cpuPioDelay;
560}
561
562void
563GicV2::writeCpu(ContextID ctx, Addr daddr, uint32_t data)
564{
565 switch(daddr) {
566 case GICC_CTLR:
312 int active_int = cpuHighestInt[ctx];
313 IAR iar = 0;
314 iar.ack_id = active_int;
315 iar.cpu_id = 0;
316 if (active_int < SGI_MAX) {
317 // this is a software interrupt from another CPU
318 if (!gem5ExtensionsEnabled) {
319 panic_if(!cpuSgiPending[active_int],

--- 239 unchanged lines hidden (view full) ---

559 return cpuPioDelay;
560}
561
562void
563GicV2::writeCpu(ContextID ctx, Addr daddr, uint32_t data)
564{
565 switch(daddr) {
566 case GICC_CTLR:
567 cpuEnabled[ctx] = data;
567 cpuControl[ctx] = data;
568 break;
569 case GICC_PMR:
570 cpuPriority[ctx] = data;
571 break;
572 case GICC_BPR: {
573 auto bpr = data & 0x7;
574 if (bpr < GICC_BPR_MINIMUM)
575 bpr = GICC_BPR_MINIMUM;

--- 35 unchanged lines hidden (view full) ---

611 case GICC_APR2:
612 case GICC_APR3:
613 warn("GIC APRn write ignored because not implemented: %#x\n", daddr);
614 break;
615 default:
616 panic("Tried to write Gic cpu at offset %#x\n", daddr);
617 break;
618 }
568 break;
569 case GICC_PMR:
570 cpuPriority[ctx] = data;
571 break;
572 case GICC_BPR: {
573 auto bpr = data & 0x7;
574 if (bpr < GICC_BPR_MINIMUM)
575 bpr = GICC_BPR_MINIMUM;

--- 35 unchanged lines hidden (view full) ---

611 case GICC_APR2:
612 case GICC_APR3:
613 warn("GIC APRn write ignored because not implemented: %#x\n", daddr);
614 break;
615 default:
616 panic("Tried to write Gic cpu at offset %#x\n", daddr);
617 break;
618 }
619 if (cpuEnabled[ctx]) updateIntState(-1);
619 if (cpuEnabled(ctx)) updateIntState(-1);
620}
621
622GicV2::BankedRegs&
623GicV2::getBankedRegs(ContextID ctx) {
624 if (bankedRegs.size() <= ctx)
625 bankedRegs.resize(ctx + 1);
626
627 if (!bankedRegs[ctx])

--- 6 unchanged lines hidden (view full) ---

634{
635 if (gem5ExtensionsEnabled) {
636 switch (swi.list_type) {
637 case 0: {
638 // interrupt cpus specified
639 int dest = swi.cpu_list;
640 DPRINTF(IPI, "Generating softIRQ from CPU %d for CPU %d\n",
641 ctx, dest);
620}
621
622GicV2::BankedRegs&
623GicV2::getBankedRegs(ContextID ctx) {
624 if (bankedRegs.size() <= ctx)
625 bankedRegs.resize(ctx + 1);
626
627 if (!bankedRegs[ctx])

--- 6 unchanged lines hidden (view full) ---

634{
635 if (gem5ExtensionsEnabled) {
636 switch (swi.list_type) {
637 case 0: {
638 // interrupt cpus specified
639 int dest = swi.cpu_list;
640 DPRINTF(IPI, "Generating softIRQ from CPU %d for CPU %d\n",
641 ctx, dest);
642 if (cpuEnabled[dest]) {
642 if (cpuEnabled(dest)) {
643 cpuSgiPendingExt[dest] |= (1 << swi.sgi_id);
644 DPRINTF(IPI, "SGI[%d]=%#x\n", dest,
645 cpuSgiPendingExt[dest]);
646 }
647 } break;
648 case 1: {
649 // interrupt all
650 for (int i = 0; i < sys->numContexts(); i++) {
651 DPRINTF(IPI, "Processing CPU %d\n", i);
643 cpuSgiPendingExt[dest] |= (1 << swi.sgi_id);
644 DPRINTF(IPI, "SGI[%d]=%#x\n", dest,
645 cpuSgiPendingExt[dest]);
646 }
647 } break;
648 case 1: {
649 // interrupt all
650 for (int i = 0; i < sys->numContexts(); i++) {
651 DPRINTF(IPI, "Processing CPU %d\n", i);
652 if (!cpuEnabled[i])
652 if (!cpuEnabled(i))
653 continue;
654 cpuSgiPendingExt[i] |= 1 << swi.sgi_id;
655 DPRINTF(IPI, "SGI[%d]=%#x\n", swi.sgi_id,
656 cpuSgiPendingExt[i]);
657 }
658 } break;
659 case 2: {
660 // Interrupt requesting cpu only
661 DPRINTF(IPI, "Generating softIRQ from CPU %d for CPU %d\n",
662 ctx, ctx);
653 continue;
654 cpuSgiPendingExt[i] |= 1 << swi.sgi_id;
655 DPRINTF(IPI, "SGI[%d]=%#x\n", swi.sgi_id,
656 cpuSgiPendingExt[i]);
657 }
658 } break;
659 case 2: {
660 // Interrupt requesting cpu only
661 DPRINTF(IPI, "Generating softIRQ from CPU %d for CPU %d\n",
662 ctx, ctx);
663 if (cpuEnabled[ctx]) {
663 if (cpuEnabled(ctx)) {
664 cpuSgiPendingExt[ctx] |= (1 << swi.sgi_id);
665 DPRINTF(IPI, "SGI[%d]=%#x\n", ctx,
666 cpuSgiPendingExt[ctx]);
667 }
668 } break;
669 }
670 } else {
671 switch (swi.list_type) {
672 case 1:
673 // interrupt all
674 uint8_t cpu_list;
675 cpu_list = 0;
676 for (int x = 0; x < sys->numContexts(); x++)
664 cpuSgiPendingExt[ctx] |= (1 << swi.sgi_id);
665 DPRINTF(IPI, "SGI[%d]=%#x\n", ctx,
666 cpuSgiPendingExt[ctx]);
667 }
668 } break;
669 }
670 } else {
671 switch (swi.list_type) {
672 case 1:
673 // interrupt all
674 uint8_t cpu_list;
675 cpu_list = 0;
676 for (int x = 0; x < sys->numContexts(); x++)
677 cpu_list |= cpuEnabled[x] ? 1 << x : 0;
677 cpu_list |= cpuEnabled(x) ? 1 << x : 0;
678 swi.cpu_list = cpu_list;
679 break;
680 case 2:
681 // interrupt requesting cpu only
682 swi.cpu_list = 1 << ctx;
683 break;
684 // else interrupt cpus specified
685 }
686
687 DPRINTF(IPI, "Generating softIRQ from CPU %d for %#x\n", ctx,
688 swi.cpu_list);
689 for (int i = 0; i < sys->numContexts(); i++) {
690 DPRINTF(IPI, "Processing CPU %d\n", i);
678 swi.cpu_list = cpu_list;
679 break;
680 case 2:
681 // interrupt requesting cpu only
682 swi.cpu_list = 1 << ctx;
683 break;
684 // else interrupt cpus specified
685 }
686
687 DPRINTF(IPI, "Generating softIRQ from CPU %d for %#x\n", ctx,
688 swi.cpu_list);
689 for (int i = 0; i < sys->numContexts(); i++) {
690 DPRINTF(IPI, "Processing CPU %d\n", i);
691 if (!cpuEnabled[i])
691 if (!cpuEnabled(i))
692 continue;
693 if (swi.cpu_list & (1 << i))
694 cpuSgiPending[swi.sgi_id] |= (1 << i) << (8 * ctx);
695 DPRINTF(IPI, "SGI[%d]=%#x\n", swi.sgi_id,
696 cpuSgiPending[swi.sgi_id]);
697 }
698 }
699 updateIntState(-1);

--- 17 unchanged lines hidden (view full) ---

717 // actually creates a higher priority, not lower.
718 return cpuPriority[cpu] & (0xff00 >> (7 - cpuBpr[cpu]));
719}
720
721void
722GicV2::updateIntState(int hint)
723{
724 for (int cpu = 0; cpu < sys->numContexts(); cpu++) {
692 continue;
693 if (swi.cpu_list & (1 << i))
694 cpuSgiPending[swi.sgi_id] |= (1 << i) << (8 * ctx);
695 DPRINTF(IPI, "SGI[%d]=%#x\n", swi.sgi_id,
696 cpuSgiPending[swi.sgi_id]);
697 }
698 }
699 updateIntState(-1);

--- 17 unchanged lines hidden (view full) ---

717 // actually creates a higher priority, not lower.
718 return cpuPriority[cpu] & (0xff00 >> (7 - cpuBpr[cpu]));
719}
720
721void
722GicV2::updateIntState(int hint)
723{
724 for (int cpu = 0; cpu < sys->numContexts(); cpu++) {
725 if (!cpuEnabled[cpu])
725 if (!cpuEnabled(cpu))
726 continue;
727
728 /*@todo use hint to do less work. */
729 int highest_int = SPURIOUS_INT;
730 // Priorities below that set in GICC_PMR can be ignored
731 uint8_t highest_pri = getCpuPriority(cpu);
732
733 // Check SGIs

--- 60 unchanged lines hidden (view full) ---

794 DPRINTF(Interrupt, "Clear IRQ for cpu%d\n", cpu);
795 platform->intrctrl->clear(cpu, ArmISA::INT_IRQ, 0);
796 }
797 continue;
798 }
799
800 /* @todo make this work for more than one cpu, need to handle 1:N, N:N
801 * models */
726 continue;
727
728 /*@todo use hint to do less work. */
729 int highest_int = SPURIOUS_INT;
730 // Priorities below that set in GICC_PMR can be ignored
731 uint8_t highest_pri = getCpuPriority(cpu);
732
733 // Check SGIs

--- 60 unchanged lines hidden (view full) ---

794 DPRINTF(Interrupt, "Clear IRQ for cpu%d\n", cpu);
795 platform->intrctrl->clear(cpu, ArmISA::INT_IRQ, 0);
796 }
797 continue;
798 }
799
800 /* @todo make this work for more than one cpu, need to handle 1:N, N:N
801 * models */
802 if (enabled && cpuEnabled[cpu] &&
802 if (enabled && cpuEnabled(cpu) &&
803 (highest_pri < getCpuPriority(cpu)) &&
804 !(getActiveInt(cpu, intNumToWord(highest_int))
805 & (1 << intNumToBit(highest_int)))) {
806
807 DPRINTF(Interrupt, "Posting interrupt %d to cpu%d\n", highest_int,
808 cpu);
809 postInt(cpu, curTick() + intLatency);
810 }
811 }
812}
813
814void
815GicV2::updateRunPri()
816{
817 for (int cpu = 0; cpu < sys->numContexts(); cpu++) {
803 (highest_pri < getCpuPriority(cpu)) &&
804 !(getActiveInt(cpu, intNumToWord(highest_int))
805 & (1 << intNumToBit(highest_int)))) {
806
807 DPRINTF(Interrupt, "Posting interrupt %d to cpu%d\n", highest_int,
808 cpu);
809 postInt(cpu, curTick() + intLatency);
810 }
811 }
812}
813
814void
815GicV2::updateRunPri()
816{
817 for (int cpu = 0; cpu < sys->numContexts(); cpu++) {
818 if (!cpuEnabled[cpu])
818 if (!cpuEnabled(cpu))
819 continue;
820 uint8_t maxPriority = 0xff;
821 for (int i = 0; i < itLines; i++) {
822 if (i < SGI_MAX) {
823 if (((cpuSgiActive[i] & genSwiMask(cpu)) ||
824 (cpuSgiActiveExt[cpu] & (1 << i))) &&
825 (getIntPriority(cpu, i) < maxPriority))
826 maxPriority = getIntPriority(cpu, i);

--- 110 unchanged lines hidden (view full) ---

937 SERIALIZE_SCALAR(itLines);
938 SERIALIZE_ARRAY(intEnabled, INT_BITS_MAX-1);
939 SERIALIZE_ARRAY(pendingInt, INT_BITS_MAX-1);
940 SERIALIZE_ARRAY(activeInt, INT_BITS_MAX-1);
941 SERIALIZE_ARRAY(iccrpr, CPU_MAX);
942 SERIALIZE_ARRAY(intPriority, GLOBAL_INT_LINES);
943 SERIALIZE_ARRAY(cpuTarget, GLOBAL_INT_LINES);
944 SERIALIZE_ARRAY(intConfig, INT_BITS_MAX * 2);
819 continue;
820 uint8_t maxPriority = 0xff;
821 for (int i = 0; i < itLines; i++) {
822 if (i < SGI_MAX) {
823 if (((cpuSgiActive[i] & genSwiMask(cpu)) ||
824 (cpuSgiActiveExt[cpu] & (1 << i))) &&
825 (getIntPriority(cpu, i) < maxPriority))
826 maxPriority = getIntPriority(cpu, i);

--- 110 unchanged lines hidden (view full) ---

937 SERIALIZE_SCALAR(itLines);
938 SERIALIZE_ARRAY(intEnabled, INT_BITS_MAX-1);
939 SERIALIZE_ARRAY(pendingInt, INT_BITS_MAX-1);
940 SERIALIZE_ARRAY(activeInt, INT_BITS_MAX-1);
941 SERIALIZE_ARRAY(iccrpr, CPU_MAX);
942 SERIALIZE_ARRAY(intPriority, GLOBAL_INT_LINES);
943 SERIALIZE_ARRAY(cpuTarget, GLOBAL_INT_LINES);
944 SERIALIZE_ARRAY(intConfig, INT_BITS_MAX * 2);
945 SERIALIZE_ARRAY(cpuEnabled, CPU_MAX);
945 SERIALIZE_ARRAY(cpuControl, CPU_MAX);
946 SERIALIZE_ARRAY(cpuPriority, CPU_MAX);
947 SERIALIZE_ARRAY(cpuBpr, CPU_MAX);
948 SERIALIZE_ARRAY(cpuHighestInt, CPU_MAX);
949 SERIALIZE_ARRAY(cpuSgiActive, SGI_MAX);
950 SERIALIZE_ARRAY(cpuSgiPending, SGI_MAX);
951 SERIALIZE_ARRAY(cpuSgiActiveExt, CPU_MAX);
952 SERIALIZE_ARRAY(cpuSgiPendingExt, CPU_MAX);
953 SERIALIZE_ARRAY(cpuPpiActive, CPU_MAX);

--- 25 unchanged lines hidden (view full) ---

979 UNSERIALIZE_SCALAR(itLines);
980 UNSERIALIZE_ARRAY(intEnabled, INT_BITS_MAX-1);
981 UNSERIALIZE_ARRAY(pendingInt, INT_BITS_MAX-1);
982 UNSERIALIZE_ARRAY(activeInt, INT_BITS_MAX-1);
983 UNSERIALIZE_ARRAY(iccrpr, CPU_MAX);
984 UNSERIALIZE_ARRAY(intPriority, GLOBAL_INT_LINES);
985 UNSERIALIZE_ARRAY(cpuTarget, GLOBAL_INT_LINES);
986 UNSERIALIZE_ARRAY(intConfig, INT_BITS_MAX * 2);
946 SERIALIZE_ARRAY(cpuPriority, CPU_MAX);
947 SERIALIZE_ARRAY(cpuBpr, CPU_MAX);
948 SERIALIZE_ARRAY(cpuHighestInt, CPU_MAX);
949 SERIALIZE_ARRAY(cpuSgiActive, SGI_MAX);
950 SERIALIZE_ARRAY(cpuSgiPending, SGI_MAX);
951 SERIALIZE_ARRAY(cpuSgiActiveExt, CPU_MAX);
952 SERIALIZE_ARRAY(cpuSgiPendingExt, CPU_MAX);
953 SERIALIZE_ARRAY(cpuPpiActive, CPU_MAX);

--- 25 unchanged lines hidden (view full) ---

979 UNSERIALIZE_SCALAR(itLines);
980 UNSERIALIZE_ARRAY(intEnabled, INT_BITS_MAX-1);
981 UNSERIALIZE_ARRAY(pendingInt, INT_BITS_MAX-1);
982 UNSERIALIZE_ARRAY(activeInt, INT_BITS_MAX-1);
983 UNSERIALIZE_ARRAY(iccrpr, CPU_MAX);
984 UNSERIALIZE_ARRAY(intPriority, GLOBAL_INT_LINES);
985 UNSERIALIZE_ARRAY(cpuTarget, GLOBAL_INT_LINES);
986 UNSERIALIZE_ARRAY(intConfig, INT_BITS_MAX * 2);
987 UNSERIALIZE_ARRAY(cpuEnabled, CPU_MAX);
987 UNSERIALIZE_ARRAY(cpuControl, CPU_MAX);
988 UNSERIALIZE_ARRAY(cpuPriority, CPU_MAX);
989 UNSERIALIZE_ARRAY(cpuBpr, CPU_MAX);
990 UNSERIALIZE_ARRAY(cpuHighestInt, CPU_MAX);
991 UNSERIALIZE_ARRAY(cpuSgiActive, SGI_MAX);
992 UNSERIALIZE_ARRAY(cpuSgiPending, SGI_MAX);
993 UNSERIALIZE_ARRAY(cpuSgiActiveExt, CPU_MAX);
994 UNSERIALIZE_ARRAY(cpuSgiPendingExt, CPU_MAX);
995 UNSERIALIZE_ARRAY(cpuPpiActive, CPU_MAX);

--- 39 unchanged lines hidden ---
988 UNSERIALIZE_ARRAY(cpuPriority, CPU_MAX);
989 UNSERIALIZE_ARRAY(cpuBpr, CPU_MAX);
990 UNSERIALIZE_ARRAY(cpuHighestInt, CPU_MAX);
991 UNSERIALIZE_ARRAY(cpuSgiActive, SGI_MAX);
992 UNSERIALIZE_ARRAY(cpuSgiPending, SGI_MAX);
993 UNSERIALIZE_ARRAY(cpuSgiActiveExt, CPU_MAX);
994 UNSERIALIZE_ARRAY(cpuSgiPendingExt, CPU_MAX);
995 UNSERIALIZE_ARRAY(cpuPpiActive, CPU_MAX);

--- 39 unchanged lines hidden ---