Creating Valid IRQ Tables

The wiki is being retired!

Documentation is now handled by the same processes we use for code: Add something to the Documentation/ directory in the coreboot repo, and it will be rendered to https://doc.coreboot.org/. Contributions welcome!

This article should help people who can't read back a valid interrupt routing table from their system.

What you will need

For documentation only: Here is the generic routing for up to four slots

Patching the development kernel

We start with a faked pirq table for coreboot to make its build system happy. It really doesn't matter what's in it, due to we will provide Linux itself with its own table.

Here's what I did

I have two PCI devices connected to my Geode GX1 based board (CS5530 chipset):

There is no additional slot, it is a very small Win-Terminal.

I assumed the Realtek outputs its interrupt on its INTA# pin (the starting kernel will state this if the DEBUG macro in pci.h is defined, so read the dmesg output if you're unsure). The same I assumed for the USB device. Also I assumed RealTek's INTA# output is connected to chipset's INTA# input, and USB's INTA# output is connected to chipset's INTB# input.

To find a start, I tried to use IRQ15 and IRQ11 for these devices. I wanted the network device connected to IRQ15 (green line) and the USB device connected to IRQ11 (red line). The PCI chip info the table needs I got from coreboot, when it scans the PCI bus. So activate a higher level of debug output in coreboot to collect all information you need here. Ignore the black lines in the picture. They may or may not exist.

So my first routing table in "my_pirq_table.c" looked like this:

 00:0f slot=00 0:01/8000 1:02/0800 2:03/0000 3:04/0000
 00:13 slot=00 0:02/0800 1:03/0000 2:04/0000 3:01/8000

Building this kernel and preparing it for boot

 $ mkelfImage "--command-line=console=ttyS0,115200 ip=dhcp rw root=/dev/nfs irqpoll"
    --type=bzImage-i386 --kernel=arch/i386/boot/bzImage --output=/tftpboot/igel-kernel

The important kernel parameter is irqpoll. This lets the network card do its job without a valid interrupt routing! It slows down the system, but makes it work! (in my case the NFS root filesystem)

Boot this kernel (I did it with etherboot). When the system is up and running, login to it and run a

 $ cat /proc/interrupts

to see what happens with the interrupts.

Note: Check the interrupt steering setting the Linux routing setup stores into the IRQ router! In my case it took hours to see, Linux didn't know my IRQ router! So the steering registers were still at their reset value, which means "No routing"! After adding the IRQ router support for my chipset it routes the interrupts!

 00:13 slot=00 0:01/0800 1:02/0000 2:03/8000 3:04/0000
 00:0f slot=00 0:03/8000 1:04/0000 2:01/0800 3:02/0000

This is the source I used in this case.

With this table also the network interrupt receives signals. Then I removed the "irqpoll" option and rebooted this kernel again. The system runs with interrupts only (and no more polling).

The interrupt routing table from my_pirq_table.c is now ready to be used in coreboot. Only the checksum may not be usable.

My kernel patch ignores a wrong checksum but calculates the right one instead! See dmesg's output, search for the right checksum and change it in the source file. Rebuild coreboot with this new IRQ routing table and flash it into your target.

Now you can run an unpatched kernel on your system.

Required patches for Geode's companion CS5530

Creative Commons License
Creative Commons Attribution icon
This file is licensed under Creative Commons Attribution 2.5 License.
In short: you are free to distribute and modify the file as long as you attribute its author(s) or licensor(s).