From patchwork Tue May 3 05:04:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gavin Shan X-Patchwork-Id: 617759 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 AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3qzTgZ4Gbsz9ssP for ; Tue, 3 May 2016 15:07:22 +1000 (AEST) Received: from ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3qzTgZ3Gy2zDqVw for ; Tue, 3 May 2016 15:07:22 +1000 (AEST) 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.2 with cipher CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3qzTfL5wsYzDqCB for ; Tue, 3 May 2016 15:06:18 +1000 (AEST) Received: from localhost by e23smtp06.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 3 May 2016 15:06:17 +1000 Received: from d23dlp01.au.ibm.com (202.81.31.203) by e23smtp06.au.ibm.com (202.81.31.212) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 3 May 2016 15:06:14 +1000 X-IBM-Helo: d23dlp01.au.ibm.com X-IBM-MailFrom: gwshan@linux.vnet.ibm.com X-IBM-RcptTo: skiboot@lists.ozlabs.org Received: from d23relay07.au.ibm.com (d23relay07.au.ibm.com [9.190.26.37]) by d23dlp01.au.ibm.com (Postfix) with ESMTP id CD31B2CE8046 for ; Tue, 3 May 2016 15:06:13 +1000 (EST) Received: from d23av03.au.ibm.com (d23av03.au.ibm.com [9.190.234.97]) by d23relay07.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u43565TS48889934 for ; Tue, 3 May 2016 15:06:13 +1000 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 u4355fnB024561 for ; Tue, 3 May 2016 15:05:41 +1000 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 u4355ffo023820; Tue, 3 May 2016 15:05:41 +1000 Received: from bran.ozlabs.ibm.com (haven.au.ibm.com [9.192.254.114]) by ozlabs.au.ibm.com (Postfix) with ESMTP id 71B9CA030E; Tue, 3 May 2016 15:04:46 +1000 (AEST) Received: from gwshan (shangw.ozlabs.ibm.com [10.61.2.199]) by bran.ozlabs.ibm.com (Postfix) with ESMTP id 71A5DE3A33; Tue, 3 May 2016 15:04:46 +1000 (AEST) Received: by gwshan (Postfix, from userid 1000) id 50BCB94268E; Tue, 3 May 2016 15:04:46 +1000 (AEST) From: Gavin Shan To: skiboot@lists.ozlabs.org Date: Tue, 3 May 2016 15:04:29 +1000 Message-Id: <1462251882-12762-5-git-send-email-gwshan@linux.vnet.ibm.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1462251882-12762-1-git-send-email-gwshan@linux.vnet.ibm.com> References: <1462251882-12762-1-git-send-email-gwshan@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16050305-0021-0000-0000-0000096A8D14 Subject: [Skiboot] [PATCH v10 04/17] core/fdt: OPAL API opal_get_device_tree() X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.22 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. The argument @phandle of the API indicates the specified device node that is the PCI slot's device node in PCI hotplug case. @buf is the memory buffer allocated from kernel to hold the FDT blob. @len is the length of the memory buffer. The FDT blob is put into the memory buffer indicated by @buf and OPAL_SUCCESS is returned on success. Otherwise, errcode is returned accordingly. Signed-off-by: Gavin Shan --- core/fdt.c | 111 +++++++++++++++++++++++++++++++++++------------------ include/opal-api.h | 3 +- 2 files changed, 75 insertions(+), 39 deletions(-) diff --git a/core/fdt.c b/core/fdt.c index a9392b1..f82927a 100644 --- a/core/fdt.c +++ b/core/fdt.c @@ -126,19 +126,25 @@ 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 exclusive) { const struct dt_node *i; + if (!exclusive) { #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, false); + + if (!exclusive) + dt_end_node(fdt); } static void create_dtb_reservemap(void *fdt, const struct dt_node *root) @@ -163,51 +169,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 exclusive) { - 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 && !exclusive) + create_dtb_reservemap(fdt, root); + + /* Unflatten our live tree */ + flatten_dt_node(fdt, root, exclusive); + + 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_PARAMETER; - /* Unflatten our live tree */ - flatten_dt_node(fdt, root); + ret = __create_dtb(fdt, len, root, true); + 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, false); + 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 0b7b0bb..41af0e5 100644 --- a/include/opal-api.h +++ b/include/opal-api.h @@ -163,7 +163,8 @@ #define OPAL_LEDS_SET_INDICATOR 115 #define OPAL_CEC_REBOOT2 116 #define OPAL_CONSOLE_FLUSH 117 -#define OPAL_LAST 117 +#define OPAL_GET_DEVICE_TREE 118 +#define OPAL_LAST 118 /* Device tree flags */