diff options
-rw-r--r-- | arch/arm/boot/compressed/atags_to_fdt.c | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/arch/arm/boot/compressed/atags_to_fdt.c b/arch/arm/boot/compressed/atags_to_fdt.c index aabc02a68482..d1153c8a765a 100644 --- a/arch/arm/boot/compressed/atags_to_fdt.c +++ b/arch/arm/boot/compressed/atags_to_fdt.c | |||
@@ -53,6 +53,17 @@ static const void *getprop(const void *fdt, const char *node_path, | |||
53 | return fdt_getprop(fdt, offset, property, len); | 53 | return fdt_getprop(fdt, offset, property, len); |
54 | } | 54 | } |
55 | 55 | ||
56 | static uint32_t get_cell_size(const void *fdt) | ||
57 | { | ||
58 | int len; | ||
59 | uint32_t cell_size = 1; | ||
60 | const uint32_t *size_len = getprop(fdt, "/", "#size-cells", &len); | ||
61 | |||
62 | if (size_len) | ||
63 | cell_size = fdt32_to_cpu(*size_len); | ||
64 | return cell_size; | ||
65 | } | ||
66 | |||
56 | static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline) | 67 | static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline) |
57 | { | 68 | { |
58 | char cmdline[COMMAND_LINE_SIZE]; | 69 | char cmdline[COMMAND_LINE_SIZE]; |
@@ -95,9 +106,11 @@ static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline) | |||
95 | int atags_to_fdt(void *atag_list, void *fdt, int total_space) | 106 | int atags_to_fdt(void *atag_list, void *fdt, int total_space) |
96 | { | 107 | { |
97 | struct tag *atag = atag_list; | 108 | struct tag *atag = atag_list; |
98 | uint32_t mem_reg_property[2 * NR_BANKS]; | 109 | /* In the case of 64 bits memory size, need to reserve 2 cells for |
110 | * address and size for each bank */ | ||
111 | uint32_t mem_reg_property[2 * 2 * NR_BANKS]; | ||
99 | int memcount = 0; | 112 | int memcount = 0; |
100 | int ret; | 113 | int ret, memsize; |
101 | 114 | ||
102 | /* make sure we've got an aligned pointer */ | 115 | /* make sure we've got an aligned pointer */ |
103 | if ((u32)atag_list & 0x3) | 116 | if ((u32)atag_list & 0x3) |
@@ -137,8 +150,25 @@ int atags_to_fdt(void *atag_list, void *fdt, int total_space) | |||
137 | continue; | 150 | continue; |
138 | if (!atag->u.mem.size) | 151 | if (!atag->u.mem.size) |
139 | continue; | 152 | continue; |
140 | mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start); | 153 | memsize = get_cell_size(fdt); |
141 | mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size); | 154 | |
155 | if (memsize == 2) { | ||
156 | /* if memsize is 2, that means that | ||
157 | * each data needs 2 cells of 32 bits, | ||
158 | * so the data are 64 bits */ | ||
159 | uint64_t *mem_reg_prop64 = | ||
160 | (uint64_t *)mem_reg_property; | ||
161 | mem_reg_prop64[memcount++] = | ||
162 | cpu_to_fdt64(atag->u.mem.start); | ||
163 | mem_reg_prop64[memcount++] = | ||
164 | cpu_to_fdt64(atag->u.mem.size); | ||
165 | } else { | ||
166 | mem_reg_property[memcount++] = | ||
167 | cpu_to_fdt32(atag->u.mem.start); | ||
168 | mem_reg_property[memcount++] = | ||
169 | cpu_to_fdt32(atag->u.mem.size); | ||
170 | } | ||
171 | |||
142 | } else if (atag->hdr.tag == ATAG_INITRD2) { | 172 | } else if (atag->hdr.tag == ATAG_INITRD2) { |
143 | uint32_t initrd_start, initrd_size; | 173 | uint32_t initrd_start, initrd_size; |
144 | initrd_start = atag->u.initrd.start; | 174 | initrd_start = atag->u.initrd.start; |
@@ -150,8 +180,10 @@ int atags_to_fdt(void *atag_list, void *fdt, int total_space) | |||
150 | } | 180 | } |
151 | } | 181 | } |
152 | 182 | ||
153 | if (memcount) | 183 | if (memcount) { |
154 | setprop(fdt, "/memory", "reg", mem_reg_property, 4*memcount); | 184 | setprop(fdt, "/memory", "reg", mem_reg_property, |
185 | 4 * memcount * memsize); | ||
186 | } | ||
155 | 187 | ||
156 | return fdt_pack(fdt); | 188 | return fdt_pack(fdt); |
157 | } | 189 | } |