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-changelog

[Xen-changelog] [qemu-xen-unstable] passthrough: multi-function PCI in A

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [qemu-xen-unstable] passthrough: multi-function PCI in ACPI
From: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
Date: Mon, 29 Jun 2009 03:01:42 -0700
Delivery-date: Mon, 29 Jun 2009 03:01:55 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
commit a41a773ac5a8aed20222593711509d43bafaf275
Author: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Date:   Thu Jun 25 18:32:29 2009 +0100

    passthrough: multi-function PCI in ACPI
    
    This changes the interface beween qemu-xen and the ACPI portion
    of hvmlader. As such it breaks compatibility with older
    hvmloaders and a companion patch to hvmloader is needed.
    
    There is a subsequent "noise" companion to this change
    which changes slot to devfn as appropriate.
    
    Cc: Dexuan Cui <dexuan.cui@xxxxxxxxx>
    Cc: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx>
    Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx>
    
    [6/8; cross-compatibility issues with xen-unstable.hg]
---
 hw/piix4acpi.c |  112 +++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 82 insertions(+), 30 deletions(-)

diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c
index 49c5204..48aebf0 100644
--- a/hw/piix4acpi.c
+++ b/hw/piix4acpi.c
@@ -56,8 +56,9 @@
 /* The bit in GPE0_STS/EN to notify the pci hotplug event */
 #define ACPI_PHP_GPE_BIT 3
 
