In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >
Share
Shulou(Shulou.com)06/01 Report--
1. Overview
This document mainly introduces the implementation process and method of GIC general interrupt controller based on SylixOS integrated development environment on IMX6UL platform.
2. GIC controller base address acquisition
The GIC controller base address is obtained by calling the armPrivatePeriphBaseGet function. As shown in figure 2.1, the Ctrl+h office searches for the armPrivatePeriphBaseGet function, and the search results are shown in figure 2.2.
Figure 2.1 Global search for armPrivatePeriphBaseGet functions
Figure 2.2 search results for armPrivatePeriphBaseGet function
Referring to the DDI0464F_cortex_a7_mpcore_r0p5_trm.pdf manual, this instruction transfers the data from the register of the coprocessor P15 to the register R0 of the ARM processor, and finally obtains it through the armPrivatePeriphBaseGet function. As shown in figures 2.3 and 2.4.
Figure 2.3 CP15 coprocessor opcode
Figure 2.4 CP15 read base address instruction
Note: the format of the MRC instruction is:
MRC {condition} coprocessor coding, coprocessor opcode 1, destination register, source register 1, source register 2, coprocessor opcode 2.
The MRC instruction is used to transfer the data from the coprocessor register to the ARM processor register. If the coprocessor cannot successfully complete the operation, an undefined instruction exception is generated. The coprocessor opcode 1 and the coprocessor opcode 2 are the operations to be performed by the coprocessor, the destination register is the register of the ARM processor, and the source register 1 and the source register 2 are the registers of the coprocessor.
Example of directive:
MRC P3, 3, R0, C4, C5, 6; the instruction transfers the data in the register of the coprocessor P3 to the register of the ARM processor.
3. GIC controller structure description
The distributor-side register structure definition in the GIC controller is shown in figure 3.1, and the CPU interface-side structure definition is shown in figure 3.2.
Figure 3.1 Distributor-side register structure definition
Figure 3.2 CPU interface side structure definition
4. Implementation of GIC related functions.
4.1 GIC controller initialization
4.1.1 dispenser initialization
Operate on the members of the distributor structure, turn off all pending interrupts and disable all interrupts, while setting all interrupts to safe mode. The implementation is shown in listing 4.1 of the program.
Program listing 4.1 dispatcher initialization
VOID armGicInit (VOID) {REGISTER GIC_DISTRIBUTOR_REG * pDistributor = armGicIntDistributorGet (); REGISTER INT iCnt; armGicEnable (LW_FALSE); / * First disable the distributor * / for (iCnt = 0; iCnt
< GIC_INT_NUM; iCnt++) { /* Clear all pending interrupts */ write32(~0, (addr_t)&pDistributor->UiICPENDRn [iCnt]);} for (iCnt = 0; iCnt)
< GIC_INT_NUM; iCnt++) { /* Disable all interrupts. */ write32(~0, (addr_t)&pDistributor->UiICENABLERn [iCnt]);} for (iCnt = 0; iCnt)
< GIC_INT_GRP_NUM; iCnt++) { /* Set all interrupts to secure */ write32(0, (addr_t)&pDistributor->UiIGROUPRn [iCnt]);} armGicEnable (LW_TRUE); / * Now enable the distributor * /}
4.1.2 CPU interface initialization
Operate on the cpu interface side structure members, set the priority mask of the current CPU to 255, prohibit interrupt preemption, and enable the current CPU to the GIC interface. The implementation is shown in listing 4.2 of the program.
Listing 4.2 initialization of the CPU interface
VOID armGicCpuInit (BOOL bPreemption, UINT32 uiPriority) {REGISTER GIC_CPU_INTERFACE_REGS * pInterface = armGicCpuInterfaceGet (); armGicCpuPriorityMaskSet (uiPriority); / * Init the GIC CPU interface * / if (bPreemption) {/ * * Enable preemption. * / write32 (GIC_CPU_INTERFACE_PREEM_EN, (addr_t) & pInterface- > uiBPR);} else {/ * * Disable preemption. * / write32 (GIC_CPU_INTERFACE_PREEM_DISEN, (addr_t) & pInterface- > uiBPR);} armGicCpuEnable (LW_TRUE); / * Enable signaling the CPU * /}
4.2 interrupt vector base address setting
As shown in figures 4.1 and 4.2, Ctrl+h searches for the armVectorBaseAddrSet function globally.
Figure 4.1 Global search for armVectorBaseAddrSet functions
Figure 4.2 search results for armVectorBaseAddrSet function
Refer to the DDI0464F_cortex_a7_mpcore_r0p5_trm.pdf manual, as shown in figure 4.3.
Figure 4.3 introduction of interrupt vector base address
When prompted, refer to the DDI0406C_C_arm_architecture_reference_manual.pdf manual as shown in figure 4.4 below.
Figure 4.4 interrupt vector base address description
It can be seen that the register stores the base address of the interrupt vector table with reference to the bspMap.h file, and the physical address of the interrupt vector table is BSP_CFG_RAM_BASE (0x80000000).
4.3 implementation of system interrupt controller
The interrupt processor needs to be initialized during the power-up of the system, otherwise the programs used later on to the interrupt will not run normally.
As you can see from startup.S, as shown in figure 4.5, the system only responds to irq interrupts and does not handle fiq interrupts.
Figure 4.5 irq interrupt entry address
The interrupt function needs to be implemented as shown in figure 4.6.
Figure 4.6 list of functions
4.4 interrupt service program
By reading the hardware register, the current generated interrupt vector number is obtained, and the system interface archIntHandle is called for processing. After the processing is completed, the GIC is informed that the interrupt has been processed.
4.4.1 read the register GICC_IAR to get the interrupt number, as shown in listing 4.3 of the program.
Listing 4.3 gets the interrupt number
UINT32 armGicIrqReadAck (VOID) {REGISTER GIC_CPU_INTERFACE_REGS * pInterface = armGicCpuInterfaceGet (); return (read32 ((addr_t) & pInterface- > uiIAR);}
4.4.2 write a break number to GICC_EOIR to inform GIC that the interrupt processing is complete, as shown in listing 4.4 of the program.
Listing 4. 4 informs GIC that the interrupt processing is complete
VOID armGicIrqWriteDone (UINT32 uiIrqID) {REGISTER GIC_CPU_INTERFACE_REGS * pInterface = armGicCpuInterfaceGet (); write32 (uiIrqID, (addr_t) & pInterface- > uiEOIR);}
4.5 enable specified interrupt
The specified interrupt vector is enabled by setting the hardware register. The implementation is shown in listing 4.5.
Listing 4.5 enables you to specify interrupts
VOID armGicIntVecterEnable (ULONG ulVector, BOOL bSecurity, ULONG ulPriority, ULONG uiCpuMask) {armGicIrqEnable (ulVector, LW_FALSE); armGicIrqSecuritySet (ulVector, bSecurity); armGicIrqPrioritySet (ulVector, ulPriority); armGicIrqTargetSet (ulVector, GIC_CPU_MASK, LW_FALSE); armGicIrqTargetSet (ulVector, uiCpuMask, LW_TRUE); armGicIrqEnable (ulVector, LW_TRUE);}
Note: since imx6ul is a single-core processor, it is not necessary to select the target CPU in theory, but because the GIC interrupt controller is used, the target register group needs to be configured to 0, that is, CPU0 is selected by default.
4.6 disable specified interrupt
By setting hardware registers, interrupts can be disabled. The implementation is shown in listing 4.6 of the program.
Listing 4.6 disables specifying interrupts
VOID armGicIntVecterDisable (ULONG ulVector) {armGicIrqEnable (ulVector, LW_FALSE); armGicIrqTargetSet (ulVector, GIC_CPU_MASK, LW_FALSE);}
4.7 determine whether the interrupt is enabled
Check whether the specified interrupt vector is enabled by reading the hardware register. The implementation is shown in listing 4.7.
Listing 4.7 determines whether the specified interrupt vector is enabled or not
BOOL armGicIrqIsEnable (UINT32 uiIrqID) {REGISTER GIC_DISTRIBUTOR_REG * pDistributor = armGicIntDistributorGet (); REGISTER UINT32 uiReg = armGicIntRegOffsGet (uiIrqID); REGISTER UINT32 uiMask = armGicIntBitMaskGet (uiIrqID); return ((read32 ((addr_t) & pDistributor- > uiICENABLERn [uiReg]) & uiMask)? LW_TRUE: LW_FALSE);}
4.8 get / set interrupt priority
This item is generated by default by the project and is not implemented, as shown in listing 4.8.
Listing 4.8 gets / sets the interrupt priority
ULONG bspIntVectorSetPriority (ULONG ulVector, UINT uiPrio) {return (ERROR_NONE);} ULONG bspIntVectorGetPriority (ULONG ulVector, UINT * puiPrio) {* puiPrio = 0; return (ERROR_NONE);}
4.9 get / set interrupt target CPU
Because imx6ul is a single-core processor, although GIC general interrupt controller is used, CPU0 is selected by default.
The implementation in bsplib.c is shown in listing 4.9.
Listing 4.9 gets / sets the interrupt target CPU
ULONG bspIntVectorSetTarget (ULONG ulVector, size_t stSize, const PLW_CLASS_CPUSET pcpuset) {return (ERROR_NONE);} ULONG bspIntVectorGetTarget (ULONG ulVector, size_t stSize, PLW_CLASS_CPUSET pcpuset) {LW_CPU_ZERO (pcpuset); LW_CPU_SET (0, pcpuset); return (ERROR_NONE);}
5. Fill the contents related to bsplib.c interrupt
Add the corresponding function functions to bspLib.c, as shown in listing 5.1 of the program.
Listing 5.1 bspLib.c interrupt related padding
/ * interrupt correlation * * / VOID bspIntInit (VOID) {armGicInit () / * * lowest priority of interrupts that can be passed to the current CPU * / armGicCpuInit (LW_FALSE, 255); armVectorBaseAddrSet (BSP_CFG_RAM_BASE);} VOID bspIntHandle (VOID) {REGISTER UINT32 uiAck = armGicIrqReadAck (); REGISTER UINT32 uiSourceCpu = (uiAck > > 10) & 0x7; REGISTER UINT32 uiVector = uiAck & 0x1FF; (VOID) uiSourceCpu; archIntHandle ((ULONG) uiVector, LW_FALSE) ArmGicIrqWriteDone (uiAck);} VOID bspIntVectorEnable (ULONG ulVector) {/ * * 1
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.