Unit ARMGIC

From Ultibo.org
Jump to: navigation, search

Return to Unit Reference


Description


ARM Generic Interrupt Controller Driver unit

Constants



ARM GIC specific 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 GIC distributor registers 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 GIC distributor control register 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 GIC interrupt controller type register 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 GIC distributor implementer identification register 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 GIC interrupt priority register ARM_GICD_IPRIORITYR_*
ARM_GICD_IPRIORITYR_MASK = $FF; Each byte of the priority register holds a priority value


ARM GIC interrupt processor targets register ARM_GICD_ITARGETSR_*
ARM_GICD_ITARGETSR_MASK = $FF; Each byte of the targets register holds a bit mask of the CPU targets


ARM GIC interrupt configuration register 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 GIC non-secure access control register (Group 0 Interrupts) 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 GIC software generated interrupt register 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 GIC SGI clear-pending registers ARM_GICD_CPENDSGIR_*
ARM_GICD_CPENDSGIR_MASK = $FF;  


ARM GIC SGI set-pending registers ARM_GICD_SPENDSGIR_*
ARM_GICD_SPENDSGIR_MASK = $FF;  


ARM GIC CPU registers 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 GIC CPU interface control 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 GIC interrupt priority mask register 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 GIC binary point register 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 GIC interrupt acknowledge register 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 GIC end of interrupt register 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 GIC running priority register ARM_GICC_RPR_*
ARM_GICC_RPR_PRIORITY_MASK = $FF; The current running priority on the CPU interface


ARM GIC highest priority pending interrupt register 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 GIC aliased binary point register ARM_GICC_ABPR_*
ARM_GICC_ABPR_BINARYPOINT_MASK = ARM_GICC_BPR_BINARYPOINT_MASK; A Binary Point Register for handling Group 1 interrupts


ARM GIC aliased interrupt acknowledge register 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 GIC aliased end of interrupt register 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 GIC aliased highest priority pending interrupt register 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 GIC CPU interface identification register 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 GIC deactivate interrupt register 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;
Description: To be documented
Note None documented


function ARMGICStart(GIC:PGICDevice):LongWord;
Description: To be documented
Note None documented


function ARMGICGetEntry(GIC:PGICDevice; CPUID,Number,Flags:LongWord; var Entry:TInterruptEntry; Index:LongWord):LongWord;
Description: To be documented
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;
Description: To be documented
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;
Description: To be documented
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;
Description: To be documented
Note Called by ARMv7/8IRQHandler in PlatformARMv7/8


function ARMGICDispatchFIQ(CPUID:LongWord; Thread:TThreadHandle):TThreadHandle;
Description: To be documented
Note Called by ARMv7/8FIQHandler in PlatformARMv7/8


function ARMGICDispatchInterrupt(CPUID:LongWord; Thread:TThreadHandle):TThreadHandle;
Description: Process any pending IRQ/FIQ requests
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;
Description: To be documented
Note None documented


function ARMGICIsLocal(GIC:PGICDevice; Number:LongWord):Boolean;
Description: To be documented
Note None documented


function ARMGICIsSoftware(GIC:PGICDevice; Number:LongWord):Boolean;
Description: To be documented
Note None documented


function ARMGICIsGlobal(GIC:PGICDevice; Number:LongWord):Boolean;
Description: To be documented
Note None documented


function ARMGICGetIRQCount(GIC:PGICDevice):LongWord;
Description: To be documented
Note None documented


function ARMGICGetFIQCount(GIC:PGICDevice):LongWord;
Description: To be documented
Note None documented


function ARMGICGetIRQStart(GIC:PGICDevice):LongWord;
Description: To be documented
Note None documented


function ARMGICGetIRQRouting(GIC:PGICDevice):LongWord;
Description: To be documented
Note None documented


function ARMGICGetFIQRouting(GIC:PGICDevice):LongWord;
Description: To be documented
Note None documented


function ARMGICGetIRQLocalCount(GIC:PGICDevice):LongWord;
Description: To be documented
Note None documented


function ARMGICGetFIQLocalCount(GIC:PGICDevice):LongWord;
Description: To be documented
Note None documented


function ARMGICGetIRQLocalStart(GIC:PGICDevice):LongWord;
Description: To be documented
Note None documented


function ARMGICGetIRQSoftwareCount(GIC:PGICDevice):LongWord;
Description: To be documented
Note None documented


function ARMGICGetFIQSoftwareCount(GIC:PGICDevice):LongWord;
Description: To be documented
Note None documented


function ARMGICGetIRQSoftwateStart(GIC:PGICDevice):LongWord;
Description: To be documented
Note None documented


Return to Unit Reference