qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


From: Jason Thorpe
Subject: [PATCH 6/8] Provide interrupt mapping information in PCI config registers.
Date: Wed, 2 Jun 2021 20:53:15 -0700

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]