From patchwork Mon Dec 12 07:14:54 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Rossi X-Patchwork-Id: 704937 X-Patchwork-Delegate: monstr@monstr.eu 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 3tcYyX6VKRz9vF4 for ; Mon, 12 Dec 2016 18:15:32 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=nathanrossi.com header.i=@nathanrossi.com header.b="eLyj/1Iu"; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 1EAE9A7607; Mon, 12 Dec 2016 08:15:28 +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 KUwLs657NDwI; Mon, 12 Dec 2016 08:15:27 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 7E116B384C; Mon, 12 Dec 2016 08:15:23 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 3A74CA75CA for ; Mon, 12 Dec 2016 08:15:16 +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 wKvhJSCduJLw for ; Mon, 12 Dec 2016 08:15:16 +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 mail-pg0-f67.google.com (mail-pg0-f67.google.com [74.125.83.67]) by theia.denx.de (Postfix) with ESMTPS id 0AD27A75F3 for ; Mon, 12 Dec 2016 08:15:14 +0100 (CET) Received: by mail-pg0-f67.google.com with SMTP id x23so113093pgx.3 for ; Sun, 11 Dec 2016 23:15:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nathanrossi.com; s=google; h=from:mime-version:content-transfer-encoding:date:subject:message-id :in-reply-to:references:to:cc; bh=O7Mvj2HULu9qBOeti27euKGWW8WULROUYc9NveKUTGk=; b=eLyj/1IuBh6UZbJ1C4IPktl+vrBzLl7fq0oVnxP6RcLc9kvUrmMuoOMHEtDlSo5NMB 6Sl3I5zyqI2LH4BGB2+MyICdIU4ozmEpzScaD8DRn+FlAS+yrFpvvX/Sxpfu6H/9/k9Q ow7exCCpBAkbb+F8nABrM5y2S9XQv4pEp3A1sv0K45C5OHdBsHWltvc14Ym2VHqLlejk jgLEJlpN4bCJKrbyml848lBNP1UMFfAaf/DfXr+fT6bh6tKziBpFFYWBwal053HKCq0Y vXSbvbwpd5NalKpHpjakhvX3MvxkV4Ji9lptOl65IBokuZuJV7uoCKP+x2JvcgUv1q3+ buCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:mime-version:content-transfer-encoding:date :subject:message-id:in-reply-to:references:to:cc; bh=O7Mvj2HULu9qBOeti27euKGWW8WULROUYc9NveKUTGk=; b=LP5d/ynkjWCINhQIIYAokHBzXKIdzXaJwfW9jtmmdivAW3hisDtsTSCXpY/CcGbFFo 4Sq4cZ6CVr3dsJSd+t/gmBVGxit6/2td+80QSPj7TRywG1XUgwh3nBeLAn7EIwvobqXf rqU7geuoYYn6TdFmUBG+DYFxsHFKq+rcr17n/WNPN4Hf7BRRkCYecjDqjD84aKLqd6+8 isTLqJe3gtd3pDvzvlPcnj6NgPqcSOITGgfXwkgyw4y9xi9DtLwbZah7H+bcu55zFlF/ 4k07rJKACCxe2uf3HTI40U4zBfdimnsiQaBvM4WAO07o9yVhiwNPqeo+P8kC5NCcixqi i3WQ== X-Gm-Message-State: AKaTC03SCe8H4a3Wt/l/1+jVVZzXS7fA2YKGU+FjxHXRZe1X1RrLuHzjBrfRuflqCaLQ5Q== X-Received: by 10.99.101.65 with SMTP id z62mr167541495pgb.74.1481526913508; Sun, 11 Dec 2016 23:15:13 -0800 (PST) Received: from [127.0.1.1] (CPE-1-121-152-133.qwl9.woo.bigpond.net.au. [1.121.152.133]) by smtp.gmail.com with ESMTPSA id k67sm73871483pfk.69.2016.12.11.23.15.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 11 Dec 2016 23:15:12 -0800 (PST) From: Nathan Rossi MIME-Version: 1.0 Date: Mon, 12 Dec 2016 17:14:54 +1000 Message-Id: <20161212071454.16659-2-nathan@nathanrossi.com> In-Reply-To: <20161212071454.16659-0-nathan@nathanrossi.com> References: <20161212071454.16659-0-nathan@nathanrossi.com> To: u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 2/3] ARM: zynq: Replace board specific with generic memory bank decoding 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: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" The dram_init and dram_init_banksize functions were using a board specific implementation for decoding the memory banks from the fdt. This board specific implementation uses a static variable 'tmp' which makes these functions unsafe for execution from within the board_init_f context. This unsafe use of a static variable was causing a specific bug when using the zynq_zybo configuration, U-Boot would generate the following error during image load. This was caused due to dram_init overwriting the relocations for the 'image' variable within the do_bootm function. Out of coincidence the un-initialized memory has a compression type which is the same as the value for the relocation type R_ARM_RELATIVE. Uncompressing Invalid Image ... Unimplemented compression type 23 It should be noted that this is just one way the issue could surface, other cases my not be observed in normal boot flow. Depending on the size of various sections, and location of relocations within __rel_dyn and the compiler/linker the outcome of this bug can differ greatly. This change makes the dram_init* functions use a generic implementation of decoding and populating memory bank and size data. Signed-off-by: Nathan Rossi Fixes: 758f29d0f8 ("ARM: zynq: Support systems with more memory banks") Cc: Michal Simek --- board/xilinx/zynq/board.c | 112 ++-------------------------------------------- 1 file changed, 3 insertions(+), 109 deletions(-) diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 2c86940957..5cd9bbf711 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -124,121 +124,15 @@ int zynq_board_read_rom_ethaddr(unsigned char *ethaddr) } #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE) -/* - * fdt_get_reg - Fill buffer by information from DT - */ -static phys_size_t fdt_get_reg(const void *fdt, int nodeoffset, void *buf, - const u32 *cell, int n) -{ - int i = 0, b, banks; - int parent_offset = fdt_parent_offset(fdt, nodeoffset); - int address_cells = fdt_address_cells(fdt, parent_offset); - int size_cells = fdt_size_cells(fdt, parent_offset); - char *p = buf; - u64 val; - u64 vals; - - debug("%s: addr_cells=%x, size_cell=%x, buf=%p, cell=%p\n", - __func__, address_cells, size_cells, buf, cell); - - /* Check memory bank setup */ - banks = n % (address_cells + size_cells); - if (banks) - panic("Incorrect memory setup cells=%d, ac=%d, sc=%d\n", - n, address_cells, size_cells); - - banks = n / (address_cells + size_cells); - - for (b = 0; b < banks; b++) { - debug("%s: Bank #%d:\n", __func__, b); - if (address_cells == 2) { - val = cell[i + 1]; - val <<= 32; - val |= cell[i]; - val = fdt64_to_cpu(val); - debug("%s: addr64=%llx, ptr=%p, cell=%p\n", - __func__, val, p, &cell[i]); - *(phys_addr_t *)p = val; - } else { - debug("%s: addr32=%x, ptr=%p\n", - __func__, fdt32_to_cpu(cell[i]), p); - *(phys_addr_t *)p = fdt32_to_cpu(cell[i]); - } - p += sizeof(phys_addr_t); - i += address_cells; - - debug("%s: pa=%p, i=%x, size=%zu\n", __func__, p, i, - sizeof(phys_addr_t)); - - if (size_cells == 2) { - vals = cell[i + 1]; - vals <<= 32; - vals |= cell[i]; - vals = fdt64_to_cpu(vals); - - debug("%s: size64=%llx, ptr=%p, cell=%p\n", - __func__, vals, p, &cell[i]); - *(phys_size_t *)p = vals; - } else { - debug("%s: size32=%x, ptr=%p\n", - __func__, fdt32_to_cpu(cell[i]), p); - *(phys_size_t *)p = fdt32_to_cpu(cell[i]); - } - p += sizeof(phys_size_t); - i += size_cells; - - debug("%s: ps=%p, i=%x, size=%zu\n", - __func__, p, i, sizeof(phys_size_t)); - } - - /* Return the first address size */ - return *(phys_size_t *)((char *)buf + sizeof(phys_addr_t)); -} - -#define FDT_REG_SIZE sizeof(u32) -/* Temp location for sharing data for storing */ -/* Up to 64-bit address + 64-bit size */ -static u8 tmp[CONFIG_NR_DRAM_BANKS * 16]; - void dram_init_banksize(void) { - int bank; - - memcpy(&gd->bd->bi_dram[0], &tmp, sizeof(tmp)); - - for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { - debug("Bank #%d: start %llx\n", bank, - (unsigned long long)gd->bd->bi_dram[bank].start); - debug("Bank #%d: size %llx\n", bank, - (unsigned long long)gd->bd->bi_dram[bank].size); - } + fdtdec_setup_memory_banksize(); } int dram_init(void) { - int node, len; - const void *blob = gd->fdt_blob; - const u32 *cell; - - memset(&tmp, 0, sizeof(tmp)); - - /* find or create "/memory" node. */ - node = fdt_subnode_offset(blob, 0, "memory"); - if (node < 0) { - printf("%s: Can't get memory node\n", __func__); - return node; - } - - /* Get pointer to cells and lenght of it */ - cell = fdt_getprop(blob, node, "reg", &len); - if (!cell) { - printf("%s: Can't get reg property\n", __func__); - return -1; - } - - gd->ram_size = fdt_get_reg(blob, node, &tmp, cell, len / FDT_REG_SIZE); - - debug("%s: Initial DRAM size %llx\n", __func__, (u64)gd->ram_size); + if (fdtdec_setup_memory_size() != 0) + return -EINVAL; zynq_ddrc_init();