|
@@ -18,7 +18,7 @@ License along with uClibc; see the file COPYING.LIB. If not, write to
|
|
|
the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
|
|
|
USA. */
|
|
|
|
|
|
-#include <bits/bfin_sram.h>
|
|
|
+#include <bfin_sram.h>
|
|
|
|
|
|
#ifndef _dl_assert
|
|
|
# define _dl_assert(expr)
|
|
@@ -463,6 +463,17 @@ __dl_loadaddr_unmap (struct elf32_fdpic_loadaddr loadaddr,
|
|
|
struct elf32_fdpic_loadseg *segdata;
|
|
|
ssize_t offs;
|
|
|
segdata = loadaddr.map->segs + i;
|
|
|
+
|
|
|
+ /* FIXME:
|
|
|
+ A more cleaner way is to add type for struct elf32_fdpic_loadseg,
|
|
|
+ and release the memory according to the type.
|
|
|
+ Currently, we hardcode the memory address of L1 SRAM. */
|
|
|
+ if ((segdata->addr & 0xff800000) == 0xff800000)
|
|
|
+ {
|
|
|
+ _dl_sram_free ((void *)segdata->addr);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
offs = (segdata->p_vaddr & ADDR_ALIGN);
|
|
|
_dl_munmap ((void*)segdata->addr - offs,
|
|
|
segdata->p_memsz + offs);
|
|
@@ -493,7 +504,15 @@ __dl_is_special_segment (Elf32_Ehdr *epnt,
|
|
|
&& !(ppnt->p_flags & PF_X))
|
|
|
return 1;
|
|
|
|
|
|
- return 0;
|
|
|
+ /* 0xff700000, 0xff800000, 0xff900000 and 0xffa00000 are also used in
|
|
|
+ GNU ld and linux kernel. They need to be keep synchronized. */
|
|
|
+ if (ppnt->p_vaddr == 0xff700000
|
|
|
+ || ppnt->p_vaddr == 0xff800000
|
|
|
+ || ppnt->p_vaddr == 0xff900000
|
|
|
+ || ppnt->p_vaddr == 0xffa00000)
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
inline static char *
|
|
@@ -505,7 +524,7 @@ __dl_map_segment (Elf32_Ehdr *epnt,
|
|
|
char *status, *tryaddr, *l1addr;
|
|
|
size_t size;
|
|
|
|
|
|
- if ((epnt->e_flags & EF_BFIN_CODE_IN_L1)
|
|
|
+ if (((epnt->e_flags & EF_BFIN_CODE_IN_L1) || ppnt->p_vaddr == 0xffa00000)
|
|
|
&& !(ppnt->p_flags & PF_W)
|
|
|
&& (ppnt->p_flags & PF_X)) {
|
|
|
status = (char *) _dl_mmap
|
|
@@ -522,20 +541,32 @@ __dl_map_segment (Elf32_Ehdr *epnt,
|
|
|
_dl_dma_memcpy (l1addr, status + (ppnt->p_vaddr & ADDR_ALIGN), ppnt->p_filesz);
|
|
|
_dl_munmap (status, size);
|
|
|
if (l1addr == NULL)
|
|
|
- return NULL;
|
|
|
+ _dl_dprintf(2, "%s:%i: L1 allocation failed\n", _dl_progname, __LINE__);
|
|
|
return l1addr;
|
|
|
}
|
|
|
|
|
|
- if ((epnt->e_flags & EF_BFIN_DATA_IN_L1)
|
|
|
+ if (((epnt->e_flags & EF_BFIN_DATA_IN_L1)
|
|
|
+ || ppnt->p_vaddr == 0xff700000
|
|
|
+ || ppnt->p_vaddr == 0xff800000
|
|
|
+ || ppnt->p_vaddr == 0xff900000)
|
|
|
&& (ppnt->p_flags & PF_W)
|
|
|
&& !(ppnt->p_flags & PF_X)) {
|
|
|
- l1addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_SRAM);
|
|
|
- if (l1addr == NULL
|
|
|
- || (_DL_PREAD (infile, l1addr, ppnt->p_filesz, ppnt->p_offset)
|
|
|
- != ppnt->p_filesz))
|
|
|
- return NULL;
|
|
|
- if (ppnt->p_filesz < ppnt->p_memsz)
|
|
|
- _dl_memset (l1addr + ppnt->p_filesz, 0, ppnt->p_memsz - ppnt->p_filesz);
|
|
|
+ if (ppnt->p_vaddr == 0xff800000)
|
|
|
+ l1addr = (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);
|
|
|
+ else
|
|
|
+ l1addr = (char *) _dl_sram_alloc (ppnt->p_memsz, L1_DATA_SRAM);
|
|
|
+ if (l1addr == 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);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ if (ppnt->p_filesz < ppnt->p_memsz)
|
|
|
+ _dl_memset (l1addr + ppnt->p_filesz, 0, ppnt->p_memsz - ppnt->p_filesz);
|
|
|
+ }
|
|
|
return l1addr;
|
|
|
}
|
|
|
|