Provide interrupt mapping information in PCI config registers.

Use system-specific information to program the interrupt line register
with the interrupt mappings, which is what the SRM console does on real
hardware; some operating systems (e.g. NetBSD) use this information
rather than having interrupt mappings tables for every possible system
variation.

Signed-off-by: Jason Thorpe <thorpej@me.com>
Message-Id: <20210603035317.6814-7-thorpej@me.com>
[rth: Use inline not macro; fold -1 -> 0xff map into interface.]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Jason Thorpe
2021-06-02 20:53:15 -07:00
committed by Richard Henderson
parent 4793b28415
commit b5bee82277
2 changed files with 28 additions and 1 deletions

12
pci.c
View File

@ -29,6 +29,7 @@
#include "protos.h"
#include "pci.h"
#include "pci_regs.h"
#include SYSTEM_H
#define PCI_SLOT_MAX 32
@ -131,7 +132,16 @@ pci_setup_device(int bdf, uint32_t *p_io_base, uint32_t *p_mem_base)
pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
/* Map the interrupt. */
/* Map the interrupt and program the IRQ into the line register.
Some operating systems rely on the Console providing this information
in order to avoid having mapping tables for every possible system
variation. */
const uint8_t pin = pci_config_readb(bdf, PCI_INTERRUPT_PIN);
const uint8_t slot = PCI_SLOT(bdf);
const uint8_t irq = MAP_PCI_INTERRUPT(slot, pin, class_id);
pci_config_writeb(bdf, PCI_INTERRUPT_LINE, irq);
}
void

View File

@ -27,4 +27,21 @@
#define SYS_VARIATION (5 << 10)
#define SYS_REVISION 0
#ifndef __ASSEMBLER__
static inline uint8_t MAP_PCI_INTERRUPT(int slot, int pin, int class_id)
{
uint8_t irq = 0xff; /* no interrupt mapping */
/* PCI-ISA bridge is hard-wired to IRQ 55 on real hardware, and comes in
at a different SCB vector; force the line register to 0xff.
Otherwise, see qemu hw/alpha/dp264.c:clipper_pci_map_irq() */
if (class_id != 0x0601 && pin >= 1 && pin <= 4)
irq = (slot + 1) * 4 + (pin - 1);
return irq;
}
#endif /* ! __ASSEMBLER__ */
#endif