qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH] spapr: generate DT node names


From: Laurent Vivier
Subject: [Qemu-devel] [PATCH] spapr: generate DT node names
Date: Sat, 19 Sep 2015 00:06:45 +0200

When DT node names for PCI devices are generated by SLOF,
they are generated according to the type of the device
(for instance, ethernet for virtio-net-pci device).

Node name for hotplugged devices is generated by QEMU.
This patch adds the mechanic to QEMU to create the node
name according to the device type too.

The data structure has been roughly copied from OpenBIOS/OpenHackware,
node names from SLOF.

Example:

Hotplugging some PCI cards with QEMU monitor:

device_add virtio-tablet-pci
device_add virtio-serial-pci
device_add virtio-mouse-pci
device_add virtio-scsi-pci
device_add virtio-gpu-pci
device_add ne2k_pci
device_add nec-usb-xhci
device_add intel-hda

What we can see in linux device tree:

    echo $dir
    cat $dir/name
    echo
done

WITHOUT this patch:

/proc/device-tree/address@hidden/address@hidden/
pci
/proc/device-tree/address@hidden/address@hidden/
pci
/proc/device-tree/address@hidden/address@hidden/
pci
/proc/device-tree/address@hidden/address@hidden/
pci
/proc/device-tree/address@hidden/address@hidden/
pci
/proc/device-tree/address@hidden/address@hidden/
pci
/proc/device-tree/address@hidden/address@hidden/
pci
/proc/device-tree/address@hidden/address@hidden/

WITH this patch:

/proc/device-tree/address@hidden/address@hidden/
ethernet
/proc/device-tree/address@hidden/address@hidden/
misc-communication-controller
/proc/device-tree/address@hidden/address@hidden/
misc-display-controller
/proc/device-tree/address@hidden/address@hidden/
misc-input-device
/proc/device-tree/address@hidden/address@hidden/
mouse
/proc/device-tree/address@hidden/address@hidden/
multimedia-device
/proc/device-tree/address@hidden/address@hidden/
scsi
/proc/device-tree/address@hidden/address@hidden/
usb-xhci

Signed-off-by: Laurent Vivier <address@hidden>
---
 hw/ppc/spapr_pci.c | 502 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 488 insertions(+), 14 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index a2feb4c..ca3a0ba 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -944,6 +944,487 @@ static void populate_resource_props(PCIDevice *d, 
ResourceProps *rp)
     rp->assigned_len = assigned_idx * sizeof(ResourceFields);
 }
 
