From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33830) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YRBLR-0000Ng-Vv for qemu-devel@nongnu.org; Thu, 26 Feb 2015 22:12:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YRBLC-0003HO-LO for qemu-devel@nongnu.org; Thu, 26 Feb 2015 22:12:05 -0500 Received: from e39.co.us.ibm.com ([32.97.110.160]:40057) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YRBLC-0003H5-C7 for qemu-devel@nongnu.org; Thu, 26 Feb 2015 22:11:50 -0500 Received: from /spool/local by e39.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 26 Feb 2015 20:11:49 -0700 From: Michael Roth Date: Thu, 26 Feb 2015 21:11:10 -0600 Message-Id: <1425006675-19976-11-git-send-email-mdroth@linux.vnet.ibm.com> In-Reply-To: <1425006675-19976-1-git-send-email-mdroth@linux.vnet.ibm.com> References: <1425006675-19976-1-git-send-email-mdroth@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH v6 10/15] spapr_drc: add spapr_drc_populate_dt() List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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, david@gibson.dropbear.id.au 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: Nathan Fontenot Signed-off-by: Michael Roth --- hw/ppc/spapr_drc.c | 165 +++++++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/spapr_drc.h | 2 + 2 files changed, 167 insertions(+) diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index bf22e1d..2a3195c 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -583,3 +583,168 @@ sPAPRDRConnector *spapr_dr_connector_by_id(sPAPRDRConnectorType type, (get_type_shift(type) << DRC_INDEX_TYPE_SHIFT) | (id & DRC_INDEX_ID_MASK)); } + +/* 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 char *spapr_drc_get_type_str(sPAPRDRConnectorType type) +{ + char *type_str = NULL; + + switch (type) { + case SPAPR_DR_CONNECTOR_TYPE_CPU: + type_str = g_strdup_printf("CPU"); + break; + case SPAPR_DR_CONNECTOR_TYPE_PHB: + type_str = g_strdup_printf("PHB"); + break; + case SPAPR_DR_CONNECTOR_TYPE_VIO: + type_str = g_strdup_printf("SLOT"); + break; + case SPAPR_DR_CONNECTOR_TYPE_PCI: + type_str = g_strdup_printf("28"); + break; + case SPAPR_DR_CONNECTOR_TYPE_LMB: + type_str = g_strdup_printf("MEM"); + break; + default: + g_assert(false); + } + + return type_str; +} + +/** + * spapr_drc_populate_dt + * + * @fdt: libfdt device tree + * @path: path in the DT to generate properties + * @owner: parent Object/DeviceState for which to generate DRC + * descriptions for + * @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, Object *owner, + uint32_t drc_type_mask) +{ + Object *root_container; + ObjectProperty *prop; + uint32_t drc_count = 0; + GArray *drc_indexes, *drc_power_domains; + GString *drc_names, *drc_types; + int ret; + + /* the first entry of each properties is a 32-bit integer encoding + * the number of elements in the array. we won't know this until + * we complete the iteration through all the matching DRCs, but + * reserve the space now and set the offsets accordingly so we + * can fill them in later. + */ + drc_indexes = g_array_new(false, true, sizeof(uint32_t)); + drc_indexes = g_array_set_size(drc_indexes, 1); + drc_power_domains = g_array_new(false, true, sizeof(uint32_t)); + drc_power_domains = g_array_set_size(drc_power_domains, 1); + drc_names = g_string_set_size(g_string_new(NULL), sizeof(uint32_t)); + drc_types = g_string_set_size(g_string_new(NULL), sizeof(uint32_t)); + + /* aliases for all DRConnector objects will be rooted in QOM + * composition tree at DRC_CONTAINER_PATH + */ + root_container = container_get(object_get_root(), DRC_CONTAINER_PATH); + + QTAILQ_FOREACH(prop, &root_container->properties, node) { + Object *obj; + sPAPRDRConnector *drc; + sPAPRDRConnectorClass *drck; + char *drc_type; + uint32_t drc_index, drc_power_domain; + + 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 (owner && (drc->owner != owner)) { + continue; + } + + if ((drc->type & drc_type_mask) == 0) { + continue; + } + + drc_count++; + + /* ibm,drc-indexes */ + drc_index = cpu_to_be32(drck->get_index(drc)); + g_array_append_val(drc_indexes, drc_index); + + /* ibm,drc-power-domains */ + drc_power_domain = cpu_to_be32(-1); + g_array_append_val(drc_power_domains, drc_power_domain); + + /* ibm,drc-names */ + drc_names = g_string_append(drc_names, drck->get_name(drc)); + drc_names = g_string_insert_len(drc_names, -1, "\0", 1); + + /* ibm,drc-types */ + drc_type = spapr_drc_get_type_str(drc->type); + drc_types = g_string_append(drc_types, drc_type); + drc_types = g_string_insert_len(drc_types, -1, "\0", 1); + g_free(drc_type); + } + + /* now write the drc count into the space we reserved at the + * beginning of the arrays previously + */ + *(uint32_t *)drc_indexes->data = cpu_to_be32(drc_count); + *(uint32_t *)drc_power_domains->data = cpu_to_be32(drc_count); + *(uint32_t *)drc_names->str = cpu_to_be32(drc_count); + *(uint32_t *)drc_types->str = cpu_to_be32(drc_count); + + ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-indexes", + drc_indexes->data, + drc_indexes->len * sizeof(uint32_t)); + if (ret) { + fprintf(stderr, "Couldn't create ibm,drc-indexes property\n"); + goto out; + } + + ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-power-domains", + drc_power_domains->data, + drc_power_domains->len * sizeof(uint32_t)); + if (ret) { + fprintf(stderr, "Couldn't finalize ibm,drc-power-domains property\n"); + goto out; + } + + ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-names", + drc_names->str, drc_names->len); + if (ret) { + fprintf(stderr, "Couldn't finalize ibm,drc-names property\n"); + goto out; + } + + ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-types", + drc_types->str, drc_types->len); + if (ret) { + fprintf(stderr, "Couldn't finalize ibm,drc-types property\n"); + goto out; + } + +out: + g_array_free(drc_indexes, true); + g_array_free(drc_power_domains, true); + g_string_free(drc_names, true); + g_string_free(drc_types, true); + + return ret; +} diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h index ece8e09..5895534 100644 --- a/include/hw/ppc/spapr_drc.h +++ b/include/hw/ppc/spapr_drc.h @@ -201,5 +201,7 @@ sPAPRDRConnector *spapr_dr_connector_new(Object *owner, 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, Object *owner, + uint32_t drc_type_mask); #endif /* __HW_SPAPR_DRC_H__ */ -- 1.9.1