From patchwork Sun Nov 13 21:21:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 694138 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 3tH67Y4ND2z9t0q for ; Mon, 14 Nov 2016 08:22:49 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 01CE24B98A; Sun, 13 Nov 2016 22:22:45 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Y8Kf5oNG_QJj; Sun, 13 Nov 2016 22:22:44 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 84432A7574; Sun, 13 Nov 2016 22:22:38 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D668A4B99D for ; Sun, 13 Nov 2016 22:22:29 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ofPdA4ulsYT5 for ; Sun, 13 Nov 2016 22:22:29 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from kaki.bld.corp.google.com (unknown [104.132.211.80]) by theia.denx.de (Postfix) with ESMTPS id 8B8FF4B624 for ; Sun, 13 Nov 2016 22:22:29 +0100 (CET) Received: by kaki.bld.corp.google.com (Postfix, from userid 121222) id 3D2B94039F; Sun, 13 Nov 2016 14:22:28 -0700 (MST) From: Simon Glass To: U-Boot Mailing List Date: Sun, 13 Nov 2016 14:21:58 -0700 Message-Id: <1479072136-14246-5-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 In-Reply-To: <1479072136-14246-1-git-send-email-sjg@chromium.org> References: <1479072136-14246-1-git-send-email-sjg@chromium.org> Cc: Stephen Warren , huang lin , Jeffy Chen Subject: [U-Boot] [PATCH v2 04/22] dm: core: Handle global_data moving in SPL X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" When CONFIG_SPL_STACK_R is enabled, and spl_init() is called before board_init_r(), spl_relocate_stack_gd() will move global_data to a new place in memory. This affects driver model since it uses a list for the uclasses. Unless this is updated the list will become invalid. When looking for a non-existent uclass, such as when adding a new one, the loop in uclass_find() may continue forever, thus causing a hang. Add a function to correct this rather obscure bug. Signed-off-by: Simon Glass --- Changes in v2: - Fix CONFIG_IS_ENABLED condition common/spl/spl.c | 3 +++ drivers/core/root.c | 7 +++++++ include/dm/root.h | 10 ++++++++++ 3 files changed, 20 insertions(+) diff --git a/common/spl/spl.c b/common/spl/spl.c index bdb165a..d16cd18 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -511,6 +511,9 @@ ulong spl_relocate_stack_gd(void) ptr = CONFIG_SPL_STACK_R_ADDR - roundup(sizeof(gd_t),16); new_gd = (gd_t *)ptr; memcpy(new_gd, (void *)gd, sizeof(gd_t)); +#if CONFIG_IS_ENABLED(DM) + dm_fixup_for_gd_move(new_gd); +#endif #if !defined(CONFIG_ARM) gd = new_gd; #endif diff --git a/drivers/core/root.c b/drivers/core/root.c index 33dc9c0..9edfc1e 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -41,6 +41,13 @@ struct udevice *dm_root(void) return gd->dm_root; } +void dm_fixup_for_gd_move(struct global_data *new_gd) +{ + /* The sentinel node has moved, so update things that point to it */ + new_gd->uclass_root.next->prev = &new_gd->uclass_root; + new_gd->uclass_root.prev->next = &new_gd->uclass_root; +} + fdt_addr_t dm_get_translation_offset(void) { struct udevice *root = dm_root(); diff --git a/include/dm/root.h b/include/dm/root.h index c7f0c1d..3cf730d 100644 --- a/include/dm/root.h +++ b/include/dm/root.h @@ -21,6 +21,16 @@ struct udevice; */ struct udevice *dm_root(void); +struct global_data; +/** + * dm_fixup_for_gd_move() - Handle global_data moving to a new place + * + * The uclass list is part of global_data. Due to the way lists work, moving + * the list will cause it to become invalid. This function fixes that up so + * that the uclass list will work correctly. + */ +void dm_fixup_for_gd_move(struct global_data *new_gd); + /** * dm_scan_platdata() - Scan all platform data and bind drivers *