summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/codecs.c7
-rw-r--r--apps/codecs.h23
-rw-r--r--apps/codecs/codec_crt0.c28
-rw-r--r--apps/plugin.c17
-rw-r--r--apps/plugin.h21
-rw-r--r--apps/plugins/lib/overlay.c76
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
182static int codec_load_ram(void *handle, struct codec_api *api) 182static 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 */
242struct codec_header { 243struct 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
25struct codec_api *ci DATA_ATTR; 25struct codec_api *ci DATA_ATTR;
26 26
27extern unsigned char iramcopy[];
28extern unsigned char iramstart[];
29extern unsigned char iramend[];
30extern unsigned char iedata[];
31extern unsigned char iend[];
32extern unsigned char plugin_bss_start[]; 27extern unsigned char plugin_bss_start[];
33extern unsigned char plugin_end_addr[]; 28extern 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
728int plugin_load(const char* plugin, const void* parameter) 733int 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 */
901struct plugin_header { 908struct 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 @@
47enum plugin_status run_overlay(const void* parameter, 47enum 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
98error_close:
99 rb->lc_close(handle);
100error:
101 return PLUGIN_ERROR;
110} 102}