2009-06-13 01:01:27

by Mike Frysinger

[permalink] [raw]
Subject: [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

From: Jie Zhang <[email protected]>

The Blackfin port has custom program header flags/addresses for
automatically loading regions into the dedicated on-chip SRAM. So add a
hook for ports to leverage.

Signed-off-by: Jie Zhang <[email protected]>
Signed-off-by: Mike Frysinger <[email protected]>
CC: Bernd Schmidt <[email protected]>
---
arch/blackfin/include/asm/elf.h | 8 +++
arch/blackfin/kernel/Makefile | 1 +
arch/blackfin/kernel/binfmt_elf_fdpic.c | 80 +++++++++++++++++++++++++++++++
fs/binfmt_elf_fdpic.c | 7 +++
4 files changed, 96 insertions(+), 0 deletions(-)
create mode 100644 arch/blackfin/kernel/binfmt_elf_fdpic.c

diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h
index 230e160..aba2506 100644
--- a/arch/blackfin/include/asm/elf.h
+++ b/arch/blackfin/include/asm/elf.h
@@ -124,4 +124,12 @@ do { \

#define SET_PERSONALITY(ex) set_personality(PER_LINUX)

+struct mm_struct;
+struct elf_fdpic_params;
+struct elf32_phdr;
+extern int elf_fdpic_plat_process_phdr(struct mm_struct *, struct elf_fdpic_params *,
+ struct elf32_phdr *, unsigned long *, unsigned long *);
+#define ELF_FDPIC_PLAT_PROCESS_PHDR(mm, params, phdr, maddr, disp) \
+ elf_fdpic_plat_process_phdr(mm, params, phdr, maddr, disp)
+
#endif
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
index fd4d432..71c2291 100644
--- a/arch/blackfin/kernel/Makefile
+++ b/arch/blackfin/kernel/Makefile
@@ -15,6 +15,7 @@ else
obj-y += time.o
endif

+obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o
obj-$(CONFIG_IPIPE) += ipipe.o
obj-$(CONFIG_IPIPE_TRACE_MCOUNT) += mcount.o
obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o
diff --git a/arch/blackfin/kernel/binfmt_elf_fdpic.c b/arch/blackfin/kernel/binfmt_elf_fdpic.c
new file mode 100644
index 0000000..d8192cf
--- /dev/null
+++ b/arch/blackfin/kernel/binfmt_elf_fdpic.c
@@ -0,0 +1,80 @@
+/*
+ * FDPIC ELF hooks
+ *
+ * Copyright (c) 2006-2009 Analog Devices Inc.
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/mm.h>
+#include <linux/elf.h>
+#include <linux/elf-fdpic.h>
+#include <linux/kernel.h>
+
+#include <asm/cacheflush.h>
+#include <asm/dma.h>
+
+int elf_fdpic_plat_process_phdr(struct mm_struct *mm,
+ struct elf_fdpic_params *params,
+ struct elf32_phdr *phdr,
+ unsigned long *maddr, unsigned long *disp)
+{
+ /* 0xfeb00000, 0xfec00000, 0xff700000, 0xff800000, 0xff900000
+ * and 0xffa00000 are also used in Dynamic linker and GNU ld.
+ * They need to be kept synchronized.
+ */
+ unsigned long flag = 0;
+ const char *type = NULL;
+
+ unsigned int e_flags = params->hdr.e_flags;
+ unsigned long p_vaddr = phdr->p_vaddr;
+ unsigned long p_flags = phdr->p_flags;
+
+ if (((e_flags & EF_BFIN_CODE_IN_L1) || p_vaddr == 0xffa00000) &&
+ (p_flags & (PF_W | PF_X)) == PF_X)
+ {
+ flag = L1_INST_SRAM;
+ type = "L1 instruction";
+
+ } else if (((e_flags & EF_BFIN_DATA_IN_L1) ||
+ p_vaddr == 0xff700000 ||
+ p_vaddr == 0xff800000 ||
+ p_vaddr == 0xff900000) &&
+ (p_flags & (PF_X | PF_W)) == PF_W)
+ {
+ if (p_vaddr == 0xff800000) {
+ flag = L1_DATA_A_SRAM;
+ type = "L1 Data A";
+ } else if (p_vaddr == 0xff900000) {
+ flag = L1_DATA_B_SRAM;
+ type = "L1 Data B";
+ } else {
+ flag = L1_DATA_SRAM;
+ type = "L1 Data";
+ }
+
+ } else if (p_vaddr == 0xfeb00000 || p_vaddr == 0xfec00000) {
+ flag = L2_SRAM;
+ type = "L2";
+ }
+
+ if (flag) {
+ void *sram_addr = sram_alloc_with_lsl(phdr->p_memsz, flag);
+ if (sram_addr == NULL) {
+ printk(KERN_ERR "elf_fdpic: not enough %s sram\n", type);
+ return -ENOMEM;
+ }
+
+ if (flag & L1_INST_SRAM)
+ safe_dma_memcpy(sram_addr, (const void *)(*maddr + *disp), phdr->p_memsz);
+ else
+ memcpy(sram_addr, (const void *)(*maddr + *disp), phdr->p_memsz);
+
+ down_write(&mm->mmap_sem);
+ do_munmap(mm, *maddr, phdr->p_memsz + *disp);
+ up_write(&mm->mmap_sem);
+ *maddr = (unsigned long)sram_addr;
+ *disp = 0;
+ }
+
+ return 0;
+}
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index fdb66fa..1bad16c 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -1105,6 +1105,13 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
ELF_FDPIC_FLAG_CONTIGUOUS)
load_addr += PAGE_ALIGN(phdr->p_memsz + disp);

