I am writing an AHCI driver for a minimal kernel and need to handle PCIe interrupts without MSI, relying solely on the legacy PIC 8259 and PCIe INTx virtual wire signaling.
I have already implemented PCI device init/scanner function and can read or write to the configuration registers of each PCI device. Now I am going through the checklist on OSDEV for implementing the AHCI driver. - https://wiki.osdev.org/AHCI#Checklist
One of the steps is:
Since the interrupt line can be shared among several devices how am I going to differentiate between them and check which device has issued an interrupt?
In the PCI specifications I can see that at offset 0x3C in the configuration register lies the interrupt line and the interrupt PIN that tells me which INTx# (e.g., INTA-D) the device uses. However I am not sure when the interrupt is issued by a device how would I check in my interrupt service routine what was the INTx# in order to match it with the correct device on this interrupt line?
how am I going to differentiate between them and check which device has issued an interrupt
Your interrupt handler is supposed to poll each device that could've possibly issued that interrupt. For AHCI specifically, see "IRQ handler checklist" at the same page - it says things like "Check global interrupt status" and "Check port interrupt status". Your shared IRQ handler must ask the connected devices if one (or more!) of them did issue an interrupt(s), and this is how you know which of them did raise interrupt on an INT# line.
how would I check in my interrupt service routine what was the INTx# in order to match it with the correct device on this interrupt line
You are supposed to configure a PCI controller, route INT# lines from the devices onto PCI controller's IRQ pins, route those IRQ pins onto 8259 IRQ lines in such a way as to balance PCI devices across as many separate IRQs as possible. Or maybe use whatever routing BIOS did, but you need to get that routing information. So you should generally have up to 4 different ISRs, and each of them is responsible for its subset of PCI devices (which ones is determined by the routing). See e.g. https://papers.freebsd.org/2007/bsdcan/baldwin-PCI_Interrupts_for_x86_Machines_under_FreeBSD.files/article.pdf for a good explanation on this whole topic. You probably want to use PCI BIOS to achieve this.