Difference between revisions of "Unit ARMGIC"
(3 intermediate revisions by the same user not shown) | |||
Line 5: | Line 5: | ||
---- | ---- | ||
− | '''ARM Generic Interrupt Controller Driver''' | + | '''ARM Generic Interrupt Controller Driver unit''' |
=== Constants === | === Constants === | ||
---- | ---- | ||
− | '' | + | |
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC specific constants''' <code> ARM_GIC_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GIC_MAX_DEVICES = 4;</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ARM_GIC_SGI_BASE = 0;</code> | ||
+ | | Software Generated Interrupts from 0 to 15 | ||
+ | |- | ||
+ | | <code>ARM_GIC_PPI_BASE = 16;</code> | ||
+ | | Private Peripheral Interrupts from 16 to 31 | ||
+ | |- | ||
+ | | <code>ARM_GIC_SPI_BASE = 32;</code> | ||
+ | | Shared Peripheral Interrupts from 32 to 1019 (Maximum) | ||
+ | |- | ||
+ | | <code>ARM_GIC_SPI_MAX = 1019;</code> | ||
+ | | | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ARM_GIC_SGI_COUNT = 16;</code> | ||
+ | | 16 Software Generated Interrupts | ||
+ | |- | ||
+ | | <code>ARM_GIC_PPI_COUNT = 16;</code> | ||
+ | | 16 Private Peripheral Interrupts | ||
+ | |- | ||
+ | | <code>ARM_GIC_SPI_COUNT = 988;</code> | ||
+ | | 988 Shared Peripheral Interrupts (Maximum) | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ARM_GIC_GROUP1_INTERRUPT = 1022;</code> | ||
+ | | Returned by GICC_IAR when a Group1 interrupt is the highest priority interrupt pending | ||
+ | |- | ||
+ | | <code>ARM_GIC_SPURIOUS_INTERRUPT = 1023;</code> | ||
+ | | Return by GICC_IAR when there is no pending interrupt | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC distributor registers''' <code> ARM_GICD_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICD_CTLR = $000;</code> | ||
+ | | style="width: 50%;"|Distributor Control Register | ||
+ | |- | ||
+ | | <code>ARM_GICD_TYPER = $004;</code> | ||
+ | | Interrupt Controller Type Register | ||
+ | |- | ||
+ | | <code>ARM_GICD_IIDR = $008;</code> | ||
+ | | Distributor Implementer Identification Register | ||
+ | |- | ||
+ | | <code>ARM_GICD_IGROUPR0 = $080;</code> | ||
+ | | Interrupt Group Registers | ||
+ | |- | ||
+ | | <code>ARM_GICD_ISENABLER0 = $100;</code> | ||
+ | | Interrupt Set-Enable Registers | ||
+ | |- | ||
+ | | <code>ARM_GICD_ICENABLER0 = $180;</code> | ||
+ | | Interrupt Clear-Enable Registers | ||
+ | |- | ||
+ | | <code>ARM_GICD_ISPENDR0 = $200;</code> | ||
+ | | Interrupt Set-Pending Registers | ||
+ | |- | ||
+ | | <code>ARM_GICD_ICPENDR0 = $280;</code> | ||
+ | | Interrupt Clear-Pending Registers | ||
+ | |- | ||
+ | | <code>ARM_GICD_ISACTIVER0 = $300;</code> | ||
+ | | GICv2 Interrupt Set-Active Registers | ||
+ | |- | ||
+ | | <code>ARM_GICD_ICACTIVER0 = $380;</code> | ||
+ | | Interrupt Clear-Active Registers | ||
+ | |- | ||
+ | | <code>ARM_GICD_IPRIORITYR0 = $400;</code> | ||
+ | | Interrupt Priority Registers | ||
+ | |- | ||
+ | | <code>ARM_GICD_ITARGETSR0 = $800;</code> | ||
+ | | Interrupt Processor Targets Registers | ||
+ | |- | ||
+ | | <code>ARM_GICD_ICFGR0 = $C00;</code> | ||
+ | | Interrupt Configuration Registers | ||
+ | |- | ||
+ | | <code>ARM_GICD_NSACR0 = $E00;</code> | ||
+ | | Non-secure Access Control Registers (Optional) | ||
+ | |- | ||
+ | | <code>ARM_GICD_SGIR = $F00;</code> | ||
+ | | Software Generated Interrupt Register | ||
+ | |- | ||
+ | | <code>ARM_GICD_CPENDSGIR0 = $F10;</code> | ||
+ | | SGI Clear-Pending Registers | ||
+ | |- | ||
+ | | <code>ARM_GICD_SPENDSGIR0 = $F20;</code> | ||
+ | | SGI Set-Pending Registers | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC distributor control register''' <code> ARM_GICD_CTLR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | |colspan="2"|Non secure copy (Also appropriate bits for Secure copy) | ||
+ | |- | ||
+ | | <code>ARM_GICD_CTLR_DISABLE = (0 shl 0);</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | | <code>ARM_GICD_CTLR_ENABLE = (1 shl 0);</code> | ||
+ | | Global enable for forwarding pending interrupts from the Distributor to the CPU interfaces | ||
+ | |- | ||
+ | |colspan="2"|Secure copy | ||
+ | |- | ||
+ | | <code>ARM_GICD_CTLRS_DISABLE = (0 shl 0);</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICD_CTLRS_ENABLE_GROUP1 = (1 shl 1);</code> | ||
+ | | Global enable for forwarding pending Group 1 interrupts from the Distributor to the CPU interfaces | ||
+ | |- | ||
+ | | <code>ARM_GICD_CTLRS_ENABLE_GROUP0 = (1 shl 0);</code> | ||
+ | | Global enable for forwarding pending Group 0 interrupts from the Distributor to the CPU interfaces | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC interrupt controller type register''' <code> ARM_GICD_TYPER_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICD_TYPER_LSPI_MASK = ($1F shl 11);</code> | ||
+ | | style="width: 50%;"|If the GIC implements the Security Extensions, the value of this field is the maximum number of implemented lockable SPIs, from 0 (0b00000) to 31 (0b11111) | ||
+ | |- | ||
+ | | <code>ARM_GICD_TYPER_SECURITY_EXT = (1 shl 10);</code> | ||
+ | | Indicates whether the GIC implements the Security Extensions | ||
+ | |- | ||
+ | | <code>ARM_GICD_TYPER_CPUNUM_MASK = (7 shl 5);</code> | ||
+ | | Indicates the number of implemented CPU interfaces. The number of implemented CPU interfaces is one more than the value of this field | ||
+ | |- | ||
+ | | <code>ARM_GICD_TYPER_IRQNUM_MASK = ($1F shl 0);</code> | ||
+ | | Indicates the maximum number of interrupts that the GIC supports. The maximum number of interrupts is 32(N+1) | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ARM_GICD_TYPER_LSPI_SHIFT = 11;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICD_TYPER_SECURITY_SHIFT = 10;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICD_TYPER_CPUNUM_SHIFT = 5;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICD_TYPER_IRQNUM_SHIFT = 0;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC distributor implementer identification register''' <code> ARM_GICD_IIDR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICD_IIDR_PRODUCTID_MASK = ($FF shl 24);</code> | ||
+ | | style="width: 50%;"|An IMPLEMENTATION DEFINED product identifier | ||
+ | |- | ||
+ | | <code>ARM_GICD_IIDR_VARIANT_MASK = ($F shl 16);</code> | ||
+ | | An IMPLEMENTATION DEFINED variant number | ||
+ | |- | ||
+ | | <code>ARM_GICD_IIDR_REVISION_MASK = ($F shl 12);</code> | ||
+ | | An IMPLEMENTATION DEFINED revision number | ||
+ | |- | ||
+ | | <code>ARM_GICD_IIDR_IMPLEMENTOR_MASK = ($FFF shl 0);</code> | ||
+ | | Contains the JEP106 code of the company that implemented the GIC Distributor | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ARM_GICD_IIDR_PRODUCTID_SHIFT = 24;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICD_IIDR_VARIANT_SHIFT = 16;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICD_IIDR_REVISION_SHIFT = 12;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICD_IIDR_IMPLEMENTOR_SHIFT = 0;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC interrupt priority register''' <code> ARM_GICD_IPRIORITYR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICD_IPRIORITYR_MASK = $FF;</code> | ||
+ | | style="width: 50%;"|Each byte of the priority register holds a priority value | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC interrupt processor targets register''' <code> ARM_GICD_ITARGETSR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICD_ITARGETSR_MASK = $FF;</code> | ||
+ | | style="width: 50%;"|Each byte of the targets register holds a bit mask of the CPU targets | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC interrupt configuration register''' <code> ARM_GICD_ICFGR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICD_ICFGR_MASK = $03;</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | | <code>ARM_GICD_ICFGR_LEVEL_SENSITIVE = (0 shl 1);</code> | ||
+ | | Corresponding interrupt is level-sensitive | ||
+ | |- | ||
+ | | <code>ARM_GICD_ICFGR_EDGE_TRIGGERED = (1 shl 1);</code> | ||
+ | | Corresponding interrupt is edge-triggered | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC non-secure access control register (Group 0 Interrupts)''' <code> ARM_GICD_NSACR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICD_NSACR_MASK = $03;</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | | <code>ARM_GICD_NSACR_NONE = $0;</code> | ||
+ | | No Non-secure access is permitted to fields associated with the corresponding interrupt | ||
+ | |- | ||
+ | | <code>ARM_GICD_NSACR_SET = $1;</code> | ||
+ | | Non-secure write access is permitted to fields associated with the corresponding interrupt in the GICD_ISPENDRn registers | ||
+ | |- | ||
+ | | <code>ARM_GICD_NSACR_CLEAR = $2;</code> | ||
+ | | Adds Non-secure write access permission to fields associated with the corresponding interrupt in the GICD_ICPENDRn registers | ||
+ | |- | ||
+ | | <code>ARM_GICD_NSACR_TARGET = $3;</code> | ||
+ | | Adds Non-secure read and write access permission to fields associated with the corresponding interrupt in the GICD_ITARGETSRn registers | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC software generated interrupt register''' <code> ARM_GICD_SGIR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICD_SGIR_CPUFILTER_MASK = ($03 shl 24);</code> | ||
+ | | style="width: 50%;"|Determines how the distributor must process the requested SGI | ||
+ | |- | ||
+ | | <code>ARM_GICD_SGIR_CPUTARGET_MASK = ($FF shl 16);</code> | ||
+ | | When TargetList Filter = 0b00, defines the CPU interfaces to which the Distributor must forward the interrupt | ||
+ | |- | ||
+ | | <code>ARM_GICD_SGIR_NSATT = (1 shl 15);</code> | ||
+ | | Specifies the required security value of the SGI | ||
+ | |- | ||
+ | | <code>ARM_GICD_SGIR_INTID_MASK = ($F shl 0);</code> | ||
+ | | The Interrupt ID of the SGI to forward to the specified CPU interfaces | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ARM_GICD_SGIR_CPUFILTER_SHIFT = 24;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICD_SGIR_CPUTARGET_SHIFT = 16;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICD_SGIR_NSATT_SHIFT = 15;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICD_SGIR_INTID_SHIFT = 0;</code> | ||
+ | | | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ARM_GICD_SGIR_CPUFILTER_LIST = $0;</code> | ||
+ | | Forward the interrupt to the CPU interfaces specified in the CPUTargetList field | ||
+ | |- | ||
+ | | <code>ARM_GICD_SGIR_CPUFILTER_ALL = $1;</code> | ||
+ | | Forward the interrupt to all CPU interfaces except that of the processor that requested the interrupt | ||
+ | |- | ||
+ | | <code>ARM_GICD_SGIR_CPUFILTER_SELF = $2;</code> | ||
+ | | Forward the interrupt only to the CPU interface of the processor that requested the interrupt | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC SGI clear-pending registers''' <code> ARM_GICD_CPENDSGIR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICD_CPENDSGIR_MASK = $FF;</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC SGI set-pending registers''' <code> ARM_GICD_SPENDSGIR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICD_SPENDSGIR_MASK = $FF;</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC CPU registers''' <code> ARM_GICC_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLR = $0000;</code> | ||
+ | | style="width: 50%;"|CPU Interface Control Register | ||
+ | |- | ||
+ | | <code>ARM_GICC_PMR = $0004;</code> | ||
+ | | Interrupt Priority Mask Register | ||
+ | |- | ||
+ | | <code>ARM_GICC_BPR = $0008;</code> | ||
+ | | Binary Point Register | ||
+ | |- | ||
+ | | <code>ARM_GICC_IAR = $000C;</code> | ||
+ | | Interrupt Acknowledge Register | ||
+ | |- | ||
+ | | <code>ARM_GICC_EOIR = $0010;</code> | ||
+ | | End of Interrupt Register | ||
+ | |- | ||
+ | | <code>ARM_GICC_RPR = $0014;</code> | ||
+ | | Running Priority Register | ||
+ | |- | ||
+ | | <code>ARM_GICC_HPPIR = $0018;</code> | ||
+ | | Highest Priority Pending Interrupt Register | ||
+ | |- | ||
+ | | <code>ARM_GICC_ABPR = $001C;</code> | ||
+ | | Aliased Binary Point Register | ||
+ | |- | ||
+ | | <code>ARM_GICC_AIAR = $0020;</code> | ||
+ | | Aliased Interrupt Acknowledge Register | ||
+ | |- | ||
+ | | <code>ARM_GICC_AEOIR = $0024;</code> | ||
+ | | Aliased End of Interrupt Register | ||
+ | |- | ||
+ | | <code>ARM_GICC_AHPPIR = $0028;</code> | ||
+ | | Aliased Highest Priority Pending Interrupt Register | ||
+ | |- | ||
+ | | <code>ARM_GICC_APR0 = $00D0;</code> | ||
+ | | Active Priorities Registers | ||
+ | |- | ||
+ | | <code>ARM_GICC_NSAPR0 = $00E0;</code> | ||
+ | | Non-secure Active Priorities Registers | ||
+ | |- | ||
+ | | <code>ARM_GICC_IIDR = $00FC;</code> | ||
+ | | CPU Interface Identification Register | ||
+ | |- | ||
+ | | <code>ARM_GICC_DIR = $1000;</code> | ||
+ | | Deactivate Interrupt Register | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC CPU interface control register''' <code> ARM_GICC_CTLR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | |colspan="2"|Non secure copy (Also appropriate bits for Secure copy) | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLR_DISABLE = (0 shl 0);</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLR_EOI_MODE = (1 shl 9);</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLR_IRQ_BYPASS = (1 shl 6);</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLR_FIQ_BYPASS = (1 shl 5);</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLR_ENABLE = (1 shl 0);</code> | ||
+ | | Enable for the signaling of Group 1 interrupts by the CPU interface to the connected processor | ||
+ | |- | ||
+ | |colspan="2"|Secure copy | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLRS_DISABLE = (0 shl 0);</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLRS_EOI_MODE_NS = (1 shl 10);</code> | ||
+ | | Alias of EOImodeNS from the Non-secure copy of this register | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLRS_EOI_MODE = (1 shl 9);</code> | ||
+ | | Controls the behavior of accesses to GICC_EOIR and GICC_DIR register | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLRS_IRQ_BYPASS_GROUP1 = (1 shl 8);</code> | ||
+ | | Alias of IRQBypDisGrp1 from the Non-secure copy of this register | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLRS_FIQ_BYPASS_GROUP1 = (1 shl 7);</code> | ||
+ | | Alias of FIQBypDisGrp1 from the Non-secure copy of this register | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLRS_IRQ_BYPASS_GROUP0 = (1 shl 6);</code> | ||
+ | | When the signaling of IRQs by the CPU interface is disabled, this bit partly controls whether the bypass IRQ signal is signaled to the processor | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLRS_FIQ_BYPASS_GROUP0 = (1 shl 5);</code> | ||
+ | | When the signaling of FIQs by the CPU interface is disabled, this bit partly controls whether the bypass FIQ signal is signaled to the processor | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLRS_CBPR = (1 shl 4);</code> | ||
+ | | Controls whether the GICC_BPR provides common control to Group 0 and Group 1 interrupts | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLRS_FIQ_ENABLE = (1 shl 3);</code> | ||
+ | | Controls whether the CPU interface signals Group 0 interrupts to a target processor using the FIQ or the IRQ signal | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLRS_ACKCTL = (1 shl 2);</code> | ||
+ | | Controls behaviour when the highest priority pending interrupt is a Group 1 interrupt | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLRS_ENABLE_GROUP1 = (1 shl 1);</code> | ||
+ | | Enable for the signaling of Group 1 interrupts by the CPU interface to the connected processor | ||
+ | |- | ||
+ | | <code>ARM_GICC_CTLRS_ENABLE_GROUP0 = (1 shl 0);</code> | ||
+ | | Enable for the signaling of Group 0 interrupts by the CPU interface to the connected processor | ||
+ | |- | ||
+ | |||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC interrupt priority mask register''' <code> ARM_GICC_PMR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICC_PMR_PRIORITY = $F0;</code> | ||
+ | | style="width: 50%;"|The priority mask level for the CPU interface. If the priority of an interrupt is higher than the value indicated by this field, the interface signals the interrupt to the processor | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC binary point register''' <code> ARM_GICC_BPR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICC_BPR_BINARYPOINT_MASK = (7 shl 0);</code> | ||
+ | | style="width: 50%;"|The value of this field controls how the 8-bit interrupt priority field is split into a group priority field, used to determine interrupt preemption, and a subpriority field | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC interrupt acknowledge register''' <code> ARM_GICC_IAR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICC_IAR_CPUID_MASK = $07;</code> | ||
+ | | style="width: 50%;"|For SGIs in a multiprocessor implementation, this field identifies the processor that requested the interrupt | ||
+ | |- | ||
+ | | <code>ARM_GICC_IAR_INTERRUPTID_MASK = $3FF;</code> | ||
+ | | A read of the GICC_IAR returns the interrupt ID of the highest priority pending interrupt for the CPU interface. The read returns a spurious interrupt ID of 1023 if any of the following apply: forwarding of interrupts by the Distributor to the CPU interface is disabled, signaling of interrupts by the CPU interface to the connected processor is disabled orno pending interrupt on the CPU interface has sufficient priority for the interface to signal it to the processor. | ||
+ | |- | ||
+ | | <code>ARM_GICC_IAR_CPUID_SHIFT = 10;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICC_IAR_INTERRUPTID_SHIFT = 0;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC end of interrupt register''' <code> ARM_GICC_EOIR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICC_EOIR_CPUID_MASK = $07;</code> | ||
+ | | style="width: 50%;"|On a multiprocessor implementation, if the write refers to an SGI, this field contains the CPUID value from the corresponding GICC_IAR access | ||
+ | |- | ||
+ | | <code>ARM_GICC_EOIR_EOIINTID_MASK = $3FF;</code> | ||
+ | | The Interrupt ID value from the corresponding GICC_IAR access | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ARM_GICC_EOIR_CPUID_SHIFT = 10;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICC_EOIR_EOIINTID_SHIFT = 0;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC running priority register''' <code> ARM_GICC_RPR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICC_RPR_PRIORITY_MASK = $FF;</code> | ||
+ | | style="width: 50%;"|The current running priority on the CPU interface | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC highest priority pending interrupt register''' <code> ARM_GICC_HPPIR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICC_HPPIR_CPUID_MASK = $07;</code> | ||
+ | | style="width: 50%;"|On a multiprocessor implementation, if the PENDINTID field returns the ID of an SGI, this field contains the CPUID value for that interrupt | ||
+ | |- | ||
+ | | <code>ARM_GICC_HPPIR_PENDINTID_MASK = $3FF;</code> | ||
+ | | The interrupt ID of the highest priority pending interrupt | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ARM_GICC_HPPIR_CPUID_SHIFT = 10;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICC_HPPIR_PENDINTID_SHIFT = 0;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC aliased binary point register''' <code> ARM_GICC_ABPR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICC_ABPR_BINARYPOINT_MASK = ARM_GICC_BPR_BINARYPOINT_MASK;</code> | ||
+ | | style="width: 50%;"|A Binary Point Register for handling Group 1 interrupts | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC aliased interrupt acknowledge register''' <code> ARM_GICC_AIAR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICC_AIAR_CPUID_MASK = ARM_GICC_IAR_CPUID_MASK;</code> | ||
+ | | style="width: 50%;"|An Interrupt Acknowledge register for handling Group 1 interrupts | ||
+ | |- | ||
+ | | <code>ARM_GICC_AIAR_INTERRUPTID_MASK = ARM_GICC_IAR_INTERRUPTID_MASK;</code> | ||
+ | | | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ARM_GICC_AIAR_CPUID_SHIFT = ARM_GICC_IAR_CPUID_SHIFT;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICC_AIAR_INTERRUPTID_SHIFT = ARM_GICC_IAR_INTERRUPTID_SHIFT;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC aliased end of interrupt register''' <code> ARM_GICC_AEOIR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICC_AEOIR_CPUID_MASK = ARM_GICC_EOIR_CPUID_MASK;</code> | ||
+ | | style="width: 50%;"|An end of interrupt register for handling Group 1 interrupts | ||
+ | |- | ||
+ | | <code>ARM_GICC_AEOIR_EOIINTID_MASK = ARM_GICC_EOIR_EOIINTID_MASK;</code> | ||
+ | | | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ARM_GICC_AEOIR_CPUID_SHIFT = ARM_GICC_EOIR_CPUID_SHIFT;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICC_AEOIR_EOIINTID_SHIFT = ARM_GICC_EOIR_EOIINTID_SHIFT;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC aliased highest priority pending interrupt register''' <code> ARM_GICC_AHPPIR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICC_AHPPIR_CPUID_MASK = ARM_GICC_HPPIR_CPUID_MASK;</code> | ||
+ | | style="width: 50%;"|A Highest Priority Pending Interrupt register for the handling of Group 1 interrupts | ||
+ | |- | ||
+ | | <code>ARM_GICC_AHPPIR_PENDINTID_MASK = ARM_GICC_HPPIR_PENDINTID_MASK;</code> | ||
+ | | | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ARM_GICC_AHPPIR_CPUID_SHIFT = ARM_GICC_HPPIR_CPUID_SHIFT;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICC_AHPPIR_PENDINTID_SHIFT = ARM_GICC_HPPIR_PENDINTID_SHIFT;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC CPU interface identification register''' <code> ARM_GICC_IIDR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICC_IIDR_PRODUCTID_MASK = ($FFF shl 20);</code> | ||
+ | | style="width: 50%;"|An IMPLEMENTATION DEFINED product identifier | ||
+ | |- | ||
+ | | <code>ARM_GICC_IIDR_ARCHITECTURE_MASK = ($F shl 16);</code> | ||
+ | | The value of this field depends on the GIC architecture version (0x1 for GICv1 / 0x2 for GICv2) | ||
+ | |- | ||
+ | | <code>ARM_GICC_IIDR_REVISION_MASK = ($F shl 12);</code> | ||
+ | | An IMPLEMENTATION DEFINED revision number for the CPU interface | ||
+ | |- | ||
+ | | <code>ARM_GICC_IIDR_IMPLEMENTOR_MASK = ($FFF shl 0);</code> | ||
+ | | Contains the JEP106 code of the company that implemented the GIC CPU interface | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ARM_GICC_IIDR_PRODUCTID_SHIFT = 20;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICC_IIDR_ARCHITECTURE_SHIFT = 16;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICC_IIDR_REVISION_SHIFT = 12;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICC_IIDR_IMPLEMENTOR_SHIFT = 0;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''ARM GIC deactivate interrupt register''' <code> ARM_GICC_DIR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>ARM_GICC_DIR_CPUID_MASK = $07;</code> | ||
+ | | style="width: 50%;"|For an SGI in a multiprocessor implementation, this field identifies the processor that requested the interrupt | ||
+ | |- | ||
+ | | <code>ARM_GICC_DIR_INTERRUPTID_MASK = $3FF;</code> | ||
+ | | The interrupt ID | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>ARM_GICC_DIR_CPUID_SHIFT = 10;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>ARM_GICC_DIR_INTERRUPTID_SHIFT = 0;</code> | ||
+ | | | ||
+ | |- | ||
+ | |||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
=== Type definitions === | === Type definitions === | ||
---- | ---- | ||
− | '' | + | |
+ | '''ARM GIC state''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | |||
+ | <code>TGICState = record</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | |colspan="2"|Describes the state of a block of interrupts (32 per record) | ||
+ | |- | ||
+ | | <code>Enabled:LongWord;</code> | ||
+ | | style="width: 50%;"|Bit mask of the enabled interrupts | ||
+ | |- | ||
+ | | <code>Available:LongWord;</code> | ||
+ | | Bit mask of the available interrupts | ||
+ | |- | ||
+ | | <code>Permanent:LongWord;</code> | ||
+ | | Bit mask of the permanently enabled interrupts | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | |||
+ | '''ARM GIC states''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PGICStates = ^TGICStates;</code> | ||
+ | |||
+ | <code>TGICStates = array[0..31] of TGICState;</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | |||
+ | '''ARM GIC entries''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PGICEntries = ^TGICEntries;</code> | ||
+ | |||
+ | <code>TGICEntries = array[0..1023] of PInterruptEntry;</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | |||
+ | '''ARM GIC arrays''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PGICArrays = ^TGICArrays;</code> | ||
+ | |||
+ | <code>TGICArrays = array[0..7] of PGICEntries;</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | |||
+ | '''ARM GIC device''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PGICDevice = ^TGICDevice;</code> | ||
+ | |||
+ | <code>TGICDevice = record</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | |colspan="2"|''GIC Properties'' | ||
+ | |- | ||
+ | | <code>DistAddress:PtrUInt;</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | | <code>CPUAddress:PtrUInt;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>CPUCount:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>IRQCount:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>SecureMode:LongBool;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>FIQAvailable:LongBool;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>GICEnabled:LongBool;</code> | ||
+ | | | ||
+ | |- | ||
+ | |colspan="2"|''Interrupt Properties'' | ||
+ | |- | ||
+ | | <code>Interrupts:PGICEntries;</code> | ||
+ | | Array of interrupt entries | ||
+ | |- | ||
+ | | <code>LocalInterrupts:PGICArrays;</code> | ||
+ | | Arrays of local interrupt entries (1 array per CPU) | ||
+ | |- | ||
+ | | <code>SoftwareInterrupts:PGICArrays;</code> | ||
+ | | Arrays of software interrupt entries (1 array per CPU) | ||
+ | |- | ||
+ | |colspan="2"|''State Properties'' | ||
+ | |- | ||
+ | | <code>States:PGICStates;</code> | ||
+ | | Array of interrupt states | ||
+ | |- | ||
+ | | <code>LocalStates:PGICStates;</code> | ||
+ | | Array of local interrupt states (1 element per CPU) | ||
+ | |- | ||
+ | | <code>SoftwareStates:PGICStates;</code> | ||
+ | | Array of software interrupt states (1 element per CPU) | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
=== Public variables === | === Public variables === | ||
Line 125: | Line 924: | ||
|- | |- | ||
! Note | ! Note | ||
− | | Called by ARMGICDispatchIRQ/ARMGICDispatchFIQ. A DataMemoryBarrier is executed before and after calling this function. | + | | Called by ARMGICDispatchIRQ/ARMGICDispatchFIQ. |
+ | A DataMemoryBarrier is executed before and after calling this function. | ||
|- | |- | ||
|} | |} |
Latest revision as of 05:10, 31 August 2021
Return to Unit Reference
Description
ARM Generic Interrupt Controller Driver unit
Constants
ARM_GIC_*
ARM_GIC_MAX_DEVICES = 4;
|
|
ARM_GIC_SGI_BASE = 0;
|
Software Generated Interrupts from 0 to 15 |
ARM_GIC_PPI_BASE = 16;
|
Private Peripheral Interrupts from 16 to 31 |
ARM_GIC_SPI_BASE = 32;
|
Shared Peripheral Interrupts from 32 to 1019 (Maximum) |
ARM_GIC_SPI_MAX = 1019;
|
|
ARM_GIC_SGI_COUNT = 16;
|
16 Software Generated Interrupts |
ARM_GIC_PPI_COUNT = 16;
|
16 Private Peripheral Interrupts |
ARM_GIC_SPI_COUNT = 988;
|
988 Shared Peripheral Interrupts (Maximum) |
ARM_GIC_GROUP1_INTERRUPT = 1022;
|
Returned by GICC_IAR when a Group1 interrupt is the highest priority interrupt pending |
ARM_GIC_SPURIOUS_INTERRUPT = 1023;
|
Return by GICC_IAR when there is no pending interrupt |
ARM_GICD_*
ARM_GICD_CTLR = $000;
|
Distributor Control Register |
ARM_GICD_TYPER = $004;
|
Interrupt Controller Type Register |
ARM_GICD_IIDR = $008;
|
Distributor Implementer Identification Register |
ARM_GICD_IGROUPR0 = $080;
|
Interrupt Group Registers |
ARM_GICD_ISENABLER0 = $100;
|
Interrupt Set-Enable Registers |
ARM_GICD_ICENABLER0 = $180;
|
Interrupt Clear-Enable Registers |
ARM_GICD_ISPENDR0 = $200;
|
Interrupt Set-Pending Registers |
ARM_GICD_ICPENDR0 = $280;
|
Interrupt Clear-Pending Registers |
ARM_GICD_ISACTIVER0 = $300;
|
GICv2 Interrupt Set-Active Registers |
ARM_GICD_ICACTIVER0 = $380;
|
Interrupt Clear-Active Registers |
ARM_GICD_IPRIORITYR0 = $400;
|
Interrupt Priority Registers |
ARM_GICD_ITARGETSR0 = $800;
|
Interrupt Processor Targets Registers |
ARM_GICD_ICFGR0 = $C00;
|
Interrupt Configuration Registers |
ARM_GICD_NSACR0 = $E00;
|
Non-secure Access Control Registers (Optional) |
ARM_GICD_SGIR = $F00;
|
Software Generated Interrupt Register |
ARM_GICD_CPENDSGIR0 = $F10;
|
SGI Clear-Pending Registers |
ARM_GICD_SPENDSGIR0 = $F20;
|
SGI Set-Pending Registers |
ARM_GICD_CTLR_*
Non secure copy (Also appropriate bits for Secure copy) | |
ARM_GICD_CTLR_DISABLE = (0 shl 0);
|
|
ARM_GICD_CTLR_ENABLE = (1 shl 0);
|
Global enable for forwarding pending interrupts from the Distributor to the CPU interfaces |
Secure copy | |
ARM_GICD_CTLRS_DISABLE = (0 shl 0);
|
|
ARM_GICD_CTLRS_ENABLE_GROUP1 = (1 shl 1);
|
Global enable for forwarding pending Group 1 interrupts from the Distributor to the CPU interfaces |
ARM_GICD_CTLRS_ENABLE_GROUP0 = (1 shl 0);
|
Global enable for forwarding pending Group 0 interrupts from the Distributor to the CPU interfaces |
ARM_GICD_TYPER_*
ARM_GICD_TYPER_LSPI_MASK = ($1F shl 11);
|
If the GIC implements the Security Extensions, the value of this field is the maximum number of implemented lockable SPIs, from 0 (0b00000) to 31 (0b11111) |
ARM_GICD_TYPER_SECURITY_EXT = (1 shl 10);
|
Indicates whether the GIC implements the Security Extensions |
ARM_GICD_TYPER_CPUNUM_MASK = (7 shl 5);
|
Indicates the number of implemented CPU interfaces. The number of implemented CPU interfaces is one more than the value of this field |
ARM_GICD_TYPER_IRQNUM_MASK = ($1F shl 0);
|
Indicates the maximum number of interrupts that the GIC supports. The maximum number of interrupts is 32(N+1) |
ARM_GICD_TYPER_LSPI_SHIFT = 11;
|
|
ARM_GICD_TYPER_SECURITY_SHIFT = 10;
|
|
ARM_GICD_TYPER_CPUNUM_SHIFT = 5;
|
|
ARM_GICD_TYPER_IRQNUM_SHIFT = 0;
|
ARM_GICD_IIDR_*
ARM_GICD_IIDR_PRODUCTID_MASK = ($FF shl 24);
|
An IMPLEMENTATION DEFINED product identifier |
ARM_GICD_IIDR_VARIANT_MASK = ($F shl 16);
|
An IMPLEMENTATION DEFINED variant number |
ARM_GICD_IIDR_REVISION_MASK = ($F shl 12);
|
An IMPLEMENTATION DEFINED revision number |
ARM_GICD_IIDR_IMPLEMENTOR_MASK = ($FFF shl 0);
|
Contains the JEP106 code of the company that implemented the GIC Distributor |
ARM_GICD_IIDR_PRODUCTID_SHIFT = 24;
|
|
ARM_GICD_IIDR_VARIANT_SHIFT = 16;
|
|
ARM_GICD_IIDR_REVISION_SHIFT = 12;
|
|
ARM_GICD_IIDR_IMPLEMENTOR_SHIFT = 0;
|
ARM_GICD_IPRIORITYR_*
ARM_GICD_IPRIORITYR_MASK = $FF;
|
Each byte of the priority register holds a priority value |
ARM_GICD_ITARGETSR_*
ARM_GICD_ITARGETSR_MASK = $FF;
|
Each byte of the targets register holds a bit mask of the CPU targets |
ARM_GICD_ICFGR_*
ARM_GICD_ICFGR_MASK = $03;
|
|
ARM_GICD_ICFGR_LEVEL_SENSITIVE = (0 shl 1);
|
Corresponding interrupt is level-sensitive |
ARM_GICD_ICFGR_EDGE_TRIGGERED = (1 shl 1);
|
Corresponding interrupt is edge-triggered |
ARM_GICD_NSACR_*
ARM_GICD_NSACR_MASK = $03;
|
|
ARM_GICD_NSACR_NONE = $0;
|
No Non-secure access is permitted to fields associated with the corresponding interrupt |
ARM_GICD_NSACR_SET = $1;
|
Non-secure write access is permitted to fields associated with the corresponding interrupt in the GICD_ISPENDRn registers |
ARM_GICD_NSACR_CLEAR = $2;
|
Adds Non-secure write access permission to fields associated with the corresponding interrupt in the GICD_ICPENDRn registers |
ARM_GICD_NSACR_TARGET = $3;
|
Adds Non-secure read and write access permission to fields associated with the corresponding interrupt in the GICD_ITARGETSRn registers |
ARM_GICD_SGIR_*
ARM_GICD_SGIR_CPUFILTER_MASK = ($03 shl 24);
|
Determines how the distributor must process the requested SGI |
ARM_GICD_SGIR_CPUTARGET_MASK = ($FF shl 16);
|
When TargetList Filter = 0b00, defines the CPU interfaces to which the Distributor must forward the interrupt |
ARM_GICD_SGIR_NSATT = (1 shl 15);
|
Specifies the required security value of the SGI |
ARM_GICD_SGIR_INTID_MASK = ($F shl 0);
|
The Interrupt ID of the SGI to forward to the specified CPU interfaces |
ARM_GICD_SGIR_CPUFILTER_SHIFT = 24;
|
|
ARM_GICD_SGIR_CPUTARGET_SHIFT = 16;
|
|
ARM_GICD_SGIR_NSATT_SHIFT = 15;
|
|
ARM_GICD_SGIR_INTID_SHIFT = 0;
|
|
ARM_GICD_SGIR_CPUFILTER_LIST = $0;
|
Forward the interrupt to the CPU interfaces specified in the CPUTargetList field |
ARM_GICD_SGIR_CPUFILTER_ALL = $1;
|
Forward the interrupt to all CPU interfaces except that of the processor that requested the interrupt |
ARM_GICD_SGIR_CPUFILTER_SELF = $2;
|
Forward the interrupt only to the CPU interface of the processor that requested the interrupt |
ARM_GICD_CPENDSGIR_*
ARM_GICD_CPENDSGIR_MASK = $FF;
|
ARM_GICD_SPENDSGIR_*
ARM_GICD_SPENDSGIR_MASK = $FF;
|
ARM_GICC_*
ARM_GICC_CTLR = $0000;
|
CPU Interface Control Register |
ARM_GICC_PMR = $0004;
|
Interrupt Priority Mask Register |
ARM_GICC_BPR = $0008;
|
Binary Point Register |
ARM_GICC_IAR = $000C;
|
Interrupt Acknowledge Register |
ARM_GICC_EOIR = $0010;
|
End of Interrupt Register |
ARM_GICC_RPR = $0014;
|
Running Priority Register |
ARM_GICC_HPPIR = $0018;
|
Highest Priority Pending Interrupt Register |
ARM_GICC_ABPR = $001C;
|
Aliased Binary Point Register |
ARM_GICC_AIAR = $0020;
|
Aliased Interrupt Acknowledge Register |
ARM_GICC_AEOIR = $0024;
|
Aliased End of Interrupt Register |
ARM_GICC_AHPPIR = $0028;
|
Aliased Highest Priority Pending Interrupt Register |
ARM_GICC_APR0 = $00D0;
|
Active Priorities Registers |
ARM_GICC_NSAPR0 = $00E0;
|
Non-secure Active Priorities Registers |
ARM_GICC_IIDR = $00FC;
|
CPU Interface Identification Register |
ARM_GICC_DIR = $1000;
|
Deactivate Interrupt Register |
ARM_GICC_CTLR_*
Non secure copy (Also appropriate bits for Secure copy) | |
ARM_GICC_CTLR_DISABLE = (0 shl 0);
|
|
ARM_GICC_CTLR_EOI_MODE = (1 shl 9);
|
|
ARM_GICC_CTLR_IRQ_BYPASS = (1 shl 6);
|
|
ARM_GICC_CTLR_FIQ_BYPASS = (1 shl 5);
|
|
ARM_GICC_CTLR_ENABLE = (1 shl 0);
|
Enable for the signaling of Group 1 interrupts by the CPU interface to the connected processor |
Secure copy | |
ARM_GICC_CTLRS_DISABLE = (0 shl 0);
|
|
ARM_GICC_CTLRS_EOI_MODE_NS = (1 shl 10);
|
Alias of EOImodeNS from the Non-secure copy of this register |
ARM_GICC_CTLRS_EOI_MODE = (1 shl 9);
|
Controls the behavior of accesses to GICC_EOIR and GICC_DIR register |
ARM_GICC_CTLRS_IRQ_BYPASS_GROUP1 = (1 shl 8);
|
Alias of IRQBypDisGrp1 from the Non-secure copy of this register |
ARM_GICC_CTLRS_FIQ_BYPASS_GROUP1 = (1 shl 7);
|
Alias of FIQBypDisGrp1 from the Non-secure copy of this register |
ARM_GICC_CTLRS_IRQ_BYPASS_GROUP0 = (1 shl 6);
|
When the signaling of IRQs by the CPU interface is disabled, this bit partly controls whether the bypass IRQ signal is signaled to the processor |
ARM_GICC_CTLRS_FIQ_BYPASS_GROUP0 = (1 shl 5);
|
When the signaling of FIQs by the CPU interface is disabled, this bit partly controls whether the bypass FIQ signal is signaled to the processor |
ARM_GICC_CTLRS_CBPR = (1 shl 4);
|
Controls whether the GICC_BPR provides common control to Group 0 and Group 1 interrupts |
ARM_GICC_CTLRS_FIQ_ENABLE = (1 shl 3);
|
Controls whether the CPU interface signals Group 0 interrupts to a target processor using the FIQ or the IRQ signal |
ARM_GICC_CTLRS_ACKCTL = (1 shl 2);
|
Controls behaviour when the highest priority pending interrupt is a Group 1 interrupt |
ARM_GICC_CTLRS_ENABLE_GROUP1 = (1 shl 1);
|
Enable for the signaling of Group 1 interrupts by the CPU interface to the connected processor |
ARM_GICC_CTLRS_ENABLE_GROUP0 = (1 shl 0);
|
Enable for the signaling of Group 0 interrupts by the CPU interface to the connected processor |
ARM_GICC_PMR_*
ARM_GICC_PMR_PRIORITY = $F0;
|
The priority mask level for the CPU interface. If the priority of an interrupt is higher than the value indicated by this field, the interface signals the interrupt to the processor |
ARM_GICC_BPR_*
ARM_GICC_BPR_BINARYPOINT_MASK = (7 shl 0);
|
The value of this field controls how the 8-bit interrupt priority field is split into a group priority field, used to determine interrupt preemption, and a subpriority field |
ARM_GICC_IAR_*
ARM_GICC_IAR_CPUID_MASK = $07;
|
For SGIs in a multiprocessor implementation, this field identifies the processor that requested the interrupt |
ARM_GICC_IAR_INTERRUPTID_MASK = $3FF;
|
A read of the GICC_IAR returns the interrupt ID of the highest priority pending interrupt for the CPU interface. The read returns a spurious interrupt ID of 1023 if any of the following apply: forwarding of interrupts by the Distributor to the CPU interface is disabled, signaling of interrupts by the CPU interface to the connected processor is disabled orno pending interrupt on the CPU interface has sufficient priority for the interface to signal it to the processor. |
ARM_GICC_IAR_CPUID_SHIFT = 10;
|
|
ARM_GICC_IAR_INTERRUPTID_SHIFT = 0;
|
ARM_GICC_EOIR_*
ARM_GICC_EOIR_CPUID_MASK = $07;
|
On a multiprocessor implementation, if the write refers to an SGI, this field contains the CPUID value from the corresponding GICC_IAR access |
ARM_GICC_EOIR_EOIINTID_MASK = $3FF;
|
The Interrupt ID value from the corresponding GICC_IAR access |
ARM_GICC_EOIR_CPUID_SHIFT = 10;
|
|
ARM_GICC_EOIR_EOIINTID_SHIFT = 0;
|
ARM_GICC_RPR_*
ARM_GICC_RPR_PRIORITY_MASK = $FF;
|
The current running priority on the CPU interface |
ARM_GICC_HPPIR_*
ARM_GICC_HPPIR_CPUID_MASK = $07;
|
On a multiprocessor implementation, if the PENDINTID field returns the ID of an SGI, this field contains the CPUID value for that interrupt |
ARM_GICC_HPPIR_PENDINTID_MASK = $3FF;
|
The interrupt ID of the highest priority pending interrupt |
ARM_GICC_HPPIR_CPUID_SHIFT = 10;
|
|
ARM_GICC_HPPIR_PENDINTID_SHIFT = 0;
|
ARM_GICC_ABPR_*
ARM_GICC_ABPR_BINARYPOINT_MASK = ARM_GICC_BPR_BINARYPOINT_MASK;
|
A Binary Point Register for handling Group 1 interrupts |
ARM_GICC_AIAR_*
ARM_GICC_AIAR_CPUID_MASK = ARM_GICC_IAR_CPUID_MASK;
|
An Interrupt Acknowledge register for handling Group 1 interrupts |
ARM_GICC_AIAR_INTERRUPTID_MASK = ARM_GICC_IAR_INTERRUPTID_MASK;
|
|
ARM_GICC_AIAR_CPUID_SHIFT = ARM_GICC_IAR_CPUID_SHIFT;
|
|
ARM_GICC_AIAR_INTERRUPTID_SHIFT = ARM_GICC_IAR_INTERRUPTID_SHIFT;
|
ARM_GICC_AEOIR_*
ARM_GICC_AEOIR_CPUID_MASK = ARM_GICC_EOIR_CPUID_MASK;
|
An end of interrupt register for handling Group 1 interrupts |
ARM_GICC_AEOIR_EOIINTID_MASK = ARM_GICC_EOIR_EOIINTID_MASK;
|
|
ARM_GICC_AEOIR_CPUID_SHIFT = ARM_GICC_EOIR_CPUID_SHIFT;
|
|
ARM_GICC_AEOIR_EOIINTID_SHIFT = ARM_GICC_EOIR_EOIINTID_SHIFT;
|
ARM_GICC_AHPPIR_*
ARM_GICC_AHPPIR_CPUID_MASK = ARM_GICC_HPPIR_CPUID_MASK;
|
A Highest Priority Pending Interrupt register for the handling of Group 1 interrupts |
ARM_GICC_AHPPIR_PENDINTID_MASK = ARM_GICC_HPPIR_PENDINTID_MASK;
|
|
ARM_GICC_AHPPIR_CPUID_SHIFT = ARM_GICC_HPPIR_CPUID_SHIFT;
|
|
ARM_GICC_AHPPIR_PENDINTID_SHIFT = ARM_GICC_HPPIR_PENDINTID_SHIFT;
|
ARM_GICC_IIDR_*
ARM_GICC_IIDR_PRODUCTID_MASK = ($FFF shl 20);
|
An IMPLEMENTATION DEFINED product identifier |
ARM_GICC_IIDR_ARCHITECTURE_MASK = ($F shl 16);
|
The value of this field depends on the GIC architecture version (0x1 for GICv1 / 0x2 for GICv2) |
ARM_GICC_IIDR_REVISION_MASK = ($F shl 12);
|
An IMPLEMENTATION DEFINED revision number for the CPU interface |
ARM_GICC_IIDR_IMPLEMENTOR_MASK = ($FFF shl 0);
|
Contains the JEP106 code of the company that implemented the GIC CPU interface |
ARM_GICC_IIDR_PRODUCTID_SHIFT = 20;
|
|
ARM_GICC_IIDR_ARCHITECTURE_SHIFT = 16;
|
|
ARM_GICC_IIDR_REVISION_SHIFT = 12;
|
|
ARM_GICC_IIDR_IMPLEMENTOR_SHIFT = 0;
|
ARM_GICC_DIR_*
ARM_GICC_DIR_CPUID_MASK = $07;
|
For an SGI in a multiprocessor implementation, this field identifies the processor that requested the interrupt |
ARM_GICC_DIR_INTERRUPTID_MASK = $3FF;
|
The interrupt ID |
ARM_GICC_DIR_CPUID_SHIFT = 10;
|
|
ARM_GICC_DIR_INTERRUPTID_SHIFT = 0;
|
Type definitions
ARM GIC state
TGICState = record
Describes the state of a block of interrupts (32 per record) | |
Enabled:LongWord;
|
Bit mask of the enabled interrupts |
Available:LongWord;
|
Bit mask of the available interrupts |
Permanent:LongWord;
|
Bit mask of the permanently enabled interrupts |
ARM GIC states
PGICStates = ^TGICStates;
TGICStates = array[0..31] of TGICState;
ARM GIC entries
PGICEntries = ^TGICEntries;
TGICEntries = array[0..1023] of PInterruptEntry;
ARM GIC arrays
PGICArrays = ^TGICArrays;
TGICArrays = array[0..7] of PGICEntries;
ARM GIC device
PGICDevice = ^TGICDevice;
TGICDevice = record
GIC Properties | |
DistAddress:PtrUInt;
|
|
CPUAddress:PtrUInt;
|
|
CPUCount:LongWord;
|
|
IRQCount:LongWord;
|
|
SecureMode:LongBool;
|
|
FIQAvailable:LongBool;
|
|
GICEnabled:LongBool;
|
|
Interrupt Properties | |
Interrupts:PGICEntries;
|
Array of interrupt entries |
LocalInterrupts:PGICArrays;
|
Arrays of local interrupt entries (1 array per CPU) |
SoftwareInterrupts:PGICArrays;
|
Arrays of software interrupt entries (1 array per CPU) |
State Properties | |
States:PGICStates;
|
Array of interrupt states |
LocalStates:PGICStates;
|
Array of local interrupt states (1 element per CPU) |
SoftwareStates:PGICStates;
|
Array of software interrupt states (1 element per CPU) |
Public variables
None defined
Function declarations
ARM GIC functions
function ARMGICCreate(DistAddress,CPUAddress:PtrUInt):PGICDevice;
Note | None documented |
---|
function ARMGICStart(GIC:PGICDevice):LongWord;
Note | None documented |
---|
function ARMGICGetEntry(GIC:PGICDevice; CPUID,Number,Flags:LongWord; var Entry:TInterruptEntry; Index:LongWord):LongWord;
Note | The returned Entry is a copy of the registered value. Caller should free Entry if required.
For shared entries the Index parameter indicates which entry in the chain to return (0 equals first etc). |
---|
function ARMGICRegisterEntry(GIC:PGICDevice; const Entry:TInterruptEntry):LongWord;
Note | Entry must be allocated from heap as a pointer so it will be retained while the interrupt remains registered.
Entry must not be freed by the caller. |
---|
function ARMGICDeregisterEntry(GIC:PGICDevice; const Entry:TInterruptEntry):LongWord;
Note | The Entry can be a local temporary copy allocated either from the stack or on the heap, this routine will free the original Entry passed to Register once it is successfully deregistered.
Caller should free Entry if required. |
---|
ARM GIC interrupt functions
function ARMGICDispatchIRQ(CPUID:LongWord; Thread:TThreadHandle):TThreadHandle;
Note | Called by ARMv7/8IRQHandler in PlatformARMv7/8 |
---|
function ARMGICDispatchFIQ(CPUID:LongWord; Thread:TThreadHandle):TThreadHandle;
Note | Called by ARMv7/8FIQHandler in PlatformARMv7/8 |
---|
function ARMGICDispatchInterrupt(CPUID:LongWord; Thread:TThreadHandle):TThreadHandle;
Note | Called by ARMGICDispatchIRQ/ARMGICDispatchFIQ.
A DataMemoryBarrier is executed before and after calling this function. |
---|
ARM GIC helper functions
function ARMGICIsValid(GIC:PGICDevice; Number:LongWord):Boolean;
Note | None documented |
---|
function ARMGICIsLocal(GIC:PGICDevice; Number:LongWord):Boolean;
Note | None documented |
---|
function ARMGICIsSoftware(GIC:PGICDevice; Number:LongWord):Boolean;
Note | None documented |
---|
function ARMGICIsGlobal(GIC:PGICDevice; Number:LongWord):Boolean;
Note | None documented |
---|
function ARMGICGetIRQCount(GIC:PGICDevice):LongWord;
Note | None documented |
---|
function ARMGICGetFIQCount(GIC:PGICDevice):LongWord;
Note | None documented |
---|
function ARMGICGetIRQStart(GIC:PGICDevice):LongWord;
Note | None documented |
---|
function ARMGICGetIRQRouting(GIC:PGICDevice):LongWord;
Note | None documented |
---|
function ARMGICGetFIQRouting(GIC:PGICDevice):LongWord;
Note | None documented |
---|
function ARMGICGetIRQLocalCount(GIC:PGICDevice):LongWord;
Note | None documented |
---|
function ARMGICGetFIQLocalCount(GIC:PGICDevice):LongWord;
Note | None documented |
---|
function ARMGICGetIRQLocalStart(GIC:PGICDevice):LongWord;
Note | None documented |
---|
function ARMGICGetIRQSoftwareCount(GIC:PGICDevice):LongWord;
Note | None documented |
---|
function ARMGICGetFIQSoftwareCount(GIC:PGICDevice):LongWord;
Note | None documented |
---|
function ARMGICGetIRQSoftwateStart(GIC:PGICDevice):LongWord;
Note | None documented |
---|
Return to Unit Reference