diff options
author | Nathan Rossi <nathan@nathanrossi.com> | 2016-12-20 19:20:42 +1000 |
---|---|---|
committer | Nathan Rossi <nathan@nathanrossi.com> | 2016-12-21 22:05:09 +1000 |
commit | 3e2319675cf104b2183261aad63acc095f114657 (patch) | |
tree | 4d0320a88f742036bcf9ca796b1e4867dffef198 | |
parent | 47f17c451a534cb8a7d7360ea6f97a6c9f6be798 (diff) | |
download | meta-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>
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" | |||
7 | PV = "v2016.07-xilinx-${XILINX_RELEASE_VERSION}+git${SRCPV}" | 7 | PV = "v2016.07-xilinx-${XILINX_RELEASE_VERSION}+git${SRCPV}" |
8 | 8 | ||
9 | FILESEXTRAPATHS_prepend := "${THISDIR}/u-boot-xlnx:" | 9 | FILESEXTRAPATHS_prepend := "${THISDIR}/u-boot-xlnx:" |
10 | FILESEXTRAPATHS_prepend := "${THISDIR}/u-boot:" | ||
11 | |||
12 | SRC_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 | ||
11 | SRC_URI_append_kc705-microblazeel = " file://microblaze-kc705-Convert-microblaze-generic-to-k.patch" | 18 | SRC_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 @@ | |||
1 | From 623f60198b38c4fdae596038cd5956e44b6224a4 Mon Sep 17 00:00:00 2001 | ||
2 | From: Nathan Rossi <nathan@nathanrossi.com> | ||
3 | Date: Mon, 19 Dec 2016 00:03:34 +1000 | ||
4 | Subject: [PATCH 1/3] fdt: add memory bank decoding functions for board setup | ||
5 | |||
6 | Add two functions for use by board implementations to decode the memory | ||
7 | banks of the /memory node so as to populate the global data with | ||
8 | ram_size and board info for memory banks. | ||
9 | |||
10 | The fdtdec_setup_memory_size() function decodes the first memory bank | ||
11 | and sets up the gd->ram_size with the size of the memory bank. This | ||
12 | function should be called from the boards dram_init(). | ||
13 | |||
14 | The fdtdec_setup_memory_banksize() function decode the memory banks | ||
15 | (up to the CONFIG_NR_DRAM_BANKS) and populates the base address and size | ||
16 | into the gd->bd->bi_dram array of banks. This function should be called | ||
17 | from the boards dram_init_banksize(). | ||
18 | |||
19 | Signed-off-by: Nathan Rossi <nathan@nathanrossi.com> | ||
20 | Cc: Simon Glass <sjg@chromium.org> | ||
21 | Cc: Michal Simek <monstr@monstr.eu> | ||
22 | Reviewed-by: Simon Glass <sjg@chromium.org> | ||
23 | Signed-off-by: Michal Simek <michal.simek@xilinx.com> | ||
24 | Upstream-Status: Backport | ||
25 | --- | ||
26 | include/fdtdec.h | 34 ++++++++++++++++++++++++++++++++++ | ||
27 | lib/fdtdec.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
28 | 2 files changed, 90 insertions(+) | ||
29 | |||
30 | diff --git a/include/fdtdec.h b/include/fdtdec.h | ||
31 | index 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 | */ | ||
75 | diff --git a/lib/fdtdec.c b/lib/fdtdec.c | ||
76 | index 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 | -- | ||
143 | 2.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 @@ | |||
1 | From de9bf1b591a80ef8fce8cad5c3d5a1139d136a77 Mon Sep 17 00:00:00 2001 | ||
2 | From: Nathan Rossi <nathan@nathanrossi.com> | ||
3 | Date: Mon, 19 Dec 2016 00:03:34 +1000 | ||
4 | Subject: [PATCH 2/3] ARM: zynq: Replace board specific with generic memory | ||
5 | bank decoding | ||
6 | |||
7 | The dram_init and dram_init_banksize functions were using a board | ||
8 | specific implementation for decoding the memory banks from the fdt. This | ||
9 | board specific implementation uses a static variable 'tmp' which makes | ||
10 | these functions unsafe for execution from within the board_init_f | ||
11 | context. | ||
12 | |||
13 | This unsafe use of a static variable was causing a specific bug when | ||
14 | using the zynq_zybo configuration, U-Boot would generate the following | ||
15 | error during image load. This was caused due to dram_init overwriting | ||
16 | the relocations for the 'image' variable within the do_bootm function. | ||
17 | Out of coincidence the un-initialized memory has a compression type | ||
18 | which is the same as the value for the relocation type R_ARM_RELATIVE. | ||
19 | |||
20 | Uncompressing Invalid Image ... Unimplemented compression type 23 | ||
21 | |||
22 | It should be noted that this is just one way the issue could surface, | ||
23 | other cases my not be observed in normal boot flow. Depending on the | ||
24 | size of various sections, and location of relocations within __rel_dyn | ||
25 | and the compiler/linker the outcome of this bug can differ greatly. | ||
26 | |||
27 | This change makes the dram_init* functions use a generic implementation | ||
28 | of decoding and populating memory bank and size data. | ||
29 | |||
30 | Signed-off-by: Nathan Rossi <nathan@nathanrossi.com> | ||
31 | Fixes: 758f29d0f8 ("ARM: zynq: Support systems with more memory banks") | ||
32 | Cc: Michal Simek <monstr@monstr.eu> | ||
33 | Signed-off-by: Michal Simek <michal.simek@xilinx.com> | ||
34 | Upstream-Status: Backport | ||
35 | --- | ||
36 | board/xilinx/zynq/board.c | 112 ++-------------------------------------------- | ||
37 | 1 file changed, 3 insertions(+), 109 deletions(-) | ||
38 | |||
39 | diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c | ||
40 | index 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 | -- | ||
169 | 2.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 @@ | |||
1 | From 950f86ca38325c9ae7874895d2cdbdda5496e712 Mon Sep 17 00:00:00 2001 | ||
2 | From: Nathan Rossi <nathan@nathanrossi.com> | ||
3 | Date: Mon, 19 Dec 2016 00:03:34 +1000 | ||
4 | Subject: [PATCH 3/3] ARM64: zynqmp: Replace board specific with generic memory | ||
5 | bank decoding | ||
6 | |||
7 | The dram_init and dram_init_banksize functions were using a board | ||
8 | specific implementation for decoding the memory banks from the fdt. This | ||
9 | board specific implementation uses a static variable 'tmp' which makes | ||
10 | these functions unsafe for execution from within the board_init_f | ||
11 | context. | ||
12 | |||
13 | This change makes the dram_init* functions use a generic implementation | ||
14 | of decoding and populating memory bank and size data. | ||
15 | |||
16 | Signed-off-by: Nathan Rossi <nathan@nathanrossi.com> | ||
17 | Fixes: 8d59d7f63b ("ARM64: zynqmp: Read RAM information from DT") | ||
18 | Cc: Michal Simek <michal.simek@xilinx.com> | ||
19 | Signed-off-by: Michal Simek <michal.simek@xilinx.com> | ||
20 | Upstream-Status: Backport | ||
21 | --- | ||
22 | board/xilinx/zynqmp/zynqmp.c | 112 ++----------------------------------------- | ||
23 | 1 file changed, 3 insertions(+), 109 deletions(-) | ||
24 | |||
25 | diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c | ||
26 | index 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 | -- | ||
155 | 2.11.0 | ||
156 | |||