From patchwork Mon Feb 16 15:15:33 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ananth N Mavinakayanahalli X-Patchwork-Id: 440188 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 8A45A1401F0 for ; Tue, 17 Feb 2015 02:14:27 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 798301A0BC9 for ; Tue, 17 Feb 2015 02:14:27 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from e28smtp04.in.ibm.com (e28smtp04.in.ibm.com [122.248.162.4]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 63F0E1A09F9 for ; Tue, 17 Feb 2015 02:14:24 +1100 (AEDT) Received: from /spool/local by e28smtp04.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 16 Feb 2015 20:44:22 +0530 Received: from d28dlp01.in.ibm.com (9.184.220.126) by e28smtp04.in.ibm.com (192.168.1.134) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 16 Feb 2015 20:44:20 +0530 Received: from d28relay02.in.ibm.com (d28relay02.in.ibm.com [9.184.220.59]) by d28dlp01.in.ibm.com (Postfix) with ESMTP id 96C83E0056 for ; Mon, 16 Feb 2015 20:45:57 +0530 (IST) Received: from d28av01.in.ibm.com (d28av01.in.ibm.com [9.184.220.63]) by d28relay02.in.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t1GFEHZj30474410 for ; Mon, 16 Feb 2015 20:44:18 +0530 Received: from d28av01.in.ibm.com (localhost [127.0.0.1]) by d28av01.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t1GFEHJ6023119 for ; Mon, 16 Feb 2015 20:44:17 +0530 Received: from thinktux.in.ibm.com ([9.79.200.14]) by d28av01.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t1GFEHQd023108 for ; Mon, 16 Feb 2015 20:44:17 +0530 To: skiboot@lists.ozlabs.org From: Ananth N Mavinakayanahalli Date: Mon, 16 Feb 2015 20:45:33 +0530 Message-ID: <20150216151533.1774.39642.stgit@thinktux.in.ibm.com> In-Reply-To: <20150216151522.1774.34084.stgit@thinktux.in.ibm.com> References: <20150216151522.1774.34084.stgit@thinktux.in.ibm.com> User-Agent: StGit/0.16 MIME-Version: 1.0 X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15021615-0013-0000-0000-000003CC842E Subject: [Skiboot] [PATCH 3/3] ... to prevent any potential poller recursions during lid load. X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" See bz121430 for one such case. With this change: ... [10810950484,5] CUPD: P side ML Keyword = FW830.00 [10832756491,6] HBRT: 1 lids to load [10832762732,7] FSP: Fetch data id: 05 sid: 81e00430 to 0x306cf500(0x100000 bytes) [10832766825,7] FSP: 0x00100000 bytes balign=306cf000 boff=500 bsize=101000 [10857829395,5] CUPD: Marker LID id : size : status = 0x80a08001 : 0x5d0 : 0x0 [10966464432,7] FSP: -> rc=0x00 off: 00000000 twritten: 0007fb80 [10966468418,7] HBRT: LID 0x81e00430 successfully loaded, len=0x31b83db8 ... [19485180658,7] HBRT: stopOCCs() rc = 0 [19582727570,6] OCC: Got OCC Load message, scope=0x2 dbob=0x0 seq=0x10 [19582732660,7] HBRT: OCC Load requested [19582734678,7] HBRT: Calling loadOCC() homer 0000000401400000, occ_common_area 0000000400800000, chip 0000 [19582803643,6] HBRT: Lid load request for 0x81e00430 [19582806532,7] HBRT: Serviced from cache, len=0x7fb80 [19582996931,7] HBRT: -> rc = 0 [19582999113,7] HBRT: Calling loadOCC() homer 0000000401c00000, occ_common_area 0000000400800000, chip 0001 [19583097594,6] HBRT: Lid load request for 0x81e00430 [19583100343,7] HBRT: Serviced from cache, len=0x7fb80 [19583274638,7] HBRT: -> rc = 0 [19583277114,6] HBRT: OCC Start requested Signed-off-by: Ananth N Mavinakayanahalli --- core/hostservices.c | 117 +++++++++++++++++++++++++++++++++++------------- core/init.c | 3 + include/hostservices.h | 1 3 files changed, 89 insertions(+), 32 deletions(-) diff --git a/core/hostservices.c b/core/hostservices.c index 952f6b8..1bda67f 100644 --- a/core/hostservices.c +++ b/core/hostservices.c @@ -386,36 +386,26 @@ static int hservice_scom_write(uint64_t chip_id, uint64_t addr, return xscom_write(chip_id, addr, val); } -static int hservice_lid_load(uint32_t lid, void **buf, size_t *len) +struct hbrt_lid { + void *load_addr; + size_t len; + uint32_t id; + struct list_node link; +}; +static LIST_HEAD(hbrt_lid_list); + +/* TODO: Few of the following routines can be generalized */ +static int __hservice_lid_load(uint32_t lid, void **buf, size_t *len) { int rc; - static void *lid_cache; - static size_t lid_cache_len; - static uint32_t lid_cache_id; - - prlog(PR_INFO, "HBRT: LID load request for 0x%08x\n", lid); /* Adjust LID side first or we get a cache mismatch */ lid = fsp_adjust_lid_side(lid); - /* Check for cache */ - if (lid_cache && lid_cache_id == lid) { - *buf = lid_cache; - *len = lid_cache_len; - prlog(PR_DEBUG, "HBRT: Serviced from cache, len=0x%lx\n", - lid_cache_len); - return 0; - } - - /* Cache mismatch, discard old one */ - if (lid_cache) { - prlog(PR_DEBUG, "HBRT: Cache mismatch, discarding old" - " 0x%08x\n", lid_cache_id); - free(lid_cache); - lid_cache = NULL; - } - - /* Allocate a new buffer and load the LID into it */ + /* + * Allocate a new buffer and load the LID into it + * XXX: We currently use the same size for each HBRT lid. + */ *buf = malloc(HBRT_LOAD_LID_SIZE); *len = HBRT_LOAD_LID_SIZE; rc = fsp_fetch_data(0, FSP_DATASET_NONSP_LID, lid, 0, *buf, len); @@ -424,17 +414,80 @@ static int hservice_lid_load(uint32_t lid, void **buf, size_t *len) *len = 0; *buf = realloc(*buf, *len); - /* We managed, let's cache it */ - if (rc == 0 && *len) { - lid_cache = *buf; - lid_cache_len = *len; - lid_cache_id = lid; + prlog(PR_DEBUG, "HBRT: LID 0x%08x successfully loaded, len=0x%lx\n", + lid, (unsigned long)len); - prlog(PR_DEBUG, "HBRT: LID 0x%08x successfully loaded and" - " cached, len=0x%lx\n", lid, lid_cache_len); + return rc; +} + +static int __hservice_lid_preload(const uint32_t lid) +{ + struct hbrt_lid *hlid; + void *buf; + size_t len; + int rc; + + hlid = zalloc(sizeof(struct hbrt_lid)); + if (!hlid) { + prerror("HBRT: Could not allocate struct hbrt_lid\n"); + return -ENOMEM; } - return rc; + rc = __hservice_lid_load(lid, &buf, &len); + if (rc) { + free(hlid); + return rc; + } + + hlid->load_addr = buf; + hlid->len = len; + hlid->id = lid; + list_add_tail(&hbrt_lid_list, &hlid->link); + + return 0; +} + +/* Find and preload all lids needed by hostservices */ +void hservices_lid_preload(void) +{ + const uint32_t *lid_list = NULL; + size_t num_lids; + + if (!hservice_runtime) + return; + + lid_list = (const uint32_t *)hservice_runtime->get_lid_list(&num_lids); + if (!lid_list) { + prerror("HBRT: get_lid_list() returned NULL\n"); + return; + } + + prlog(PR_INFO, "HBRT: %d lids to load\n", (int)num_lids); + + /* Currently HBRT needs only one (OCC) lid */ + while (num_lids--) + __hservice_lid_preload(lid_list[num_lids]); +} + +static int hservice_lid_load(uint32_t lid, void **buf, size_t *len) +{ + struct hbrt_lid *hlid; + + prlog(PR_INFO, "HBRT: Lid load request for 0x%08x\n", lid); + + if (list_empty(&hbrt_lid_list)) /* Should not happen */ + hservices_lid_preload(); + + list_for_each(&hbrt_lid_list, hlid, link) { + if (hlid->id == lid) { + *buf = hlid->load_addr; + *len = hlid->len; + prlog(PR_DEBUG, "HBRT: Serviced from cache," + " len=0x%lx\n", hlid->len); + return 0; + } + } + return -ENOENT; } static int hservice_lid_unload(void *buf __unused) diff --git a/core/init.c b/core/init.c index 0b29e2b..018f10f 100644 --- a/core/init.c +++ b/core/init.c @@ -645,6 +645,9 @@ void __noreturn main_cpu_entry(const void *fdt, u32 master_cpu) if (platform.init) platform.init(); + /* Preload hostservices lids */ + hservices_lid_preload(); + /* Setup dummy console nodes if it's enabled */ if (dummy_console_enabled()) dummy_console_add_nodes(); diff --git a/include/hostservices.h b/include/hostservices.h index 7279c8e..c8958a3 100644 --- a/include/hostservices.h +++ b/include/hostservices.h @@ -18,6 +18,7 @@ #define __HOSTSERVICES_H bool hservices_init(void); +void hservices_lid_preload(void); int host_services_occ_load(void); int host_services_occ_start(void);