summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Rossi <nathan@nathanrossi.com>2016-12-20 19:20:42 +1000
committerNathan Rossi <nathan@nathanrossi.com>2016-12-21 22:05:09 +1000
commit3e2319675cf104b2183261aad63acc095f114657 (patch)
tree4d0320a88f742036bcf9ca796b1e4867dffef198
parent47f17c451a534cb8a7d7360ea6f97a6c9f6be798 (diff)
downloadmeta-xilinx-3e2319675cf104b2183261aad63acc095f114657.tar.gz
u-boot-xlnx_2016.07: Backport fix for memory corruption
Backport the dram_init* memory corruption fix, this resolves issues with some configurations where the dram_init function for zynq/zynqmp would trash non-relocated locations in memory due to the use of static variables before bss initialization. Signed-off-by: Nathan Rossi <nathan@nathanrossi.com>
-rw-r--r--recipes-bsp/u-boot/u-boot-xlnx_2016.07.bb7
-rw-r--r--recipes-bsp/u-boot/u-boot/0001-fdt-add-memory-bank-decoding-functions-for-board-set.patch144
-rw-r--r--recipes-bsp/u-boot/u-boot/0002-ARM-zynq-Replace-board-specific-with-generic-memory-.patch170
-rw-r--r--recipes-bsp/u-boot/u-boot/0003-ARM64-zynqmp-Replace-board-specific-with-generic-mem.patch156
4 files changed, 477 insertions, 0 deletions
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 61f1cb79..af33a4cf 100644
--- a/recipes-bsp/u-boot/u-boot-xlnx_2016.07.bb
+++ b/recipes-bsp/u-boot/u-boot-xlnx_2016.07.bb
@@ -7,6 +7,13 @@ SRCREV = "95e11f6eb4bc07bbee12a4217c58146bddac61b2"
7PV = "v2016.07-xilinx-${XILINX_RELEASE_VERSION}+git${SRCPV}" 7PV = "v2016.07-xilinx-${XILINX_RELEASE_VERSION}+git${SRCPV}"
8 8
9FILESEXTRAPATHS_prepend := "${THISDIR}/u-boot-xlnx:" 9FILESEXTRAPATHS_prepend := "${THISDIR}/u-boot-xlnx:"
10FILESEXTRAPATHS_prepend := "${THISDIR}/u-boot:"
11
12SRC_URI_append = " \
13 file://0001-fdt-add-memory-bank-decoding-functions-for-board-set.patch \
14 file://0002-ARM-zynq-Replace-board-specific-with-generic-memory-.patch \
15 file://0003-ARM64-zynqmp-Replace-board-specific-with-generic-mem.patch \
16 "
10 17
11SRC_URI_append_kc705-microblazeel = " file://microblaze-kc705-Convert-microblaze-generic-to-k.patch" 18SRC_URI_append_kc705-microblazeel = " file://microblaze-kc705-Convert-microblaze-generic-to-k.patch"
12 19
diff --git a/recipes-bsp/u-boot/u-boot/0001-fdt-add-memory-bank-decoding-functions-for-board-set.patch b/recipes-bsp/u-boot/u-boot/0001-fdt-add-memory-bank-decoding-functions-for-board-set.patch
new file mode 100644
index 00000000..b7d179f8
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot/0001-fdt-add-memory-bank-decoding-functions-for-board-set.patch
@@ -0,0 +1,144 @@
1From 623f60198b38c4fdae596038cd5956e44b6224a4 Mon Sep 17 00:00:00 2001
2From: Nathan Rossi <nathan@nathanrossi.com>
3Date: Mon, 19 Dec 2016 00:03:34 +1000
4Subject: [PATCH 1/3] fdt: add memory bank decoding functions for board setup
5
6Add two functions for use by board implementations to decode the memory
7banks of the /memory node so as to populate the global data with
8ram_size and board info for memory banks.
9
10The fdtdec_setup_memory_size() function decodes the first memory bank
11and sets up the gd->ram_size with the size of the memory bank. This
12function should be called from the boards dram_init().
13
14The fdtdec_setup_memory_banksize() function decode the memory banks
15(up to the CONFIG_NR_DRAM_BANKS) and populates the base address and size
16into the gd->bd->bi_dram array of banks. This function should be called
17from the boards dram_init_banksize().
18
19Signed-off-by: Nathan Rossi <nathan@nathanrossi.com>
20Cc: Simon Glass <sjg@chromium.org>
21Cc: Michal Simek <monstr@monstr.eu>
22Reviewed-by: Simon Glass <sjg@chromium.org>
23Signed-off-by: Michal Simek <michal.simek@xilinx.com>
24Upstream-Status: Backport
25---
26 include/fdtdec.h | 34 ++++++++++++++++++++++++++++++++++
27 lib/fdtdec.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
28 2 files changed, 90 insertions(+)
29
30diff --git a/include/fdtdec.h b/include/fdtdec.h
31index 27887c8c21..d074478f14 100644
32--- a/include/fdtdec.h
33+++ b/include/fdtdec.h
34@@ -976,6 +976,40 @@ struct display_timing {
35 */
36 int fdtdec_decode_display_timing(const void *blob, int node, int index,
37 struct display_timing *config);
38+
39+/**
40+ * fdtdec_setup_memory_size() - decode and setup gd->ram_size
41+ *
42+ * Decode the /memory 'reg' property to determine the size of the first memory
43+ * bank, populate the global data with the size of the first bank of memory.
44+ *
45+ * This function should be called from a boards dram_init(). This helper
46+ * function allows for boards to query the device tree for DRAM size instead of
47+ * hard coding the value in the case where the memory size cannot be detected
48+ * automatically.
49+ *
50+ * @return 0 if OK, -EINVAL if the /memory node or reg property is missing or
51+ * invalid
52+ */
53+int fdtdec_setup_memory_size(void);
54+
55+/**
56+ * fdtdec_setup_memory_banksize() - decode and populate gd->bd->bi_dram
57+ *
58+ * Decode the /memory 'reg' property to determine the address and size of the
59+ * memory banks. Use this data to populate the global data board info with the
60+ * phys address and size of memory banks.
61+ *
62+ * This function should be called from a boards dram_init_banksize(). This
63+ * helper function allows for boards to query the device tree for memory bank
64+ * information instead of hard coding the information in cases where it cannot
65+ * be detected automatically.
66+ *
67+ * @return 0 if OK, -EINVAL if the /memory node or reg property is missing or
68+ * invalid
69+ */
70+int fdtdec_setup_memory_banksize(void);
71+
72 /**
73 * Set up the device tree ready for use
74 */
75diff --git a/lib/fdtdec.c b/lib/fdtdec.c
76index 4e619c49a2..81f47ef2c7 100644
77--- a/lib/fdtdec.c
78+++ b/lib/fdtdec.c
79@@ -1174,6 +1174,62 @@ int fdtdec_decode_display_timing(const void *blob, int parent, int index,
80 return ret;
81 }
82
83+int fdtdec_setup_memory_size(void)
84+{
85+ int ret, mem;
86+ struct fdt_resource res;
87+
88+ mem = fdt_path_offset(gd->fdt_blob, "/memory");
89+ if (mem < 0) {
90+ debug("%s: Missing /memory node\n", __func__);
91+ return -EINVAL;
92+ }
93+
94+ ret = fdt_get_resource(gd->fdt_blob, mem, "reg", 0, &res);
95+ if (ret != 0) {
96+ debug("%s: Unable to decode first memory bank\n", __func__);
97+ return -EINVAL;
98+ }
99+
100+ gd->ram_size = (phys_size_t)(res.end - res.start + 1);
101+ debug("%s: Initial DRAM size %llx\n", __func__, (u64)gd->ram_size);
102+
103+ return 0;
104+}
105+
106+#if defined(CONFIG_NR_DRAM_BANKS)
107+int fdtdec_setup_memory_banksize(void)
108+{
109+ int bank, ret, mem;
110+ struct fdt_resource res;
111+
112+ mem = fdt_path_offset(gd->fdt_blob, "/memory");
113+ if (mem < 0) {
114+ debug("%s: Missing /memory node\n", __func__);
115+ return -EINVAL;
116+ }
117+
118+ for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
119+ ret = fdt_get_resource(gd->fdt_blob, mem, "reg", bank, &res);
120+ if (ret == -FDT_ERR_NOTFOUND)
121+ break;
122+ if (ret != 0)
123+ return -EINVAL;
124+
125+ gd->bd->bi_dram[bank].start = (phys_addr_t)res.start;
126+ gd->bd->bi_dram[bank].size =
127+ (phys_size_t)(res.end - res.start + 1);
128+
129+ debug("%s: DRAM Bank #%d: start = 0x%llx, size = 0x%llx\n",
130+ __func__, bank,
131+ (unsigned long long)gd->bd->bi_dram[bank].start,
132+ (unsigned long long)gd->bd->bi_dram[bank].size);
133+ }
134+
135+ return 0;
136+}
137+#endif
138+
139 int fdtdec_setup(void)
140 {
141 #if CONFIG_IS_ENABLED(OF_CONTROL)
142--
1432.11.0
144
diff --git a/recipes-bsp/u-boot/u-boot/0002-ARM-zynq-Replace-board-specific-with-generic-memory-.patch b/recipes-bsp/u-boot/u-boot/0002-ARM-zynq-Replace-board-specific-with-generic-memory-.patch
new file mode 100644
index 00000000..41806966
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot/0002-ARM-zynq-Replace-board-specific-with-generic-memory-.patch
@@ -0,0 +1,170 @@
1From de9bf1b591a80ef8fce8cad5c3d5a1139d136a77 Mon Sep 17 00:00:00 2001
2From: Nathan Rossi <nathan@nathanrossi.com>
3Date: Mon, 19 Dec 2016 00:03:34 +1000
4Subject: [PATCH 2/3] ARM: zynq: Replace board specific with generic memory
5 bank decoding
6
7The dram_init and dram_init_banksize functions were using a board
8specific implementation for decoding the memory banks from the fdt. This
9board specific implementation uses a static variable 'tmp' which makes
10these functions unsafe for execution from within the board_init_f
11context.
12
13This unsafe use of a static variable was causing a specific bug when
14using the zynq_zybo configuration, U-Boot would generate the following
15error during image load. This was caused due to dram_init overwriting
16the relocations for the 'image' variable within the do_bootm function.
17Out of coincidence the un-initialized memory has a compression type
18which is the same as the value for the relocation type R_ARM_RELATIVE.
19
20 Uncompressing Invalid Image ... Unimplemented compression type 23
21
22It should be noted that this is just one way the issue could surface,
23other cases my not be observed in normal boot flow. Depending on the
24size of various sections, and location of relocations within __rel_dyn
25and the compiler/linker the outcome of this bug can differ greatly.
26
27This change makes the dram_init* functions use a generic implementation
28of decoding and populating memory bank and size data.
29
30Signed-off-by: Nathan Rossi <nathan@nathanrossi.com>
31Fixes: 758f29d0f8 ("ARM: zynq: Support systems with more memory banks")
32Cc: Michal Simek <monstr@monstr.eu>
33Signed-off-by: Michal Simek <michal.simek@xilinx.com>
34Upstream-Status: Backport
35---
36 board/xilinx/zynq/board.c | 112 ++--------------------------------------------
37 1 file changed, 3 insertions(+), 109 deletions(-)
38
39diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c
40index 2c86940957..5cd9bbf711 100644
41--- a/board/xilinx/zynq/board.c
42+++ b/board/xilinx/zynq/board.c
43@@ -124,121 +124,15 @@ int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
44 }
45
46 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
47-/*
48- * fdt_get_reg - Fill buffer by information from DT
49- */
50-static phys_size_t fdt_get_reg(const void *fdt, int nodeoffset, void *buf,
51- const u32 *cell, int n)
52-{
53- int i = 0, b, banks;
54- int parent_offset = fdt_parent_offset(fdt, nodeoffset);
55- int address_cells = fdt_address_cells(fdt, parent_offset);
56- int size_cells = fdt_size_cells(fdt, parent_offset);
57- char *p = buf;
58- u64 val;
59- u64 vals;
60-
61- debug("%s: addr_cells=%x, size_cell=%x, buf=%p, cell=%p\n",
62- __func__, address_cells, size_cells, buf, cell);
63-
64- /* Check memory bank setup */
65- banks = n % (address_cells + size_cells);
66- if (banks)
67- panic("Incorrect memory setup cells=%d, ac=%d, sc=%d\n",
68- n, address_cells, size_cells);
69-
70- banks = n / (address_cells + size_cells);
71-
72- for (b = 0; b < banks; b++) {
73- debug("%s: Bank #%d:\n", __func__, b);
74- if (address_cells == 2) {
75- val = cell[i + 1];
76- val <<= 32;
77- val |= cell[i];
78- val = fdt64_to_cpu(val);
79- debug("%s: addr64=%llx, ptr=%p, cell=%p\n",
80- __func__, val, p, &cell[i]);
81- *(phys_addr_t *)p = val;
82- } else {
83- debug("%s: addr32=%x, ptr=%p\n",
84- __func__, fdt32_to_cpu(cell[i]), p);
85- *(phys_addr_t *)p = fdt32_to_cpu(cell[i]);
86- }
87- p += sizeof(phys_addr_t);
88- i += address_cells;
89-
90- debug("%s: pa=%p, i=%x, size=%zu\n", __func__, p, i,
91- sizeof(phys_addr_t));
92-
93- if (size_cells == 2) {
94- vals = cell[i + 1];
95- vals <<= 32;
96- vals |= cell[i];
97- vals = fdt64_to_cpu(vals);
98-
99- debug("%s: size64=%llx, ptr=%p, cell=%p\n",
100- __func__, vals, p, &cell[i]);
101- *(phys_size_t *)p = vals;
102- } else {
103- debug("%s: size32=%x, ptr=%p\n",
104- __func__, fdt32_to_cpu(cell[i]), p);
105- *(phys_size_t *)p = fdt32_to_cpu(cell[i]);
106- }
107- p += sizeof(phys_size_t);
108- i += size_cells;
109-
110- debug("%s: ps=%p, i=%x, size=%zu\n",
111- __func__, p, i, sizeof(phys_size_t));
112- }
113-
114- /* Return the first address size */
115- return *(phys_size_t *)((char *)buf + sizeof(phys_addr_t));
116-}
117-
118-#define FDT_REG_SIZE sizeof(u32)
119-/* Temp location for sharing data for storing */
120-/* Up to 64-bit address + 64-bit size */
121-static u8 tmp[CONFIG_NR_DRAM_BANKS * 16];
122-
123 void dram_init_banksize(void)
124 {
125- int bank;
126-
127- memcpy(&gd->bd->bi_dram[0], &tmp, sizeof(tmp));
128-
129- for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
130- debug("Bank #%d: start %llx\n", bank,
131- (unsigned long long)gd->bd->bi_dram[bank].start);
132- debug("Bank #%d: size %llx\n", bank,
133- (unsigned long long)gd->bd->bi_dram[bank].size);
134- }
135+ fdtdec_setup_memory_banksize();
136 }
137
138 int dram_init(void)
139 {
140- int node, len;
141- const void *blob = gd->fdt_blob;
142- const u32 *cell;
143-
144- memset(&tmp, 0, sizeof(tmp));
145-
146- /* find or create "/memory" node. */
147- node = fdt_subnode_offset(blob, 0, "memory");
148- if (node < 0) {
149- printf("%s: Can't get memory node\n", __func__);
150- return node;
151- }
152-
153- /* Get pointer to cells and lenght of it */
154- cell = fdt_getprop(blob, node, "reg", &len);
155- if (!cell) {
156- printf("%s: Can't get reg property\n", __func__);
157- return -1;
158- }
159-
160- gd->ram_size = fdt_get_reg(blob, node, &tmp, cell, len / FDT_REG_SIZE);
161-
162- debug("%s: Initial DRAM size %llx\n", __func__, (u64)gd->ram_size);
163+ if (fdtdec_setup_memory_size() != 0)
164+ return -EINVAL;
165
166 zynq_ddrc_init();
167
168--
1692.11.0
170
diff --git a/recipes-bsp/u-boot/u-boot/0003-ARM64-zynqmp-Replace-board-specific-with-generic-mem.patch b/recipes-bsp/u-boot/u-boot/0003-ARM64-zynqmp-Replace-board-specific-with-generic-mem.patch
new file mode 100644
index 00000000..2e6e9e31
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot/0003-ARM64-zynqmp-Replace-board-specific-with-generic-mem.patch
@@ -0,0 +1,156 @@
1From 950f86ca38325c9ae7874895d2cdbdda5496e712 Mon Sep 17 00:00:00 2001
2From: Nathan Rossi <nathan@nathanrossi.com>
3Date: Mon, 19 Dec 2016 00:03:34 +1000
4Subject: [PATCH 3/3] ARM64: zynqmp: Replace board specific with generic memory
5 bank decoding
6
7The dram_init and dram_init_banksize functions were using a board
8specific implementation for decoding the memory banks from the fdt. This
9board specific implementation uses a static variable 'tmp' which makes
10these functions unsafe for execution from within the board_init_f
11context.
12
13This change makes the dram_init* functions use a generic implementation
14of decoding and populating memory bank and size data.
15
16Signed-off-by: Nathan Rossi <nathan@nathanrossi.com>
17Fixes: 8d59d7f63b ("ARM64: zynqmp: Read RAM information from DT")
18Cc: Michal Simek <michal.simek@xilinx.com>
19Signed-off-by: Michal Simek <michal.simek@xilinx.com>
20Upstream-Status: Backport
21---
22 board/xilinx/zynqmp/zynqmp.c | 112 ++-----------------------------------------
23 1 file changed, 3 insertions(+), 109 deletions(-)
24
25diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
26index a23c38acd9..4e5871b76a 100644
27--- a/board/xilinx/zynqmp/zynqmp.c
28+++ b/board/xilinx/zynqmp/zynqmp.c
29@@ -180,121 +180,15 @@ int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
30 }
31
32 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
33-/*
34- * fdt_get_reg - Fill buffer by information from DT
35- */
36-static phys_size_t fdt_get_reg(const void *fdt, int nodeoffset, void *buf,
37- const u32 *cell, int n)
38-{
39- int i = 0, b, banks;
40- int parent_offset = fdt_parent_offset(fdt, nodeoffset);
41- int address_cells = fdt_address_cells(fdt, parent_offset);
42- int size_cells = fdt_size_cells(fdt, parent_offset);
43- char *p = buf;
44- u64 val;
45- u64 vals;
46-
47- debug("%s: addr_cells=%x, size_cell=%x, buf=%p, cell=%p\n",
48- __func__, address_cells, size_cells, buf, cell);
49-
50- /* Check memory bank setup */
51- banks = n % (address_cells + size_cells);
52- if (banks)
53- panic("Incorrect memory setup cells=%d, ac=%d, sc=%d\n",
54- n, address_cells, size_cells);
55-
56- banks = n / (address_cells + size_cells);
57-
58- for (b = 0; b < banks; b++) {
59- debug("%s: Bank #%d:\n", __func__, b);
60- if (address_cells == 2) {
61- val = cell[i + 1];
62- val <<= 32;
63- val |= cell[i];
64- val = fdt64_to_cpu(val);
65- debug("%s: addr64=%llx, ptr=%p, cell=%p\n",
66- __func__, val, p, &cell[i]);
67- *(phys_addr_t *)p = val;
68- } else {
69- debug("%s: addr32=%x, ptr=%p\n",
70- __func__, fdt32_to_cpu(cell[i]), p);
71- *(phys_addr_t *)p = fdt32_to_cpu(cell[i]);
72- }
73- p += sizeof(phys_addr_t);
74- i += address_cells;
75-
76- debug("%s: pa=%p, i=%x, size=%zu\n", __func__, p, i,
77- sizeof(phys_addr_t));
78-
79- if (size_cells == 2) {
80- vals = cell[i + 1];
81- vals <<= 32;
82- vals |= cell[i];
83- vals = fdt64_to_cpu(vals);
84-
85- debug("%s: size64=%llx, ptr=%p, cell=%p\n",
86- __func__, vals, p, &cell[i]);
87- *(phys_size_t *)p = vals;
88- } else {
89- debug("%s: size32=%x, ptr=%p\n",
90- __func__, fdt32_to_cpu(cell[i]), p);
91- *(phys_size_t *)p = fdt32_to_cpu(cell[i]);
92- }
93- p += sizeof(phys_size_t);
94- i += size_cells;
95-
96- debug("%s: ps=%p, i=%x, size=%zu\n",
97- __func__, p, i, sizeof(phys_size_t));
98- }
99-
100- /* Return the first address size */
101- return *(phys_size_t *)((char *)buf + sizeof(phys_addr_t));
102-}
103-
104-#define FDT_REG_SIZE sizeof(u32)
105-/* Temp location for sharing data for storing */
106-/* Up to 64-bit address + 64-bit size */
107-static u8 tmp[CONFIG_NR_DRAM_BANKS * 16];
108-
109 void dram_init_banksize(void)
110 {
111- int bank;
112-
113- memcpy(&gd->bd->bi_dram[0], &tmp, sizeof(tmp));
114-
115- for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
116- debug("Bank #%d: start %llx\n", bank,
117- (unsigned long long)gd->bd->bi_dram[bank].start);
118- debug("Bank #%d: size %llx\n", bank,
119- (unsigned long long)gd->bd->bi_dram[bank].size);
120- }
121+ fdtdec_setup_memory_banksize();
122 }
123
124 int dram_init(void)
125 {
126- int node, len;
127- const void *blob = gd->fdt_blob;
128- const u32 *cell;
129-
130- memset(&tmp, 0, sizeof(tmp));
131-
132- /* find or create "/memory" node. */
133- node = fdt_subnode_offset(blob, 0, "memory");
134- if (node < 0) {
135- printf("%s: Can't get memory node\n", __func__);
136- return node;
137- }
138-
139- /* Get pointer to cells and lenght of it */
140- cell = fdt_getprop(blob, node, "reg", &len);
141- if (!cell) {
142- printf("%s: Can't get reg property\n", __func__);
143- return -1;
144- }
145-
146- gd->ram_size = fdt_get_reg(blob, node, &tmp, cell, len / FDT_REG_SIZE);
147-
148- debug("%s: Initial DRAM size %llx\n", __func__, (u64)gd->ram_size);
149+ if (fdtdec_setup_memory_size() != 0)
150+ return -EINVAL;
151
152 return 0;
153 }
154--
1552.11.0
156