qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: aik@ozlabs.ru, agraf@suse.de, ncmike@ncultra.org,
	qemu-ppc@nongnu.org, tyreld@linux.vnet.ibm.com,
	bharata.rao@gmail.com, nfont@linux.vnet.ibm.com
Subject: [Qemu-devel] [PATCH v4 10/17] spapr_drc: add spapr_drc_populate_dt()
Date: Tue, 23 Dec 2014 06:30:24 -0600	[thread overview]
Message-ID: <1419337831-16552-11-git-send-email-mdroth@linux.vnet.ibm.com> (raw)
In-Reply-To: <1419337831-16552-1-git-send-email-mdroth@linux.vnet.ibm.com>

This function handles generation of ibm,drc-* array device tree
properties to describe DRC topology to guests. This will by used
by the guest to direct RTAS calls to manage any dynamic resources
we associate with a particular DR Connector as part of
hotplug/unplug.

Since general management of boot-time device trees are handled
outside of sPAPRDRConnector, we insert these values blindly given
an FDT and offset. A mask of sPAPRDRConnector types is given to
instruct us on what types of connectors entries should be generated
for, since descriptions for different connectors may live in
different parts of the device tree.

Based on code originally written by Nathan Fontenot.

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 hw/ppc/spapr_drc.c         | 225 +++++++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/spapr_drc.h |   3 +-
 2 files changed, 227 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index f81c6d1..b162184 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -501,3 +501,228 @@ sPAPRDRConnector *spapr_dr_connector_by_id(sPAPRDRConnectorType type,
             (get_type_shift(type) << DRC_INDEX_TYPE_SHIFT) |
             (id & DRC_INDEX_ID_MASK));
 }
