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 6/8] qemu-xen: pass-through: multi-function PCI in ACPI

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [rfc 6/8] qemu-xen: pass-through: multi-function PCI in ACPI
From: Simon Horman <horms@xxxxxxxxxxxx>
Date: Wed, 17 Jun 2009 18:07:42 +1000
Cc: 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:21:22 -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
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>

--- 

This patch is co-dependent on
"hvmloader: multi-function PCI hot-plug"

Index: ioemu-remote/hw/piix4acpi.c
===================================================================
--- ioemu-remote.orig/hw/piix4acpi.c    2009-04-06 14:56:00.000000000 +1000
+++ ioemu-remote/hw/piix4acpi.c 2009-04-06 15:01:49.000000000 +1000
@@ -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
  * 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 *opa
         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 *opa
 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
     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, v
 {
     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, vo
     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);
 

-- 

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