+#ifndef ELF_FDPIC_PLAT_PROCESS_PHDR
+# define ELF_FDPIC_PLAT_PROCESS_PHDR(mm, params, phdr, maddr, disp) 0
+#endif
+ ret = ELF_FDPIC_PLAT_PROCESS_PHDR(mm, params, phdr, &maddr, &disp);
+ if (ret)
+ return ret;
+
seg->addr = maddr + disp;
seg->p_vaddr = phdr->p_vaddr;
seg->p_memsz = phdr->p_memsz;
--
1.6.3.1


2009-06-13 12:24:43

by David Howells

[permalink] [raw]
Subject: Re: [uClinux-dev] [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

Mike Frysinger <[email protected]> wrote:

> From: Jie Zhang <[email protected]>
>
> The Blackfin port has custom program header flags/addresses for
> automatically loading regions into the dedicated on-chip SRAM. So add a
> hook for ports to leverage.
>
> Signed-off-by: Jie Zhang <[email protected]>
> Signed-off-by: Mike Frysinger <[email protected]>
> CC: Bernd Schmidt <[email protected]>

Acked-by: David Howells <[email protected]>

2009-06-13 16:13:31

by Jamie Lokier

[permalink] [raw]
Subject: Re: [uClinux-dev] [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

Mike Frysinger wrote:
> From: Jie Zhang <[email protected]>
>
> The Blackfin port has custom program header flags/addresses for
> automatically loading regions into the dedicated on-chip SRAM. So add a
> hook for ports to leverage.

What does this have to do with FDPIC? I don't see anything that is
specific to FDPIC about this code, other than FDPIC being the type of
ELF used on Blackfin. If an MMU were added to some future Blackfins,
wouldn't this code be used for non-FDPIC ELF too?

It looks like a way for certain special executables to load themselves
into fixed regions of the on-chip SRAM - and promptly crash if another
executable does the same. Not so much a general executable format, as
a hack to load something specific which should only be done once at a
time. What am I missing here?

-- Jamie

2009-06-13 16:41:42

by Mike Frysinger

[permalink] [raw]
Subject: Re: [uClinux-dev] [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

On Sat, Jun 13, 2009 at 12:13, Jamie Lokier wrote:
> Mike Frysinger wrote:
>> From: Jie Zhang <[email protected]>
>>
>> The Blackfin port has custom program header flags/addresses for
>> automatically loading regions into the dedicated on-chip SRAM.  So add a
>> hook for ports to leverage.
>
> What does this have to do with FDPIC?  I don't see anything that is
> specific to FDPIC about this code, other than FDPIC being the type of
> ELF used on Blackfin.  If an MMU were added to some future Blackfins,
> wouldn't this code be used for non-FDPIC ELF too?

no, because with a MMU, the memory would be virtualized and we could
handle it dynamically

> It looks like a way for certain special executables to load themselves
> into fixed regions of the on-chip SRAM - and promptly crash if another
> executable does the same.  Not so much a general executable format, as
> a hack to load something specific which should only be done once at a
> time.  What am I missing here?

the addresses are keys, not fixed and/or "real" addresses
-mike

2009-06-13 18:25:51

by Jamie Lokier

[permalink] [raw]
Subject: Re: [uClinux-dev] [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

Mike Frysinger wrote:
> On Sat, Jun 13, 2009 at 12:13, Jamie Lokier wrote:
> > Mike Frysinger wrote:
> >> From: Jie Zhang <[email protected]>
> >>
> >> The Blackfin port has custom program header flags/addresses for
> >> automatically loading regions into the dedicated on-chip SRAM. ?So add a
> >> hook for ports to leverage.
> >
> > What does this have to do with FDPIC? ?I don't see anything that is
> > specific to FDPIC about this code, other than FDPIC being the type of
> > ELF used on Blackfin. ?If an MMU were added to some future Blackfins,
> > wouldn't this code be used for non-FDPIC ELF too?
>
> no, because with a MMU, the memory would be virtualized and we could
> handle it dynamically

Wouldn't you still want to put some things into local L1 SRAM, using thos, perhaps by
flagging it instead of

> > It looks like a way for certain special executables to load themselves
> > into fixed regions of the on-chip SRAM - and promptly crash if another
> > executable does the same. ?Not so much a general executable format, as
> > a hack to load something specific which should only be done once at a
> > time. ?What am I missing here?
>
> the addresses are keys, not fixed and/or "real" addresses

Oh, I see that is indeed quite nice :-)

I see it checks for both flags and special address values. Are the
special address checks mainly historical, as usually flags/types are
used to designate special memory types in ELF.

Anyway,

Acked-By: Jamie Lokier <[email protected]>

-- Jamie

2009-06-13 18:27:15

by Jamie Lokier

[permalink] [raw]
Subject: Re: [uClinux-dev] [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

Jamie Lokier wrote:
> Wouldn't you still want to put some things into local L1 SRAM, using thos, perhaps by
> flagging it instead of
...

Aiee, slipped on the keyboard. Ignore.

-- Jamie

2009-06-14 00:33:31

by Mike Frysinger

[permalink] [raw]
Subject: Re: [uClinux-dev] [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

On Sat, Jun 13, 2009 at 14:25, Jamie Lokier wrote:
> Mike Frysinger wrote:
>> On Sat, Jun 13, 2009 at 12:13, Jamie Lokier wrote:
>> > Mike Frysinger wrote:
>> >> From: Jie Zhang <[email protected]>
>> >>
>> >> The Blackfin port has custom program header flags/addresses for
>> >> automatically loading regions into the dedicated on-chip SRAM.  So add a
>> >> hook for ports to leverage.
>> >
>> > It looks like a way for certain special executables to load themselves
>> > into fixed regions of the on-chip SRAM - and promptly crash if another
>> > executable does the same.  Not so much a general executable format, as
>> > a hack to load something specific which should only be done once at a
>> > time.  What am I missing here?
>>
>> the addresses are keys, not fixed and/or "real" addresses
>
> Oh, I see that is indeed quite nice :-)
>
> I see it checks for both flags and special address values.  Are the
> special address checks mainly historical, as usually flags/types are
> used to designate special memory types in ELF.

the EF bits are more for smaller/statically linked applications where
you want to place the entire ELF into SRAM. the special PHDRs are for
selectively compiled code -- i.e. you've done a little bit of
profiling and testing and know which ones are the hot spots.
-mike

2009-06-14 00:49:00

by Jie Zhang

[permalink] [raw]
Subject: Re: [uClinux-dev] [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

Mike Frysinger wrote:
> On Sat, Jun 13, 2009 at 14:25, Jamie Lokier wrote:
>> Mike Frysinger wrote:
>>> On Sat, Jun 13, 2009 at 12:13, Jamie Lokier wrote:
>>>> Mike Frysinger wrote:
>>>>> From: Jie Zhang <[email protected]>
>>>>>
>>>>> The Blackfin port has custom program header flags/addresses for
>>>>> automatically loading regions into the dedicated on-chip SRAM. So add a
>>>>> hook for ports to leverage.
>>>> It looks like a way for certain special executables to load themselves
>>>> into fixed regions of the on-chip SRAM - and promptly crash if another
>>>> executable does the same. Not so much a general executable format, as
>>>> a hack to load something specific which should only be done once at a
>>>> time. What am I missing here?
>>> the addresses are keys, not fixed and/or "real" addresses
>> Oh, I see that is indeed quite nice :-)
>>
>> I see it checks for both flags and special address values. Are the
>> special address checks mainly historical, as usually flags/types are
>> used to designate special memory types in ELF.
>
> the EF bits are more for smaller/statically linked applications where
> you want to place the entire ELF into SRAM. the special PHDRs are for
> selectively compiled code -- i.e. you've done a little bit of
> profiling and testing and know which ones are the hot spots.

Yes. Those e_flags works for the whole ELF file. And these specific
addresses work as p_flags. May be in future I can add processor specific
p_flags.


Jie

2009-06-14 09:44:11

by Paul Mundt

[permalink] [raw]
Subject: Re: [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

On Fri, Jun 12, 2009 at 09:01:09PM -0400, Mike Frysinger wrote:
> From: Jie Zhang <[email protected]>
>
> The Blackfin port has custom program header flags/addresses for
> automatically loading regions into the dedicated on-chip SRAM. So add a
> hook for ports to leverage.
>
> Signed-off-by: Jie Zhang <[email protected]>
> Signed-off-by: Mike Frysinger <[email protected]>
> CC: Bernd Schmidt <[email protected]>

Acked-by: Paul Mundt <[email protected]>

2009-06-15 01:44:13

by Greg Ungerer

[permalink] [raw]
Subject: Re: [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing


Mike Frysinger wrote:
> From: Jie Zhang <[email protected]>
>
> The Blackfin port has custom program header flags/addresses for
> automatically loading regions into the dedicated on-chip SRAM. So add a
> hook for ports to leverage.
>
> Signed-off-by: Jie Zhang <[email protected]>
> Signed-off-by: Mike Frysinger <[email protected]>
> CC: Bernd Schmidt <[email protected]>

Acked-by: Greg Ungerer <[email protected]>


> arch/blackfin/include/asm/elf.h | 8 +++
> arch/blackfin/kernel/Makefile | 1 +
> arch/blackfin/kernel/binfmt_elf_fdpic.c | 80 +++++++++++++++++++++++++++++++
> fs/binfmt_elf_fdpic.c | 7 +++
> 4 files changed, 96 insertions(+), 0 deletions(-)
> create mode 100644 arch/blackfin/kernel/binfmt_elf_fdpic.c
>
> diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h
> index 230e160..aba2506 100644
> --- a/arch/blackfin/include/asm/elf.h
> +++ b/arch/blackfin/include/asm/elf.h
> @@ -124,4 +124,12 @@ do { \
>
> #define SET_PERSONALITY(ex) set_personality(PER_LINUX)
>
> +struct mm_struct;
> +struct elf_fdpic_params;
> +struct elf32_phdr;
> +extern int elf_fdpic_plat_process_phdr(struct mm_struct *, struct elf_fdpic_params *,
> + struct elf32_phdr *, unsigned long *, unsigned long *);
> +#define ELF_FDPIC_PLAT_PROCESS_PHDR(mm, params, phdr, maddr, disp) \
> + elf_fdpic_plat_process_phdr(mm, params, phdr, maddr, disp)
> +
> #endif
> diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
> index fd4d432..71c2291 100644
> --- a/arch/blackfin/kernel/Makefile
> +++ b/arch/blackfin/kernel/Makefile
> @@ -15,6 +15,7 @@ else
> obj-y += time.o
> endif
>
> +obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o
> obj-$(CONFIG_IPIPE) += ipipe.o
> obj-$(CONFIG_IPIPE_TRACE_MCOUNT) += mcount.o
> obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o
> diff --git a/arch/blackfin/kernel/binfmt_elf_fdpic.c b/arch/blackfin/kernel/binfmt_elf_fdpic.c
> new file mode 100644
> index 0000000..d8192cf
> --- /dev/null
> +++ b/arch/blackfin/kernel/binfmt_elf_fdpic.c
> @@ -0,0 +1,80 @@
> +/*
> + * FDPIC ELF hooks
> + *
> + * Copyright (c) 2006-2009 Analog Devices Inc.
> + * Licensed under the GPL-2 or later.
> + */
> +
> +#include <linux/mm.h>
> +#include <linux/elf.h>
> +#include <linux/elf-fdpic.h>
> +#include <linux/kernel.h>
> +
> +#include <asm/cacheflush.h>
> +#include <asm/dma.h>
> +
> +int elf_fdpic_plat_process_phdr(struct mm_struct *mm,
> + struct elf_fdpic_params *params,
> + struct elf32_phdr *phdr,
> + unsigned long *maddr, unsigned long *disp)
> +{
> + /* 0xfeb00000, 0xfec00000, 0xff700000, 0xff800000, 0xff900000
> + * and 0xffa00000 are also used in Dynamic linker and GNU ld.
> + * They need to be kept synchronized.
> + */
> + unsigned long flag = 0;
> + const char *type = NULL;
> +
> + unsigned int e_flags = params->hdr.e_flags;
> + unsigned long p_vaddr = phdr->p_vaddr;
> + unsigned long p_flags = phdr->p_flags;
> +
> + if (((e_flags & EF_BFIN_CODE_IN_L1) || p_vaddr == 0xffa00000) &&
> + (p_flags & (PF_W | PF_X)) == PF_X)
> + {
> + flag = L1_INST_SRAM;
> + type = "L1 instruction";
> +
> + } else if (((e_flags & EF_BFIN_DATA_IN_L1) ||
> + p_vaddr == 0xff700000 ||
> + p_vaddr == 0xff800000 ||
> + p_vaddr == 0xff900000) &&
> + (p_flags & (PF_X | PF_W)) == PF_W)
> + {
> + if (p_vaddr == 0xff800000) {
> + flag = L1_DATA_A_SRAM;
> + type = "L1 Data A";
> + } else if (p_vaddr == 0xff900000) {
> + flag = L1_DATA_B_SRAM;
> + type = "L1 Data B";
> + } else {
> + flag = L1_DATA_SRAM;
> + type = "L1 Data";
> + }
> +
> + } else if (p_vaddr == 0xfeb00000 || p_vaddr == 0xfec00000) {
> + flag = L2_SRAM;
> + type = "L2";
> + }
> +
> + if (flag) {
> + void *sram_addr = sram_alloc_with_lsl(phdr->p_memsz, flag);
> + if (sram_addr == NULL) {
> + printk(KERN_ERR "elf_fdpic: not enough %s sram\n", type);
> + return -ENOMEM;
> + }
> +
> + if (flag & L1_INST_SRAM)
> + safe_dma_memcpy(sram_addr, (const void *)(*maddr + *disp), phdr->p_memsz);
> + else
> + memcpy(sram_addr, (const void *)(*maddr + *disp), phdr->p_memsz);
> +
> + down_write(&mm->mmap_sem);
> + do_munmap(mm, *maddr, phdr->p_memsz + *disp);
> + up_write(&mm->mmap_sem);
> + *maddr = (unsigned long)sram_addr;
> + *disp = 0;
> + }
> +
> + return 0;
> +}
> diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
> index fdb66fa..1bad16c 100644
> --- a/fs/binfmt_elf_fdpic.c
> +++ b/fs/binfmt_elf_fdpic.c
> @@ -1105,6 +1105,13 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
> ELF_FDPIC_FLAG_CONTIGUOUS)
> load_addr += PAGE_ALIGN(phdr->p_memsz + disp);
>
> +#ifndef ELF_FDPIC_PLAT_PROCESS_PHDR
> +# define ELF_FDPIC_PLAT_PROCESS_PHDR(mm, params, phdr, maddr, disp) 0
> +#endif
> + ret = ELF_FDPIC_PLAT_PROCESS_PHDR(mm, params, phdr, &maddr, &disp);
> + if (ret)
> + return ret;
> +
> seg->addr = maddr + disp;
> seg->p_vaddr = phdr->p_vaddr;
> seg->p_memsz = phdr->p_memsz;

--
------------------------------------------------------------------------
Greg Ungerer -- Principal Engineer EMAIL: [email protected]
SnapGear Group, McAfee PHONE: +61 7 3435 2888
825 Stanley St, FAX: +61 7 3891 3630
Woolloongabba, QLD, 4102, Australia WEB: http://www.SnapGear.com

2009-06-16 08:25:15

by Mike Frysinger

[permalink] [raw]
Subject: [PATCH] FDPIC: add hook for arches to customize program header parsing

From: Jie Zhang <[email protected]>

The Blackfin port has custom program header flags/addresses for
automatically loading regions into the dedicated on-chip SRAM. So add a
hook for ports to leverage.

Signed-off-by: Jie Zhang <[email protected]>
Signed-off-by: Mike Frysinger <[email protected]>
CC: Bernd Schmidt <[email protected]>
Acked-by: David Howells <[email protected]>
Acked-by: Paul Mundt <[email protected]>
Acked-by: Greg Ungerer <[email protected]>
---
Andrew: could you pick this up ? same patch as before, just with the
additional tags added.

arch/blackfin/include/asm/elf.h | 8 +++
arch/blackfin/kernel/Makefile | 1 +
arch/blackfin/kernel/binfmt_elf_fdpic.c | 80 +++++++++++++++++++++++++++++++
fs/binfmt_elf_fdpic.c | 7 +++
4 files changed, 96 insertions(+), 0 deletions(-)
create mode 100644 arch/blackfin/kernel/binfmt_elf_fdpic.c

diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h
index 230e160..aba2506 100644
--- a/arch/blackfin/include/asm/elf.h
+++ b/arch/blackfin/include/asm/elf.h
@@ -124,4 +124,12 @@ do { \

#define SET_PERSONALITY(ex) set_personality(PER_LINUX)

+struct mm_struct;
+struct elf_fdpic_params;
+struct elf32_phdr;
+extern int elf_fdpic_plat_process_phdr(struct mm_struct *, struct elf_fdpic_params *,
+ struct elf32_phdr *, unsigned long *, unsigned long *);
+#define ELF_FDPIC_PLAT_PROCESS_PHDR(mm, params, phdr, maddr, disp) \
+ elf_fdpic_plat_process_phdr(mm, params, phdr, maddr, disp)
+
#endif
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
index fd4d432..71c2291 100644
--- a/arch/blackfin/kernel/Makefile
+++ b/arch/blackfin/kernel/Makefile
@@ -15,6 +15,7 @@ else
obj-y += time.o
endif

+obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o
obj-$(CONFIG_IPIPE) += ipipe.o
obj-$(CONFIG_IPIPE_TRACE_MCOUNT) += mcount.o
obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o
diff --git a/arch/blackfin/kernel/binfmt_elf_fdpic.c b/arch/blackfin/kernel/binfmt_elf_fdpic.c
new file mode 100644
index 0000000..d8192cf
--- /dev/null
+++ b/arch/blackfin/kernel/binfmt_elf_fdpic.c
@@ -0,0 +1,80 @@
+/*
+ * FDPIC ELF hooks
+ *
+ * Copyright (c) 2006-2009 Analog Devices Inc.
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/mm.h>
+#include <linux/elf.h>
+#include <linux/elf-fdpic.h>
+#include <linux/kernel.h>
+
+#include <asm/cacheflush.h>
+#include <asm/dma.h>
+
+int elf_fdpic_plat_process_phdr(struct mm_struct *mm,
+ struct elf_fdpic_params *params,
+ struct elf32_phdr *phdr,
+ unsigned long *maddr, unsigned long *disp)
+{
+ /* 0xfeb00000, 0xfec00000, 0xff700000, 0xff800000, 0xff900000
+ * and 0xffa00000 are also used in Dynamic linker and GNU ld.
+ * They need to be kept synchronized.
+ */
+ unsigned long flag = 0;
+ const char *type = NULL;
+
+ unsigned int e_flags = params->hdr.e_flags;
+ unsigned long p_vaddr = phdr->p_vaddr;
+ unsigned long p_flags = phdr->p_flags;
+
+ if (((e_flags & EF_BFIN_CODE_IN_L1) || p_vaddr == 0xffa00000) &&
+ (p_flags & (PF_W | PF_X)) == PF_X)
+ {
+ flag = L1_INST_SRAM;
+ type = "L1 instruction";
+
+ } else if (((e_flags & EF_BFIN_DATA_IN_L1) ||
+ p_vaddr == 0xff700000 ||
+ p_vaddr == 0xff800000 ||
+ p_vaddr == 0xff900000) &&
+ (p_flags & (PF_X | PF_W)) == PF_W)
+ {
+ if (p_vaddr == 0xff800000) {
+ flag = L1_DATA_A_SRAM;
+ type = "L1 Data A";
+ } else if (p_vaddr == 0xff900000) {
+ flag = L1_DATA_B_SRAM;
+ type = "L1 Data B";
+ } else {
+ flag = L1_DATA_SRAM;
+ type = "L1 Data";
+ }
+
+ } else if (p_vaddr == 0xfeb00000 || p_vaddr == 0xfec00000) {
+ flag = L2_SRAM;
+ type = "L2";
+ }
+
+ if (flag) {
+ void *sram_addr = sram_alloc_with_lsl(phdr->p_memsz, flag);
+ if (sram_addr == NULL) {
+ printk(KERN_ERR "elf_fdpic: not enough %s sram\n", type);
+ return -ENOMEM;
+ }
+
+ if (flag & L1_INST_SRAM)
+ safe_dma_memcpy(sram_addr, (const void *)(*maddr + *disp), phdr->p_memsz);
+ else
+ memcpy(sram_addr, (const void *)(*maddr + *disp), phdr->p_memsz);
+
+ down_write(&mm->mmap_sem);
+ do_munmap(mm, *maddr, phdr->p_memsz + *disp);
+ up_write(&mm->mmap_sem);
+ *maddr = (unsigned long)sram_addr;
+ *disp = 0;
+ }
+
+ return 0;
+}
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index fdb66fa..1bad16c 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -1105,6 +1105,13 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
ELF_FDPIC_FLAG_CONTIGUOUS)
load_addr += PAGE_ALIGN(phdr->p_memsz + disp);

+#ifndef ELF_FDPIC_PLAT_PROCESS_PHDR
+# define ELF_FDPIC_PLAT_PROCESS_PHDR(mm, params, phdr, maddr, disp) 0
+#endif
+ ret = ELF_FDPIC_PLAT_PROCESS_PHDR(mm, params, phdr, &maddr, &disp);
+ if (ret)
+ return ret;
+
seg->addr = maddr + disp;
seg->p_vaddr = phdr->p_vaddr;
seg->p_memsz = phdr->p_memsz;
--
1.6.3.1

2009-06-23 05:32:18

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH] FDPIC: add hook for arches to customize program header parsing

On Tue, 16 Jun 2009 04:24:48 -0400 Mike Frysinger <[email protected]> wrote:

> From: Jie Zhang <[email protected]>
>
> The Blackfin port has custom program header flags/addresses for
> automatically loading regions into the dedicated on-chip SRAM. So add a
> hook for ports to leverage.
>
> Signed-off-by: Jie Zhang <[email protected]>
> Signed-off-by: Mike Frysinger <[email protected]>
> CC: Bernd Schmidt <[email protected]>
> Acked-by: David Howells <[email protected]>
> Acked-by: Paul Mundt <[email protected]>
> Acked-by: Greg Ungerer <[email protected]>
> ---
> Andrew: could you pick this up ? same patch as before, just with the
> additional tags added.
>

I suppose we want to squeeze this into 2.6.31.

> diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h
> index 230e160..aba2506 100644
> --- a/arch/blackfin/include/asm/elf.h
> +++ b/arch/blackfin/include/asm/elf.h
> @@ -124,4 +124,12 @@ do { \
>
> #define SET_PERSONALITY(ex) set_personality(PER_LINUX)
>
> +struct mm_struct;
> +struct elf_fdpic_params;
> +struct elf32_phdr;
> +extern int elf_fdpic_plat_process_phdr(struct mm_struct *, struct elf_fdpic_params *,
> + struct elf32_phdr *, unsigned long *, unsigned long *);
> +#define ELF_FDPIC_PLAT_PROCESS_PHDR(mm, params, phdr, maddr, disp) \
> + elf_fdpic_plat_process_phdr(mm, params, phdr, maddr, disp)
> +
> #endif
> diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
> index fd4d432..71c2291 100644
> --- a/arch/blackfin/kernel/Makefile
> +++ b/arch/blackfin/kernel/Makefile
> @@ -15,6 +15,7 @@ else
> obj-y += time.o
> endif
>
> +obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o
> obj-$(CONFIG_IPIPE) += ipipe.o
> obj-$(CONFIG_IPIPE_TRACE_MCOUNT) += mcount.o
> obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o
> diff --git a/arch/blackfin/kernel/binfmt_elf_fdpic.c b/arch/blackfin/kernel/binfmt_elf_fdpic.c
> new file mode 100644
> index 0000000..d8192cf
> --- /dev/null
> +++ b/arch/blackfin/kernel/binfmt_elf_fdpic.c
> @@ -0,0 +1,80 @@
> +/*
> + * FDPIC ELF hooks
> + *
> + * Copyright (c) 2006-2009 Analog Devices Inc.
> + * Licensed under the GPL-2 or later.
> + */
> +
> +#include <linux/mm.h>
> +#include <linux/elf.h>
> +#include <linux/elf-fdpic.h>
> +#include <linux/kernel.h>
> +
> +#include <asm/cacheflush.h>
> +#include <asm/dma.h>
> +
> +int elf_fdpic_plat_process_phdr(struct mm_struct *mm,
> + struct elf_fdpic_params *params,
> + struct elf32_phdr *phdr,
> + unsigned long *maddr, unsigned long *disp)
> +{
> + /* 0xfeb00000, 0xfec00000, 0xff700000, 0xff800000, 0xff900000
> + * and 0xffa00000 are also used in Dynamic linker and GNU ld.
> + * They need to be kept synchronized.
> + */
> + unsigned long flag = 0;
> + const char *type = NULL;
> +
> + unsigned int e_flags = params->hdr.e_flags;
> + unsigned long p_vaddr = phdr->p_vaddr;
> + unsigned long p_flags = phdr->p_flags;
> +
> + if (((e_flags & EF_BFIN_CODE_IN_L1) || p_vaddr == 0xffa00000) &&
> + (p_flags & (PF_W | PF_X)) == PF_X)
> + {
> + flag = L1_INST_SRAM;
> + type = "L1 instruction";
> +
> + } else if (((e_flags & EF_BFIN_DATA_IN_L1) ||
> + p_vaddr == 0xff700000 ||
> + p_vaddr == 0xff800000 ||
> + p_vaddr == 0xff900000) &&
> + (p_flags & (PF_X | PF_W)) == PF_W)
> + {
> + if (p_vaddr == 0xff800000) {
> + flag = L1_DATA_A_SRAM;
> + type = "L1 Data A";
> + } else if (p_vaddr == 0xff900000) {
> + flag = L1_DATA_B_SRAM;
> + type = "L1 Data B";
> + } else {
> + flag = L1_DATA_SRAM;
> + type = "L1 Data";
> + }
> +
> + } else if (p_vaddr == 0xfeb00000 || p_vaddr == 0xfec00000) {
> + flag = L2_SRAM;
> + type = "L2";
> + }
> +
> + if (flag) {
> + void *sram_addr = sram_alloc_with_lsl(phdr->p_memsz, flag);
> + if (sram_addr == NULL) {
> + printk(KERN_ERR "elf_fdpic: not enough %s sram\n", type);
> + return -ENOMEM;
> + }
> +
> + if (flag & L1_INST_SRAM)
> + safe_dma_memcpy(sram_addr, (const void *)(*maddr + *disp), phdr->p_memsz);
> + else
> + memcpy(sram_addr, (const void *)(*maddr + *disp), phdr->p_memsz);
> +
> + down_write(&mm->mmap_sem);
> + do_munmap(mm, *maddr, phdr->p_memsz + *disp);
> + up_write(&mm->mmap_sem);
> + *maddr = (unsigned long)sram_addr;
> + *disp = 0;
> + }
> +
> + return 0;
> +}

blah. Is this a checkpatch stress test or what?

Geeze.

> diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
> index fdb66fa..1bad16c 100644
> --- a/fs/binfmt_elf_fdpic.c
> +++ b/fs/binfmt_elf_fdpic.c
> @@ -1105,6 +1105,13 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
> ELF_FDPIC_FLAG_CONTIGUOUS)
> load_addr += PAGE_ALIGN(phdr->p_memsz + disp);
>
> +#ifndef ELF_FDPIC_PLAT_PROCESS_PHDR
> +# define ELF_FDPIC_PLAT_PROCESS_PHDR(mm, params, phdr, maddr, disp) 0
> +#endif
> + ret = ELF_FDPIC_PLAT_PROCESS_PHDR(mm, params, phdr, &maddr, &disp);
> + if (ret)
> + return ret;
> +

Wouldn't it be simpler to do

#ifdef ELF_FDPIC_PLAT_PROCESS_PHDR
ret = ELF_FDPIC_PLAT_PROCESS_PHDR(mm, params, phdr, &maddr,
&disp);
if (ret)
return ret;
#endif

?

If there's any prospect that we'll use ELF_FDPIC_PLAT_PROCESS_PHDR() a
second time from within this file then yes, adding a definition as
you did is appropriate. But it should be near the top of the file, not
stuck stupidly in the middle of a C function.

2009-06-23 11:04:31

by Mike Frysinger

[permalink] [raw]
Subject: Re: [PATCH] FDPIC: add hook for arches to customize program header parsing

On Tue, Jun 23, 2009 at 01:32, Andrew Morton wrote:
> On Tue, 16 Jun 2009 04:24:48 -0400 Mike Frysinger wrote:
>> From: Jie Zhang <[email protected]>
>> The Blackfin port has custom program header flags/addresses for
>> automatically loading regions into the dedicated on-chip SRAM.  So add a
>> hook for ports to leverage.
>>
>> Signed-off-by: Jie Zhang <[email protected]>
>> Signed-off-by: Mike Frysinger <[email protected]>
>> CC: Bernd Schmidt <[email protected]>
>> Acked-by: David Howells <[email protected]>
>> Acked-by: Paul Mundt <[email protected]>
>> Acked-by: Greg Ungerer <[email protected]>
>> ---
>> Andrew: could you pick this up ?  same patch as before, just with the
>> additional tags added.
>
> I suppose we want to squeeze this into 2.6.31.

would be nice, but not terribly critical

>> --- a/fs/binfmt_elf_fdpic.c
>> +++ b/fs/binfmt_elf_fdpic.c
>> @@ -1105,6 +1105,13 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
>>                   ELF_FDPIC_FLAG_CONTIGUOUS)
>>                       load_addr += PAGE_ALIGN(phdr->p_memsz + disp);
>>
>> +#ifndef ELF_FDPIC_PLAT_PROCESS_PHDR
>> +# define ELF_FDPIC_PLAT_PROCESS_PHDR(mm, params, phdr, maddr, disp) 0
>> +#endif
>> +             ret = ELF_FDPIC_PLAT_PROCESS_PHDR(mm, params, phdr, &maddr, &disp);
>> +             if (ret)
>> +                     return ret;
>> +
>
> Wouldn't it be simpler to do
>
> #ifdef ELF_FDPIC_PLAT_PROCESS_PHDR
>                ret = ELF_FDPIC_PLAT_PROCESS_PHDR(mm, params, phdr, &maddr,
>                                                  &disp);
>                if (ret)
>                        return ret;
> #endif
>
> ?
>
> If there's any prospect that we'll use ELF_FDPIC_PLAT_PROCESS_PHDR() a
> second time from within this file then yes, adding a definition as
> you did is appropriate.  But it should be near the top of the file, not
> stuck stupidly in the middle of a C function.

the purpose was to stick to current conventions used in the file and
to maximize the amount of code compiled. i dont particularly care wrt
the method used here.
-mike

2009-12-04 17:47:16

by David Howells

[permalink] [raw]
Subject: Re: [uClinux-dev] [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

Mike Frysinger <[email protected]> wrote:

> The Blackfin port has custom program header flags/addresses for
> automatically loading regions into the dedicated on-chip SRAM. So add a
> hook for ports to leverage.

Now that I've ACK'd this, I feel I'm going to have to NAK it. I'm not against
the general concept, but:

> + do_munmap(mm, *maddr, phdr->p_memsz + *disp);

There needs to be a mapping covering the SRAM region for the purposes of the
debugger. Do you have a chardev covering the SRAM device? Perhaps through
MTD?

David

2009-12-05 00:29:44

by Jie Zhang

[permalink] [raw]
Subject: Re: [uClinux-dev] [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

On 12/05/2009 01:44 AM, David Howells wrote:
> Mike Frysinger<[email protected]> wrote:
>
>> The Blackfin port has custom program header flags/addresses for
>> automatically loading regions into the dedicated on-chip SRAM. So add a
>> hook for ports to leverage.
>
> Now that I've ACK'd this, I feel I'm going to have to NAK it. I'm not against
> the general concept, but:
>
>> + do_munmap(mm, *maddr, phdr->p_memsz + *disp);
>
> There needs to be a mapping covering the SRAM region for the purposes of the

Our GDB is still lack of the feature to debug applications using SRAM.
So this part of code was not got exercised. So if we remove this line,
can this patch got merged?

> debugger. Do you have a chardev covering the SRAM device? Perhaps through
> MTD?
>
Sorry, I don't know the answer to these two questions.


Jie

2009-12-05 15:16:47

by David Howells

[permalink] [raw]
Subject: Re: [uClinux-dev] [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

Jie Zhang <[email protected]> wrote:

> > There needs to be a mapping covering the SRAM region for the purposes of the
>
> Our GDB is still lack of the feature to debug applications using SRAM. So this
> part of code was not got exercised. So if we remove this line, can this patch
> got merged?

No. Firstly, the piece of storage that gets munmapped isn't used, so unmapping
it isn't wrong. What you need to do is to put a mapping over the bit of the
SRAM you wish to use and then fill it and use it. Ideally, you'd do this
inside of do_mmap_pgoff() - that way those bits of the SRAM can be shared, but
I'm not sure how best to do that.

But you need to stick a VMA over it so that various checks don't spit
EFAULT/EIO at you.

David

2009-12-07 03:23:33

by Zhang, Sonic

[permalink] [raw]
Subject: RE: [Uclinux-dist-devel] [uClinux-dev] [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

No. The sram device can not be accessed by any user space application.
The applications can only do malloc/free via system call.

Sonic

-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of
Jie Zhang
Sent: Saturday, December 05, 2009 8:28 AM
To: David Howells
Cc: [email protected]; Greg Ungerer; uClinux
development list; David McCullough; [email protected]
Subject: Re: [Uclinux-dist-devel] [uClinux-dev] [PATCH/RFC] FDPIC: add
hook for arches to customize program header parsing

On 12/05/2009 01:44 AM, David Howells wrote:
> Mike Frysinger<[email protected]> wrote:
>
>> The Blackfin port has custom program header flags/addresses for
>> automatically loading regions into the dedicated on-chip SRAM. So
>> add a hook for ports to leverage.
>
> Now that I've ACK'd this, I feel I'm going to have to NAK it. I'm not

> against the general concept, but:
>
>> + do_munmap(mm, *maddr, phdr->p_memsz + *disp);
>
> There needs to be a mapping covering the SRAM region for the purposes
> of the

Our GDB is still lack of the feature to debug applications using SRAM.
So this part of code was not got exercised. So if we remove this line,
can this patch got merged?

> debugger. Do you have a chardev covering the SRAM device? Perhaps
> through MTD?
>
Sorry, I don't know the answer to these two questions.


Jie


_______________________________________________
Uclinux-dist-devel mailing list
[email protected]
https://blackfin.uclinux.org/mailman/listinfo/uclinux-dist-devel

2009-12-07 10:10:11

by Mike Frysinger

[permalink] [raw]
Subject: Re: [uClinux-dev] [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

On Sat, Dec 5, 2009 at 10:14, David Howells wrote:
> Jie Zhang <[email protected]> wrote:
>> > There needs to be a mapping covering the SRAM region for the purposes of the
>>
>> Our GDB is still lack of the feature to debug applications using SRAM. So this
>> part of code was not got exercised. So if we remove this line, can this patch
>> got merged?
>
> No.  Firstly, the piece of storage that gets munmapped isn't used, so unmapping
> it isn't wrong.  What you need to do is to put a mapping over the bit of the
> SRAM you wish to use and then fill it and use it.  Ideally, you'd do this
> inside of do_mmap_pgoff() - that way those bits of the SRAM can be shared, but
> I'm not sure how best to do that.

we've looked into trying to represent the SRAM regions with normal
VMA's a few times, but i think the conclusion every time has been that
it isnt [currently] doable. i vaguely recall it's due to the fact
that Blackfin SRAM is harvard based and VMA's cant cope with this
restriction. Sonic should be able to provide more details though.

currently we have a simpler allocator for kernel/user space to
leverage so that small pieces can be dynamically allocated/freed.

> But you need to stick a VMA over it so that various checks don't spit
> EFAULT/EIO at you.

we give SRAM's a "pass" in every place where addresses are checked
-mike

2009-12-07 10:10:27

by Mike Frysinger

[permalink] [raw]
Subject: Re: [uClinux-dev] [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

On Fri, Dec 4, 2009 at 19:28, Jie Zhang <wrote:
> On 12/05/2009 01:44 AM, David Howells wrote:
>> Mike Frysinger<[email protected]>  wrote:
>>> The Blackfin port has custom program header flags/addresses for
>>> automatically loading regions into the dedicated on-chip SRAM.  So add a
>>> hook for ports to leverage.
>>
>> Now that I've ACK'd this, I feel I'm going to have to NAK it.  I'm not
>> against
>> the general concept, but:
>>
>>> +               do_munmap(mm, *maddr, phdr->p_memsz + *disp);
>>
>> There needs to be a mapping covering the SRAM region for the purposes of
>> the
>
> Our GDB is still lack of the feature to debug applications using SRAM.

semi true. L1 text appears to work fine:
(gdb) stepi
0xffa02aac in moo ()
(gdb) dis
Dump of assembler code from 0xffa02aac to 0xffa02aec:
0xffa02aac <moo+0>: LINK 0xc; /* (12) */
0xffa02ab0 <moo+4>: [FP + 0x8] = R0;
....

but L1 data doesnt seem to work (probably something simple to fix in
our kernel ptrace?):
(gdb) print i
Cannot access memory at address 0xff803e58

the simple code:
int i __attribute__((l1_data));

> So this part of code was not got exercised. So if we remove this line, can
> this patch got merged?

this code does get exercised -- it's run every time code is loaded
from initramfs for example. the
-mike

2009-12-07 10:10:40

by Mike Frysinger

[permalink] [raw]
Subject: Re: [uClinux-dev] [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

On Fri, Dec 4, 2009 at 12:44, David Howells wrote:
> Mike Frysinger <[email protected]> wrote:
>> The Blackfin port has custom program header flags/addresses for
>> automatically loading regions into the dedicated on-chip SRAM.  So add a
>> hook for ports to leverage.
>
> Now that I've ACK'd this, I feel I'm going to have to NAK it.  I'm not against
> the general concept, but:
>
>> +             do_munmap(mm, *maddr, phdr->p_memsz + *disp);
>
> There needs to be a mapping covering the SRAM region for the purposes of the
> debugger.  Do you have a chardev covering the SRAM device?  Perhaps through
> MTD?

SRAM is accessed directly by kernel/user space. there is no device
indirection nor are there any mappings.
-mike

2009-12-07 10:17:17

by Jie Zhang

[permalink] [raw]
Subject: Re: [uClinux-dev] [PATCH/RFC] FDPIC: add hook for arches to customize program header parsing

On 12/07/2009 06:10 PM, Mike Frysinger wrote:
> On Fri, Dec 4, 2009 at 19:28, Jie Zhang<wrote:
>> On 12/05/2009 01:44 AM, David Howells wrote:
>>> Mike Frysinger<[email protected]> wrote:
>>>> The Blackfin port has custom program header flags/addresses for
>>>> automatically loading regions into the dedicated on-chip SRAM. So add a
>>>> hook for ports to leverage.
>>>
>>> Now that I've ACK'd this, I feel I'm going to have to NAK it. I'm not
>>> against
>>> the general concept, but:
>>>
>>>> + do_munmap(mm, *maddr, phdr->p_memsz + *disp);
>>>
>>> There needs to be a mapping covering the SRAM region for the purposes of
>>> the
>>
>> Our GDB is still lack of the feature to debug applications using SRAM.
>
> semi true. L1 text appears to work fine:

This is by lucky. We need some feature in GDB 7.0 to cope with code or
data in L1 SRAM.


Jie