General IRQ routing on x86_64

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

General IRQ routing on x86_64

Post by NickJohnson »

I'm working on a general-purpose limited hardware abstraction layer (limited in that it only deals with the processor and core platform components, not peripheral devices) and I'm trying to figure out the easiest and least limiting way to initialize IRQ routing so that whatever is built on top of it can express which IRQs it wants to wait for in a consistent fashion. I've already got what I believe to be an adequate API on the software side, which resembles a select() interface with an additional call for sending EOIs.

What I'm stuck on is getting the APIC architecture to send interrupts to the right places in such a way that I can figure out which device they actually came from. I'm used to dealing with the legacy 8259 PIC, which I used in my last project, so I'm not yet fully acquainted with the whole I/O APIC mess. It seems like there are a lot of methods out there to try and untangle IRQ routing (MP tables, ACPI tables, etc.) but a lot of it is old, and I can't seem to figure out what the "standard" method is nowadays. I really only want to target x86_64 hardware with SMP support, and can deal with dropping support for anything more than 5 years old. The primary purpose of the project is as a didactic tool, and it will be running mostly on virtualized hardware.

What would those of you who have dealt with the I/O APIC recommend in this situation?
User avatar
trinopoty
Member
Member
Posts: 87
Joined: Wed Feb 09, 2011 2:21 am
Location: Raipur, India

Re: General IRQ routing on x86_64

Post by trinopoty »

If you don't want your HAL to deal with devices other than the Core devices, you have almost no way of telling which device is causing an interrupt. Specially so when you allow drivers to specify an IRQ number.
My way of doing it would be: receive IRQ; (I will already know the IRQ number); iterate through a list of drivers waiting for IRQs; find one that is waiting for the IRQ just received; invoke it.

Of course, this is just an example and may or may not (most likely) be efficient or feasible in the real world.
Always give a difficult task to a lazy person. He will find an easy way to do it.
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

Re: General IRQ routing on x86_64

Post by NickJohnson »

I already have that part figured out. What I'm stuck on is getting IRQ numbering that can be predictably used by a system running under the HAL, so that the system can predict which devices it is configuring will be connected to which (virtual) IRQ lines the HAL presents.
Cognition
Member
Member
Posts: 191
Joined: Tue Apr 15, 2008 6:37 pm
Location: Gotham, Batmanistan

Re: General IRQ routing on x86_64

Post by Cognition »

In terms of hardware representation resource wise you'll have a combination of IRQs and global system interrupts. Basically IRQs are assumed to map to the first 16 global system interrupts unless there's an entry in the MADT or MP tables overriding the routing (as well as trigger mode). In terms of the APIC and EOIs, I simply have a class of devices described as an interrupt router that supply a range of global system interrupts and describe the EOI method of the device.

The interrupt interface for software interrupts on the processor itself basically consists of an array of function pointers and another array of argument values. When an interrupt is triggered the ISR will call the function with the argument. That argument is stored when the interrupt is initially enabled and routed to the processor(s). For sake of forward compatibility and perhaps better diagnostics you would probably want to store a structure containing a function pointer to an EOI method, a pointer to the interrupt router object itself and whatever other information you feel is necessary.
Reserved for OEM use.
rdos
Member
Member
Posts: 3306
Joined: Wed Oct 01, 2008 1:55 pm

Re: General IRQ routing on x86_64

Post by rdos »

There are several new issues with APIC.

1. You allocate the interrupt vector number from the IDT, rather than having a fixed mapping as between PIC entry and interrupt vector.
2. Some services need several consecutive interrupt vectors (AHCI for instance).
3. Priority is based on the higher bits of the vector number, meaning that the allocation algorithm should have a priority indicator
4. In order to determine PCI IRQ routings, you need ACPI and AML (or detection logic).
5. There is a new (superior) method for interrupts with PCI called MSI, which should be preferred if present.
Post Reply