Changed the DDR rate to 1333 and fixed the HUA boot from NOR problem
[keystone-rtos/ibl.git] / src / interp / elf / dlw_client.c
1 /*
2 * dlw_client.c
3 *
4 * RIDL implementation of client functions required by dynamic loader API.
5 * Please see list of client-required API functions in dload_api.h.
6 *
7 * This implementation of RIDL is expected to run on the DSP.  It uses C6x 
8 * RTS functions for file I/O and memory management (both host and target 
9 * memory).
10 *
11 * A loader that runs on a GPP for the purposes of loading C6x code onto a
12 * DSP will likely need to re-write all of the functions contained in this
13 * module.
14 *
15 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
16  * 
17  *  Redistribution and use in source and binary forms, with or without 
18  *  modification, are permitted provided that the following conditions 
19  *  are met:
20  *
21  *    Redistributions of source code must retain the above copyright 
22  *    notice, this list of conditions and the following disclaimer.
23  *
24  *    Redistributions in binary form must reproduce the above copyright
25  *    notice, this list of conditions and the following disclaimer in the 
26  *    documentation and/or other materials provided with the   
27  *    distribution.
28  *
29  *    Neither the name of Texas Instruments Incorporated nor the names of
30  *    its contributors may be used to endorse or promote products derived
31  *    from this software without specific prior written permission.
32  *
33  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
34  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
35  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
36  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
37  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
38  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
39  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
40  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
41  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
42  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
43  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44  *
45 */
47 #include "types.h"
48 #include "ewrap.h"
49 #include "ArrayList.h"
50 #include "dload_api.h"
51 #include <stdarg.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include "file_ovr.h"
56 /* Eat printfs. */
57 #define printf  mprintf
58 #define vprintf(x,y) 
60 #if 0
61 #include "dlw_debug.h"
62 #include "dlw_dsbt.h"
63 #include "dlw_trgmem.h"
64 #endif
66 /*****************************************************************************/
67 /* Client Provided File I/O                                                  */
68 /*****************************************************************************/
69 /*****************************************************************************/
70 /* DLIF_FSEEK() - Seek to a position in specified file.                      */
71 /*****************************************************************************/
72 int DLIF_fseek(LOADER_FILE_DESC *stream, int32_t offset, int origin)
73 {
74    return fseek(stream, offset, origin);
75 }
77 /*****************************************************************************/
78 /* DLIF_FTELL() - Return the current position in the given file.             */
79 /*****************************************************************************/
80 int32_t DLIF_ftell(LOADER_FILE_DESC *stream)
81 {
82    return ftell(stream);
83 }
85 /*****************************************************************************/
86 /* DLIF_FREAD() - Read data from file into a host-accessible data buffer     */
87 /*      that can be accessed through "ptr".                                  */
88 /*****************************************************************************/
89 size_t DLIF_fread(void *ptr, size_t size, size_t nmemb,
90                   LOADER_FILE_DESC *stream)
91 {
92    return fread(ptr, size, nmemb, stream);
93 }
95 /*****************************************************************************/
96 /* DLIF_FCLOSE() - Close a file that was opened on behalf of the core        */
97 /*      loader. Core loader has ownership of the file pointer, but client    */
98 /*      has access to file system.                                           */
99 /*****************************************************************************/
100 int32_t DLIF_fclose(LOADER_FILE_DESC *fd)
102    return fclose(fd);
105 /*****************************************************************************/
106 /* Client Provided Host Memory Management                                    */
107 /*****************************************************************************/
108 /*****************************************************************************/
109 /* DLIF_MALLOC() - Allocate host memory suitable for loader scratch space.   */
110 /*****************************************************************************/
111 void* DLIF_malloc(size_t size)
113    return iblMalloc(size*sizeof(uint8_t));
116 /*****************************************************************************/
117 /* DLIF_FREE() - Free host memory previously allocated with DLIF_malloc().   */
118 /*****************************************************************************/
119 void DLIF_free(void* ptr)
121    iblFree(ptr);
124 /*****************************************************************************/
125 /* Client Provided Target Memory Management                                  */
126 /*****************************************************************************/
128 /*****************************************************************************/
129 /* RIDL-Specific hack to facilitate target memory allocation.                */
130 /*****************************************************************************/
131 /*****************************************************************************/
132 /* DLIF_ALLOCATE() - Return the load address of the segment/section          */
133 /*      described in its parameters and record the run address in            */
134 /*      run_address field of DLOAD_MEMORY_REQUEST.                           */
135 /*****************************************************************************/
136 BOOL DLIF_allocate(struct DLOAD_MEMORY_REQUEST *targ_req)
138    /*------------------------------------------------------------------------*/
139    /* Get pointers to API segment and file descriptors.                      */
140    /*------------------------------------------------------------------------*/
141    struct DLOAD_MEMORY_SEGMENT* obj_desc = targ_req->segment;
142    LOADER_FILE_DESC* f = targ_req->fp;
144    /*------------------------------------------------------------------------*/
145    /* Request target memory for this segment from the "blob".                */
146    /*------------------------------------------------------------------------*/
147    if (!DLTMM_malloc(targ_req, obj_desc))
148    {
149       DLIF_error(DLET_MEMORY, "Failed to allocate target memory for segment.\n");
150       return 0;
151    }
153    /*------------------------------------------------------------------------*/
154    /* As required by API, copy the described segment into memory from file.  */
155    /* We're the client, not the loader, so we can use fseek() and fread().   */
156    /*------------------------------------------------------------------------*/
157    /* ??? I don't think we want to do this if we are allocating target       */
158    /*   memory for the run only placement of this segment.  If it is the     */
159    /*   load placement or both load and run placement, then we can do the    */
160    /*   copy.                                                                */
161    /*------------------------------------------------------------------------*/
162    if (obj_desc->objsz_in_bytes)
163    {
164        /* Do not clear uninitialized data section, so that the section can 
165           be mapped to the same region IBL uses */ 
166        memset(targ_req->host_address, 0, obj_desc->memsz_in_bytes);
167        fseek(f,targ_req->offset,SEEK_SET);
168        fread(targ_req->host_address,obj_desc->objsz_in_bytes,1,f);
169    }
171    /*------------------------------------------------------------------------*/
172    /* Once we have target address for this allocation, add debug information */
173    /* about this segment to the debug record for the module that is          */
174    /* currently being loaded.                                                */
175    /*------------------------------------------------------------------------*/
176    if (DLL_debug)
177    {
178       /*---------------------------------------------------------------------*/
179       /* Add information about this segment's location to the segment debug  */
180       /* information associated with the module that is currently being      */
181       /* loaded.                                                             */
182       /*---------------------------------------------------------------------*/
183       /* ??? We need a way to determine whether the target address in the    */
184       /*        segment applies to the load address of the segment or the    */
185       /*        run address.  For the time being, we assume that it applies  */
186       /*        to both (that is, the dynamic loader does not support        */
187       /*        separate load and run placement for a given segment).        */
188       /*---------------------------------------------------------------------*/
189       DLDBG_add_segment_record(obj_desc);
190    }
192 #if LOADER_DEBUG
193    if (debugging_on)
194       printf("DLIF_allocate: buffer 0x%x\n", targ_req->host_address);
195 #endif
197    /*------------------------------------------------------------------------*/
198    /* Target memory request was successful.                                  */
199    /*------------------------------------------------------------------------*/
200    return 1;
203 /*****************************************************************************/
204 /* DLIF_RELEASE() - Unmap or free target memory that was previously          */
205 /*      allocated by DLIF_allocate().                                        */
206 /*****************************************************************************/
207 BOOL DLIF_release(struct DLOAD_MEMORY_SEGMENT* ptr)
209 #if LOADER_DEBUG
210    if (debugging_on)
211       printf("DLIF_free: %d bytes starting at 0x%x\n",
212                                      ptr->memsz_in_bytes, ptr->target_address);
213 #endif
215    /*------------------------------------------------------------------------*/
216    /* Find the target memory packet associated with this address and mark it */
217    /* as available (will also merge with adjacent free packets).             */
218    /*------------------------------------------------------------------------*/
219    DLTMM_free(ptr->target_address);
221    return 1;
224 /*****************************************************************************/
225 /* DLIF_COPY() - Copy data from file to host-accessible memory.              */
226 /*      Returns a host pointer to the data in the host_address field of the  */
227 /*      DLOAD_MEMORY_REQUEST object.                                         */
228 /*****************************************************************************/
229 BOOL DLIF_copy(struct DLOAD_MEMORY_REQUEST* targ_req)
231    targ_req->host_address = (void*)(targ_req->segment->target_address);
232    return 1;
235 /*****************************************************************************/
236 /* DLIF_READ() - Read content from target memory address into host-          */
237 /*      accessible buffer.                                                   */
238 /*****************************************************************************/
239 BOOL DLIF_read(void *ptr, size_t size, size_t nmemb, TARGET_ADDRESS src)
241    if (!memcpy(ptr, (const void *)src, size * nmemb)) 
242       return 0;
244    return 1;
247 /*****************************************************************************/
248 /* DLIF_WRITE() - Write updated (relocated) segment contents to target       */
249 /*      memory.                                                              */
250 /*****************************************************************************/
251 BOOL DLIF_write(struct DLOAD_MEMORY_REQUEST* req)
253    /*------------------------------------------------------------------------*/
254    /* Nothing to do since we are relocating directly into target memory.     */
255    /*------------------------------------------------------------------------*/
256    return 1;
259 /*****************************************************************************/
260 /* DLIF_EXECUTE() - Transfer control to specified target address.            */
261 /*****************************************************************************/
262 int32_t DLIF_execute(TARGET_ADDRESS exec_addr)
264    /*------------------------------------------------------------------------*/
265    /* This call will only work if the host and target are the same instance. */
266    /* The compiler may warn about this conversion from an object to a        */
267    /* function pointer.                                                      */
268    /*------------------------------------------------------------------------*/
269    return ((int32_t(*)())(exec_addr))();
273 #if 0
274 /*****************************************************************************/
275 /* Client Provided Communication Mechanisms to assist with creation of       */
276 /* DLLView debug information.  Client needs to know exactly when a segment   */
277 /* is being loaded or unloaded so that it can keep its debug information     */
278 /* up to date.                                                               */
279 /*****************************************************************************/
280 /*****************************************************************************/
281 /* DLIF_LOAD_DEPENDENT() - Perform whatever maintenance is needed in the     */
282 /*      client when loading of a dependent file is initiated by the core     */
283 /*      loader.  Open the dependent file on behalf of the core loader,       */
284 /*      then invoke the core loader to get it into target memory. The core   */
285 /*      loader assumes ownership of the dependent file pointer and must ask  */
286 /*      the client to close the file when it is no longer needed.            */
287 /*                                                                           */
288 /*      If debug support is needed under the Braveheart model, then create   */
289 /*      a host version of the debug module record for this object.  This     */
290 /*      version will get updated each time we allocate target memory for a   */
291 /*      segment that belongs to this module.  When the load returns, the     */
292 /*      client will allocate memory for the debug module from target memory  */
293 /*      and write the host version of the debug module into target memory    */
294 /*      at the appropriate location.  After this takes place the new debug   */
295 /*      module needs to be added to the debug module list.  The client will  */
296 /*      need to update the tail of the DLModules list to link the new debug  */
297 /*      module onto the end of the list.                                     */
298 /*                                                                           */
299 /*****************************************************************************/
300 int DLIF_load_dependent(const char* so_name)
302    /*------------------------------------------------------------------------*/
303    /* Find the path and file name associated with the given so_name in the   */
304    /* client's file registry.                                                */
305    /*------------------------------------------------------------------------*/
306    /* If we can't find the so_name in the file registry (or if the registry  */
307    /* is not implemented yet), we'll open the file using the so_name.        */
308    /*------------------------------------------------------------------------*/
309    int to_ret = 0;
310    FILE* fp = fopen(so_name, "rb");
311    
312    /*------------------------------------------------------------------------*/
313    /* We need to make sure that the file was properly opened.                */
314    /*------------------------------------------------------------------------*/
315    if (!fp)
316    {
317       DLIF_error(DLET_FILE, "Can't open dependent file '%s'.\n", so_name);
318       return 0;
319    }
321    /*------------------------------------------------------------------------*/
322    /* If the dynamic loader is providing debug support for a DLL View plug-  */
323    /* in or script of some sort, then we are going to create a host version  */
324    /* of the debug module record for the so_name module.                     */
325    /*------------------------------------------------------------------------*/
326    /* In the Braveheart view of the world, debug support is only to be       */
327    /* provided if the DLModules symbol is defined in the base image.         */
328    /* We will set up a DLL_debug flag when the command to load the base      */
329    /* image is issued.                                                       */
330    /*------------------------------------------------------------------------*/
331    if (DLL_debug)
332       DLDBG_add_host_record(so_name);
334    /*------------------------------------------------------------------------*/
335    /* Tell the core loader to proceed with loading the module.               */
336    /*------------------------------------------------------------------------*/
337    /* Note that the client is turning ownership of the file pointer over to  */
338    /* the core loader at this point. The core loader will need to ask the    */
339    /* client to close the dependent file when it is done using the dependent */
340    /* file pointer.                                                          */
341    /*------------------------------------------------------------------------*/
342    to_ret = DLOAD_load(fp, 0, NULL);
344    /*------------------------------------------------------------------------*/
345    /* If the dependent load was successful, update the DLModules list in     */
346    /* target memory as needed.                                               */
347    /*------------------------------------------------------------------------*/
348    if (to_ret != 0)
349    {
350       /*---------------------------------------------------------------------*/
351       /* We will need to copy the information from our host version of the   */
352       /* debug record into actual target memory.                             */
353       /*---------------------------------------------------------------------*/
354       if (DLL_debug)
355       {
356          /*---------------------------------------------------------------*/
357          /* Allocate target memory for the module's debug record.  Use    */
358          /* host version of the debug information to determine how much   */
359          /* target memory we need and how it is to be filled in.          */
360          /*---------------------------------------------------------------*/
361          /* Note that we don't go through the normal API functions to get */
362          /* target memory and write the debug information since we're not */
363          /* dealing with object file content here.  The DLL View debug is */
364          /* supported entirely on the client side.                        */
365          /*---------------------------------------------------------------*/
366          DLDBG_add_target_record(to_ret);
367       }
368    }
370    /*------------------------------------------------------------------------*/
371    /* Report failure to load dependent.                                      */
372    /*------------------------------------------------------------------------*/
373    else
374       DLIF_error(DLET_MISC, "Failed load of dependent file '%s'.\n", so_name);
375    
376    return to_ret;
379 #endif
381 #if 0
382 /*****************************************************************************/
383 /* DLIF_UNLOAD_DEPENDENT() - Perform whatever maintenance is needed in the   */
384 /*      client when unloading of a dependent file is initiated by the core   */
385 /*      loader.  Invoke the DLOAD_unload() function to get the core loader   */
386 /*      to release any target memory that is associated with the dependent   */
387 /*      file's segments.                                                     */
388 /*****************************************************************************/
389 void DLIF_unload_dependent(uint32_t handle)
391    /*------------------------------------------------------------------------*/
392    /* If the specified module is no longer needed, DLOAD_load() will spin    */
393    /* through the object descriptors associated with the module and free up  */
394    /* target memory that was allocated to any segment in the module.         */
395    /*------------------------------------------------------------------------*/
396    /* If DLL debugging is enabled, find module debug record associated with  */
397    /* this module and remove it from the DLL debug list.                     */
398    /*------------------------------------------------------------------------*/
399    if (DLOAD_unload(handle))
400    {
401       DSBT_release_entry(handle);
402       if (DLL_debug) DLDBG_rm_target_record(handle);
403    }
406 #endif
408 /*****************************************************************************/
409 /* Client Provided API Functions to Support Logging Warnings/Errors          */
410 /*****************************************************************************/
412 /*****************************************************************************/
413 /* DLIF_WARNING() - Write out a warning message from the core loader.        */
414 /*****************************************************************************/
415 void DLIF_warning(LOADER_WARNING_TYPE wtype, const char *fmt, ...)
417    va_list ap;
418    va_start(ap,fmt);
419    printf("<< D L O A D >> WARNING: ");
420    vprintf(fmt,ap);
421    va_end(ap);
424 /*****************************************************************************/
425 /* DLIF_ERROR() - Write out an error message from the core loader.           */
426 /*****************************************************************************/
427 void DLIF_error(LOADER_ERROR_TYPE etype, const char *fmt, ...)
429    va_list ap;
430    va_start(ap,fmt);
431    printf("<< D L O A D >> ERROR: ");
432    vprintf(fmt,ap);
433    va_end(ap);
436 /*****************************************************************************
437  * END API FUNCTION DEFINITIONS
438  *****************************************************************************/