summaryrefslogtreecommitdiff
path: root/firmware/load_code.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/load_code.c')
-rw-r--r--firmware/load_code.c59
1 files changed, 49 insertions, 10 deletions
diff --git a/firmware/load_code.c b/firmware/load_code.c
index 75bac8b2ac..5b5307e622 100644
--- a/firmware/load_code.c
+++ b/firmware/load_code.c
@@ -26,37 +26,77 @@
26#include "load_code.h" 26#include "load_code.h"
27 27
28#if (CONFIG_PLATFORM & PLATFORM_NATIVE) 28#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
29
29/* load binary blob from disk to memory, returning a handle */ 30/* load binary blob from disk to memory, returning a handle */
30void * lc_open(const char *filename, char *buf, size_t buf_size) 31void * lc_open(const char *filename, unsigned char *buf, size_t buf_size)
31{ 32{
32 int fd = open(filename, O_RDONLY); 33 int fd = open(filename, O_RDONLY);
33 ssize_t read_size; 34 ssize_t read_size;
35 struct lc_header hdr;
36 unsigned char *buf_end = buf+buf_size;
37 off_t copy_size;
34 38
35 if (fd < 0) 39 if (fd < 0)
36 { 40 {
37 DEBUGF("Could not open file"); 41 DEBUGF("Could not open file");
38 return NULL; 42 goto error;
39 } 43 }
40 44
41#if NUM_CORES > 1 45#if NUM_CORES > 1
42 /* Make sure COP cache is flushed and invalidated before loading */ 46 /* Make sure COP cache is flushed and invalidated before loading */
43 { 47 {
44 int my_core = switch_core(CURRENT_CORE ^ 1); 48 int my_core = switch_core(CURRENT_CORE ^ 1);
45 cpucache_invalidate(); 49 cpucache_commit_discard();
46 switch_core(my_core); 50 switch_core(my_core);
47 } 51 }
48#endif 52#endif
49 53
50 read_size = read(fd, buf, buf_size); 54 /* read the header to obtain the load address */
55 read_size = read(fd, &hdr, sizeof(hdr));
56
57 if (read_size < 0)
58 {
59 DEBUGF("Could not read from file");
60 goto error_fd;
61 }
62
63 /* hdr.end_addr points to the end of the bss section,
64 * but there might be idata/icode behind that so the bytes to copy
65 * can be larger */
66 copy_size = MAX(filesize(fd), hdr.end_addr - hdr.load_addr);
67
68 if (hdr.load_addr < buf || (hdr.load_addr+copy_size) > buf_end)
69 {
70 DEBUGF("Binary doesn't fit into memory");
71 goto error_fd;
72 }
73
74 /* go back to beginning to load the whole thing (incl. header) */
75 if (lseek(fd, 0, SEEK_SET) < 0)
76 {
77 DEBUGF("lseek failed");
78 goto error_fd;
79 }
80
81 /* the header has the addresses where the code is linked at */
82 read_size = read(fd, hdr.load_addr, copy_size);
51 close(fd); 83 close(fd);
52 cpucache_invalidate();
53 84
54 if (read_size < 0) 85 if (read_size < 0)
55 { 86 {
56 DEBUGF("Could not read from file"); 87 DEBUGF("Could not read from file");
57 return NULL; 88 goto error;
58 } 89 }
59 return buf; 90
91 /* commit dcache and discard icache */
92 cpucache_commit_discard();
93 /* return a pointer the header, reused by lc_get_header() */
94 return hdr.load_addr;
95
96error_fd:
97 close(fd);
98error:
99 return NULL;
60} 100}
61 101
62#elif (CONFIG_PLATFORM & PLATFORM_HOSTED) 102#elif (CONFIG_PLATFORM & PLATFORM_HOSTED)
@@ -85,12 +125,11 @@ static inline char *_dlerror(void)
85#include "rbpaths.h" 125#include "rbpaths.h"
86#include "general.h" 126#include "general.h"
87 127
88void * _lc_open(const _lc_open_char *filename, char *buf, size_t buf_size) 128void * _lc_open(const _lc_open_char *filename, unsigned char *buf, size_t buf_size)
89{ 129{
90 (void)buf; 130 (void)buf;
91 (void)buf_size; 131 (void)buf_size;
92 void* dl_handle = dlopen(filename, RTLD_NOW); 132 return dlopen(filename, RTLD_NOW);
93 return dl_handle;
94} 133}
95 134
96void *lc_open_from_mem(void *addr, size_t blob_size) 135void *lc_open_from_mem(void *addr, size_t blob_size)