public inbox for ecos-discuss@sourceware.org
 help / color / mirror / Atom feed
* RE: [ECOS] Objloader question
@ 2005-08-26 16:23 Retallack, Mark (Siemens)
  2005-08-28  1:35 ` Andrew Lunn
  0 siblings, 1 reply; 4+ messages in thread
From: Retallack, Mark (Siemens) @ 2005-08-26 16:23 UTC (permalink / raw)
  To: ecos-discuss

[-- Attachment #1: Type: text/plain, Size: 2424 bytes --]

I have started looking at using a branch island. I have attached the
first version. Still lots of stuff that needs to be done to it.



-----Original Message-----
From: ecos-discuss-owner@ecos.sourceware.org
[mailto:ecos-discuss-owner@ecos.sourceware.org] On Behalf Of Retallack,
Mark (Siemens)
Sent: 26 August 2005 10:13
To: ecos-discuss@ecos.sourceware.org
Subject: [ECOS] Objloader question


Sorry if this is a repeat mail, problems with the mail server.

Hello, I have just been looking at the new objloader (a very useful and
cool package), and I have run into a problem. 

I have written a very simple test app to see how it works, all the app
does is export the open_library and a myapp function. When the myapp
function is loaded and called, it should just call the diag_printf
function. However the diag_printf function is stored in flash  (starts
at 0x40000000) and the myapp function is stored in ram (starts at
0x00000000). 

In the myapp.o file, the diag_printf function is defined as a
R_PPC_REL24  relocatable entry, I am running a PowerPC system which
means that it is not possible to perform a branch over the 16MB
boundary. To get this to work I need a method of making the R_PPC_REL24
perform a jump instead. 

I have looked into the following options:

Option 1: Use gcc with the -mlongcall option. 

I have looked at the gcc manual and I believe this should work, however
my version of gcc (3.2.1) does not support the -mlongcall option and I
would prefer not to have to use a different gcc toolchain.

Option 2: Add a branch island 

This would be a ram located "trampoline" than would perform a jump to
the diag_printf in flash when is is called from the myapp function. This
looks like the best long term solution, but I still need to come up with
a way of doing it.


Does anyone have any other ideas? I did think that the MMU could be used
somehow?

Thanks in advance. 


Mark Retallack
Embedded Software Engineer
Siemens Traffic Controls 
Sopers Lane, Poole, Dorset. BH17 7ER. UK.
Tel: 01202 782189
Fax: 01202 782545
www.siemenstraffic.com

Committed to quality traffic solutions and service excellence


Todays Quote:

I can't decide which WRONG TURN to make first!!  


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss


[-- Attachment #2: my.patch2 --]
[-- Type: application/octet-stream, Size: 11202 bytes --]

diff -auEbB -r -u5 -N -x CVS -x '*~' -x '.#*' clean/ecos/packages/services/objloader/current/include/relocate_i386.h devo/ecos/packages/services/objloader/current/include/relocate_i386.h
--- clean/ecos/packages/services/objloader/current/include/relocate_i386.h	2005-07-08 21:14:13.000000000 +0100
+++ devo/ecos/packages/services/objloader/current/include/relocate_i386.h	2005-08-26 15:52:23.879324800 +0100
@@ -64,8 +64,8 @@
 
 #define R_386_32        1
 #define R_386_PC32      2
 
 void      cyg_ldr_flush_cache( void );
-cyg_int32 cyg_ldr_relocate( cyg_int32, cyg_uint32, cyg_int32 );
+cyg_int32 cyg_ldr_relocate( cyg_int32, cyg_uint32, cyg_int32, cyg_uint8 * );
 
 #endif //__RELOCATE_I386_H__
diff -auEbB -r -u5 -N -x CVS -x '*~' -x '.#*' clean/ecos/packages/services/objloader/current/include/relocate_ppc.h devo/ecos/packages/services/objloader/current/include/relocate_ppc.h
--- clean/ecos/packages/services/objloader/current/include/relocate_ppc.h	2005-07-07 11:55:13.000000000 +0100
+++ devo/ecos/packages/services/objloader/current/include/relocate_ppc.h	2005-08-26 15:52:22.867870400 +0100
@@ -125,8 +125,8 @@
 #define _lo_(x)    (x & 0xFFFF) 
 #define _hi_(x)    ((x >> 16) & 0xFFFF)
 #define _ha_(x)    (((x >> 16)+((x & 0x8000) ? 1 : 0)) & 0xFFFF)
 
 void      cyg_ldr_flush_cache( void );
-cyg_int32 cyg_ldr_relocate( cyg_int32, cyg_uint32, cyg_int32 );
+cyg_int32 cyg_ldr_relocate( cyg_int32, cyg_uint32, cyg_int32, cyg_uint8 * );
 
 #endif //__RELOCATE_PPC_H__
diff -auEbB -r -u5 -N -x CVS -x '*~' -x '.#*' clean/ecos/packages/services/objloader/current/src/objelf.c devo/ecos/packages/services/objloader/current/src/objelf.c
--- clean/ecos/packages/services/objloader/current/src/objelf.c	2005-07-08 21:14:13.000000000 +0100
+++ devo/ecos/packages/services/objloader/current/src/objelf.c	2005-08-26 16:40:30.049433600 +0100
@@ -319,15 +319,15 @@
     Elf32_Rela* p_rela = (Elf32_Rela*)cyg_ldr_load_elf_section( p, r_shndx );
 #else
     Elf32_Rel*  p_rel = (Elf32_Rel*)cyg_ldr_load_elf_section( p, r_shndx );
 #endif
 
-#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
     Elf32_Sym *p_symtab = (Elf32_Sym*)cyg_ldr_section_address( p, 
                                                            p->hdrndx_symtab );
     cyg_uint8 *p_strtab = (cyg_uint8*)cyg_ldr_section_address( p, 
                                                            p->hdrndx_strtab );
+#if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
     cyg_uint8 *p_shstrtab = (cyg_uint8*)cyg_ldr_section_address( p, 
                                                      p->p_elfhdr->e_shstrndx );
 #endif
 
     // Now we can get the address of the contents of the section to modify.
@@ -387,11 +387,12 @@
         }    
         diag_printf( "\n" );         
 #endif
         rc = cyg_ldr_relocate( r_type,
                                r_target_addr + r_offset, 
-                               sym_value + r_addend );
+                               sym_value + r_addend,
+                               p_strtab + p_symtab[sym_index].st_name);
         if ( rc != 0 )
         {
 #if CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL > 0
             diag_printf( "Relocation error: Cannot find symbol: %s\n",
                       p_strtab + p_symtab[sym_index].st_name );
diff -auEbB -r -u5 -N -x CVS -x '*~' -x '.#*' clean/ecos/packages/services/objloader/current/src/relocate_i386.c devo/ecos/packages/services/objloader/current/src/relocate_i386.c
--- clean/ecos/packages/services/objloader/current/src/relocate_i386.c	2005-07-08 21:14:14.000000000 +0100
+++ devo/ecos/packages/services/objloader/current/src/relocate_i386.c	2005-08-26 15:52:40.583344000 +0100
@@ -73,11 +73,11 @@
 // 
 // sym_type  Type of relocation to apply,
 // mem       Address in memory to modify (relocate).
 // sym_value 
 cyg_int32 
-cyg_ldr_relocate( cyg_int32 sym_type, cyg_uint32 mem, cyg_int32 sym_value )
+cyg_ldr_relocate( cyg_int32 sym_type, cyg_uint32 mem, cyg_int32 sym_value, cyg_uint8 *strname )
 {
   cyg_int32  i;
   
   // PPC uses rela, so we have to add the addend.
   switch( sym_type )
diff -auEbB -r -u5 -N -x CVS -x '*~' -x '.#*' clean/ecos/packages/services/objloader/current/src/relocate_ppc.c devo/ecos/packages/services/objloader/current/src/relocate_ppc.c
--- clean/ecos/packages/services/objloader/current/src/relocate_ppc.c	2005-07-07 11:55:13.000000000 +0100
+++ devo/ecos/packages/services/objloader/current/src/relocate_ppc.c	2005-08-26 15:54:05.725772800 +0100
@@ -63,11 +63,62 @@
 
 #include <pkgconf/objloader.h>
 #include <cyg/objloader/elf.h>
 #include <cyg/objloader/objelf.h>
 
+
+#include <cyg/infra/diag.h>
+
 #ifdef CYGPKG_HAL_POWERPC
+
+// The code block is make up of
+// the following instructions
+// NOTE: the bctrl opcode generates 0x4e, 0x80, 0x04, 0x21,
+// and we need 0x4e, 0x80, 0x04, 0x20, this will
+// leave the LR intact
+//
+//    asm volatile(
+//                "subi 1,1,8\n"
+//                "stw 3,0(1)\n"
+//                "lis 3,16386\n"
+//                "ori 3,3,8192\n"
+//                "mtctr 3\n"
+//                "lwz 3,0(1)\n"
+//                "addi 1,1,8\n"
+//                "bctrl\n"
+//                );
+//
+
+static const char cyg_ldr_rel24_code[] =
+{
+    0x38, 0x21, 0xff, 0xf8,
+    0x90, 0x61, 0x00, 0x00,
+    0x3c, 0x60, 0x40, 0x02,
+    0x60, 0x63, 0x20, 0x00,
+    0x7c, 0x69, 0x03, 0xa6,
+    0x80, 0x61, 0x00, 0x00,
+    0x38, 0x21, 0x00, 0x08,
+    0x4e, 0x80, 0x04, 0x20
+};
+
+
+typedef struct
+{
+    char cayTrampoline[sizeof(cyg_ldr_rel24_code)];
+    char *pcaName;
+    void *pNextTrampoline;
+} cyg_ldr_rel24_trampoline_type;
+
+
+// this assumes that the trampoline will be placed
+// in the same memory space as the loaded function
+// NOTE: this is a very simple linked list
+// we dont free it because we may need the entrys later
+// but we could free it!!
+static cyg_ldr_rel24_trampoline_type *cyg_ldr_rel24_trampoline_head = NULL;
+static cyg_ldr_rel24_trampoline_type *cyg_ldr_rel24_trampoline_tail = NULL;
+
 void
 cyg_ldr_flush_cache( void )
 {
     HAL_DCACHE_SYNC();
     HAL_ICACHE_SYNC();
@@ -77,11 +128,11 @@
 // 
 // sym_type  Type of relocation to apply,
 // mem       Address in memory to modify (relocate).
 // sym_value 
 cyg_int32 
-cyg_ldr_relocate( cyg_int32 sym_type, cyg_uint32 mem, cyg_int32 sym_value )
+cyg_ldr_relocate( cyg_int32 sym_type, cyg_uint32 mem, cyg_int32 sym_value, cyg_uint8 *strname)
 {
     cyg_int32  rel_offset, i;
 
     // PPC uses rela, so we have to add the addend.
     switch( sym_type )
@@ -94,10 +145,101 @@
         return 0;
     case R_PPC_ADDR16_LO:
         HAL_WRITE_UINT16( mem, _lo_( sym_value ) );
         return 0;
     case R_PPC_REL24:
+
+        // only do this if the name is valid
+        if (strlen(strname) > 0)
+        {
+            if (cyg_ldr_rel24_trampoline_head == NULL )
+            {
+                // need to setup the list
+                cyg_ldr_rel24_trampoline_head = malloc(sizeof(cyg_ldr_rel24_trampoline_type));
+                // TODO: there may be an error here
+                cyg_ldr_rel24_trampoline_tail = cyg_ldr_rel24_trampoline_head;
+
+                if (cyg_ldr_rel24_trampoline_tail != NULL)
+                    memset(cyg_ldr_rel24_trampoline_tail, 0x0, sizeof(cyg_ldr_rel24_trampoline_type));
+
+            }
+
+            if (cyg_ldr_rel24_trampoline_head != NULL )
+            {
+
+                bool blnFound = false;
+
+                cyg_ldr_rel24_trampoline_type *pCurrentTrampoline;
+
+                pCurrentTrampoline = cyg_ldr_rel24_trampoline_head;
+
+                // ok, name is valid
+                // now scan the list for a matching entry
+                while((pCurrentTrampoline != NULL)&&(blnFound == false))
+                {
+                    if ((cyg_ldr_rel24_trampoline_tail->pcaName != NULL)&&
+                            (strcmp(pCurrentTrampoline->pcaName, strname) == 0))
+                    {
+                        // we have a match, so use it
+                        blnFound = true;
+                    }
+                    else
+                    {
+                        // select the next entry
+                        pCurrentTrampoline = pCurrentTrampoline->pNextTrampoline;
+                    }
+                }
+
+                // ok, did we find it?
+                if (blnFound == false)
+                {
+                    // no, so we need to alloc a new entry
+
+                    // Ok we need to construct the trampoline
+                    // this will be called instead of the function
+                    // directly and will inturn jump to the function.
+                    memcpy(&cyg_ldr_rel24_trampoline_tail->cayTrampoline[0], cyg_ldr_rel24_code, sizeof(cyg_ldr_rel24_code));
+
+                    // need to mod the address,
+                    // first to the top 16 bits
+                    cyg_ldr_rel24_trampoline_tail->cayTrampoline[10] = (char)((sym_value>>24)&0xff);
+                    cyg_ldr_rel24_trampoline_tail->cayTrampoline[11] = (char)((sym_value>>16)&0xff);
+                    // now the bottom 16 bits
+                    cyg_ldr_rel24_trampoline_tail->cayTrampoline[14] = (char)((sym_value>>8)&0xff);
+                    cyg_ldr_rel24_trampoline_tail->cayTrampoline[15] = (char)((sym_value>>0)&0xff);
+
+                    cyg_ldr_rel24_trampoline_tail->pcaName = malloc(strlen(strname)+1);
+
+                    if (cyg_ldr_rel24_trampoline_tail->pcaName != NULL)
+                    {
+                        // set this new entry to the correct name
+                        strcpy(cyg_ldr_rel24_trampoline_tail->pcaName, strname);
+                    }
+
+                    // ok, use this entry for the Trampoline
+                    pCurrentTrampoline = cyg_ldr_rel24_trampoline_tail;
+
+
+                    // now create the next entry
+                    cyg_ldr_rel24_trampoline_tail->pNextTrampoline = malloc(sizeof(cyg_ldr_rel24_trampoline_type));
+                    // set us to the next trampiline
+                    cyg_ldr_rel24_trampoline_tail = (cyg_ldr_rel24_trampoline_type*)cyg_ldr_rel24_trampoline_tail->pNextTrampoline;
+
+                    if (cyg_ldr_rel24_trampoline_tail != NULL)
+                        memset(cyg_ldr_rel24_trampoline_tail, 0x0, sizeof(cyg_ldr_rel24_trampoline_type));
+                }
+                else
+                {
+                    // we found an entry so use it
+                }
+
+                // set the location of the
+                // function to the trampoline instead
+                sym_value = (cyg_int32)&pCurrentTrampoline->cayTrampoline[0];
+            }
+        }
+
         // Now it is time to seek the destination address of the call.
         // We need to do something in case the user jumps more than 16MB.
         rel_offset = ( sym_value - mem ) & 0x03FFFFFC; 
         HAL_READ_UINT32( mem, i );
         i &= 0xFC000003;

[-- Attachment #3: Type: text/plain, Size: 148 bytes --]

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [ECOS] Objloader question
  2005-08-26 16:23 [ECOS] Objloader question Retallack, Mark (Siemens)
@ 2005-08-28  1:35 ` Andrew Lunn
  0 siblings, 0 replies; 4+ messages in thread
