Can't understand /proc/interrupts output for GICv3 case

Chan Kim ckim at etri.re.kr
Mon Apr 11 09:16:43 EDT 2022


Hi Ozgur,

The SPI I meant was ‘shared peripheral interrupt’ of armv8 architecture.

(the interrupt is shared among cores. The interrupt controller distributes it)

I’ll look into your link when I’ll be working with SPI (serial peripheral interface) later :).

Thank you.

Chan 

 

From: Ozgur Kara <ozgur at goosey.org> 
Sent: Monday, April 11, 2022 10:10 PM
To: Chan Kim <ckim at etri.re.kr>; 'qemu-discuss' <qemu-discuss at nongnu.org>; kernelnewbies at kernelnewbies.org
Subject: Re: Can't understand /proc/interrupts output for GICv3 case

 

Hello,

 

firstly when you say SPI so can you give some more information about your hardware?

I think you are doing an embedded development in that case you should do some research on howto understand SPI interface under the kernel.

 

I think for example, source code of a previously written hardware using SPI bus can give you an idea. You can look at examples for example spi-based Xilinx however I think all SPI hardware is declared under /linux/drivers/spi with "spi.c". Also we see a "spi.h" header file depending on kernel headers.

 

So, if you define a master mode (MOSI) then "interrupt.h" header file will be useful because must first determine free irq and these calls are defined in interrupt.h.

 

Please attention some kernel call:

 

- request_irq

- irqsave()

- irqrestore()

 

and maybe check out the "Interrupt Handling" book and please read follow website:

 

https://www.kernel.org/doc/html/v4.11/driver-api/spi.html

 

* Book (Understand the Linux Kernel)

  - Section: Interrupt Handling

 

Salut!

 

11.04.2022, 16:36, "Chan Kim" <ckim at etri.re.kr <mailto:ckim at etri.re.kr> >:

Hi,
nobody's replying to my question.. so sad..
I found the kernel makes an array (actually a radix tree) of 'irq_desc's.
And my hwirq (SPI 15) is assigned to one of these irq_descs while processing
device tree.
In my case it was assigned irq 6 (this irq is what is called virtual irq).
So I registered the handler by request_irq(6,...) and the interrupt works
fine.
So now my question is : how can find my irq number (correct irq_desc number)
in kernel driver module?
I'll appreciate it if you could tell me how to do it.
Thank you!

