WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [rfc 1/8] qemu-xen: pass-through: Read the interrupt pin fro

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [rfc 1/8] qemu-xen: pass-through: Read the interrupt pin from hardware
From: Simon Horman <horms@xxxxxxxxxxxx>
Date: Wed, 17 Jun 2009 18:07:37 +1000
Cc: Yuji Shimada <shimada-yxb@xxxxxxxxxxxxxxx>, Ian Jackson <ian.jackson@xxxxxxxxxxxxx>, Akio Takebe <takebe_akio@xxxxxxxxxxxxxx>, Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx>, Dexuan Cui <dexuan.cui@xxxxxxxxx>
Delivery-date: Wed, 17 Jun 2009 01:12:46 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20090617080736.631945993@xxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: quilt/0.46-1
Preparation for multi-fucntion devices in guests.

Up until now guests have only seen devices with one function,
so it is both safe and sensible to always use INTA. But if
if multiple functions appear, it makes sense to use
the interrupt pin specified by the hardware.

Cc: Dexuan Cui <dexuan.cui@xxxxxxxxx>
Cc: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx>
Cc: Yuji Shimada <shimada-yxb@xxxxxxxxxxxxxxx>
Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx>

Index: ioemu-remote/hw/pass-through.c
===================================================================
--- ioemu-remote.orig/hw/pass-through.c 2009-06-15 11:25:38.000000000 +1000
+++ ioemu-remote/hw/pass-through.c      2009-06-15 11:25:40.000000000 +1000
@@ -2296,8 +2296,7 @@ static int pt_init_pci_config(struct pt_
     if (ret < 0 && ptdev->machine_irq != 0)
     {
         uint8_t e_device = PCI_SLOT(ptdev->dev.devfn);
-        /* fix virtual interrupt pin to INTA# */
-        uint8_t e_intx = 0;
+        uint8_t e_intx = pci_intx(ptdev);
 
         ret = xc_domain_bind_pt_pci_irq(xc_handle, domid, ptdev->machine_irq,
                                        0, e_device, e_intx);
@@ -3580,7 +3579,6 @@ static int pt_msgctrl_reg_write(struct p
     uint16_t writable_mask = 0;
     uint16_t throughable_mask = 0;
     uint16_t old_ctrl = cfg_entry->data;
-    uint8_t e_device, e_intx;
     PCIDevice *pd = (PCIDevice *)ptdev;
     uint16_t val;
 
@@ -4106,7 +4104,7 @@ static struct pt_dev * register_real_dev
     {
         e_device = PCI_SLOT(assigned_device->dev.devfn);
         /* fix virtual interrupt pin to INTA# */
-        e_intx = 0;
+        e_intx = pci_intx(assigned_device);
 
         rc = xc_domain_bind_pt_pci_irq(xc_handle, domid, machine_irq, 0,
                                        e_device, e_intx);
@@ -4164,8 +4162,7 @@ static int unregister_real_device(int sl
 
     /* Unbind interrupt */
     e_device = PCI_SLOT(assigned_device->dev.devfn);
-    /* fix virtual interrupt pin to INTA# */
-    e_intx = 0;
+    e_intx = pci_intx(assigned_device);
     machine_irq = assigned_device->machine_irq;
 
     if ( assigned_device->msi_trans_en == 0 && machine_irq ) {
@@ -4258,3 +4255,60 @@ int pt_init(PCIBus *e_bus)
     return 0;
 }
 
+/* The PCI Local Bus Specification, Rev. 3.0,
+ * Section 6.2.4 Miscellaneous Registers, pp 223
+ * outlines 5 valid values for the intertupt pin (intx).
+ *  0: For devices (or device functions) that don't use an interrupt in
+ *  1: INTA#
+ *  2: INTB#
+ *  3: INTC#
+ *  4: INTD#
+ *
+ * Xen uses the following 4 values for intx
+ *  0: INTA#
+ *  1: INTB#
+ *  2: INTC#
+ *  3: INTD#
+ *
+ * Observing that these list of values are not the same, pci_read_intx()
+ * uses the following mapping from hw to xen values.
+ * This seems to reflect the current usage within Xen.
+ *
+ * PCI hardware    | Xen | Notes
+ * ----------------+-----+----------------------------------------------------
+ * 0               | 0   | No interrupt
+ * 1               | 0   | INTA#
+ * 2               | 1   | INTB#
+ * 3               | 2   | INTC#
+ * 4               | 3   | INTD#
+ * any other value | 0   | This should never happen, log error message
+ */
+static uint8_t pci_read_intx(struct pt_dev *ptdev)
+{
+    uint8_t r_val = pci_read_byte(ptdev->pci_dev, PCI_INTERRUPT_PIN);
+
+    PT_LOG("intx=%i\n", r_val);
+    if (r_val < 1 || r_val > 4)
+    {
+        PT_LOG("Interrupt pin read from hardware is out of range: "
+               "value=%i, acceptable range is 1 - 4\n", r_val);
+        r_val = 0;
+    }
+    else
+    {
+        r_val -= 1;
+    }
+
+    return r_val;
+}
+
+/*
+ * For virtual function 0, always use INTA#,
+ * otherwise use the hardware value
+ */
+uint8_t pci_intx(struct pt_dev *ptdev)
+{
+    if (!PCI_FUNC(ptdev->dev.devfn))
+        return 0;
+    return pci_read_intx(ptdev);
+}
Index: ioemu-remote/hw/pt-msi.c
===================================================================
--- ioemu-remote.orig/hw/pt-msi.c       2009-06-15 11:25:38.000000000 +1000
+++ ioemu-remote/hw/pt-msi.c    2009-06-15 11:25:40.000000000 +1000
@@ -153,8 +153,7 @@ void pt_msi_disable(struct pt_dev *dev)
     msi_set_enable(dev, 0);
 
     e_device = PCI_SLOT(dev->dev.devfn);
-    /* fix virtual interrupt pin to INTA# */
-    e_intx = 0;
+    e_intx = pci_intx(dev);
 
     if (dev->msi_trans_en)
     {
@@ -224,7 +223,7 @@ int pt_enable_msi_translate(struct pt_de
 
     e_device = PCI_SLOT(dev->dev.devfn);
     /* fix virtual interrupt pin to INTA# */
-    e_intx = 0;
+    e_intx = pci_intx(dev);
 
     if (xc_domain_bind_pt_irq(xc_handle, domid, dev->msi->pirq,
                                PT_IRQ_TYPE_MSI_TRANSLATE, 0,
@@ -253,8 +252,7 @@ void pt_disable_msi_translate(struct pt_
     msi_set_enable(dev, 0);
 
     e_device = PCI_SLOT(dev->dev.devfn);
-    /* fix virtual interrupt pin to INTA# */
-    e_intx = 0;
+    e_intx = pci_intx(dev);
 
     if (xc_domain_unbind_pt_irq(xc_handle, domid, dev->msi->pirq,
                                  PT_IRQ_TYPE_MSI_TRANSLATE, 0,
Index: ioemu-remote/hw/pass-through.h
===================================================================
--- ioemu-remote.orig/hw/pass-through.h 2009-06-15 11:25:38.000000000 +1000
+++ ioemu-remote/hw/pass-through.h      2009-06-15 11:25:40.000000000 +1000
@@ -402,5 +402,7 @@ static inline pciaddr_t pt_pci_base_addr
     return base & PCI_ADDR_MEM_MASK;
 }
 
+uint8_t pci_intx(struct pt_dev *ptdev);
+
 #endif /* __PASSTHROUGH_H__ */
 

-- 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel