summaryrefslogtreecommitdiffstats
path: root/ldso
diff options
context:
space:
mode:
authorJie Zhang <jie.zhang@analog.com>2008-09-02 07:16:44 +0000
committerMike Frysinger <vapier@gentoo.org>2009-07-23 05:41:20 -0400
commitfaec5053312194f9f9c05a3a98f0980c0054ad29 (patch)
treeead0b47936ee72ed11f1b99d5ba43f2535bb8eb1 /ldso
parent65980d91aa9e4d11a247b3e36296cfa2bacf2e10 (diff)
downloaduClibc-alpine-faec5053312194f9f9c05a3a98f0980c0054ad29.tar.bz2
uClibc-alpine-faec5053312194f9f9c05a3a98f0980c0054ad29.tar.xz
Blackfin: add support for automatic loading of L2 SRAM regions
These match the kernel/etc... pieces already merged. Signed-off-by: Jie Zhang <jie.zhang@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'ldso')
-rw-r--r--ldso/ldso/bfin/dl-inlines.h53
1 files changed, 36 insertions, 17 deletions
diff --git a/ldso/ldso/bfin/dl-inlines.h b/ldso/ldso/bfin/dl-inlines.h
index 6ed1bdaf9..01f130009 100644
--- a/ldso/ldso/bfin/dl-inlines.h
+++ b/ldso/ldso/bfin/dl-inlines.h
@@ -504,12 +504,15 @@ __dl_is_special_segment (Elf32_Ehdr *epnt,
&& !(ppnt->p_flags & PF_X))
return 1;
- /* 0xff700000, 0xff800000, 0xff900000 and 0xffa00000 are also used in
- GNU ld and linux kernel. They need to be keep synchronized. */
+ /* 0xfeb00000, 0xfec00000, 0xff700000, 0xff800000, 0xff900000,
+ and 0xffa00000 are also used in GNU ld and linux kernel.
+ They need to be kept synchronized. */
if (ppnt->p_vaddr == 0xff700000
|| ppnt->p_vaddr == 0xff800000
|| ppnt->p_vaddr == 0xff900000
- || ppnt->p_vaddr == 0xffa00000)
+ || ppnt->p_vaddr == 0xffa00000
+ || ppnt->p_vaddr == 0xfeb00000
+ || ppnt->p_vaddr == 0xfec00000)
return 1;
return 0;
@@ -521,7 +524,7 @@ __dl_map_segment (Elf32_Ehdr *epnt,
int infile,
int flags)
{
- char *status, *tryaddr, *l1addr;
+ char *status, *tryaddr, *addr;
size_t size;
if (((epnt->e_flags & EF_BFIN_CODE_IN_L1) || ppnt->p_vaddr == 0xffa00000)
@@ -536,13 +539,13 @@ __dl_map_segment (Elf32_Ehdr *epnt,
if (_dl_mmap_check_error(status)
|| (tryaddr && tryaddr != status))
return NULL;
- l1addr = (char *) _dl_sram_alloc (ppnt->p_filesz, L1_INST_SRAM);
- if (l1addr != NULL)
- _dl_dma_memcpy (l1addr, status + (ppnt->p_vaddr & ADDR_ALIGN), ppnt->p_filesz);
+ addr = (char *) _dl_sram_alloc (ppnt->p_filesz, L1_INST_SRAM);
+ if (addr != NULL)
+ _dl_dma_memcpy (addr, status + (ppnt->p_vaddr & ADDR_ALIGN), ppnt->p_filesz);
_dl_munmap (status, size);
- if (l1addr == NULL)
+ if (addr == NULL)
_dl_dprintf(2, "%s:%i: L1 allocation failed\n", _dl_progname, __LINE__);
- return l1addr;
+ return addr;
}
if (((epnt->e_flags & EF_BFIN_DATA_IN_L1)
@@ -552,22 +555,38 @@ __dl_map_segment (Elf32_Ehdr *epnt,
&& (ppnt->p_flags & PF_W)
&& !(ppnt->p_flags & PF_X)) {
if (ppnt->p_vaddr == 0xff800000)
- l1addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_A_SRAM);
+ addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_A_SRAM);
else if (ppnt->p_vaddr == 0xff900000)
- l1addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_B_SRAM);
+ addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_B_SRAM);
else
- l1addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_SRAM);
- if (l1addr == NULL) {
+ addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_SRAM);
+ if (addr == NULL) {
_dl_dprintf(2, "%s:%i: L1 allocation failed\n", _dl_progname, __LINE__);
} else {
- if (_DL_PREAD (infile, l1addr, ppnt->p_filesz, ppnt->p_offset) != ppnt->p_filesz) {
- _dl_sram_free (l1addr);
+ if (_DL_PREAD (infile, addr, ppnt->p_filesz, ppnt->p_offset) != ppnt->p_filesz) {
+ _dl_sram_free (addr);
return NULL;
}
if (ppnt->p_filesz < ppnt->p_memsz)
- _dl_memset (l1addr + ppnt->p_filesz, 0, ppnt->p_memsz - ppnt->p_filesz);
+ _dl_memset (addr + ppnt->p_filesz, 0, ppnt->p_memsz - ppnt->p_filesz);
}
- return l1addr;
+ return addr;
+ }
+
+ if (ppnt->p_vaddr == 0xfeb00000
+ || ppnt->p_vaddr == 0xfec00000) {
+ addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L2_SRAM);
+ if (addr == NULL) {
+ _dl_dprintf(2, "%s:%i: L2 allocation failed\n", _dl_progname, __LINE__);
+ } else {
+ if (_DL_PREAD (infile, addr, ppnt->p_filesz, ppnt->p_offset) != ppnt->p_filesz) {
+ _dl_sram_free (addr);
+ return NULL;
+ }
+ if (ppnt->p_filesz < ppnt->p_memsz)
+ _dl_memset (addr + ppnt->p_filesz, 0, ppnt->p_memsz - ppnt->p_filesz);
+ }
+ return addr;
}
return 0;