a19a21
From dfdf950e893c23e77c9dc0be18fca66ad195d260 Mon Sep 17 00:00:00 2001
a19a21
From: Greg Kurz <gkurz@redhat.com>
a19a21
Date: Wed, 10 Feb 2021 15:56:45 +0000
a19a21
Subject: [PATCH 2/2] spapr: Adjust firmware path of PCI devices
a19a21
MIME-Version: 1.0
a19a21
Content-Type: text/plain; charset=UTF-8
a19a21
Content-Transfer-Encoding: 8bit
a19a21
a19a21
RH-Author: Greg Kurz <gkurz@redhat.com>
a19a21
Message-id: <20210210165645.470195-2-gkurz@redhat.com>
a19a21
Patchwork-id: 101038
a19a21
O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 1/1] spapr: Adjust firmware path of PCI devices
a19a21
Bugzilla: 1912891
a19a21
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
a19a21
RH-Acked-by: David Gibson <dgibson@redhat.com>
a19a21
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
a19a21
a19a21
From: Greg Kurz <groug@kaod.org>
a19a21
a19a21
It is currently not possible to perform a strict boot from USB storage:
a19a21
a19a21
$ qemu-system-ppc64 -accel kvm -nodefaults -nographic -serial stdio \
a19a21
	-boot strict=on \
a19a21
	-device qemu-xhci \
a19a21
	-device usb-storage,drive=disk,bootindex=0 \
a19a21
	-blockdev driver=file,node-name=disk,filename=fedora-ppc64le.qcow2
a19a21
a19a21
SLOF **********************************************************************
a19a21
QEMU Starting
a19a21
 Build Date = Jul 17 2020 11:15:24
a19a21
 FW Version = git-e18ddad8516ff2cf
a19a21
 Press "s" to enter Open Firmware.
a19a21
a19a21
Populating /vdevice methods
a19a21
Populating /vdevice/vty@71000000
a19a21
Populating /vdevice/nvram@71000001
a19a21
Populating /pci@800000020000000
a19a21
                     00 0000 (D) : 1b36 000d    serial bus [ usb-xhci ]
a19a21
No NVRAM common partition, re-initializing...
a19a21
Scanning USB
a19a21
  XHCI: Initializing
a19a21
    USB Storage
a19a21
       SCSI: Looking for devices
a19a21
          101000000000000 DISK     : "QEMU     QEMU HARDDISK    2.5+"
a19a21
Using default console: /vdevice/vty@71000000
a19a21
a19a21
  Welcome to Open Firmware
a19a21
a19a21
  Copyright (c) 2004, 2017 IBM Corporation All rights reserved.
a19a21
  This program and the accompanying materials are made available
a19a21
  under the terms of the BSD License available at
a19a21
  http://www.opensource.org/licenses/bsd-license.php
a19a21
a19a21
Trying to load:  from: /pci@800000020000000/usb@0/storage@1/disk@101000000000000 ...
a19a21
E3405: No such device
a19a21
a19a21
E3407: Load failed
a19a21
a19a21
  Type 'boot' and press return to continue booting the system.
a19a21
  Type 'reset-all' and press return to reboot the system.
a19a21
a19a21
Ready!
a19a21
0 >
a19a21
a19a21
The device tree handed over by QEMU to SLOF indeed contains:
a19a21
a19a21
qemu,boot-list =
a19a21
	"/pci@800000020000000/usb@0/storage@1/disk@101000000000000 HALT";
a19a21
a19a21
but the device node is named usb-xhci@0, not usb@0.
a19a21
a19a21
This happens because the firmware names of PCI devices returned
a19a21
by get_boot_devices_list() come from pcibus_get_fw_dev_path(),
a19a21
while the sPAPR PHB code uses a different naming scheme for
a19a21
device nodes. This inconsistency has always been there but it was
a19a21
hidden for a long time because SLOF used to rename USB device
a19a21
nodes, until this commit, merged in QEMU 4.2.0 :
a19a21
a19a21
commit 85164ad4ed9960cac842fa4cc067c6b6699b0994
a19a21
Author: Alexey Kardashevskiy <aik@ozlabs.ru>
a19a21
Date:   Wed Sep 11 16:24:32 2019 +1000
a19a21
a19a21
    pseries: Update SLOF firmware image
a19a21
a19a21
    This fixes USB host bus adapter name in the device tree to match QEMU's
a19a21
    one.
a19a21
a19a21
    Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
a19a21
    Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
a19a21
a19a21
Fortunately, sPAPR implements the firmware path provider interface.
a19a21
This provides a way to override the default firmware paths.
a19a21
a19a21
Just factor out the sPAPR PHB naming logic from spapr_dt_pci_device()
a19a21
to a helper, and use it in the sPAPR firmware path provider hook.
a19a21
a19a21
Fixes: 85164ad4ed99 ("pseries: Update SLOF firmware image")
a19a21
Signed-off-by: Greg Kurz <groug@kaod.org>
a19a21
Message-Id: <20210122170157.246374-1-groug@kaod.org>
a19a21
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
a19a21
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
a19a21
(cherry picked from commit 040bdafce12f750816d879442014df2999a995c4)
a19a21
Signed-off-by: Greg Kurz <gkurz@redhat.com>
a19a21
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
a19a21
---
a19a21
 hw/ppc/spapr.c              |  5 +++++
a19a21
 hw/ppc/spapr_pci.c          | 33 ++++++++++++++++++---------------