Chan Kim
 

 -----Original Message-----
 From: Chan Kim <ckim at etri.re.kr <mailto:ckim at etri.re.kr> >
 Sent: Friday, April 8, 2022 1:53 PM
 To: 'qemu-discuss' <qemu-discuss at nongnu.org <mailto:qemu-discuss at nongnu.org> >;
 kernelnewbies at kernelnewbies.org <mailto:kernelnewbies at kernelnewbies.org> 
 Subject: Can't understand /proc/interrupts output for GICv3 case
 
 Hello all
 
 I think I'm asking too many question recently but sometimes I get very big
 help from here so please forgive me.
 (and I think someone else can get help from this email thread) I'm doing
 experiment for interrupt of a device called axpu on an arm64 virtual
 machine.
 In QEMU virtual machine, the interrupts are assigned as below.
 (These numbers are SPI(shared peripheral interrupt) numbers, and there are
 16 SGI and 16 PPI before SPI, so we have to add 32 to get the INTID
 value(hwirq number))
 
 static const int a15irqmap[] = {
     [AB21Q_UART] = 1,
     [AB21Q_RTC] = 2,
     [AB21Q_PCIE] = 3, /* ... to 6 */
     [AB21Q_GPIO] = 7,
     [AB21Q_SECURE_UART] = 8,
     [AB21Q_ACPI_GED] = 9,
     [AB21Q_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
     [AB21Q_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
     [AB21Q_SMMU] = 74, /* ...to 74 + NUM_SMMU_IRQS - 1 */
     [AB21Q_PLATFORM_BUS] = 112, /* ...to 112 + PLATFORM_BUS_NUM_IRQS -1 */
     [AB21Q_AXPU] = 15,
 };
 
 In the driver, when I do request_irq(32+15, axpu_irq_handler, IRQF_SHARED,
 "axpu_irq", &axpu_cdev) for my device axpu, the /proc/interrupts' looks
 like this. See the 10th item(axpu_irq).
 
                    CPU0
           1: 0 GICv3 25 Level vgic
           3: 0 GICv3 30 Level kvm guest ptimer
           4: 0 GICv3 27 Level kvm guest vtimer
           5: 20432 GICv3 26 Level arch_timer
          40: 0 GICv3 106 Edge arm-smmu-v3-evtq
          43: 0 GICv3 109 Edge arm-smmu-v3-gerror
          44: 0 GICv3 34 Level rtc-pl031
          45: 164 GICv3 33 Level uart-pl011
          46: 0 GICv3 23 Level arm-pmu
          47: 7789 GICv3 36 Level virtio0, axpu_irq
          48: 0 9030000.pl061 3 Edge GPIO Key Poweroff
         IPI0: 0 Rescheduling interrupts
         IPI1: 0 Function call interrupts
         IPI2: 0 CPU stop interrupts
         IPI3: 0 CPU stop (for crash dump) interrupts
         IPI4: 0 Timer broadcast interrupts
         IPI5: 0 IRQ work interrupts
         IPI6: 0 CPU wake-up interrupts
         Err: 0
 
 There are two numbers. One in the first column and the other in the 4th
 column.
 After observing uart-pl011 driver's action(who's irq in 8th row), I found
 the number in the first column is the one I should pass to the request_irq
 funcion, and the second number in the 4th column is the input to the

GICv3.

 (uart was assigned SPI 1, so 32+1 = 33).
 In my axpu driver case, I requested request_irq(47, ...) so hwirq is 47
 but I don't know why it was assigned to GICv3 input 36.
 Shouldn't it be 47 too? (32+15=47).
 
 Without fixing QEMU code(still using SPI 15), I tried doing

request_irq(15,

 axpu_irq_handler, ..) for test and this time it looks like this.(see the
 5th
 row)
 
            CPU0
   1: 0 GICv3 25 Level vgic
   3: 0 GICv3 30 Level kvm guest ptimer
   4: 0 GICv3 27 Level kvm guest vtimer
   5: 8174 GICv3 26 Level arch_timer
  15: 0 GICv3 56 Edge axpu_irq
  40: 0 GICv3 106 Edge arm-smmu-v3-evtq
  43: 0 GICv3 109 Edge arm-smmu-v3-gerror
  44: 0 GICv3 34 Level rtc-pl031
  45: 175 GICv3 33 Level uart-pl011
  46: 0 GICv3 23 Level arm-pmu
  47: 7790 GICv3 36 Level virtio0
  48: 0 9030000.pl061 3 Edge GPIO Key Poweroff
 IPI0: 0 Rescheduling interrupts
 IPI1: 0 Function call interrupts
 IPI2: 0 CPU stop interrupts
 IPI3: 0 CPU stop (for crash dump) interrupts
 IPI4: 0 Timer broadcast interrupts
 IPI5: 0 IRQ work interrupts
 IPI6: 0 CPU wake-up interrupts
 Err: 0
 
 Now axpu_irq has moved to INTID 15 (as expected), but it changed to "GICv3
 56 Edge".
 How is this GICv3 number is assigned? (and I guess edge trigger is the
 default for INTID < 16. Because it's SGI..?)
 
 I thought I connected my device (axpu) to SPI 15 in qemu code but this
 GICv3 input number changes according to with what number I called
 reqeust_irq.
 Could anyone tell me what is going on here?
 
 Thank you.
 Chan Kim

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20220411/f1f6f216/attachment.html>


More information about the Kernelnewbies mailing list