I am using Linaro's Android release on Juno r1. I noticed that there are 6 user push buttons on the board, and I am trying to use the buttons to trigger a world switch (from non-secure to secure).
Firstly I found the interrupt id for the push buttons on SoC maunal, it seems that all 6 buttons share the same interrupt id 195. Then I added the following lines to configure the interrupt 195 to be a secure interrupt,
file: arm-tf/drivers/arm/gic/arm_gic.c
function: arm_gic_distif_setup
gicd_set_igroupr(g_gicd_base, 195); gicd_set_isenabler(g_gicd_base, 195);
After that, i thought that the interrupt should be routed to EL3 first. And also, to learn how the secure interrupt works, i added logs in all functions in arm-tf/plat/common/plat_gic.c. However, when i press the buttons, nothing happened.
My first question is what is the difference between the "Interrupt ID" and the "GIC IRQ ID" listed in the Juno Technical Reference Manual, Table 2-5. They are different values, and i am a litter confusion about it.
Then about the GICD_IGROUPR. From the GIC manual, the description of GICD_IGROUPR tells that these registers works for interrupt 0-31. So the interrupt 195 is out of the scope. What is the correct way to
route the interrupt of push buttons to EL3?
Thanks for any help!
Regards,
Zhenyu
Hi,
It seems you've slightly misunderstood how the GIC works.
gicd_set_igroupr(g_gicd_base, 195);
This call to the gicd_set_igroupr() function will make interrupt ID 195 be Group 1, which is actually the opposite of what you want.
You want the interrupt to be Group 0 (by instead calling gicd_clr_igroupr()), with Group 0 interrupts signalled as FIQs (by setting GICD_CTLR.FIQEn), and FIQs routed to EL3 (by setting SCR_EL3.FIQ). By default Trusted Firmware already does the latter two.
Which version of the Technical Reference Manual are you using?
I'm using ARM DDI 0515F, which shows the interrupt mapping in Table 3-4, not Table 2-5 and also doesn't show a "GIC IRQ ID". What values are shown in your version of the TRM? If I had to take a guess, the "GIC IRQ ID" may be referring to the "SPI ID" which would be the Interrupt ID minus 32 (SPIs start at Interrupt ID 32). The "correct" value to use for the GIC driver functions is the Interrupt ID.
Then about the GICD_IGROUPR. From the GIC manual, the description of GICD_IGROUPR tells that these registers works for interrupt 0-31. So the interrupt 195 is out of the scope. What is the correct way toroute the interrupt of push buttons to EL3?
There are actually up to 32 separate GICD_IGROUPR registers, numbered [0..31] inclusive, i.e. GICD_IGROUPR0, GICD_IGROUPR1, ..., GICD_IGROUPR31, where each bit corresponds to the Group of a single Interrupt ID.
For a given interrupt ID (let's say 195 since that's the one you're using), the corresponding GICD_IGROUPR register is (195 / 32) = 6, and the corresponding bit in that register is (195 % 32) = 3.
So, clearing bit [3] of GICD_IGROUPR6 will make Interrupt ID 195 be Group 0, while setting the bit will make it be Group 1.
This same logic applies to other per-interrupt registers, such as GICD_ISENABLER, GICD_IPRIORITYR, GICD_ITARGETSR, etc, though in the case of the latter two registers each field is 8 bits rather than 1 bit, so the correct register and field number is calculated as (195 / 4) and (195 % 4) because there are 4 fields per register rather than 32 fields per register.
Hope that helps,
Ash
After configure the GPIO registers correctly, now this problem is solved.
By default, the GPIO interrupts are all disabled. I enabled all pins in GPIO, and it works.
View all questions in Arm Development Platforms forum