a19a21
 include/hw/pci-host/spapr.h |  2 ++
a19a21
 3 files changed, 25 insertions(+), 15 deletions(-)
a19a21
a19a21
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
a19a21
index 00b1ef075e..bee2299199 100644
a19a21
--- a/hw/ppc/spapr.c
a19a21
+++ b/hw/ppc/spapr.c
a19a21
@@ -3013,6 +3013,7 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
a19a21
     SCSIDevice *d = CAST(SCSIDevice,  dev, TYPE_SCSI_DEVICE);
a19a21
     SpaprPhbState *phb = CAST(SpaprPhbState, dev, TYPE_SPAPR_PCI_HOST_BRIDGE);
a19a21
     VHostSCSICommon *vsc = CAST(VHostSCSICommon, dev, TYPE_VHOST_SCSI_COMMON);
a19a21
+    PCIDevice *pcidev = CAST(PCIDevice, dev, TYPE_PCI_DEVICE);
a19a21
 
a19a21
     if (d) {
a19a21
         void *spapr = CAST(void, bus->parent, "spapr-vscsi");
a19a21
@@ -3086,6 +3087,10 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
a19a21
         return g_strdup_printf("pci@%x", PCI_SLOT(pcidev->devfn));
a19a21
     }
a19a21
 
a19a21
+    if (pcidev) {
a19a21
+        return spapr_pci_fw_dev_name(pcidev);
a19a21
+    }
a19a21
+
a19a21
     return NULL;
a19a21
 }
a19a21
 
a19a21
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
a19a21
index f6fbcf99ed..befa570aa8 100644
a19a21
--- a/hw/ppc/spapr_pci.c
a19a21
+++ b/hw/ppc/spapr_pci.c
a19a21
@@ -1348,15 +1348,29 @@ static int spapr_dt_pci_bus(SpaprPhbState *sphb, PCIBus *bus,
a19a21
     return offset;
a19a21
 }
a19a21
 
a19a21
+char *spapr_pci_fw_dev_name(PCIDevice *dev)
a19a21
+{
a19a21
+    const gchar *basename;
a19a21
+    int slot = PCI_SLOT(dev->devfn);
a19a21
+    int func = PCI_FUNC(dev->devfn);
a19a21
+    uint32_t ccode = pci_default_read_config(dev, PCI_CLASS_PROG, 3);
a19a21
+
a19a21
+    basename = dt_name_from_class((ccode >> 16) & 0xff, (ccode >> 8) & 0xff,
a19a21
+                                  ccode & 0xff);
a19a21
+
a19a21
+    if (func != 0) {
a19a21
+        return g_strdup_printf("%s@%x,%x", basename, slot, func);
a19a21
+    } else {
a19a21
+        return g_strdup_printf("%s@%x", basename, slot);
a19a21
+    }
a19a21
+}
a19a21
+
a19a21
 /* create OF node for pci device and required OF DT properties */
a19a21
 static int spapr_dt_pci_device(SpaprPhbState *sphb, PCIDevice *dev,
a19a21
                                void *fdt, int parent_offset)
a19a21
 {
a19a21
     int offset;
a19a21
-    const gchar *basename;
a19a21
-    gchar *nodename;
a19a21
-    int slot = PCI_SLOT(dev->devfn);
a19a21
-    int func = PCI_FUNC(dev->devfn);
a19a21
+    g_autofree gchar *nodename = spapr_pci_fw_dev_name(dev);
a19a21
     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
a19a21
     ResourceProps rp;
a19a21
     SpaprDrc *drc = drc_from_dev(sphb, dev);
a19a21
@@ -1373,19 +1387,8 @@ static int spapr_dt_pci_device(SpaprPhbState *sphb, PCIDevice *dev,
a19a21
     uint32_t pci_status = pci_default_read_config(dev, PCI_STATUS, 2);
a19a21
     gchar *loc_code;
a19a21
 
a19a21
-    basename = dt_name_from_class((ccode >> 16) & 0xff, (ccode >> 8) & 0xff,
a19a21
-                                  ccode & 0xff);
a19a21
-
a19a21
-    if (func != 0) {
a19a21
-        nodename = g_strdup_printf("%s@%x,%x", basename, slot, func);
a19a21
-    } else {
a19a21
-        nodename = g_strdup_printf("%s@%x", basename, slot);
a19a21
-    }
a19a21
-
a19a21
     _FDT(offset = fdt_add_subnode(fdt, parent_offset, nodename));
a19a21
 
a19a21
-    g_free(nodename);
a19a21
-
a19a21
     /* in accordance with PAPR+ v2.7 13.6.3, Table 181 */
a19a21
     _FDT(fdt_setprop_cell(fdt, offset, "vendor-id", vendor_id));
a19a21
     _FDT(fdt_setprop_cell(fdt, offset, "device-id", device_id));
a19a21
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
a19a21
index 8877ff51fb..9522db9047 100644
a19a21
--- a/include/hw/pci-host/spapr.h
a19a21
+++ b/include/hw/pci-host/spapr.h
a19a21
@@ -212,4 +212,6 @@ static inline unsigned spapr_phb_windows_supported(SpaprPhbState *sphb)
a19a21
     return sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1;
a19a21
 }
a19a21
 
a19a21
+char *spapr_pci_fw_dev_name(PCIDevice *dev);
a19a21
+
a19a21
 #endif /* PCI_HOST_SPAPR_H */
a19a21
-- 
a19a21
2.27.0
a19a21