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 --- |