From patchwork Thu Nov 12 02:33:15 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gavin Shan X-Patchwork-Id: 543184 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 7D9BB141301 for ; Thu, 12 Nov 2015 13:35:38 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 638A11A037B for ; Thu, 12 Nov 2015 13:35:38 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from e23smtp06.au.ibm.com (e23smtp06.au.ibm.com [202.81.31.148]) (using TLSv1 with cipher CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 8E0521A0228 for ; Thu, 12 Nov 2015 13:34:56 +1100 (AEDT) Received: from /spool/local by e23smtp06.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 12 Nov 2015 12:34:55 +1000 Received: from d23dlp03.au.ibm.com (202.81.31.214) by e23smtp06.au.ibm.com (202.81.31.212) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 12 Nov 2015 12:34:53 +1000 X-Helo: d23dlp03.au.ibm.com X-MailFrom: gwshan@linux.vnet.ibm.com X-RcptTo: skiboot@lists.ozlabs.org Received: from d23relay10.au.ibm.com (d23relay10.au.ibm.com [9.190.26.77]) by d23dlp03.au.ibm.com (Postfix) with ESMTP id 5E3943578056 for ; Thu, 12 Nov 2015 13:34:53 +1100 (EST) Received: from d23av03.au.ibm.com (d23av03.au.ibm.com [9.190.234.97]) by d23relay10.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id tAC2Yidw5373994 for ; Thu, 12 Nov 2015 13:34:53 +1100 Received: from d23av03.au.ibm.com (localhost [127.0.0.1]) by d23av03.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id tAC2YK8s027386 for ; Thu, 12 Nov 2015 13:34:20 +1100 Received: from ozlabs.au.ibm.com (ozlabs.au.ibm.com [9.192.253.14]) by d23av03.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id tAC2YKSJ026569; Thu, 12 Nov 2015 13:34:20 +1100 Received: from bran.ozlabs.ibm.com (haven.au.ibm.com [9.192.254.114]) by ozlabs.au.ibm.com (Postfix) with ESMTP id 2FB3AA03E1; Thu, 12 Nov 2015 13:33:34 +1100 (AEDT) Received: from gwshan (shangw.ozlabs.ibm.com [10.61.2.199]) by bran.ozlabs.ibm.com (Postfix) with ESMTP id 2393EE46AC; Thu, 12 Nov 2015 13:33:34 +1100 (AEDT) Received: by gwshan (Postfix, from userid 1000) id F1FA294212B; Thu, 12 Nov 2015 13:33:33 +1100 (AEDT) From: Gavin Shan To: skiboot@lists.ozlabs.org Date: Thu, 12 Nov 2015 13:33:15 +1100 Message-Id: <1447295609-20446-9-git-send-email-gwshan@linux.vnet.ibm.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1447295609-20446-1-git-send-email-gwshan@linux.vnet.ibm.com> References: <1447295609-20446-1-git-send-email-gwshan@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15111202-0021-0000-0000-00000221E5C8 Subject: [Skiboot] [PATCH v9 08/22] core/fdt: OPAL API opal_get_device_tree() X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This implements OPAL API opal_get_device_tree(), which will be used to retrieve the device sub-tree introduced by newly hot plugged PCI devices. Signed-off-by: Gavin Shan --- core/fdt.c | 109 ++++++++++++++++++++++++++++++++++------------------- include/opal-api.h | 3 +- 2 files changed, 73 insertions(+), 39 deletions(-) diff --git a/core/fdt.c b/core/fdt.c index a9392b1..3a85618 100644 --- a/core/fdt.c +++ b/core/fdt.c @@ -126,19 +126,23 @@ static void flatten_dt_properties(void *fdt, const struct dt_node *dn) } } -static void flatten_dt_node(void *fdt, const struct dt_node *root) +static void flatten_dt_node(void *fdt, const struct dt_node *root, bool inc) { const struct dt_node *i; + if (inc) { #ifdef DEBUG_FDT - printf("FDT: node: %s\n", root->name); + printf("FDT: node: %s\n", root->name); #endif - flatten_dt_properties(fdt, root); - list_for_each(&root->children, i, list) { - dt_begin_node(fdt, i); - flatten_dt_node(fdt, i); - dt_end_node(fdt); + dt_begin_node(fdt, root); + flatten_dt_properties(fdt, root); } + + list_for_each(&root->children, i, list) + flatten_dt_node(fdt, i, true); + + if (inc) + dt_end_node(fdt); } static void create_dtb_reservemap(void *fdt, const struct dt_node *root) @@ -163,51 +167,80 @@ static void create_dtb_reservemap(void *fdt, const struct dt_node *root) save_err(fdt_finish_reservemap(fdt)); } -void *create_dtb(const struct dt_node *root) +static int __create_dtb(void *fdt, size_t len, + const struct dt_node *root, + bool inc) { - void *fdt = NULL; - size_t len = DEVICE_TREE_MAX_SIZE; uint32_t old_last_phandle = last_phandle; - do { - if (fdt) - free(fdt); + fdt_create(fdt, len); + + if (root == dt_root && inc) + create_dtb_reservemap(fdt, root); + + /* Unflatten our live tree */ + flatten_dt_node(fdt, root, inc); + + save_err(fdt_finish(fdt)); + if (fdt_error) { last_phandle = old_last_phandle; - fdt_error = 0; - fdt = malloc(len); - if (!fdt) { - prerror("dtb: could not malloc %lu\n", (long)len); - return NULL; - } + prerror("dtb: error %s\n", fdt_strerror(fdt_error)); + return fdt_error; + } + +#ifdef DEBUG_FDT + dump_fdt(fdt); +#endif + return 0; +} - fdt_create(fdt, len); +static int64_t opal_get_device_tree(uint32_t phandle, + uint64_t buf, + uint64_t len) +{ + struct dt_node *root; + void *fdt = (void *)buf; + int ret; - create_dtb_reservemap(fdt, root); + if (!fdt || !len) + return OPAL_PARAMETER; - /* Open root node */ - dt_begin_node(fdt, root); + root = dt_find_by_phandle(dt_root, phandle); + if (!root) + return OPAL_CLOSED; - /* Unflatten our live tree */ - flatten_dt_node(fdt, root); + ret = __create_dtb(fdt, len, root, false); + if (ret == -FDT_ERR_NOSPACE) + return OPAL_NO_MEM; + else if (ret) + return OPAL_EMPTY; - /* Close root node */ - dt_end_node(fdt); + return OPAL_SUCCESS; +} +opal_call(OPAL_GET_DEVICE_TREE, opal_get_device_tree, 3); - save_err(fdt_finish(fdt)); +void *create_dtb(const struct dt_node *root) +{ + void *fdt = NULL; + size_t len = DEVICE_TREE_MAX_SIZE; + int ret; - if (!fdt_error) + do { + fdt = malloc(len); + if (!fdt) { + prerror("dtb: cannot allocate FDT blob (%lu bytes)\n", + (long)len); break; + } - len *= 2; - } while (fdt_error == -FDT_ERR_NOSPACE); + ret = __create_dtb(fdt, len, root, true); + if (ret) { + free(fdt); + fdt = NULL; + } -#ifdef DEBUG_FDT - dump_fdt(fdt); -#endif + len *= 2; + } while (ret == -FDT_ERR_NOSPACE); - if (fdt_error) { - prerror("dtb: error %s\n", fdt_strerror(fdt_error)); - return NULL; - } return fdt; } diff --git a/include/opal-api.h b/include/opal-api.h index 7a11fe8..fff9148 100644 --- a/include/opal-api.h +++ b/include/opal-api.h @@ -162,7 +162,8 @@ #define OPAL_LEDS_GET_INDICATOR 114 #define OPAL_LEDS_SET_INDICATOR 115 #define OPAL_CEC_REBOOT2 116 -#define OPAL_LAST 116 +#define OPAL_GET_DEVICE_TREE 117 +#define OPAL_LAST 117 /* Device tree flags */