+
+/* internal helper to gather up DRC info specific to populating DRC
+ * topology information in the device tree.
+ */
+typedef struct DRConnectorDTInfo {
+    char drc_type[64];
+    char drc_name[64];
+    uint32_t drc_index;
+    uint32_t drc_power_domain;
+} DRConnectorDTInfo;
+
+/* generate a string the describes the DRC to encode into the
+ * device tree.
+ *
+ * as documented by PAPR+ v2.7, 13.5.2.6 and C.6.1
+ */
+static void spapr_drc_get_type_str(char *buf, sPAPRDRConnectorType type)
+{
+    switch (type) {
+    case SPAPR_DR_CONNECTOR_TYPE_CPU:
+        sprintf(buf, "CPU");
+        break;
+    case SPAPR_DR_CONNECTOR_TYPE_PHB:
+        sprintf(buf, "PHB");
+        break;
+    case SPAPR_DR_CONNECTOR_TYPE_VIO:
+        sprintf(buf, "SLOT");
+        break;
+    case SPAPR_DR_CONNECTOR_TYPE_PCI:
+        sprintf(buf, "28");
+        break;
+    case SPAPR_DR_CONNECTOR_TYPE_LMB:
+        sprintf(buf, "MEM");
+        break;
+    default:
+        g_assert(false);
+    }
+}
+
+/* generate a human-readable name for a DRC to encode into the DT
+ * description. this is mainly only used within a guest in place
+ * of the unique DRC index.
+ *
+ * in the case of VIO/PCI devices, it corresponds to a
+ * "location code" that maps a logical device/function (DRC index)
+ * to a physical (or virtual in the case of VIO) location in the
+ * system by chaining together the "location label" for each
+ * encapsulating component.
+ *
+ * since this is more to do with diagnosing physical hardware
+ * issues than guest compatibility, we choose location codes/DRC
+ * names that adhere to the documented format, but avoid encoding
+ * the entire topology information into the label/code, instead
+ * just using the location codes based on the labels for the
+ * endpoints (VIO/PCI adaptor connectors), which is basically
+ * just "C" followed by an integer ID.
+ *
+ * DRC names as documented by PAPR+ v2.7, 13.5.2.4
+ * location codes as documented by PAPR+ v2.7, 12.3.1.5
+ */
+static void spapr_drc_get_name_str(char *buf,
+                                   sPAPRDRConnectorType type,
+                                   uint32_t drc_index)
+{
+    uint32_t id = drc_index & DRC_INDEX_ID_MASK;
+
+    switch (type) {
+    case SPAPR_DR_CONNECTOR_TYPE_CPU:
+        sprintf(buf, "CPU %d", id);
+        break;
+    case SPAPR_DR_CONNECTOR_TYPE_PHB:
+        sprintf(buf, "PHB %d", id);
+        break;
+    case SPAPR_DR_CONNECTOR_TYPE_VIO:
+    case SPAPR_DR_CONNECTOR_TYPE_PCI:
+        sprintf(buf, "C%d", id);
+        break;
+    case SPAPR_DR_CONNECTOR_TYPE_LMB:
+        sprintf(buf, "LMB %d", id);
+        break;
+    default:
+        g_assert(false);
+    }
+}
+
+static DRConnectorDTInfo *spapr_dr_connector_get_info(uint32_t drc_type_mask,
+                                                      unsigned int *count)
+{
+    Object *root_container;
+    ObjectProperty *prop;
+    GArray *drc_info_list = g_array_new(false, true,
+                                        sizeof(DRConnectorDTInfo));
+
+    /* aliases for all DRConnector objects will be rooted in QOM
+     * composition tree at /dr-connector
+     */
+    root_container = container_get(object_get_root(), "/dr-connector");
+
+    QTAILQ_FOREACH(prop, &root_container->properties, node) {
+        Object *obj;
+        sPAPRDRConnector *drc;
+        sPAPRDRConnectorClass *drck;
+        DRConnectorDTInfo drc_info;
+
+        if (!strstart(prop->type, "link<", NULL)) {
+            continue;
+        }
+
+        obj = object_property_get_link(root_container, prop->name, NULL);
+        drc = SPAPR_DR_CONNECTOR(obj);
+        drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+
+        if ((drc->type & drc_type_mask) == 0) {
+            continue;
+        }
+
+        drc_info.drc_index = drck->get_index(drc);
+        drc_info.drc_power_domain = -1;
+        spapr_drc_get_type_str(drc_info.drc_type, drc->type);
+        spapr_drc_get_name_str(drc_info.drc_name, drc->type,
+                               drck->get_index(drc));
+        g_array_append_val(drc_info_list, drc_info);
+    }
+
+    if (count) {
+        *count = drc_info_list->len;
+    }
+
+    /* if count is zero, free everything, including internal storage
+     * for array
+     */
+    return (DRConnectorDTInfo *)g_array_free(drc_info_list, count == 0);
+}
+
+/**
+ * spapr_drc_populate_dt
+ *
+ * @fdt: libfdt device tree
+ * @path: path in the DT to generate properties
+ * @drc_type_mask: mask of sPAPRDRConnectorType values corresponding
+ *   to the types of DRCs to generate entries for
+ *
+ * generate OF properties to describe DRC topology/indices to guests
+ *
+ * as documented in PAPR+ v2.1, 13.5.2
+ */
+int spapr_drc_populate_dt(void *fdt, int fdt_offset, uint32_t drc_type_mask)
+{
+    DRConnectorDTInfo *drc_info_list;
+    unsigned int i, count;
+    char *char_buf;
+    uint32_t *char_buf_count;
+    uint32_t *int_buf;
+    int char_buf_offset, ret;
+
+    drc_info_list =
+        spapr_dr_connector_get_info(drc_type_mask, &count);
+
+    if (!count) {
+        return 0;
+    }
+
+    int_buf = g_new0(uint32_t, count + 1);
+    int_buf[0] = cpu_to_be32(count);
+    char_buf = g_new0(char, count * 128 + sizeof(uint32_t));
+    char_buf_count = (uint32_t *)&char_buf[0];
+    *char_buf_count = cpu_to_be32(count);
+
+    /* ibm,drc-indexes */
+    for (i = 0; i < count; i++) {
+        int_buf[i + 1] = cpu_to_be32(drc_info_list[i].drc_index);
+    }
+    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-indexes", int_buf,
+                      (count + 1) * sizeof(uint32_t));
+    if (ret) {
+        fprintf(stderr, "Couldn't create ibm,drc-indexes property\n");
+        goto out;
+    }
+
+    /* ibm,drc-power-domains */
+    for (i = 0; i < count; i++) {
+        int_buf[i + 1] = cpu_to_be32(drc_info_list[i].drc_power_domain);
+    }
+    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-power-domains", int_buf,
+                      (count + 1) * sizeof(uint32_t));
+    if (ret) {
+        fprintf(stderr, "Couldn't finalize ibm,drc-power-domains property\n");
+        goto out;
+    }
+
+    /* ibm,drc-names */
+    char_buf_offset = sizeof(uint32_t);
+
+    for (i = 0; i < count; i++) {
+        strcpy(char_buf + char_buf_offset, drc_info_list[i].drc_name);
+        char_buf_offset += strlen(drc_info_list[i].drc_name) + 1;
+    }
+    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-names", char_buf,
+                      char_buf_offset);
+    if (ret) {
+        fprintf(stderr, "Couldn't finalize ibm,drc-names property\n");
+        goto out;
+    }
+
+    /* ibm,drc-types */
+    char_buf_offset = sizeof(uint32_t);
+
+    for (i = 0; i < count; i++) {
+        strcpy(char_buf + char_buf_offset, drc_info_list[i].drc_type);
+        char_buf_offset += strlen(drc_info_list[i].drc_type) + 1;
+    }
+
+    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-types", char_buf,
+                      char_buf_offset);
+    if (ret) {
+        fprintf(stderr, "Couldn't finalize ibm,drc-types property\n");
+        goto out;
+    }
+
+out:
+    g_free(int_buf);
+    g_free(char_buf);
+    g_free(drc_info_list);
+    return ret;
+}
diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h
index 63ec687..5c70140 100644
--- a/include/hw/ppc/spapr_drc.h
+++ b/include/hw/ppc/spapr_drc.h
@@ -193,9 +193,10 @@ typedef struct sPAPRDRConnectorClass {
 
 sPAPRDRConnector *spapr_dr_connector_new(Object *owner,
                                          sPAPRDRConnectorType type,
-                                         uint32_t token);
+                                         uint32_t id);
 sPAPRDRConnector *spapr_dr_connector_by_index(uint32_t index);
 sPAPRDRConnector *spapr_dr_connector_by_id(sPAPRDRConnectorType type,
                                            uint32_t id);
