diff options
author | Sonic Zhang <sonic.zhang@analog.com> | 2008-07-19 03:42:41 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2008-07-19 03:42:41 -0400 |
commit | 262c3825a9f3eb0f4f30ebb4b1ee57397bcb3ffc (patch) | |
tree | fb5402f0de002d3e7a6671820228a2b9808d831f /arch/blackfin/kernel | |
parent | bafcc1b97323261a42d47960db99947bcc1be133 (diff) |
Blackfin arch: Extend sram malloc to handle L2 SRAM.
Extend system call to alloc L2 SRAM in application.
Automatically move following sections to L2 SRAM:
1. kernel built-in l2 attribute section
2. kernel module l2 attribute section
3. elf-fdpic application l2 attribute section
Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r-- | arch/blackfin/kernel/module.c | 74 | ||||
-rw-r--r-- | arch/blackfin/kernel/setup.c | 10 | ||||
-rw-r--r-- | arch/blackfin/kernel/vmlinux.lds.S | 40 |
3 files changed, 104 insertions, 20 deletions
diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c index 14a42848f37f..e1bebc80a5bf 100644 --- a/arch/blackfin/kernel/module.c +++ b/arch/blackfin/kernel/module.c | |||
@@ -173,7 +173,7 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, | |||
173 | for (s = sechdrs; s < sechdrs_end; ++s) { | 173 | for (s = sechdrs; s < sechdrs_end; ++s) { |
174 | if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) || | 174 | if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) || |
175 | ((strcmp(".text", secstrings + s->sh_name) == 0) && | 175 | ((strcmp(".text", secstrings + s->sh_name) == 0) && |
176 | (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) { | 176 | (hdr->e_flags & EF_BFIN_CODE_IN_L1) && (s->sh_size > 0))) { |
177 | dest = l1_inst_sram_alloc(s->sh_size); | 177 | dest = l1_inst_sram_alloc(s->sh_size); |
178 | mod->arch.text_l1 = dest; | 178 | mod->arch.text_l1 = dest; |
179 | if (dest == NULL) { | 179 | if (dest == NULL) { |
@@ -188,7 +188,7 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, | |||
188 | } | 188 | } |
189 | if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) || | 189 | if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) || |
190 | ((strcmp(".data", secstrings + s->sh_name) == 0) && | 190 | ((strcmp(".data", secstrings + s->sh_name) == 0) && |
191 | (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { | 191 | (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) { |
192 | dest = l1_data_sram_alloc(s->sh_size); | 192 | dest = l1_data_sram_alloc(s->sh_size); |
193 | mod->arch.data_a_l1 = dest; | 193 | mod->arch.data_a_l1 = dest; |
194 | if (dest == NULL) { | 194 | if (dest == NULL) { |
@@ -203,7 +203,7 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, | |||
203 | } | 203 | } |
204 | if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 || | 204 | if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 || |
205 | ((strcmp(".bss", secstrings + s->sh_name) == 0) && | 205 | ((strcmp(".bss", secstrings + s->sh_name) == 0) && |
206 | (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { | 206 | (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) { |
207 | dest = l1_data_sram_alloc(s->sh_size); | 207 | dest = l1_data_sram_alloc(s->sh_size); |
208 | mod->arch.bss_a_l1 = dest; | 208 | mod->arch.bss_a_l1 = dest; |
209 | if (dest == NULL) { | 209 | if (dest == NULL) { |
@@ -242,6 +242,51 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, | |||
242 | s->sh_flags &= ~SHF_ALLOC; | 242 | s->sh_flags &= ~SHF_ALLOC; |
243 | s->sh_addr = (unsigned long)dest; | 243 | s->sh_addr = (unsigned long)dest; |
244 | } | 244 | } |
245 | if ((strcmp(".l2.text", secstrings + s->sh_name) == 0) || | ||
246 | ((strcmp(".text", secstrings + s->sh_name) == 0) && | ||
247 | (hdr->e_flags & EF_BFIN_CODE_IN_L2) && (s->sh_size > 0))) { | ||
248 | dest = l2_sram_alloc(s->sh_size); | ||
249 | mod->arch.text_l2 = dest; | ||
250 | if (dest == NULL) { | ||
251 | printk(KERN_ERR | ||
252 | "module %s: L2 SRAM allocation failed\n", | ||
253 | mod->name); | ||
254 | return -1; | ||
255 | } | ||
256 | memcpy(dest, (void *)s->sh_addr, s->sh_size); | ||
257 | s->sh_flags &= ~SHF_ALLOC; | ||
258 | s->sh_addr = (unsigned long)dest; | ||
259 | } | ||
260 | if ((strcmp(".l2.data", secstrings + s->sh_name) == 0) || | ||
261 | ((strcmp(".data", secstrings + s->sh_name) == 0) && | ||
262 | (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) { | ||
263 | dest = l2_sram_alloc(s->sh_size); | ||
264 | mod->arch.data_l2 = dest; | ||
265 | if (dest == NULL) { | ||
266 | printk(KERN_ERR | ||
267 | "module %s: L2 SRAM allocation failed\n", | ||
268 | mod->name); | ||
269 | return -1; | ||
270 | } | ||
271 | memcpy(dest, (void *)s->sh_addr, s->sh_size); | ||
272 | s->sh_flags &= ~SHF_ALLOC; | ||
273 | s->sh_addr = (unsigned long)dest; | ||
274 | } | ||
275 | if (strcmp(".l2.bss", secstrings + s->sh_name) == 0 || | ||
276 | ((strcmp(".bss", secstrings + s->sh_name) == 0) && | ||
277 | (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) { | ||
278 | dest = l2_sram_alloc(s->sh_size); | ||
279 | mod->arch.bss_l2 = dest; | ||
280 | if (dest == NULL) { | ||
281 | printk(KERN_ERR | ||
282 | "module %s: L2 SRAM allocation failed\n", | ||
283 | mod->name); | ||
284 | return -1; | ||
285 | } | ||
286 | memset(dest, 0, s->sh_size); | ||
287 | s->sh_flags &= ~SHF_ALLOC; | ||
288 | s->sh_addr = (unsigned long)dest; | ||
289 | } | ||
245 | } | 290 | } |
246 | return 0; | 291 | return 0; |
247 | } | 292 | } |
@@ -411,9 +456,10 @@ module_finalize(const Elf_Ehdr * hdr, | |||
411 | continue; | 456 | continue; |
412 | 457 | ||
413 | if ((sechdrs[i].sh_type == SHT_RELA) && | 458 | if ((sechdrs[i].sh_type == SHT_RELA) && |
414 | ((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) || | 459 | ((strcmp(".rela.l2.text", secstrings + sechdrs[i].sh_name) == 0) || |
460 | (strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) || | ||
415 | ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) && | 461 | ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) && |
416 | (hdr->e_flags & FLG_CODE_IN_L1)))) { | 462 | (hdr->e_flags & (EF_BFIN_CODE_IN_L1|EF_BFIN_CODE_IN_L2))))) { |
417 | apply_relocate_add((Elf_Shdr *) sechdrs, strtab, | 463 | apply_relocate_add((Elf_Shdr *) sechdrs, strtab, |
418 | symindex, i, mod); | 464 | symindex, i, mod); |
419 | } | 465 | } |
@@ -423,14 +469,12 @@ module_finalize(const Elf_Ehdr * hdr, | |||
423 | 469 | ||
424 | void module_arch_cleanup(struct module *mod) | 470 | void module_arch_cleanup(struct module *mod) |
425 | { | 471 | { |
426 | if (mod->arch.text_l1) | 472 | l1_inst_sram_free(mod->arch.text_l1); |
427 | l1_inst_sram_free((void *)mod->arch.text_l1); | 473 | l1_data_A_sram_free(mod->arch.data_a_l1); |
428 | if (mod->arch.data_a_l1) | 474 | l1_data_A_sram_free(mod->arch.bss_a_l1); |
429 | l1_data_sram_free((void *)mod->arch.data_a_l1); | 475 | l1_data_B_sram_free(mod->arch.data_b_l1); |
430 | if (mod->arch.bss_a_l1) | 476 | l1_data_B_sram_free(mod->arch.bss_b_l1); |
431 | l1_data_sram_free((void *)mod->arch.bss_a_l1); | 477 | l2_sram_free(mod->arch.text_l2); |
432 | if (mod->arch.data_b_l1) | 478 | l2_sram_free(mod->arch.data_l2); |
433 | l1_data_B_sram_free((void *)mod->arch.data_b_l1); | 479 | l2_sram_free(mod->arch.bss_l2); |
434 | if (mod->arch.bss_b_l1) | ||
435 | l1_data_B_sram_free((void *)mod->arch.bss_b_l1); | ||
436 | } | 480 | } |
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 861a1db74df8..8671d1db1f99 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c | |||
@@ -104,6 +104,7 @@ void __init bf53x_relocate_l1_mem(void) | |||
104 | unsigned long l1_code_length; | 104 | unsigned long l1_code_length; |
105 | unsigned long l1_data_a_length; | 105 | unsigned long l1_data_a_length; |
106 | unsigned long l1_data_b_length; | 106 | unsigned long l1_data_b_length; |
107 | unsigned long l2_length; | ||
107 | 108 | ||
108 | l1_code_length = _etext_l1 - _stext_l1; | 109 | l1_code_length = _etext_l1 - _stext_l1; |
109 | if (l1_code_length > L1_CODE_LENGTH) | 110 | if (l1_code_length > L1_CODE_LENGTH) |
@@ -129,6 +130,15 @@ void __init bf53x_relocate_l1_mem(void) | |||
129 | /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */ | 130 | /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */ |
130 | dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + | 131 | dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + |
131 | l1_data_a_length, l1_data_b_length); | 132 | l1_data_a_length, l1_data_b_length); |
133 | |||
134 | #ifdef L2_LENGTH | ||
135 | l2_length = _ebss_l2 - _stext_l2; | ||
136 | if (l2_length > L2_LENGTH) | ||
137 | panic("L2 SRAM Overflow\n"); | ||
138 | |||
139 | /* Copy _stext_l2 to _edata_l2 to L2 SRAM */ | ||
140 | dma_memcpy(_stext_l2, _l2_lma_start, l2_length); | ||
141 | #endif | ||
132 | } | 142 | } |
133 | 143 | ||
134 | /* add_memory_region to memmap */ | 144 | /* add_memory_region to memmap */ |
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index 3ecc64cab3be..0896e38d6108 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S | |||
@@ -101,6 +101,11 @@ SECTIONS | |||
101 | #if !L1_DATA_B_LENGTH | 101 | #if !L1_DATA_B_LENGTH |
102 | *(.l1.data.B) | 102 | *(.l1.data.B) |
103 | #endif | 103 | #endif |
104 | #ifndef L2_LENGTH | ||
105 | . = ALIGN(32); | ||
106 | *(.data_l2.cacheline_aligned) | ||
107 | *(.l2.data) | ||
108 | #endif | ||
104 | 109 | ||
105 | DATA_DATA | 110 | DATA_DATA |
106 | *(.data.*) | 111 | *(.data.*) |
@@ -182,14 +187,13 @@ SECTIONS | |||
182 | *(.l1.data) | 187 | *(.l1.data) |
183 | __edata_l1 = .; | 188 | __edata_l1 = .; |
184 | 189 | ||
185 | . = ALIGN(4); | ||
186 | __sbss_l1 = .; | ||
187 | *(.l1.bss) | ||
188 | |||
189 | . = ALIGN(32); | 190 | . = ALIGN(32); |
190 | *(.data_l1.cacheline_aligned) | 191 | *(.data_l1.cacheline_aligned) |
191 | 192 | ||
192 | . = ALIGN(4); | 193 | . = ALIGN(4); |
194 | __sbss_l1 = .; | ||
195 | *(.l1.bss) | ||
196 | . = ALIGN(4); | ||
193 | __ebss_l1 = .; | 197 | __ebss_l1 = .; |
194 | } | 198 | } |
195 | 199 | ||
@@ -203,11 +207,37 @@ SECTIONS | |||
203 | . = ALIGN(4); | 207 | . = ALIGN(4); |
204 | __sbss_b_l1 = .; | 208 | __sbss_b_l1 = .; |
205 | *(.l1.bss.B) | 209 | *(.l1.bss.B) |
206 | |||
207 | . = ALIGN(4); | 210 | . = ALIGN(4); |
208 | __ebss_b_l1 = .; | 211 | __ebss_b_l1 = .; |
209 | } | 212 | } |
210 | 213 | ||
214 | #ifdef L2_LENGTH | ||
215 | __l2_lma_start = .; | ||
216 | |||
217 | .text_data_l2 L2_START : AT(LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1)) | ||
218 | { | ||
219 | . = ALIGN(4); | ||
220 | __stext_l2 = .; | ||
221 | *(.l1.text) | ||
222 | . = ALIGN(4); | ||
223 | __etext_l2 = .; | ||
224 | |||
225 | . = ALIGN(4); | ||
226 | __sdata_l2 = .; | ||
227 | *(.l1.data) | ||
228 | __edata_l2 = .; | ||
229 | |||
230 | . = ALIGN(32); | ||
231 | *(.data_l2.cacheline_aligned) | ||
232 | |||
233 | . = ALIGN(4); | ||
234 | __sbss_l2 = .; | ||
235 | *(.l1.bss) | ||
236 | . = ALIGN(4); | ||
237 | __ebss_l2 = .; | ||
238 | } | ||
239 | #endif | ||
240 | |||
211 | /* Force trailing alignment of our init section so that when we | 241 | /* Force trailing alignment of our init section so that when we |
212 | * free our init memory, we don't leave behind a partial page. | 242 | * free our init memory, we don't leave behind a partial page. |
213 | */ | 243 | */ |