+/* Device classes and subclasses */
+
+#define PCI_BASE_CLASS_STORAGE           0x01
+#define PCI_SUBCLASS_STORAGE_SCSI        0x00
+#define PCI_SUBCLASS_STORAGE_IDE         0x01
+#define PCI_SUBCLASS_STORAGE_FLOPPY      0x02
+#define PCI_SUBCLASS_STORAGE_IPI         0x03
+#define PCI_SUBCLASS_STORAGE_RAID        0x04
+#define PCI_SUBCLASS_STORAGE_ATA         0x05
+#define PCI_SUBCLASS_STORAGE_SATA        0x06
+#define PCI_SUBCLASS_STORAGE_SAS         0x07
+#define PCI_SUBCLASS_STORAGE_OTHER       0x80
+
+#define PCI_BASE_CLASS_NETWORK           0x02
+#define PCI_SUBCLASS_NETWORK_ETHERNET    0x00
+#define PCI_SUBCLASS_NETWORK_TOKEN_RING  0x01
+#define PCI_SUBCLASS_NETWORK_FDDI        0x02
+#define PCI_SUBCLASS_NETWORK_ATM         0x03
+#define PCI_SUBCLASS_NETWORK_ISDN        0x04
+#define PCI_SUBCLASS_NETWORK_WORDFIP     0x05
+#define PCI_SUBCLASS_NETWORK_PICMG214    0x06
+#define PCI_SUBCLASS_NETWORK_OTHER       0x80
+
+#define PCI_BASE_CLASS_DISPLAY           0x03
+#define PCI_SUBCLASS_DISPLAY_VGA         0x00
+#define PCI_SUBCLASS_DISPLAY_XGA         0x01
+#define PCI_SUBCLASS_DISPLAY_3D          0x02
+#define PCI_SUBCLASS_DISPLAY_OTHER       0x80
+
+#define PCI_BASE_CLASS_MULTIMEDIA        0x04
+#define PCI_SUBCLASS_MULTIMEDIA_VIDEO    0x00
+#define PCI_SUBCLASS_MULTIMEDIA_AUDIO    0x01
+#define PCI_SUBCLASS_MULTIMEDIA_PHONE    0x02
+#define PCI_SUBCLASS_MULTIMEDIA_OTHER    0x80
+
+#define PCI_BASE_CLASS_MEMORY            0x05
+#define PCI_SUBCLASS_MEMORY_RAM          0x00
+#define PCI_SUBCLASS_MEMORY_FLASH        0x01
+
+#define PCI_BASE_CLASS_BRIDGE            0x06
+#define PCI_SUBCLASS_BRIDGE_HOST         0x00
+#define PCI_SUBCLASS_BRIDGE_ISA          0x01
+#define PCI_SUBCLASS_BRIDGE_EISA         0x02
+#define PCI_SUBCLASS_BRIDGE_MC           0x03
+#define PCI_SUBCLASS_BRIDGE_PCI          0x04
+#define PCI_SUBCLASS_BRIDGE_PCMCIA       0x05
+#define PCI_SUBCLASS_BRIDGE_NUBUS        0x06
+#define PCI_SUBCLASS_BRIDGE_CARDBUS      0x07
+#define PCI_SUBCLASS_BRIDGE_RACEWAY      0x08
+#define PCI_SUBCLASS_BRIDGE_PCI_SEMITP   0x09
+#define PCI_SUBCLASS_BRIDGE_IB_PCI       0x0a
+#define PCI_SUBCLASS_BRIDGE_OTHER        0x80
+
+#define PCI_BASE_CLASS_COMMUNICATION     0x07
+#define PCI_SUBCLASS_COMMUNICATION_SERIAL 0x00
+#define PCI_SUBCLASS_COMMUNICATION_PARALLEL 0x01
+#define PCI_SUBCLASS_COMMUNICATION_MULTISERIAL 0x02
+#define PCI_SUBCLASS_COMMUNICATION_MODEM 0x03
+#define PCI_SUBCLASS_COMMUNICATION_GPIB  0x04
+#define PCI_SUBCLASS_COMMUNICATION_SC    0x05
+#define PCI_SUBCLASS_COMMUNICATION_OTHER 0x80
+
+#define PCI_BASE_CLASS_SYSTEM            0x08
+#define PCI_SUBCLASS_SYSTEM_PIC          0x00
+#define PCI_SUBCLASS_SYSTEM_DMA          0x01
+#define PCI_SUBCLASS_SYSTEM_TIMER        0x02
+#define PCI_SUBCLASS_SYSTEM_RTC          0x03
+#define PCI_SUBCLASS_SYSTEM_HOTPLUG      0x04
+#define PCI_SUBCLASS_SYSTEM_SD           0x05
+#define PCI_SUBCLASS_SYSTEM_OTHER        0x80
+
+#define PCI_BASE_CLASS_INPUT             0x09
+#define PCI_SUBCLASS_INPUT_KEYBOARD      0x00
+#define PCI_SUBCLASS_INPUT_PEN           0x01
+#define PCI_SUBCLASS_INPUT_MOUSE         0x02
+#define PCI_SUBCLASS_INPUT_SCANNER       0x03
+#define PCI_SUBCLASS_INPUT_GAMEPORT      0x04
+#define PCI_SUBCLASS_INPUT_OTHER         0x80
+
+#define PCI_BASE_CLASS_DOCKING           0x0a
+#define PCI_SUBCLASS_DOCKING_GENERIC     0x00
+#define PCI_SUBCLASS_DOCKING_OTHER       0x80
+
+#define PCI_BASE_CLASS_PROCESSOR         0x0b
+#define PCI_SUBCLASS_PROCESSOR_386       0x00
+#define PCI_SUBCLASS_PROCESSOR_486       0x01
+#define PCI_SUBCLASS_PROCESSOR_PENTIUM   0x02
+#define PCI_SUBCLASS_PROCESSOR_ALPHA     0x10
+#define PCI_SUBCLASS_PROCESSOR_POWERPC   0x20
+#define PCI_SUBCLASS_PROCESSOR_MIPS      0x30
+#define PCI_SUBCLASS_PROCESSOR_CO        0x40
+
+#define PCI_BASE_CLASS_SERIAL            0x0c
+#define PCI_SUBCLASS_SERIAL_FIREWIRE     0x00
+#define PCI_SUBCLASS_SERIAL_ACCESS       0x01
+#define PCI_SUBCLASS_SERIAL_SSA          0x02
+#define PCI_SUBCLASS_SERIAL_USB          0x03
+#define PCI_SUBCLASS_SERIAL_FIBER        0x04
+#define PCI_SUBCLASS_SERIAL_SMBUS        0x05
+#define PCI_SUBCLASS_SERIAL_IB           0x06
+#define PCI_SUBCLASS_SERIAL_IPMI         0x07
+#define PCI_SUBCLASS_SERIAL_SERCOS       0x08
+#define PCI_SUBCLASS_SERIAL_CANBUS       0x09
+
+#define PCI_BASE_CLASS_WIRELESS          0x0d
+#define PCI_SUBCLASS_WIRELESS_IRDA       0x00
+#define PCI_SUBCLASS_WIRELESS_CIR        0x01
+#define PCI_SUBCLASS_WIRELESS_RF_CONTROLLER 0x10
+#define PCI_SUBCLASS_WIRELESS_BLUETOOTH  0x11
+#define PCI_SUBCLASS_WIRELESS_BROADBAND  0x12
+#define PCI_SUBCLASS_WIRELESS_OTHER      0x80
+
+#define PCI_BASE_CLASS_SATELLITE         0x0f
+#define PCI_SUBCLASS_SATELLITE_TV        0x00
+#define PCI_SUBCLASS_SATELLITE_AUDIO     0x01
+#define PCI_SUBCLASS_SATELLITE_VOICE     0x03
+#define PCI_SUBCLASS_SATELLITE_DATA      0x04
+
+#define PCI_BASE_CLASS_CRYPT             0x10
+#define PCI_SUBCLASS_CRYPT_NETWORK       0x00
+#define PCI_SUBCLASS_CRYPT_ENTERTAINMENT 0x01
+#define PCI_SUBCLASS_CRYPT_OTHER         0x80
+
+#define PCI_BASE_CLASS_SIGNAL_PROCESSING 0x11
+#define PCI_SUBCLASS_SP_DPIO             0x00
+#define PCI_SUBCLASS_SP_PERF             0x01
+#define PCI_SUBCLASS_SP_SYNCH            0x10
+#define PCI_SUBCLASS_SP_MANAGEMENT       0x20
+#define PCI_SUBCLASS_SP_OTHER            0x80
+
+#define PCI_CLASS_OTHERS                 0xff
+
+typedef struct pci_class_t pci_class_t;
+typedef struct pci_subclass_t pci_subclass_t;
+typedef struct pci_iface_t pci_iface_t;
+
+struct pci_iface_t {
+    uint8_t iface;
+    const char *name;
+};
+
+struct pci_subclass_t {
+    uint8_t subclass;
+    const char *name;
+    const pci_iface_t *iface;
+};
+
+struct pci_class_t {
+    const char *name;
+    const pci_subclass_t *subc;
+};
+
+static const pci_subclass_t undef_subclass[] = {
+    { 0x01, "display", NULL },
+    { 0xFF, NULL, NULL, NULL },
+};
+
+static const pci_subclass_t mass_subclass[] = {
+    { PCI_SUBCLASS_STORAGE_SCSI, "scsi", NULL },
+    { PCI_SUBCLASS_STORAGE_IDE, "ide", NULL },
+    { PCI_SUBCLASS_STORAGE_FLOPPY, "fdc", NULL },
+    { PCI_SUBCLASS_STORAGE_IPI, "ipi", NULL },
+    { PCI_SUBCLASS_STORAGE_RAID, "raid", NULL },
+    { PCI_SUBCLASS_STORAGE_ATA, "ata", NULL },
+    { PCI_SUBCLASS_STORAGE_SATA, "sata", NULL },
+    { PCI_SUBCLASS_STORAGE_SAS, "sas", NULL },
+    { PCI_SUBCLASS_STORAGE_OTHER, "mass-storage", NULL },
+    { 0xFF, NULL, NULL },
+};
+
+static const pci_subclass_t net_subclass[] = {
+    { PCI_SUBCLASS_NETWORK_ETHERNET, "ethernet", NULL },
+    { PCI_SUBCLASS_NETWORK_TOKEN_RING, "token-ring", NULL },
+    { PCI_SUBCLASS_NETWORK_FDDI, "fddi", NULL },
+    { PCI_SUBCLASS_NETWORK_ATM, "atm", NULL },
+    { PCI_SUBCLASS_NETWORK_ISDN, "isdn", NULL },
+    { PCI_SUBCLASS_NETWORK_WORDFIP, "worldfip", NULL },
+    { PCI_SUBCLASS_NETWORK_PICMG214, "picmg", NULL },
+    { PCI_SUBCLASS_NETWORK_OTHER, "network", NULL },
+    { 0xFF, NULL, NULL },
+};
+
+static const struct pci_iface_t vga_iface[] = {
+    { 0x00, "VGA", },
+    { 0x01, "8514-compatible", },
+    { 0xFF, NULL, },
+};
+
+static const pci_subclass_t displ_subclass[] = {
+    { PCI_SUBCLASS_DISPLAY_VGA, "vga", vga_iface },
+    { PCI_SUBCLASS_DISPLAY_XGA, "xga", NULL },
+    { PCI_SUBCLASS_DISPLAY_3D, "3d-controller", NULL },
+    { PCI_SUBCLASS_DISPLAY_OTHER, "misc-display-controller", NULL },
+    { 0xFF, NULL, NULL },
+};
+
+static const pci_subclass_t media_subclass[] = {
+    { PCI_SUBCLASS_MULTIMEDIA_VIDEO, "video", NULL },
+    { PCI_SUBCLASS_MULTIMEDIA_AUDIO, "sound", NULL },
+    { PCI_SUBCLASS_MULTIMEDIA_PHONE, "telephony", NULL },
+    { PCI_SUBCLASS_MULTIMEDIA_OTHER, "misc-multimedia-device", NULL },
+    { 0xFF, NULL, NULL },
+};
+
+static const pci_subclass_t mem_subclass[] = {
+    { PCI_SUBCLASS_MEMORY_RAM, "memory", NULL },
+    { PCI_SUBCLASS_MEMORY_FLASH, "flash", NULL },
+    { 0xFF, NULL, NULL },
+};
+
+
+static const pci_subclass_t bridg_subclass[] = {
+    { PCI_SUBCLASS_BRIDGE_HOST, "host", NULL },
+    { PCI_SUBCLASS_BRIDGE_ISA, "isa", NULL },
+    { PCI_SUBCLASS_BRIDGE_EISA, "eisa", NULL },
+    { PCI_SUBCLASS_BRIDGE_MC, "mca", NULL },
+    { PCI_SUBCLASS_BRIDGE_PCI, "pci", NULL },
+    { PCI_SUBCLASS_BRIDGE_PCMCIA, "pcmcia", NULL },
+    { PCI_SUBCLASS_BRIDGE_NUBUS, "nubus", NULL },
+    { PCI_SUBCLASS_BRIDGE_CARDBUS, "cardbus", NULL },
+    { PCI_SUBCLASS_BRIDGE_RACEWAY, "raceway", NULL },
+    { PCI_SUBCLASS_BRIDGE_PCI_SEMITP, "semi-transparent-pci", NULL },
+    { PCI_SUBCLASS_BRIDGE_IB_PCI, "infiniband", NULL },
+    { PCI_SUBCLASS_BRIDGE_OTHER, "misc-brige", NULL },
+    { 0xFF, NULL, NULL },
+};
+
+static const pci_iface_t serial_iface[] = {
+    { 0x00, "serial" },
+    { 0x01, "16450-serial" },
+    { 0x02, "16550-serial" },
+    { 0x03, "16650-serial" },
+    { 0x04, "16750-serial" },
+    { 0x05, "16850-serial" },
+    { 0x06, "16950-serial" },
+    { 0xFF, NULL },
+};
+
+static const pci_iface_t par_iface[] = {
+    { 0x00, "parallel" },
+    { 0x01, "bi-directional-parallel" },
+    { 0x02, "ecp-1.x-parallel" },
+    { 0x03, "ieee1284-controller" },
+    { 0xFE, "ieee1284-device" },
+    { 0xFF, NULL },
+};
+
+static const pci_iface_t modem_iface[] = {
+    { 0x00, "modem" },
+    { 0x01, "16450-modem" },
+    { 0x02, "16550-modem" },
+    { 0x03, "16650-modem" },
+    { 0x04, "16750-modem" },
+    { 0xFF, NULL },
+};
+
+static const pci_subclass_t comm_subclass[] = {
+    { PCI_SUBCLASS_COMMUNICATION_SERIAL, "serial", serial_iface },
+    { PCI_SUBCLASS_COMMUNICATION_PARALLEL, "parallel", par_iface },
+    { PCI_SUBCLASS_COMMUNICATION_MULTISERIAL, "multiport-serial", NULL },
+    { PCI_SUBCLASS_COMMUNICATION_MODEM, "modem", modem_iface },
+    { PCI_SUBCLASS_COMMUNICATION_GPIB, "gpib", NULL },
+    { PCI_SUBCLASS_COMMUNICATION_SC, "smart-card", NULL },
+    { PCI_SUBCLASS_COMMUNICATION_OTHER, "misc-communication-controller",
+      NULL },
+    { 0xFF, NULL, NULL, NULL },
+};
+
+static const pci_iface_t pic_iface[] = {
+    { 0x00, "8259-pic" },
+    { 0x01, "isa-pic" },
+    { 0x02, "eisa-pic" },
+    { 0x10, "io-apic" },
+    { 0x20, "io-apic" },
+    { 0xFF, NULL },
+};
+
+static const pci_iface_t dma_iface[] = {
+    { 0x00, "dma-controller" },
+    { 0x01, "isa-dma" },
+    { 0x02, "eisa-dma" },
+    { 0xFF, NULL },
+};
+
+static const pci_iface_t tmr_iface[] = {
+    { 0x00, "8254-system-timer" },
+    { 0x01, "isa-system-timer", },
+    { 0x02, "eisa-system-timer" },
+    { 0xFF, NULL },
+};
+
+static const pci_iface_t rtc_iface[] = {
+    { 0x00, "rtc" },
+    { 0x01, "isa-rtc" },
+    { 0xFF, NULL },
+};
+
+static const pci_subclass_t sys_subclass[] = {
+    { PCI_SUBCLASS_SYSTEM_PIC, "interrupt-controller", pic_iface },
+    { PCI_SUBCLASS_SYSTEM_DMA, "dma-controller", dma_iface },
+    { PCI_SUBCLASS_SYSTEM_TIMER, "timer", tmr_iface },
+    { PCI_SUBCLASS_SYSTEM_RTC, "rtc", rtc_iface },
+    { PCI_SUBCLASS_SYSTEM_HOTPLUG, "hot-plug-controller", NULL },
+    { PCI_SUBCLASS_SYSTEM_SD, "sd-host-controller", NULL },
+    { PCI_SUBCLASS_SYSTEM_OTHER, "misc-system-peripheral", NULL },
+    { 0xFF, NULL, NULL },
+};
+
+static const pci_subclass_t inp_subclass[] = {
+    { PCI_SUBCLASS_INPUT_KEYBOARD, "keyboard", NULL },
+    { PCI_SUBCLASS_INPUT_PEN, "pen", NULL },
+    { PCI_SUBCLASS_INPUT_MOUSE, "mouse", NULL },
+    { PCI_SUBCLASS_INPUT_SCANNER, "scanner", NULL },
+    { PCI_SUBCLASS_INPUT_GAMEPORT, "gameport", NULL },
+    { PCI_SUBCLASS_INPUT_OTHER, "misc-input-device", NULL },
+    { 0xFF, NULL, NULL },
+};
+
+static const pci_subclass_t dock_subclass[] = {
+    { PCI_SUBCLASS_DOCKING_GENERIC, "dock", NULL },
+    { PCI_SUBCLASS_DOCKING_OTHER, "docking-station", NULL },
+    { 0xFF, NULL, NULL },
+};
+
+static const pci_subclass_t cpu_subclass[] = {
+    { PCI_SUBCLASS_PROCESSOR_386, "386", NULL },
+    { PCI_SUBCLASS_PROCESSOR_486, "486", NULL },
+    { PCI_SUBCLASS_PROCESSOR_PENTIUM, "pentium", NULL },
+    { PCI_SUBCLASS_PROCESSOR_ALPHA, "alpha", NULL },
+    { PCI_SUBCLASS_PROCESSOR_POWERPC, "powerpc", NULL },
+    { PCI_SUBCLASS_PROCESSOR_MIPS, "mips", NULL },
+    { PCI_SUBCLASS_PROCESSOR_CO, "co-processor", NULL },
+    { 0xFF, NULL, NULL },
+};
+
+static const pci_iface_t usb_iface[] = {
+    { 0x00, "usb-uhci" },
+    { 0x10, "usb-ohci", },
+    { 0x20, "usb-ehci" },
+    { 0x30, "usb-xhci" },
+    { 0x80, "misc-usb-controller" },
+    { 0xFE, "usb-device" },
+    { 0xFF, NULL },
+};
+
+static const pci_iface_t ipmi_iface[] = {
+    { 0x00, "ipmi-smic" },
+    { 0x01, "ipmi-kbrd" },
+    { 0x02, "IPMI-bltr" },
+    { 0xFF, NULL },
+};
+
+static const pci_subclass_t ser_subclass[] = {
+    { PCI_SUBCLASS_SERIAL_FIREWIRE, "firewire", NULL },
+    { PCI_SUBCLASS_SERIAL_ACCESS, "access-bus", NULL },
+    { PCI_SUBCLASS_SERIAL_SSA, "ssa", NULL },
+    { PCI_SUBCLASS_SERIAL_USB, "usb", usb_iface },
+    { PCI_SUBCLASS_SERIAL_FIBER, "fibre-channel", NULL },
+    { PCI_SUBCLASS_SERIAL_SMBUS, "smb", NULL },
+    { PCI_SUBCLASS_SERIAL_IB, "infiniband", NULL },
+    { PCI_SUBCLASS_SERIAL_IPMI, "ipmi", ipmi_iface },
+    { PCI_SUBCLASS_SERIAL_SERCOS, "sercos", NULL },
+    { PCI_SUBCLASS_SERIAL_CANBUS, "canbus", NULL },
+    { 0xFF, NULL, NULL },
+};
+
+static const pci_subclass_t wrl_subclass[] = {
+    { PCI_SUBCLASS_WIRELESS_IRDA, "irda", NULL },
+    { PCI_SUBCLASS_WIRELESS_CIR, "consumer-ir", NULL },
+    { PCI_SUBCLASS_WIRELESS_RF_CONTROLLER, "rf-controller", NULL },
+    { PCI_SUBCLASS_WIRELESS_BLUETOOTH, "bluetooth", NULL },
+    { PCI_SUBCLASS_WIRELESS_BROADBAND, "broadband", NULL },
+    { PCI_SUBCLASS_WIRELESS_OTHER, "misc-wireless-controller", NULL },
+    { 0xFF, NULL, NULL },
+};
+
+static const pci_subclass_t sat_subclass[] = {
+    { PCI_SUBCLASS_SATELLITE_TV, "satellite-tv", NULL },
+    { PCI_SUBCLASS_SATELLITE_AUDIO, "satellite-audio", NULL },
+    { PCI_SUBCLASS_SATELLITE_VOICE, "satellite-voice", NULL },
+    { PCI_SUBCLASS_SATELLITE_DATA, "satellite-data", NULL },
+    { 0xFF, NULL, NULL },
+};
+
+static const pci_subclass_t crypt_subclass[] = {
+    { PCI_SUBCLASS_CRYPT_NETWORK, "network-encryption", NULL },
+    { PCI_SUBCLASS_CRYPT_ENTERTAINMENT, "entertainment-encryption", NULL },
+    { PCI_SUBCLASS_CRYPT_OTHER, "misc-encryption", NULL },
+    { 0xFF, NULL, NULL },
+};
+
+static const pci_subclass_t spc_subclass[] = {
+    { PCI_SUBCLASS_SP_DPIO, "dpio", NULL },
+    { PCI_SUBCLASS_SP_PERF, "counter", NULL },
+    { PCI_SUBCLASS_SP_SYNCH, "measurement", NULL },
+    { PCI_SUBCLASS_SP_MANAGEMENT, "management-card", NULL },
+    { PCI_SUBCLASS_SP_OTHER, "misc-signal-processing-controller", NULL },
+    { 0xFF, NULL, NULL },
+};
+
+static const pci_class_t pci_classes[] = {
+    { "unknown-legacy-device", undef_subclass },
+    { "mass-storage",  mass_subclass },
+    { "network", net_subclass },
+    { "display", displ_subclass, },
+    { "multimedia-device", media_subclass },
+    { "memory-controller", mem_subclass },
+    { "unknown-bridge", bridg_subclass },
+    { "communication-controller", comm_subclass},
+    { "system-peripheral", sys_subclass },
+    { "input-controller", inp_subclass },
+    { "docking-station", dock_subclass },
+    { "cpu", cpu_subclass },
+    { "serial-bus", ser_subclass },
+    { "wireless-controller", wrl_subclass },
+    { "intelligent-io", NULL },
+    { "satellite-device", sat_subclass },
+    { "encryption", crypt_subclass },
+    { "data-processing-controller", spc_subclass },
+};
+
+static const char *pci_find_device_name(uint8_t class, uint8_t subclass,
+                                        uint8_t iface)
+{
+    const pci_class_t *pclass;
+    const pci_subclass_t *psubclass;
+    const pci_iface_t *piface;
+    const char *name;
+
+    if (class > (sizeof(pci_classes) / sizeof(pci_class_t))) {
+        return "pci";
+    }
+
+    pclass = pci_classes + class;
+    name = pclass->name;
+
+    if (pclass->subc == NULL) {
+        return name;
+    }
+
+    psubclass = pclass->subc;
+    while (psubclass->subclass != 0xff) {
+        if (psubclass->subclass == subclass) {
+            name = psubclass->name;
+            break;
+        }
+        psubclass++;
+    }
+
+    piface = psubclass->iface;
+    if (piface == NULL) {
+        return name;
+    }
+    while (piface->iface != 0xff) {
+        if (piface->iface == iface) {
+            name = piface->name;
+            break;
+        }
+        piface++;
+    }
+
+    return name;
+}
+
+static void pci_get_node_name(char *nodename, int len, PCIDevice *dev)
+{
+    int slot = PCI_SLOT(dev->devfn);
+    int func = PCI_FUNC(dev->devfn);
+    uint32_t ccode = pci_default_read_config(dev, PCI_CLASS_PROG, 3);
+    const char *name;
+
+    name = pci_find_device_name((ccode >> 16) & 0xff, (ccode >> 8) & 0xff,
+                                ccode & 0xff);
+
+    if (func != 0) {
+        snprintf(nodename, len, "address@hidden,%x", name, slot, func);
+    } else {
+        snprintf(nodename, len, "address@hidden", name, slot);
+    }
+}
+
 static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb,
                                             PCIDevice *pdev);
 
