[PATCH 6/8] Provide interrupt mapping information in PCI config registers.

Jason Thorpe posted 8 patches 4 years, 6 months ago
[PATCH 6/8] Provide interrupt mapping information in PCI config registers.
Posted by Jason Thorpe 4 years, 6 months ago
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>
---
 pci.c         | 20 +++++++++++++++++++-
 sys-clipper.h | 27 +++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/pci.c b/pci.c
index 5e9c906..e3cab26 100644
--- a/pci.c
+++ b/pci.c
@@ -29,6 +29,7 @@
 #include "protos.h"
 #include "pci.h"
 #include "pci_regs.h"
+#include SYSTEM_H
 
 
 #define PCI_SLOT_MAX		32
@@ -132,7 +133,24 @@ 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 int irq = MAP_PCI_INTERRUPT(slot, pin, class_id);
+
+  if (irq == -1)
+    {
+      /* No interrupt mapping.  */
+      pci_config_writeb(bdf, PCI_INTERRUPT_LINE, 0xff);
+    }
+  else
+    {
+      pci_config_writeb(bdf, PCI_INTERRUPT_LINE, irq);
+    }
 }
 
 void
diff --git a/sys-clipper.h b/sys-clipper.h
index 31094ff..4f563bf 100644
--- a/sys-clipper.h
+++ b/sys-clipper.h
@@ -27,4 +27,31 @@
 #define SYS_VARIATION	(5 << 10)
 #define SYS_REVISION	0
 
+#ifndef __ASSEMBLER__
+
+#define MAP_PCI_INTERRUPT(SLOT, PIN, CLASS_ID)			\
+({								\
+  int IRQ;							\
+								\
+  if (CLASS_ID == 0x0601)					\
+    {								\
+      /* 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 -1.  */			\
+      IRQ = -1;							\
+    }								\
+  else if (PIN >= 1 && PIN <= 4)				\
+    {								\
+      /* See hw/alpha/dp264.c:clipper_pci_map_irq()  */		\
+      IRQ = (SLOT + 1) * 4 + (PIN - 1);				\
+    }								\
+  else								\
+    {								\
+      IRQ = -1;							\
+    }								\
+  IRQ;								\
+})
+
+#endif /* ! __ASSEMBLER__ */
+
 #endif
-- 
2.30.2


Re: [PATCH 6/8] Provide interrupt mapping information in PCI config registers.
Posted by Richard Henderson 4 years, 6 months ago
On 6/2/21 8:53 PM, Jason Thorpe wrote:
> 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>

Thanks.

> +  /* 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 int irq = MAP_PCI_INTERRUPT(slot, pin, class_id);
> +
> +  if (irq == -1)
> +    {
> +      /* No interrupt mapping.  */
> +      pci_config_writeb(bdf, PCI_INTERRUPT_LINE, 0xff);
> +    }
> +  else
> +    {
> +      pci_config_writeb(bdf, PCI_INTERRUPT_LINE, irq);
> +    }

I've folded this non-distinction into the functional interface.

> +#define MAP_PCI_INTERRUPT(SLOT, PIN, CLASS_ID)			\

I've turned this into a static inline.


r~