From: Andrew Lunn @ 2005-08-28  1:35 UTC (permalink / raw)
  To: Retallack, Mark (Siemens); +Cc: ecos-discuss

On Fri, Aug 26, 2005 at 05:20:55PM +0100, Retallack, Mark (Siemens) wrote:
> I have started looking at using a branch island. I have attached the
> first version. Still lots of stuff that needs to be done to it.

Hi Mark

Please could you make this code conditionally compilable with a CDL
option.

Also could you think about splitting it into a generic part and a
processor specific part. The ARM will have the same problem with its
limited ability to jump.

        Andrew

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: [ECOS] Objloader question
@ 2005-08-30 23:22 Retallack, Mark (Siemens)
  0 siblings, 0 replies; 4+ messages in thread
From: Retallack, Mark (Siemens) @ 2005-08-30 23:22 UTC (permalink / raw)
  To: ecos-discuss

[-- Attachment #1: Type: text/plain, Size: 3247 bytes --]

I have made some minor mods, thanks to Anthony Tonizzo and Andrew Lunn.

1. Now only uses branch island if, and only if the call is over 26bits. 
2. Uses absolute address instead of function name. 
3. Enabled by CDL option.

I have not yet got around to making it platform independent, I did not
think that I would be able to give it the time required. I am not sure
when I will be able to work on it again, so I am sending this patch so
that it is out in the open. 

NOTE: I have not fully tested it. It is still a work in progress.


-----Original Message-----
From: ecos-discuss-owner@ecos.sourceware.org
[mailto:ecos-discuss-owner@ecos.sourceware.org] On Behalf Of Retallack,
Mark (Siemens)
Sent: 26 August 2005 17:21
To: ecos-discuss@ecos.sourceware.org
Subject: RE: [ECOS] Objloader question


I have started looking at using a branch island. I have attached the
first version. Still lots of stuff that needs to be done to it.



-----Original Message-----
From: ecos-discuss-owner@ecos.sourceware.org
[mailto:ecos-discuss-owner@ecos.sourceware.org] On Behalf Of Retallack,
Mark (Siemens)
Sent: 26 August 2005 10:13
To: ecos-discuss@ecos.sourceware.org
Subject: [ECOS] Objloader question


Sorry if this is a repeat mail, problems with the mail server.

Hello, I have just been looking at the new objloader (a very useful and
cool package), and I have run into a problem. 

I have written a very simple test app to see how it works, all the app
does is export the open_library and a myapp function. When the myapp
function is loaded and called, it should just call the diag_printf
function. However the diag_printf function is stored in flash  (starts
at 0x40000000) and the myapp function is stored in ram (starts at
0x00000000). 

In the myapp.o file, the diag_printf function is defined as a
R_PPC_REL24  relocatable entry, I am running a PowerPC system which
means that it is not possible to perform a branch over the 16MB
boundary. To get this to work I need a method of making the R_PPC_REL24
perform a jump instead. 

I have looked into the following options:

Option 1: Use gcc with the -mlongcall option. 

I have looked at the gcc manual and I believe this should work, however
my version of gcc (3.2.1) does not support the -mlongcall option and I
would prefer not to have to use a different gcc toolchain.

Option 2: Add a branch island 

This would be a ram located "trampoline" than would perform a jump to
the diag_printf in flash when is is called from the myapp function. This
looks like the best long term solution, but I still need to come up with
a way of doing it.


Does anyone have any other ideas? I did think that the MMU could be used
somehow?

Thanks in advance. 


Mark Retallack
Embedded Software Engineer
Siemens Traffic Controls 
Sopers Lane, Poole, Dorset. BH17 7ER. UK.
Tel: 01202 782189
Fax: 01202 782545
www.siemenstraffic.com

Committed to quality traffic solutions and service excellence


Todays Quote:

I can't decide which WRONG TURN to make first!!  


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss


[-- Attachment #2: my.patch --]
[-- Type: application/octet-stream, Size: 9461 bytes --]

diff -raurEbB -u5 -N -x CVS -x '*~' -x '.#*' clean/ecos/packages/services/objloader/current/ChangeLog devo/ecos/packages/services/objloader/current/ChangeLog
--- clean/ecos/packages/services/objloader/current/ChangeLog	2005-07-08 21:14:13.000000000 +0100
+++ devo/ecos/packages/services/objloader/current/ChangeLog	2005-08-30 13:11:09.614088000 +0100
@@ -1,5 +1,10 @@
+2005-08-30  Mark Retallack  <mark.retallack@siemens.com>
+
+	* src/relocate_ppc.c: Added branch Island to allow 26bit function calls
+	* cdl/objloader.cdl: Added option to enable branch island support
+
 2005-07-08  Andrew Lunn  <andrew.lunn@ascom.ch>
 
 	* include/objelf.h: Include hal_tables.h otherwise we get strange
 	linker errors.
 	* cdl/objloader.cdl: Rearranged the building of the test case.
diff -raurEbB -u5 -N -x CVS -x '*~' -x '.#*' clean/ecos/packages/services/objloader/current/cdl/objloader.cdl devo/ecos/packages/services/objloader/current/cdl/objloader.cdl
--- clean/ecos/packages/services/objloader/current/cdl/objloader.cdl	2005-07-08 21:14:13.000000000 +0100
+++ devo/ecos/packages/services/objloader/current/cdl/objloader.cdl	2005-08-30 14:56:08.010737600 +0100
@@ -102,10 +102,20 @@
 #               puts $::cdl_header "#include <cyg/objloader/relocate_arm.h>"
 #            }
 #            compile relocate_arm.c
 #        }
         
+        cdl_option CYGPKG_SERVICES_OBJLOADER_BRANCH_ISLAND {
+            display        "Enable branch islands"
+            flavor         bool
+            active_if      { CYGBLD_OBJLOADER_ARCHITECTURE_POWERPC }
+            default_value  0
+            description    "
+               This option enables support for adding branch islands
+               when a branch is over the architectures maximum address range"
+        }        
+                
     }
  
     cdl_option CYGPKG_SERVICES_OBJLOADER_DEBUG_LEVEL {
         display          "Verbosity of debug output"
         flavor           data
diff -raurEbB -u5 -N -x CVS -x '*~' -x '.#*' clean/ecos/packages/services/objloader/current/src/relocate_ppc.c devo/ecos/packages/services/objloader/current/src/relocate_ppc.c
--- clean/ecos/packages/services/objloader/current/src/relocate_ppc.c	2005-07-07 11:55:13.000000000 +0100
+++ devo/ecos/packages/services/objloader/current/src/relocate_ppc.c	2005-08-30 15:15:27.968675200 +0100
@@ -63,11 +63,66 @@
 
 #include <pkgconf/objloader.h>
 #include <cyg/objloader/elf.h>
 #include <cyg/objloader/objelf.h>
 
+
+#include <cyg/infra/diag.h>
+
 #ifdef CYGPKG_HAL_POWERPC
+
+// The code block is make up of
+// the following instructions
+// NOTE: the bctrl opcode generates 0x4e, 0x80, 0x04, 0x21,
+// and we need 0x4e, 0x80, 0x04, 0x20, this will
+// leave the LR intact
+//
+//    asm volatile(
+//                "subi 1,1,8\n"
+//                "stw 3,0(1)\n"
+//                "lis 3,16386\n"
+//                "ori 3,3,8192\n"
+//                "mtctr 3\n"
+//                "lwz 3,0(1)\n"
+//                "addi 1,1,8\n"
+//                "bctrl\n"
+//                );
+//
+#ifdef CYGPKG_SERVICES_OBJLOADER_BRANCH_ISLAND
+
+static const char cyg_ldr_rel24_code[] =
+{
+    0x38, 0x21, 0xff, 0xf8,
+    0x90, 0x61, 0x00, 0x00,
+    0x3c, 0x60, 0x40, 0x02,
+    0x60, 0x63, 0x20, 0x00,
+    0x7c, 0x69, 0x03, 0xa6,
+    0x80, 0x61, 0x00, 0x00,
+    0x38, 0x21, 0x00, 0x08,
+    0x4e, 0x80, 0x04, 0x20
+};
+
+
+typedef struct
+{
+    char cayTrampoline[sizeof(cyg_ldr_rel24_code)];
+    cyg_int32 intOriginalLocation;
+    void *pNextTrampoline;
+} cyg_ldr_rel24_trampoline_type;
+
+
+// this assumes that the trampoline will be placed
+// in the same memory space as the loaded function
+// NOTE: this is a very simple linked list
+// we dont free it because we may need the entrys later
+// but we could free it!!
+static cyg_ldr_rel24_trampoline_type *cyg_ldr_rel24_trampoline_head = NULL;
+static cyg_ldr_rel24_trampoline_type *cyg_ldr_rel24_trampoline_tail = NULL;
+
+#endif // CYGPKG_SERVICES_OBJLOADER_BRANCH_ISLAND
+
+
 void
 cyg_ldr_flush_cache( void )
 {
     HAL_DCACHE_SYNC();
     HAL_ICACHE_SYNC();
@@ -77,11 +132,11 @@
 // 
 // sym_type  Type of relocation to apply,
 // mem       Address in memory to modify (relocate).
 // sym_value 
 cyg_int32 
-cyg_ldr_relocate( cyg_int32 sym_type, cyg_uint32 mem, cyg_int32 sym_value )
+cyg_ldr_relocate( cyg_int32 sym_type, cyg_uint32 mem, cyg_int32 sym_value)
 {
     cyg_int32  rel_offset, i;
 
     // PPC uses rela, so we have to add the addend.
     switch( sym_type )
@@ -94,12 +149,104 @@
         return 0;
     case R_PPC_ADDR16_LO:
         HAL_WRITE_UINT16( mem, _lo_( sym_value ) );
         return 0;
     case R_PPC_REL24:
+
+
+#ifdef CYGPKG_SERVICES_OBJLOADER_BRANCH_ISLAND
+        // ok, check if the user is calling more than
+        // the ppc can handle. This means that if the relative
+        // address has any of the top 6 bits set, then we need
+        // to use the trampoline
+        if ((( sym_value - mem )&0xfc000000) != 0)
+        {
+            if (cyg_ldr_rel24_trampoline_head == NULL )
+            {
+                // need to setup the list
+                cyg_ldr_rel24_trampoline_head = malloc(sizeof(cyg_ldr_rel24_trampoline_type));
+                // there may be an error here, but the rest of the code is
+                // make so that we can continue without the trampoline
+                cyg_ldr_rel24_trampoline_tail = cyg_ldr_rel24_trampoline_head;
+
+                if (cyg_ldr_rel24_trampoline_tail != NULL)
+                    memset(cyg_ldr_rel24_trampoline_tail, 0x0, sizeof(cyg_ldr_rel24_trampoline_type));
+
+            }
+
+            if (cyg_ldr_rel24_trampoline_head != NULL )
+            {
+
+                bool blnFound = false;
+
+                cyg_ldr_rel24_trampoline_type *pCurrentTrampoline;
+
+                pCurrentTrampoline = cyg_ldr_rel24_trampoline_head;
+
+                // ok, name is valid
+                // now scan the list for a matching entry
+                while((pCurrentTrampoline != NULL)&&(blnFound == false))
+                {
+                    if ((pCurrentTrampoline->intOriginalLocation != 0)&&
+                            (pCurrentTrampoline->intOriginalLocation == sym_value ))
+                    {
+                        // we have a match, so use it
+                        blnFound = true;
+                    }
+                    else
+                    {
+                        // select the next entry
+                        pCurrentTrampoline = pCurrentTrampoline->pNextTrampoline;
+                    }
+                }
+
+                // ok, did we find it?
+                if (blnFound == false)
+                {
+                    // no, so we need to alloc a new entry
+
+                    // Ok we need to construct the trampoline
+                    // this will be called instead of the function
+                    // directly and will inturn jump to the function.
+                    memcpy(&cyg_ldr_rel24_trampoline_tail->cayTrampoline[0], cyg_ldr_rel24_code, sizeof(cyg_ldr_rel24_code));
+
+                    // need to mod the address,
+                    // first to the top 16 bits
+                    cyg_ldr_rel24_trampoline_tail->cayTrampoline[10] = (char)((sym_value>>24)&0xff);
+                    cyg_ldr_rel24_trampoline_tail->cayTrampoline[11] = (char)((sym_value>>16)&0xff);
+                    // now the bottom 16 bits
+                    cyg_ldr_rel24_trampoline_tail->cayTrampoline[14] = (char)((sym_value>>8)&0xff);
+                    cyg_ldr_rel24_trampoline_tail->cayTrampoline[15] = (char)((sym_value>>0)&0xff);
+
+                    // ok, set the original location to jump to, to the
+                    // location that would of been used
+                    cyg_ldr_rel24_trampoline_tail->intOriginalLocation = sym_value;
+
+                    // ok, use this entry for the Trampoline
+                    pCurrentTrampoline = cyg_ldr_rel24_trampoline_tail;
+
+                    // now create the next entry
+                    cyg_ldr_rel24_trampoline_tail->pNextTrampoline = malloc(sizeof(cyg_ldr_rel24_trampoline_type));
+                    // set us to the next trampiline
+                    cyg_ldr_rel24_trampoline_tail = (cyg_ldr_rel24_trampoline_type*)cyg_ldr_rel24_trampoline_tail->pNextTrampoline;
+
+                    if (cyg_ldr_rel24_trampoline_tail != NULL)
+                        memset(cyg_ldr_rel24_trampoline_tail, 0x0, sizeof(cyg_ldr_rel24_trampoline_type));
+                }
+                else
+                {
+                    // we found an entry so use it
+                }
+
+                // set the location of the
+                // function to the trampoline instead
+                sym_value = (cyg_int32)&pCurrentTrampoline->cayTrampoline[0];
+            }
+        }
+#endif // CYGPKG_SERVICES_OBJLOADER_BRANCH_ISLAND
+
         // Now it is time to seek the destination address of the call.
-        // We need to do something in case the user jumps more than 16MB.
         rel_offset = ( sym_value - mem ) & 0x03FFFFFC; 
         HAL_READ_UINT32( mem, i );
         i &= 0xFC000003;
         HAL_WRITE_UINT32( mem, rel_offset | i );
         return 0;

[-- Attachment #3: Type: text/plain, Size: 148 bytes --]

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ECOS] Objloader question
@ 2005-08-26  9:15 Retallack, Mark (Siemens)
  0 siblings, 0 replies; 4+ messages in thread
From: Retallack, Mark (Siemens) @ 2005-08-26  9:15 UTC (permalink / raw)
  To: ecos-discuss

Sorry if this is a repeat mail, problems with the mail server.

Hello, I have just been looking at the new objloader (a very useful and
cool package), and I have run into a problem. 

I have written a very simple test app to see how it works, all the app
does is export the open_library and a myapp function. When the myapp
function is loaded and called, it should just call the diag_printf
function. However the diag_printf function is stored in flash  (starts
at 0x40000000) and the myapp function is stored in ram (starts at
0x00000000). 

In the myapp.o file, the diag_printf function is defined as a
R_PPC_REL24  relocatable entry, I am running a PowerPC system which
means that it is not possible to perform a branch over the 16MB
boundary. To get this to work I need a method of making the R_PPC_REL24
perform a jump instead. 

I have looked into the following options:

Option 1: Use gcc with the -mlongcall option. 

I have looked at the gcc manual and I believe this should work, however
my version of gcc (3.2.1) does not support the -mlongcall option and I
would prefer not to have to use a different gcc toolchain.

Option 2: Add a branch island 

This would be a ram located "trampoline" than would perform a jump to
the diag_printf in flash when is is called from the myapp function. This
looks like the best long term solution, but I still need to come up with
a way of doing it.


Does anyone have any other ideas? I did think that the MMU could be used
somehow?

Thanks in advance. 


Mark Retallack
Embedded Software Engineer
Siemens Traffic Controls 
Sopers Lane, Poole, Dorset. BH17 7ER. UK.
Tel: 01202 782189
Fax: 01202 782545
www.siemenstraffic.com

Committed to quality traffic solutions and service excellence


Todays Quote:

I can't decide which WRONG TURN to make first!!  


--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-08-30 16:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-08-26 16:23 [ECOS] Objloader question Retallack, Mark (Siemens)
2005-08-28  1:35 ` Andrew Lunn
  -- strict thread matches above, loose matches on Subject: below --
2005-08-30 23:22 Retallack, Mark (Siemens)
2005-08-26  9:15 Retallack, Mark (Siemens)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).