@@ -955,6 +1436,7 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, 
void *fdt, int offset,
     int pci_status, err;
     char *buf = NULL;
     uint32_t drc_index = spapr_phb_get_pci_drc_index(sphb, dev);
+    uint32_t ccode = pci_default_read_config(dev, PCI_CLASS_PROG, 3);
 
     if (pci_default_read_config(dev, PCI_HEADER_TYPE, 1) ==
         PCI_HEADER_TYPE_BRIDGE) {
@@ -968,8 +1450,7 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, 
void *fdt, int offset,
                           pci_default_read_config(dev, PCI_DEVICE_ID, 2)));
     _FDT(fdt_setprop_cell(fdt, offset, "revision-id",
                           pci_default_read_config(dev, PCI_REVISION_ID, 1)));
-    _FDT(fdt_setprop_cell(fdt, offset, "class-code",
-                          pci_default_read_config(dev, PCI_CLASS_PROG, 3)));
+    _FDT(fdt_setprop_cell(fdt, offset, "class-code", ccode));
     if (pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1)) {
         _FDT(fdt_setprop_cell(fdt, offset, "interrupts",
                  pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1)));
@@ -1010,11 +1491,10 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, 
void *fdt, int offset,
         _FDT(fdt_setprop(fdt, offset, "udf-supported", NULL, 0));
     }
 