+int spapr_drc_populate_dt(void *fdt, int fdt_offset, uint32_t drc_type_mask);
 
 #endif /* __HW_SPAPR_DRC_H__ */
-- 
1.9.1

  parent reply	other threads:[~2014-12-23 12:31 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-23 12:30 [Qemu-devel] [PATCH v4 00/17] spapr: add support for pci hotplug Michael Roth
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 01/17] docs: add sPAPR hotplug/dynamic-reconfiguration documentation Michael Roth
2015-01-16  5:28   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 02/17] spapr_drc: initial implementation of sPAPRDRConnector device Michael Roth
2015-01-02 10:32   ` Bharata B Rao
2015-01-26  4:56     ` Michael Roth
2015-01-16  6:19   ` David Gibson
2015-01-26  4:01     ` Michael Roth
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 03/17] spapr_rtas: add get/set-power-level RTAS interfaces Michael Roth
2015-01-16  6:21   ` David Gibson
2015-01-26  5:21     ` Michael Roth
2015-01-27  5:24       ` David Gibson
2015-01-27 21:36         ` Michael Roth
2015-01-27 22:05           ` Tyrel Datwyler
2015-01-28  0:42             ` Michael Roth
2015-02-09 16:29               ` Nathan Fontenot
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 04/17] spapr_rtas: add set-indicator RTAS interface Michael Roth
2015-01-16  6:25   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 05/17] spapr_rtas: add get-sensor-state " Michael Roth
2015-01-16  6:28   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 06/17] spapr: add rtas_st_buffer_direct() helper Michael Roth
2015-01-19  3:25   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 07/17] spapr_rtas: add ibm, configure-connector RTAS interface Michael Roth
2015-01-19  3:44   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 08/17] spapr_events: re-use EPOW event infrastructure for hotplug events Michael Roth
2015-01-19  4:31   ` David Gibson
2015-01-26 16:56     ` Michael Roth
2015-01-27  5:27       ` David Gibson
2015-01-28  3:56       ` Bharata B Rao
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 09/17] spapr_events: event-scan RTAS interface Michael Roth
2015-01-19  4:34   ` David Gibson
2014-12-23 12:30 ` Michael Roth [this message]
2015-01-19  5:15   ` [Qemu-devel] [PATCH v4 10/17] spapr_drc: add spapr_drc_populate_dt() David Gibson
2015-01-26 20:35     ` Michael Roth
2015-01-27  5:30       ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 11/17] spapr: introduce pseries-2.3 machine type Michael Roth
2015-01-19  5:16   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 12/17] spapr_pci: add dynamic-reconfiguration option for spapr-pci-host-bridge Michael Roth
2015-01-19  5:18   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 13/17] spapr_pci: create DRConnectors for each PCI slot during PHB realize Michael Roth
2015-01-19  5:20   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 14/17] spapr_pci: populate DRC dt entries for PHBs Michael Roth
2015-01-19  5:22   ` David Gibson
2015-01-26 20:44     ` Michael Roth
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 15/17] pci: make pci_bar useable outside pci.c Michael Roth
2015-01-19  5:24   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 16/17] spapr_pci: enable basic hotplug operations Michael Roth
2015-01-19  5:58   ` David Gibson
2015-01-26 21:17     ` Michael Roth
2015-01-27  5:37       ` David Gibson
2015-01-23  5:17   ` Alexey Kardashevskiy
2015-01-26 21:20     ` Michael Roth
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 17/17] spapr_pci: emit hotplug add/remove events during hotplug Michael Roth
2015-01-19  6:00   ` David Gibson
2015-01-26 21:32     ` Michael Roth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1419337831-16552-11-git-send-email-mdroth@linux.vnet.ibm.com \
    --to=mdroth@linux.vnet.ibm.com \
    --cc=agraf@suse.de \
    --cc=aik@ozlabs.ru \
    --cc=bharata.rao@gmail.com \
    --cc=ncmike@ncultra.org \
    --cc=nfont@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=tyreld@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).