diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codecs.c | 7 | ||||
-rw-r--r-- | apps/codecs.h | 23 | ||||
-rw-r--r-- | apps/codecs/codec_crt0.c | 28 | ||||
-rw-r--r-- | apps/plugin.c | 17 | ||||
-rw-r--r-- | apps/plugin.h | 21 | ||||
-rw-r--r-- | apps/plugins/lib/overlay.c | 76 |
6 files changed, 89 insertions, 83 deletions
diff --git a/apps/codecs.c b/apps/codecs.c index 35f6363986..3fa05be59a 100644 --- a/apps/codecs.c +++ b/apps/codecs.c | |||
@@ -181,7 +181,8 @@ void codec_get_full_path(char *path, const char *codec_root_fn) | |||
181 | 181 | ||
182 | static int codec_load_ram(void *handle, struct codec_api *api) | 182 | static int codec_load_ram(void *handle, struct codec_api *api) |
183 | { | 183 | { |
184 | struct codec_header *hdr = lc_get_header(handle); | 184 | struct codec_header *c_hdr = lc_get_header(handle); |
185 | struct lc_header *hdr = c_hdr ? &c_hdr->lc_hdr : NULL; | ||
185 | int status; | 186 | int status; |
186 | 187 | ||
187 | if (hdr == NULL | 188 | if (hdr == NULL |
@@ -215,8 +216,8 @@ static int codec_load_ram(void *handle, struct codec_api *api) | |||
215 | codec_size = 0; | 216 | codec_size = 0; |
216 | #endif | 217 | #endif |
217 | 218 | ||
218 | *(hdr->api) = api; | 219 | *(c_hdr->api) = api; |
219 | status = hdr->entry_point(); | 220 | status = c_hdr->entry_point(); |
220 | 221 | ||
221 | lc_close(handle); | 222 | lc_close(handle); |
222 | 223 | ||
diff --git a/apps/codecs.h b/apps/codecs.h index f94c81ab20..1c0b9da6ba 100644 --- a/apps/codecs.h +++ b/apps/codecs.h | |||
@@ -51,6 +51,7 @@ | |||
51 | #include "settings.h" | 51 | #include "settings.h" |
52 | 52 | ||
53 | #include "gcc_extensions.h" | 53 | #include "gcc_extensions.h" |
54 | #include "load_code.h" | ||
54 | 55 | ||
55 | #ifdef CODEC | 56 | #ifdef CODEC |
56 | #if defined(DEBUG) || defined(SIMULATOR) | 57 | #if defined(DEBUG) || defined(SIMULATOR) |
@@ -240,11 +241,7 @@ struct codec_api { | |||
240 | 241 | ||
241 | /* codec header */ | 242 | /* codec header */ |
242 | struct codec_header { | 243 | struct codec_header { |
243 | unsigned long magic; /* RCOD or RENC */ | 244 | struct lc_header lc_hdr; /* must be first */ |
244 | unsigned short target_id; | ||
245 | unsigned short api_version; | ||
246 | unsigned char *load_addr; | ||
247 | unsigned char *end_addr; | ||
248 | enum codec_status(*entry_point)(void); | 245 | enum codec_status(*entry_point)(void); |
249 | struct codec_api **api; | 246 | struct codec_api **api; |
250 | }; | 247 | }; |
@@ -261,27 +258,27 @@ extern unsigned char plugin_end_addr[]; | |||
261 | #define CODEC_HEADER \ | 258 | #define CODEC_HEADER \ |
262 | const struct codec_header __header \ | 259 | const struct codec_header __header \ |
263 | __attribute__ ((section (".header")))= { \ | 260 | __attribute__ ((section (".header")))= { \ |
264 | CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, \ | 261 | { CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, \ |
265 | plugin_start_addr, plugin_end_addr, codec_start, &ci }; | 262 | plugin_start_addr, plugin_end_addr }, codec_start, &ci }; |
266 | /* encoders */ | 263 | /* encoders */ |
267 | #define CODEC_ENC_HEADER \ | 264 | #define CODEC_ENC_HEADER \ |
268 | const struct codec_header __header \ | 265 | const struct codec_header __header \ |
269 | __attribute__ ((section (".header")))= { \ | 266 | __attribute__ ((section (".header")))= { \ |
270 | CODEC_ENC_MAGIC, TARGET_ID, CODEC_API_VERSION, \ | 267 | { CODEC_ENC_MAGIC, TARGET_ID, CODEC_API_VERSION, \ |
271 | plugin_start_addr, plugin_end_addr, codec_start, &ci }; | 268 | plugin_start_addr, plugin_end_addr }, codec_start, &ci }; |
272 | 269 | ||
273 | #else /* def SIMULATOR */ | 270 | #else /* def SIMULATOR */ |
274 | /* decoders */ | 271 | /* decoders */ |
275 | #define CODEC_HEADER \ | 272 | #define CODEC_HEADER \ |
276 | const struct codec_header __header \ | 273 | const struct codec_header __header \ |
277 | __attribute__((visibility("default"))) = { \ | 274 | __attribute__((visibility("default"))) = { \ |
278 | CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, \ | 275 | { CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, NULL, NULL }, \ |
279 | NULL, NULL, codec_start, &ci }; | 276 | codec_start, &ci }; |
280 | /* encoders */ | 277 | /* encoders */ |
281 | #define CODEC_ENC_HEADER \ | 278 | #define CODEC_ENC_HEADER \ |
282 | const struct codec_header __header = { \ | 279 | const struct codec_header __header = { \ |
283 | CODEC_ENC_MAGIC, TARGET_ID, CODEC_API_VERSION, \ | 280 | { CODEC_ENC_MAGIC, TARGET_ID, CODEC_API_VERSION, NULL, NULL }, \ |
284 | NULL, NULL, codec_start, &ci }; | 281 | codec_start, &ci }; |
285 | #endif /* SIMULATOR */ | 282 | #endif /* SIMULATOR */ |
286 | #endif /* CODEC */ | 283 | #endif /* CODEC */ |
287 | 284 | ||
diff --git a/apps/codecs/codec_crt0.c b/apps/codecs/codec_crt0.c index fdb79092f4..c845f79a40 100644 --- a/apps/codecs/codec_crt0.c +++ b/apps/codecs/codec_crt0.c | |||
@@ -20,15 +20,10 @@ | |||
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #include "config.h" | 22 | #include "config.h" |
23 | #include "codeclib.h" | 23 | #include "codecs.h" |
24 | 24 | ||
25 | struct codec_api *ci DATA_ATTR; | 25 | struct codec_api *ci DATA_ATTR; |
26 | 26 | ||
27 | extern unsigned char iramcopy[]; | ||
28 | extern unsigned char iramstart[]; | ||
29 | extern unsigned char iramend[]; | ||
30 | extern unsigned char iedata[]; | ||
31 | extern unsigned char iend[]; | ||
32 | extern unsigned char plugin_bss_start[]; | 27 | extern unsigned char plugin_bss_start[]; |
33 | extern unsigned char plugin_end_addr[]; | 28 | extern unsigned char plugin_end_addr[]; |
34 | 29 | ||
@@ -42,14 +37,23 @@ enum codec_status codec_start(void) | |||
42 | { | 37 | { |
43 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) | 38 | #if (CONFIG_PLATFORM & PLATFORM_NATIVE) |
44 | #ifdef USE_IRAM | 39 | #ifdef USE_IRAM |
45 | ci->memcpy(iramstart, iramcopy, iramend - iramstart); | 40 | extern char iramcopy[], iramstart[], iramend[], iedata[], iend[]; |
46 | ci->memset(iedata, 0, iend - iedata); | 41 | size_t iram_size = iramend - iramstart; |
47 | #endif | 42 | size_t ibss_size = iend - iedata; |
43 | if (iram_size > 0 || ibss_size > 0) | ||
44 | { | ||
45 | ci->memcpy(iramstart, iramcopy, iram_size); | ||
46 | ci->memset(iedata, 0, ibss_size); | ||
47 | /* make the icache (if it exists) up to date with the new code */ | ||
48 | ci->cpucache_invalidate(); | ||
49 | /* barrier to prevent reordering iram copy and BSS clearing, | ||
50 | * because the BSS segment alias the IRAM copy. | ||
51 | */ | ||
52 | asm volatile ("" ::: "memory"); | ||
53 | } | ||
54 | #endif /* PLUGIN_USE_IRAM */ | ||
48 | ci->memset(plugin_bss_start, 0, plugin_end_addr - plugin_bss_start); | 55 | ci->memset(plugin_bss_start, 0, plugin_end_addr - plugin_bss_start); |
49 | #endif | 56 | #endif |
50 | /* writeback cleared iedata and bss areas, invalidate icache for | ||
51 | * copied code */ | ||
52 | ci->cpucache_invalidate(); | ||
53 | 57 | ||
54 | return codec_main(); | 58 | return codec_main(); |
55 | } | 59 | } |
diff --git a/apps/plugin.c b/apps/plugin.c index 9e08951828..9b490d0fa9 100644 --- a/apps/plugin.c +++ b/apps/plugin.c | |||
@@ -723,12 +723,18 @@ static const struct plugin_api rockbox_api = { | |||
723 | /* new stuff at the end, sort into place next time | 723 | /* new stuff at the end, sort into place next time |
724 | the API gets incompatible */ | 724 | the API gets incompatible */ |
725 | dir_get_info, | 725 | dir_get_info, |
726 | |||
727 | lc_open, | ||
728 | lc_open_from_mem, | ||
729 | lc_get_header, | ||
730 | lc_close, | ||
726 | }; | 731 | }; |
727 | 732 | ||
728 | int plugin_load(const char* plugin, const void* parameter) | 733 | int plugin_load(const char* plugin, const void* parameter) |
729 | { | 734 | { |
730 | int rc, i; | 735 | int rc, i; |
731 | struct plugin_header *hdr; | 736 | struct plugin_header *p_hdr; |
737 | struct lc_header *hdr; | ||
732 | 738 | ||
733 | #if LCD_DEPTH > 1 | 739 | #if LCD_DEPTH > 1 |
734 | fb_data* old_backdrop; | 740 | fb_data* old_backdrop; |
@@ -754,7 +760,10 @@ int plugin_load(const char* plugin, const void* parameter) | |||
754 | return -1; | 760 | return -1; |
755 | } | 761 | } |
756 | 762 | ||
757 | hdr = lc_get_header(current_plugin_handle); | 763 | p_hdr = lc_get_header(current_plugin_handle); |
764 | |||
765 | hdr = p_hdr ? &p_hdr->lc_hdr : NULL; | ||
766 | |||
758 | 767 | ||
759 | if (hdr == NULL | 768 | if (hdr == NULL |
760 | || hdr->magic != PLUGIN_MAGIC | 769 | || hdr->magic != PLUGIN_MAGIC |
@@ -782,7 +791,7 @@ int plugin_load(const char* plugin, const void* parameter) | |||
782 | plugin_size = 0; | 791 | plugin_size = 0; |
783 | #endif | 792 | #endif |
784 | 793 | ||
785 | *(hdr->api) = &rockbox_api; | 794 | *(p_hdr->api) = &rockbox_api; |
786 | 795 | ||
787 | #if defined HAVE_LCD_BITMAP && LCD_DEPTH > 1 | 796 | #if defined HAVE_LCD_BITMAP && LCD_DEPTH > 1 |
788 | old_backdrop = lcd_get_backdrop(); | 797 | old_backdrop = lcd_get_backdrop(); |
@@ -806,7 +815,7 @@ int plugin_load(const char* plugin, const void* parameter) | |||
806 | open_files = 0; | 815 | open_files = 0; |
807 | #endif | 816 | #endif |
808 | 817 | ||
809 | rc = hdr->entry_point(parameter); | 818 | rc = p_hdr->entry_point(parameter); |
810 | 819 | ||
811 | if (!pfn_tsr_exit) | 820 | if (!pfn_tsr_exit) |
812 | { /* close handle if plugin is no tsr one */ | 821 | { /* close handle if plugin is no tsr one */ |
diff --git a/apps/plugin.h b/apps/plugin.h index bafd4070f6..a69b85bbfd 100644 --- a/apps/plugin.h +++ b/apps/plugin.h | |||
@@ -53,6 +53,7 @@ void* plugin_get_buffer(size_t *buffer_size); | |||
53 | #include "thread.h" | 53 | #include "thread.h" |
54 | #include "button.h" | 54 | #include "button.h" |
55 | #include "action.h" | 55 | #include "action.h" |
56 | #include "load_code.h" | ||
56 | #include "usb.h" | 57 | #include "usb.h" |
57 | #include "font.h" | 58 | #include "font.h" |
58 | #include "lcd.h" | 59 | #include "lcd.h" |
@@ -895,15 +896,17 @@ struct plugin_api { | |||
895 | /* new stuff at the end, sort into place next time | 896 | /* new stuff at the end, sort into place next time |
896 | the API gets incompatible */ | 897 | the API gets incompatible */ |
897 | struct dirinfo (*dir_get_info)(DIR* parent, struct dirent *entry); | 898 | struct dirinfo (*dir_get_info)(DIR* parent, struct dirent *entry); |
899 | |||
900 | /* load code api for overlay */ | ||
901 | void* (*lc_open)(const char *filename, unsigned char *buf, size_t buf_size); | ||
902 | void* (*lc_open_from_mem)(void* addr, size_t blob_size); | ||
903 | void* (*lc_get_header)(void *handle); | ||
904 | void (*lc_close)(void *handle); | ||
898 | }; | 905 | }; |
899 | 906 | ||
900 | /* plugin header */ | 907 | /* plugin header */ |
901 | struct plugin_header { | 908 | struct plugin_header { |
902 | unsigned long magic; | 909 | struct lc_header lc_hdr; /* must be the first */ |
903 | unsigned short target_id; | ||
904 | unsigned short api_version; | ||
905 | unsigned char *load_addr; | ||
906 | unsigned char *end_addr; | ||
907 | enum plugin_status(*entry_point)(const void*); | 910 | enum plugin_status(*entry_point)(const void*); |
908 | const struct plugin_api **api; | 911 | const struct plugin_api **api; |
909 | }; | 912 | }; |
@@ -916,15 +919,15 @@ extern unsigned char plugin_end_addr[]; | |||
916 | const struct plugin_api *rb DATA_ATTR; \ | 919 | const struct plugin_api *rb DATA_ATTR; \ |
917 | const struct plugin_header __header \ | 920 | const struct plugin_header __header \ |
918 | __attribute__ ((section (".header")))= { \ | 921 | __attribute__ ((section (".header")))= { \ |
919 | PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, \ | 922 | { PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, \ |
920 | plugin_start_addr, plugin_end_addr, plugin__start, &rb }; | 923 | plugin_start_addr, plugin_end_addr }, plugin__start, &rb }; |
921 | #else /* PLATFORM_HOSTED */ | 924 | #else /* PLATFORM_HOSTED */ |
922 | #define PLUGIN_HEADER \ | 925 | #define PLUGIN_HEADER \ |
923 | const struct plugin_api *rb DATA_ATTR; \ | 926 | const struct plugin_api *rb DATA_ATTR; \ |
924 | const struct plugin_header __header \ | 927 | const struct plugin_header __header \ |
925 | __attribute__((visibility("default"))) = { \ | 928 | __attribute__((visibility("default"))) = { \ |
926 | PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, \ | 929 | { PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, NULL, NULL }, |
927 | NULL, NULL, plugin__start, &rb }; | 930 | plugin__start, &rb }; |
928 | #endif /* CONFIG_PLATFORM */ | 931 | #endif /* CONFIG_PLATFORM */ |
929 | #endif /* PLUGIN */ | 932 | #endif /* PLUGIN */ |
930 | 933 | ||
diff --git a/apps/plugins/lib/overlay.c b/apps/plugins/lib/overlay.c index 8a04cf8aa7..f64df29823 100644 --- a/apps/plugins/lib/overlay.c +++ b/apps/plugins/lib/overlay.c | |||
@@ -47,64 +47,56 @@ | |||
47 | enum plugin_status run_overlay(const void* parameter, | 47 | enum plugin_status run_overlay(const void* parameter, |
48 | unsigned char *filename, unsigned char *name) | 48 | unsigned char *filename, unsigned char *name) |
49 | { | 49 | { |
50 | int fd, readsize; | ||
51 | size_t audiobuf_size; | 50 | size_t audiobuf_size; |
52 | unsigned char *audiobuf; | 51 | unsigned char *audiobuf; |
53 | static struct plugin_header header; | 52 | void *handle; |
53 | struct plugin_header *p_hdr; | ||
54 | struct lc_header *hdr; | ||
54 | 55 | ||
55 | fd = rb->open(filename, O_RDONLY); | 56 | audiobuf = rb->plugin_get_audio_buffer(&audiobuf_size); |
56 | if (fd < 0) | 57 | if (!audiobuf) |
57 | { | 58 | { |
58 | rb->splashf(2*HZ, "Can't open %s", filename); | 59 | rb->splash(2*HZ, "Can't optain memory"); |
59 | return PLUGIN_ERROR; | 60 | goto error; |
60 | } | 61 | } |
61 | readsize = rb->read(fd, &header, sizeof(header)); | ||
62 | rb->close(fd); | ||
63 | /* Close for now. Less code than doing it in all error checks. | ||
64 | * Would need to seek back anyway. */ | ||
65 | 62 | ||
66 | if (readsize != sizeof(header)) | 63 | handle = rb->lc_open(filename, audiobuf, audiobuf_size); |
67 | { | 64 | if (!handle) |
68 | rb->splashf(2*HZ, "Reading %s overlay failed.", name); | ||
69 | return PLUGIN_ERROR; | ||
70 | } | ||
71 | if (header.magic != PLUGIN_MAGIC || header.target_id != TARGET_ID) | ||
72 | { | 65 | { |
73 | rb->splashf(2*HZ, "%s overlay: Incompatible model.", name); | 66 | rb->splashf(2*HZ, "Can't open %s", filename); |
74 | return PLUGIN_ERROR; | 67 | goto error; |
75 | } | ||
76 | if (header.api_version != PLUGIN_API_VERSION) | ||
77 | { | ||
78 | rb->splashf(2*HZ, "%s overlay: Incompatible version.", name); | ||
79 | return PLUGIN_ERROR; | ||
80 | } | 68 | } |
81 | 69 | ||
82 | audiobuf = rb->plugin_get_audio_buffer(&audiobuf_size); | 70 | p_hdr = rb->lc_get_header(handle); |
83 | if (header.load_addr < audiobuf || | 71 | if (!p_hdr) |
84 | header.end_addr > audiobuf + audiobuf_size) | ||
85 | { | 72 | { |
86 | rb->splashf(2*HZ, "%s overlay doesn't fit into memory.", name); | 73 | rb->splash(2*HZ, "Can't get header"); |
87 | return PLUGIN_ERROR; | 74 | goto error_close; |
88 | } | 75 | } |
76 | else | ||
77 | hdr = &p_hdr->lc_hdr; | ||
89 | 78 | ||
90 | fd = rb->open(filename, O_RDONLY); | 79 | if (hdr->magic != PLUGIN_MAGIC || hdr->target_id != TARGET_ID) |
91 | if (fd < 0) | ||
92 | { | 80 | { |
93 | rb->splashf(2*HZ, "Can't open %s", filename); | 81 | rb->splashf(2*HZ, "%s overlay: Incompatible model.", name); |
94 | return PLUGIN_ERROR; | 82 | goto error_close; |
95 | } | 83 | } |
96 | readsize = rb->read(fd, header.load_addr, header.end_addr - header.load_addr); | ||
97 | rb->close(fd); | ||
98 | 84 | ||
99 | if (readsize < 0) | 85 | |
86 | if (hdr->api_version > PLUGIN_API_VERSION | ||
87 | || hdr->api_version < PLUGIN_MIN_API_VERSION) | ||
100 | { | 88 | { |
101 | rb->splashf(2*HZ, "Reading %s overlay failed.", name); | 89 | rb->splashf(2*HZ, "%s overlay: Incompatible version.", name); |
102 | return PLUGIN_ERROR; | 90 | goto error_close; |
103 | } | 91 | } |
104 | /* Zero out bss area */ | ||
105 | rb->memset(header.load_addr + readsize, 0, | ||
106 | header.end_addr - (header.load_addr + readsize)); | ||
107 | 92 | ||
108 | *(header.api) = rb; | 93 | rb->lc_close(handle); |
109 | return header.entry_point(parameter); | 94 | |
95 | *(p_hdr->api) = rb; | ||
96 | return p_hdr->entry_point(parameter); | ||
97 | |||
98 | error_close: | ||
99 | rb->lc_close(handle); | ||
100 | error: | ||
101 | return PLUGIN_ERROR; | ||
110 | } | 102 | } |