-    /* NOTE: this is normally generated by firmware via path/unit name,
-     * but in our case we must set it manually since it does not get
-     * processed by OF beforehand
-     */
-    _FDT(fdt_setprop_string(fdt, offset, "name", "pci"));
+    _FDT(fdt_setprop_string(fdt, offset, "name",
+                            pci_find_device_name((ccode >> 16) & 0xff,
+                                                 (ccode >> 8) & 0xff,
+                                                 ccode & 0xff)));
     buf = spapr_phb_get_loc_code(sphb, dev);
     if (!buf) {
         error_report("Failed setting the ibm,loc-code");
@@ -1051,15 +1531,9 @@ static int spapr_create_pci_child_dt(sPAPRPHBState *phb, 
PCIDevice *dev,
                                      void *fdt, int node_offset)
 {
     int offset, ret;
-    int slot = PCI_SLOT(dev->devfn);
-    int func = PCI_FUNC(dev->devfn);
     char nodename[FDT_NAME_MAX];
 
-    if (func != 0) {
-        snprintf(nodename, FDT_NAME_MAX, "address@hidden,%x", slot, func);
-    } else {
-        snprintf(nodename, FDT_NAME_MAX, "address@hidden", slot);
-    }
+    pci_get_node_name(nodename, FDT_NAME_MAX, dev);
     offset = fdt_add_subnode(fdt, node_offset, nodename);
     ret = spapr_populate_pci_child_dt(dev, fdt, offset, phb);
 
-- 
2.4.3




reply via email to

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