From patchwork Sun Jun 18 12:35:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: maddy X-Patchwork-Id: 777437 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wrDBd3Y1bz9s3T for ; Sun, 18 Jun 2017 22:36:57 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3wrDBd2ZRgzDqnG for ; Sun, 18 Jun 2017 22:36:57 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3wrDB05pY5zDqjN for ; Sun, 18 Jun 2017 22:36:24 +1000 (AEST) Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id v5ICYKeW112244 for ; Sun, 18 Jun 2017 08:36:22 -0400 Received: from e23smtp08.au.ibm.com (e23smtp08.au.ibm.com [202.81.31.141]) by mx0a-001b2d01.pphosted.com with ESMTP id 2b5mx0f2vn-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Sun, 18 Jun 2017 08:36:22 -0400 Received: from localhost by e23smtp08.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Sun, 18 Jun 2017 22:36:20 +1000 Received: from d23relay07.au.ibm.com (202.81.31.226) by e23smtp08.au.ibm.com (202.81.31.205) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Sun, 18 Jun 2017 22:36:18 +1000 Received: from d23av02.au.ibm.com (d23av02.au.ibm.com [9.190.235.138]) by d23relay07.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v5ICaHuj4194564 for ; Sun, 18 Jun 2017 22:36:17 +1000 Received: from d23av02.au.ibm.com (localhost [127.0.0.1]) by d23av02.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id v5ICa8qC020791 for ; Sun, 18 Jun 2017 22:36:09 +1000 Received: from localhost.localdomain (sriharisrinidhi.in.ibm.com [9.182.104.211]) by d23av02.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id v5ICZmNC020488; Sun, 18 Jun 2017 22:36:07 +1000 From: Madhavan Srinivasan To: stewart@linux.vnet.ibm.com Date: Sun, 18 Jun 2017 18:05:34 +0530 X-Mailer: git-send-email 2.7.4 In-Reply-To: <1497789339-28819-1-git-send-email-maddy@linux.vnet.ibm.com> References: <1497789339-28819-1-git-send-email-maddy@linux.vnet.ibm.com> X-TM-AS-MML: disable x-cbid: 17061812-0048-0000-0000-000002455173 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17061812-0049-0000-0000-000047F5B8EF Message-Id: <1497789339-28819-5-git-send-email-maddy@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-06-18_09:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=13 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1703280000 definitions=main-1706180225 Subject: [Skiboot] [PATCH v13 4/9] dt: Add phandle fixup helpers X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mikey@neuling.org, skiboot@lists.ozlabs.org MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" When there is a new device tree that needs to be added to the main dt of the opal (ex, IMC catalog dtb loaded from pnor partition), we need to check for the phandle values in the new incoming device tree before attaching it. Reason is that, incoming device tree could already have phandle values initialized for its nodes. Now, if we attach this new device tree to the main opal DT, we could potentially hit phandle duplicate error (since the phandles value usually start with 1). To avoid this, a new helper function dt_adjust_subtree_phandle() is added to scan the incoming device tree and update node "phandle" accordingly based on the opal "last_phandle" value. Add to this, helper function also supports updates of "properties" with in a node which may refer the "phandle" value in the incoming device tree. Helper function will also fix the "properties" field accordingly. Signed-off-by: Madhavan Srinivasan Acked-by: Michael Neuling --- core/device.c | 38 ++++++++++++++++++++++++++++++++++++++ core/test/run-device.c | 35 +++++++++++++++++++++++++++++++++-- include/device.h | 4 ++++ 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/core/device.c b/core/device.c index 7211570e1b3c..36b5d7b3637b 100644 --- a/core/device.c +++ b/core/device.c @@ -1069,3 +1069,41 @@ bool dt_node_is_enabled(struct dt_node *node) return p->len > 1 && p->prop[0] == 'o' && p->prop[1] == 'k'; } + +/* + * Function to fixup the phandle in the subtree. + */ +void dt_adjust_subtree_phandle(struct dt_node *dev, + const char** (get_properties_to_fix)(struct dt_node *n)) +{ + struct dt_node *node; + struct dt_property *prop; + u32 phandle, max_phandle = 0, import_phandle = new_phandle(); + const char **name; + + dt_for_each_node(dev, node) { + const char **props_to_update; + node->phandle += import_phandle; + + /* + * calculate max_phandle(new_tree), needed to update + * last_phandle. + */ + if (node->phandle >= max_phandle) + max_phandle = node->phandle; + + props_to_update = get_properties_to_fix(node); + if (!props_to_update) + continue; + for (name = props_to_update; *name != NULL; name++) { + prop = __dt_find_property(node, *name); + if (!prop) + continue; + phandle = dt_prop_get_u32(node, *name); + phandle += import_phandle; + memcpy((char *)&prop->prop, &phandle, prop->len); + } + } + + set_last_phandle(max_phandle); +} diff --git a/core/test/run-device.c b/core/test/run-device.c index 5939afc70e54..1a4cb1edeaf5 100644 --- a/core/test/run-device.c +++ b/core/test/run-device.c @@ -33,6 +33,8 @@ static inline bool fake_is_rodata(const void *p) #include "../device.c" #include #include "../../test/dt_common.c" +const char *prop_to_fix[] = {"something", NULL}; +const char **props_to_fix(struct dt_node *node); static void check_path(const struct dt_node *node, const char * expected_path) { @@ -87,18 +89,29 @@ static bool is_sorted(const struct dt_node *root) return true; } +/*handler for phandle fixup test */ +const char **props_to_fix(struct dt_node *node) +{ + const struct dt_property *prop; + + prop = dt_find_property(node, "something"); + if (prop) + return prop_to_fix; + + return NULL; +} int main(void) { struct dt_node *root, *c1, *c2, *gc1, *gc2, *gc3, *ggc1, *ggc2; struct dt_node *addrs, *addr1, *addr2; - struct dt_node *i; + struct dt_node *i, *subtree, *ev1, *ut1, *ut2; const struct dt_property *p; struct dt_property *p2; unsigned int n; char *s; size_t sz; - u32 phandle; + u32 phandle, ev1_ph, new_prop_ph; root = dt_new_root(""); assert(!list_top(&root->properties, struct dt_property, list)); @@ -412,6 +425,24 @@ int main(void) dt_free(root); + /* phandle fixup test */ + subtree = dt_new_root("subtree"); + ev1 = dt_new(subtree, "ev@1"); + ev1_ph = ev1->phandle; + dt_new(ev1,"a@1"); + dt_new(ev1,"a@2"); + dt_new(ev1,"a@3"); + ut1 = dt_new(subtree, "ut@1"); + dt_add_property(ut1, "something", (const void *)&ev1->phandle, 4); + ut2 = dt_new(subtree, "ut@2"); + dt_add_property(ut2, "something", (const void *)&ev1->phandle, 4); + + dt_adjust_subtree_phandle(subtree, props_to_fix); + assert(!(ev1->phandle == ev1_ph)); + new_prop_ph = dt_prop_get_u32(ut1, "something"); + assert(!(new_prop_ph == ev1_ph)); + new_prop_ph = dt_prop_get_u32(ut2, "something"); + assert(!(new_prop_ph == ev1_ph)); return 0; } diff --git a/include/device.h b/include/device.h index c51b3eea298e..1e5875dca584 100644 --- a/include/device.h +++ b/include/device.h @@ -268,4 +268,8 @@ struct dt_node *__dt_find_by_name_addr(struct dt_node *parent, const char *name, struct dt_node *dt_find_by_name_addr(struct dt_node *parent, const char *name, uint64_t addr); +/* phandle fixup helper */ +void dt_adjust_subtree_phandle(struct dt_node *subtree, + const char** (get_properties_to_fix)(struct dt_node *n)); + #endif /* __DEVICE_H */