-typedef struct AcpiDeviceState AcpiDeviceState;
-AcpiDeviceState *acpi_device_table;
+#define NR_PHP_SLOT_REG (NR_PCI_DEVFN/2)
+#define DEVFN_TO_PHP_SLOT_REG(devfn) (devfn >> 1)
+#define PHP_SLOT_REG_TO_DEVFN(reg, hilo) ((reg << 1) | hilo)
 
 typedef struct PCIAcpiState {
     PCIDevice dev;
@@ -77,17 +78,46 @@ typedef struct GPEState {
 static GPEState gpe_state;
 
 typedef struct PHPSlots {
-    uint8_t status[NR_PCI_DEV]; /* Apaptor stats */
-    uint8_t plug_evt;           /* PHP_EVT_ADD or PHP_EVT_REMOVE
-                                 * PSTA in ASL */
-    uint8_t plug_slot;          /* Slot number
-                                 * PSTB in ASL */
+    uint8_t status[NR_PHP_SLOT_REG]; /* Apaptor n stats | Adaptor n+1 status */
+    uint8_t plug_evt;                /* PHP_EVT_ADD or PHP_EVT_REMOVE
+                                      * PSTA in ASL */
+    uint8_t plug_slot;               /* Slot number
+                                      * PSTB in ASL */
 } PHPSlots;
 
 static PHPSlots php_slots;
 int s3_shutdown_flag;
 static qemu_irq sci_irq;
 
+static void php_reg_set(PHPSlots *hotplug_slots, int devfn, uint8_t val)
+{
+    uint8_t *reg = &(hotplug_slots->status[DEVFN_TO_PHP_SLOT_REG(devfn)]);
+
+    /* Value may only use a nibble */
+    val &= 0xf;
+
+    if (devfn & 0x1)
+        *reg = (*reg & 0x0f) | (val << 4);
+    else
+        *reg = (*reg & 0xf0) | val;
+}
+
+
+static uint8_t php_reg_get(PHPSlots *hotplug_slots, int devfn)
+{
+    uint8_t reg = hotplug_slots->status[DEVFN_TO_PHP_SLOT_REG(devfn)];
+    uint8_t val;
+
+    if (devfn & 0x1)
+        val = (reg & 0xf0) >> 4;
+    else
+        val = reg & 0x0f;
+
+    return val;
+}
+
+typedef struct AcpiDeviceState AcpiDeviceState;
+AcpiDeviceState *acpi_device_table;
 static void piix4acpi_save(QEMUFile *f, void *opaque)
 {
     PCIAcpiState *s = opaque;
@@ -225,8 +255,8 @@ static void acpi_dbg_writel(void *opaque, uint32_t addr, 
uint32_t val)
  * ACPI_PHP_IO_ADDR + :
  * 0 - the hotplug event
  * 1 - the slot that has a hotplug event
- * 2 - 1st php slot ctr/sts reg
- * 3 - 2nd php slot ctr/sts reg
+ * 2 - 1st php slot ctr/sts reg|2nd php slot ctr/sts reg
+ * 3 - 3rd php slot ctr/sts reg|4th php slot ctr/sts reg
  * ...
  */
 static uint32_t acpi_php_readb(void *opaque, uint32_t addr)
@@ -248,7 +278,7 @@ static uint32_t acpi_php_readb(void *opaque, uint32_t addr)
         val = hotplug_slots->status[num];
     }
 
-    fprintf(logfile, "ACPI PCI hotplug: read addr=0x%x, val=0x%x.\n",
+    fprintf(logfile, "ACPI PCI hotplug: read addr=0x%x, val=0x%02x.\n",
             addr, val);
 
     return val;
@@ -257,9 +287,9 @@ static uint32_t acpi_php_readb(void *opaque, uint32_t addr)
 static void acpi_php_writeb(void *opaque, uint32_t addr, uint32_t val)
 {
     PHPSlots *hotplug_slots = opaque;
-    int slot;
+    int devfn, num, func, i;
 
-    fprintf(logfile, "ACPI PCI hotplug: write addr=0x%x, val=0x%x.\n",
+    fprintf(logfile, "ACPI PCI hotplug: write addr=0x%x, val=0x%02x.\n",
             addr, val);
 
     switch (addr)
@@ -268,17 +298,39 @@ static void acpi_php_writeb(void *opaque, uint32_t addr, 
uint32_t val)
     case ACPI_PHP_IO_ADDR + 1:
         break;
     default:
-        slot = addr - ACPI_PHP_IO_ADDR - 2;
-        if ( val == 0x1 ) { /* Eject command */
-            /* make _STA of the slot 0 */
-            hotplug_slots->status[slot] = 0;
+        num = addr - ACPI_PHP_IO_ADDR - 2;
+        if ( val == 0x01 || val == 0x10 ) { /* Eject command */
+            if ( val == 0x01 )
+                devfn = PHP_SLOT_REG_TO_DEVFN(num, 0);
+            else
+                devfn = PHP_SLOT_REG_TO_DEVFN(num, 1);
+
+            fprintf(logfile, "ACPI PCI hotplug: write devfn=0x%02x.\n",
+                    devfn);
+
+            if (hotplug_slots->plug_evt != PHP_EVT_REMOVE ||
+                hotplug_slots->plug_slot != devfn )
+            {
+                fprintf(logfile, "ACPI PCI hotplug: not expecting "
+                        "devfn 0x%02x to be removed. Expected event 0x%x "
+                        "for devfn 0x%02x\n", devfn,
+                        hotplug_slots->plug_evt, hotplug_slots->plug_slot);
+                return;
+            }
 
             /* clear the hotplug event */
             hotplug_slots->plug_evt = 0;
-            hotplug_slots->plug_slot = 0;
 
-            /* power off the slot */
-            power_off_php_devfn(PCI_DEVFN(slot, 0));
+            for ( func = NR_PCI_FUNC - 1; func >= 0; func-- )
+            {
+                i = PCI_DEVFN(PCI_SLOT(devfn), func);
+
+                /* make _STA of the slot 0 */
+                php_reg_set(hotplug_slots, i, 0);
+
+                /* power off the slot */
+                power_off_php_devfn(i);
+            }
 
             /* signal the CP ACPI hot remove done. */
             xenstore_record_dm_state("pci-removed");
@@ -290,7 +342,7 @@ static void pcislots_save(QEMUFile* f, void* opaque)
 {
     PHPSlots *hotplug_slots = opaque;
     int i;
-    for ( i = 0; i < NR_PCI_DEV; i++ ) {
+    for ( i = 0; i < NR_PHP_SLOT_REG; i++ ) {
         qemu_put_8s( f, &hotplug_slots->status[i]);
     }
     qemu_put_8s(f, &hotplug_slots->plug_evt);
@@ -303,7 +355,7 @@ static int pcislots_load(QEMUFile* f, void* opaque, int 
version_id)
     int i;
     if (version_id != 1)
         return -EINVAL;
-    for ( i = 0; i < NR_PCI_DEV; i++ ) {
+    for ( i = 0; i < NR_PHP_SLOT_REG; i++ ) {
         qemu_get_8s( f, &hotplug_slots->status[i]);
     }
     qemu_get_8s(f, &hotplug_slots->plug_evt);
@@ -317,15 +369,15 @@ static void php_slots_init(void)
     memset(&php_slots, 0, sizeof(PHPSlots));
 
     /* update the pci slot status */
-    for ( i = 0; i < NR_PCI_DEV; i++ ) {
+    for ( i = 0; i < NR_PCI_DEVFN; i++ ) {
         if ( test_pci_devfn(i) )
-            php_slots.status[i] = 0xf;
+            php_reg_set(&php_slots, i, 0xf);
     }
 
     /* ACPI PCI hotplug controller */
-    register_ioport_read(ACPI_PHP_IO_ADDR, NR_PCI_DEV + 2, 1,
+    register_ioport_read(ACPI_PHP_IO_ADDR, NR_PHP_SLOT_REG + 2, 1,
                          acpi_php_readb, &php_slots);
-    register_ioport_write(ACPI_PHP_IO_ADDR, NR_PCI_DEV + 2, 1,
+    register_ioport_write(ACPI_PHP_IO_ADDR, NR_PHP_SLOT_REG + 2, 1,
                           acpi_php_writeb, &php_slots);
     register_savevm("pcislots", 0, 1, pcislots_save, pcislots_load,
                     &php_slots);
@@ -489,7 +541,7 @@ void acpi_php_del(int devfn)
 
     /* update the php controller status */
     php_slots.plug_evt = PHP_EVT_REMOVE;
-    php_slots.plug_slot = slot;
+    php_slots.plug_slot = devfn;
 
     /* generate a SCI interrupt */
     acpi_sci_intr(s);
@@ -530,12 +582,12 @@ void acpi_php_add(int devfn)
     {
         /* update the php controller status */
         php_slots.plug_evt = PHP_EVT_ADD;
-        php_slots.plug_slot = slot;
-
-        /* update the slot status as present */
-        php_slots.status[slot] = 0xf;
+        php_slots.plug_slot = devfn;
     }
 
+    /* update the slot status as present */
+    php_reg_set(&php_slots, devfn, 0xf);
+
     /* power on the function */
     power_on_php_devfn(devfn);
 
--
generated by git-patchbot for /home/xen/git/qemu-xen-unstable.git

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [qemu-xen-unstable] passthrough: multi-function PCI in ACPI, Ian Jackson <=