On 4 December 2016 at 19:58, Nathan Rossi <[email protected]> wrote: > This patch fixes a bug that was introduced in u-boot v2016.05 as well > as xilinx-v2016.2. The bug can appear in variety of ways, but was > observed as: > > Uncompressing Invalid Image ... Unimplemented compression type 23 > > See patch for specific details. > > Signed-off-by: Nathan Rossi <[email protected]>
I'm not going to apply this patch, as I have submitted a proper fix upstream (which also fixes this issue for zynqmp too). Once accepted I will then backport (for both master and morty) to resolve this issue. Upstream patches for reference: https://patchwork.ozlabs.org/patch/704936/ https://patchwork.ozlabs.org/patch/704937/ https://patchwork.ozlabs.org/patch/704938/ Regards, Nathan > --- > ...place-dram_init-functions-with-board_init.patch | 213 > +++++++++++++++++++++ > recipes-bsp/u-boot/u-boot-xlnx_2016.07.bb | 1 + > 2 files changed, 214 insertions(+) > create mode 100644 > recipes-bsp/u-boot/u-boot-xlnx/ARM-zynq-Replace-dram_init-functions-with-board_init.patch > > diff --git > a/recipes-bsp/u-boot/u-boot-xlnx/ARM-zynq-Replace-dram_init-functions-with-board_init.patch > > b/recipes-bsp/u-boot/u-boot-xlnx/ARM-zynq-Replace-dram_init-functions-with-board_init.patch > new file mode 100644 > index 0000000000..b1885a9afc > --- /dev/null > +++ > b/recipes-bsp/u-boot/u-boot-xlnx/ARM-zynq-Replace-dram_init-functions-with-board_init.patch > @@ -0,0 +1,213 @@ > +From c5db12d072b43f1fc635edfdbece8256111faf42 Mon Sep 17 00:00:00 2001 > +From: Nathan Rossi <[email protected]> > +Date: Sun, 4 Dec 2016 19:33:22 +1000 > +Subject: [PATCH] ARM: zynq: Replace dram_init* functions with board_init_f > + safe ones > + > +The dram_init* functions for the zynq board are not safe for use from > +the board_init_f stage due to its use of the 'tmp' static variable. > + > +This incorrect use of a static variable was causing rare issues where > +the dram_init function would overwrite some parts the __rel_dyn section > +which caused obscure failures. > + > +This change removes the existing code and copies the implementation of > +the dram_init and dram_init_banksize from the > +arch/arm/mach-uniphier/dram_init.c source. This version of these > +functions does not use static variables and behaves the same (reading > +banks from fdt, and using the first bank as the ram_size). > + > +Signed-off-by: Nathan Rossi <[email protected]> > +Fixes: 758f29d0f8 ("ARM: zynq: Support systems with more memory banks") > +Upstream-Status: Pending > +--- > +This issue appears as the following error during image load for the Zybo > +board, however this is just one potential way this bug can surface. > + > + Uncompressing Invalid Image ... Unimplemented compression type 23 > + > +Changes in section sizes will vary the outcomes, and in some cases not > +present any issues during normal use. > +--- > + board/xilinx/zynq/board.c | 148 > ++++++++++++++++------------------------------ > + 1 file changed, 50 insertions(+), 98 deletions(-) > + > +diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c > +index 44ecb77b74..f6d4df6ad5 100644 > +--- a/board/xilinx/zynq/board.c > ++++ b/board/xilinx/zynq/board.c > +@@ -124,121 +124,73 @@ 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) > ++static const void *get_memory_reg_prop(const void *fdt, int *lenp) > + { > +- 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)); > +- } > ++ int offset; > + > +- /* Return the first address size */ > +- return *(phys_size_t *)((char *)buf + sizeof(phys_addr_t)); > +-} > ++ offset = fdt_path_offset(fdt, "/memory"); > ++ if (offset < 0) > ++ return NULL; > + > +-#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]; > ++ return fdt_getprop(fdt, offset, "reg", lenp); > ++} > + > + void dram_init_banksize(void) > + { > +- int bank; > ++ const void *fdt = gd->fdt_blob; > ++ const fdt32_t *val; > ++ int ac, sc, cells, len, i; > ++ > ++ val = get_memory_reg_prop(fdt, &len); > ++ if (len < 0) > ++ return; > ++ > ++ ac = fdt_address_cells(fdt, 0); > ++ sc = fdt_size_cells(fdt, 0); > ++ if (ac < 1 || sc > 2 || sc < 1 || sc > 2) { > ++ printf("invalid address/size cells\n"); > ++ return; > ++ } > + > +- memcpy(&gd->bd->bi_dram[0], &tmp, sizeof(tmp)); > ++ cells = ac + sc; > + > +- 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); > ++ len /= sizeof(*val); > ++ > ++ for (i = 0; i < CONFIG_NR_DRAM_BANKS && len >= cells; > ++ i++, len -= cells) { > ++ gd->bd->bi_dram[i].start = fdtdec_get_number(val, ac); > ++ val += ac; > ++ gd->bd->bi_dram[i].size = fdtdec_get_number(val, sc); > ++ val += sc; > ++ > ++ debug("DRAM bank %d: start = %08lx, size = %08lx\n", > ++ i, (unsigned long)gd->bd->bi_dram[i].start, > ++ (unsigned long)gd->bd->bi_dram[i].size); > + } > + } > + > + 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; > ++ const void *fdt = gd->fdt_blob; > ++ const fdt32_t *val; > ++ int ac, sc, len; > ++ > ++ ac = fdt_address_cells(fdt, 0); > ++ sc = fdt_size_cells(fdt, 0); > ++ if (ac < 0 || sc < 1 || sc > 2) { > ++ printf("invalid address/size cells\n"); > ++ return -EINVAL; > + } > + > +- /* 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; > +- } > ++ val = get_memory_reg_prop(fdt, &len); > ++ if (len / sizeof(*val) < ac + sc) > ++ return -EINVAL; > ++ > ++ val += ac; > + > +- gd->ram_size = fdt_get_reg(blob, node, &tmp, cell, len / > FDT_REG_SIZE); > ++ gd->ram_size = fdtdec_get_number(val, sc); > + > +- debug("%s: Initial DRAM size %llx\n", __func__, (u64)gd->ram_size); > ++ debug("DRAM size = %08lx\n", (unsigned long)gd->ram_size); > + > + zynq_ddrc_init(); > + > +-- > +2.10.2 > + > diff --git a/recipes-bsp/u-boot/u-boot-xlnx_2016.07.bb > b/recipes-bsp/u-boot/u-boot-xlnx_2016.07.bb > index 61f1cb793b..6e393f1b81 100644 > --- a/recipes-bsp/u-boot/u-boot-xlnx_2016.07.bb > +++ b/recipes-bsp/u-boot/u-boot-xlnx_2016.07.bb > @@ -8,6 +8,7 @@ PV = "v2016.07-xilinx-${XILINX_RELEASE_VERSION}+git${SRCPV}" > > FILESEXTRAPATHS_prepend := "${THISDIR}/u-boot-xlnx:" > > +SRC_URI_append = " > file://ARM-zynq-Replace-dram_init-functions-with-board_init.patch" > SRC_URI_append_kc705-microblazeel = " > file://microblaze-kc705-Convert-microblaze-generic-to-k.patch" > > LICENSE = "GPLv2+" > -- > 2.10.2 > -- _______________________________________________ meta-xilinx mailing list [email protected] https://lists.yoctoproject.org/listinfo/meta-xilinx
