diff --git a/apps/filetypes.h b/apps/filetypes.h index 068ec3b259..0b4fb7b812 100644 --- a/apps/filetypes.h +++ b/apps/filetypes.h @@ -56,7 +56,7 @@ void tree_get_filetypes(const struct filetype**, int*); /* init the filetypes structs. uses audio buffer for storage, so call early in init... */ -void filetype_init(void); +void filetype_init(void) INIT_ATTR; void read_viewer_theme_file(void); #ifdef HAVE_LCD_COLOR void read_color_theme_file(void); diff --git a/apps/gui/statusbar-skinned.h b/apps/gui/statusbar-skinned.h index 35bde0bcc1..7558d5a6f8 100644 --- a/apps/gui/statusbar-skinned.h +++ b/apps/gui/statusbar-skinned.h @@ -35,7 +35,7 @@ void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile); void sb_create_from_settings(enum screen_type screen); -void sb_skin_init(void); +void sb_skin_init(void) INIT_ATTR; struct viewport *sb_skin_get_info_vp(enum screen_type screen); void sb_skin_update(enum screen_type screen, bool force); diff --git a/apps/gui/statusbar.h b/apps/gui/statusbar.h index 8a938d177c..0233b56baf 100644 --- a/apps/gui/statusbar.h +++ b/apps/gui/statusbar.h @@ -100,7 +100,7 @@ struct gui_syncstatusbar struct gui_statusbar statusbars[NB_SCREENS]; }; -extern void gui_syncstatusbar_init(struct gui_syncstatusbar * bars); +extern void gui_syncstatusbar_init(struct gui_syncstatusbar * bars) INIT_ATTR; extern void gui_syncstatusbar_draw(struct gui_syncstatusbar * bars, bool force_redraw); void gui_statusbar_changed(enum screen_type screen, diff --git a/apps/gui/viewport.h b/apps/gui/viewport.h index fffd2fedf2..6a4dd02654 100644 --- a/apps/gui/viewport.h +++ b/apps/gui/viewport.h @@ -42,8 +42,7 @@ int viewport_get_nb_lines(const struct viewport *vp); * Initialize the viewportmanager, which in turns initializes the UI vp and * statusbar stuff */ -void viewportmanager_init(void); - +void viewportmanager_init(void) INIT_ATTR; void viewport_set_defaults(struct viewport *vp, const enum screen_type screen); diff --git a/apps/gui/wps.h b/apps/gui/wps.h index 0aa496748b..50fb891a14 100644 --- a/apps/gui/wps.h +++ b/apps/gui/wps.h @@ -28,7 +28,7 @@ long gui_wps_show(void); /* wrapper for the wps to load the skin (.wps/.rwps) files */ void wps_data_load(enum screen_type, const char *, bool); -void gui_sync_wps_init(void); +void gui_sync_wps_init(void) INIT_ATTR; /* fades the volume, e.g. on pause or stop */ void fade(bool fade_in, bool updatewps); diff --git a/apps/main.c b/apps/main.c index 187f0cdd96..f0bd84cf95 100644 --- a/apps/main.c +++ b/apps/main.c @@ -127,7 +127,7 @@ static void init(void); #ifdef SIMULATOR void app_main(void) #else -int main(void) __attribute__((noreturn)); +int main(void) INIT_ATTR __attribute__((noreturn)); int main(void) #endif { @@ -164,6 +164,7 @@ int main(void) root_menu(); } +static int init_dircache(bool preinit) INIT_ATTR; static int init_dircache(bool preinit) { #ifdef HAVE_DIRCACHE @@ -239,6 +240,7 @@ static int init_dircache(bool preinit) } #ifdef HAVE_TAGCACHE +static void init_tagcache(void) INIT_ATTR; static void init_tagcache(void) { bool clear = false; @@ -372,6 +374,7 @@ static void init(void) #else +static void init(void) INIT_ATTR; static void init(void) { int rc; diff --git a/apps/playlist.h b/apps/playlist.h index 638e3949b4..331d2f9f2a 100644 --- a/apps/playlist.h +++ b/apps/playlist.h @@ -119,7 +119,7 @@ struct playlist_track_info }; /* Exported functions only for current playlist. */ -void playlist_init(void); +void playlist_init(void) INIT_ATTR; void playlist_shutdown(void); int playlist_create(const char *dir, const char *file); int playlist_resume(void); diff --git a/apps/recorder/radio.h b/apps/recorder/radio.h index 7277b46b42..129d1dda09 100644 --- a/apps/recorder/radio.h +++ b/apps/recorder/radio.h @@ -27,7 +27,7 @@ #if CONFIG_TUNER void radio_load_presets(char *filename); -void radio_init(void); +void radio_init(void) INIT_ATTR; int radio_screen(void); void radio_start(void); void radio_pause(void); diff --git a/apps/tagcache.h b/apps/tagcache.h index f238bc0902..1488c3bd39 100644 --- a/apps/tagcache.h +++ b/apps/tagcache.h @@ -239,7 +239,7 @@ bool tagcache_is_ramcache(void); bool tagcache_fill_tags(struct mp3entry *id3, const char *filename); void tagcache_unload_ramcache(void); #endif -void tagcache_init(void); +void tagcache_init(void) INIT_ATTR; bool tagcache_is_initialized(void); bool tagcache_is_usable(void); void tagcache_start_scan(void); diff --git a/apps/tagtree.h b/apps/tagtree.h index a08c7433a4..aaf5158e5b 100644 --- a/apps/tagtree.h +++ b/apps/tagtree.h @@ -38,7 +38,7 @@ struct tagentry { bool tagtree_export(void); bool tagtree_import(void); -void tagtree_init(void); +void tagtree_init(void) INIT_ATTR; int tagtree_enter(struct tree_context* c); void tagtree_exit(struct tree_context* c); int tagtree_load(struct tree_context* c); diff --git a/apps/tdspeed.h b/apps/tdspeed.h index 715963a4f0..c3b7fc4635 100644 --- a/apps/tdspeed.h +++ b/apps/tdspeed.h @@ -36,7 +36,7 @@ #define GET_STRETCH(pitch, speed) \ ((speed * PITCH_SPEED_100 + pitch / 2L) / pitch) -void tdspeed_init(void); +void tdspeed_init(void) INIT_ATTR; bool tdspeed_config(int samplerate, bool stereo, int32_t factor); long tdspeed_est_output_size(void); long tdspeed_est_input_size(long size); diff --git a/apps/tree.h b/apps/tree.h index 3b31d02451..f3057e81e4 100644 --- a/apps/tree.h +++ b/apps/tree.h @@ -71,8 +71,8 @@ struct tree_context { }; void tree_drawlists(void); -void tree_mem_init(void); -void tree_gui_init(void); +void tree_mem_init(void) INIT_ATTR; +void tree_gui_init(void) INIT_ATTR; void get_current_file(char* buffer, int buffer_len); void set_dirfilter(int l_dirfilter); void set_current_file(char *path); diff --git a/firmware/export/adc.h b/firmware/export/adc.h index 275db45f07..4a0d384aba 100644 --- a/firmware/export/adc.h +++ b/firmware/export/adc.h @@ -25,7 +25,7 @@ #include "adc-target.h" unsigned short adc_read(int channel); -void adc_init(void); +void adc_init(void) INIT_ATTR; #ifndef NEED_ADC_CLOSE #define adc_close() diff --git a/firmware/export/audio.h b/firmware/export/audio.h index f6613dfe8b..0874d5868d 100644 --- a/firmware/export/audio.h +++ b/firmware/export/audio.h @@ -53,7 +53,7 @@ #define AUDIO_GAIN_MIC 1 -void audio_init(void); +void audio_init(void) INIT_ATTR; void audio_play(long offset); void audio_stop(void); void audio_pause(void); diff --git a/firmware/export/backlight.h b/firmware/export/backlight.h index c440db4668..3b33e1a019 100644 --- a/firmware/export/backlight.h +++ b/firmware/export/backlight.h @@ -36,7 +36,7 @@ void backlight_off(void); void backlight_set_timeout(int value); #ifdef HAVE_BACKLIGHT -void backlight_init(void); +void backlight_init(void) INIT_ATTR; void backlight_close(void); int backlight_get_current_timeout(void); diff --git a/firmware/export/buffer.h b/firmware/export/buffer.h index 9a2b392d64..4c80471b27 100644 --- a/firmware/export/buffer.h +++ b/firmware/export/buffer.h @@ -21,6 +21,7 @@ #ifndef BUFFER_H #define BUFFER_H +#include "config.h" /* defined in linker script */ #ifdef SIMULATOR extern unsigned char *audiobufend; @@ -30,7 +31,7 @@ extern unsigned char audiobufend[]; extern unsigned char *audiobuf; -void buffer_init(void); +void buffer_init(void) INIT_ATTR; void *buffer_alloc(size_t size); #endif diff --git a/firmware/export/button.h b/firmware/export/button.h index 3aac1af9d6..097f50a9d5 100644 --- a/firmware/export/button.h +++ b/firmware/export/button.h @@ -30,7 +30,7 @@ extern struct event_queue button_queue; -void button_init (void); +void button_init (void) INIT_ATTR; void button_close(void); int button_queue_count(void); long button_get (bool block); diff --git a/firmware/export/config.h b/firmware/export/config.h index c7ddbfc3ef..06003b45a5 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -747,6 +747,11 @@ Lyre prototype 1 */ #define IBSS_ATTR #define STATICIRAM static #endif +#if (defined(CPU_PP) || (CONFIG_CPU == AS3525)) && !defined(SIMULATOR) +#define INIT_ATTR __attribute__ ((section(".init"))) +#else +#define INIT_ATTR +#endif #if defined(SIMULATOR) && defined(__APPLE__) #define DATA_ATTR __attribute__ ((section("__DATA, .data"))) diff --git a/firmware/export/font.h b/firmware/export/font.h index 406901d072..f6915d9c09 100644 --- a/firmware/export/font.h +++ b/firmware/export/font.h @@ -115,7 +115,7 @@ struct font { }; /* font routines*/ -void font_init(void); +void font_init(void) INIT_ATTR; #ifdef HAVE_REMOTE_LCD /* Load a font into the special remote ui font slot */ int font_load_remoteui(const char* path); diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h index a21b0b3cee..734235aa2e 100644 --- a/firmware/export/kernel.h +++ b/firmware/export/kernel.h @@ -214,7 +214,7 @@ static inline void call_tick_tasks(void) #endif /* kernel functions */ -extern void kernel_init(void); +extern void kernel_init(void) INIT_ATTR; extern void yield(void); extern void sleep(int ticks); int tick_add_task(void (*f)(void)); diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index 5145e7c21a..35720900fe 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h @@ -175,8 +175,8 @@ extern void lcd_write_command(int byte); extern void lcd_write_command_e(int cmd, int data); extern void lcd_write_command_ex(int cmd, int data1, int data2); extern void lcd_write_data(const fb_data* p_bytes, int count); -extern void lcd_init(void); -extern void lcd_init_device(void); +extern void lcd_init(void) INIT_ATTR; +extern void lcd_init_device(void) INIT_ATTR; extern void lcd_backlight(bool on); extern int lcd_default_contrast(void); diff --git a/firmware/export/power.h b/firmware/export/power.h index 5cd6996eff..107158767f 100644 --- a/firmware/export/power.h +++ b/firmware/export/power.h @@ -83,7 +83,7 @@ bool charging_state(void); #ifndef SIMULATOR -void power_init(void); +void power_init(void) INIT_ATTR; bool ide_powered(void); #endif diff --git a/firmware/export/powermgmt.h b/firmware/export/powermgmt.h index c49cd0e790..23ef447e56 100644 --- a/firmware/export/powermgmt.h +++ b/firmware/export/powermgmt.h @@ -131,7 +131,7 @@ extern const unsigned short percent_to_volt_charge[11]; #endif /* Start up power management thread */ -void powermgmt_init(void); +void powermgmt_init(void) INIT_ATTR; #endif /* SIMULATOR */ diff --git a/firmware/export/scroll_engine.h b/firmware/export/scroll_engine.h index 16b11c22ee..ca94828787 100644 --- a/firmware/export/scroll_engine.h +++ b/firmware/export/scroll_engine.h @@ -28,7 +28,7 @@ #include #include "file.h" -void scroll_init(void); +void scroll_init(void) INIT_ATTR; void lcd_scroll_stop(const struct viewport* vp); void lcd_scroll_stop_line(const struct viewport* vp, int y); void lcd_scroll_fn(void); diff --git a/firmware/export/thread.h b/firmware/export/thread.h index cd27324740..2a2a7a8619 100644 --- a/firmware/export/thread.h +++ b/firmware/export/thread.h @@ -479,7 +479,7 @@ void core_idle(void); void core_wake(IF_COP_VOID(unsigned int core)); /* Initialize the scheduler */ -void init_threads(void); +void init_threads(void) INIT_ATTR; /* Allocate a thread in the scheduler */ #define CREATE_THREAD_FROZEN 0x00000001 /* Thread is frozen at create time */ diff --git a/firmware/export/tuner.h b/firmware/export/tuner.h index 63392160e5..cac038841a 100644 --- a/firmware/export/tuner.h +++ b/firmware/export/tuner.h @@ -158,7 +158,7 @@ enum /** **/ -void tuner_init(void); +void tuner_init(void) INIT_ATTR; #endif /* #if CONFIG_TUNER */ diff --git a/firmware/export/usb.h b/firmware/export/usb.h index e725f0aff4..48400b11dc 100644 --- a/firmware/export/usb.h +++ b/firmware/export/usb.h @@ -132,7 +132,7 @@ struct usb_transfer_completion_event_data }; #endif /* HAVE_USBSTACK */ -void usb_init(void); +void usb_init(void) INIT_ATTR; void usb_enable(bool on); void usb_attach(void); void usb_start_monitoring(void); diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h index 16382ed277..9fd55fab6f 100644 --- a/firmware/include/dircache.h +++ b/firmware/include/dircache.h @@ -92,7 +92,7 @@ typedef struct { DIR_UNCACHED *regulardir; } DIR_CACHED; -void dircache_init(void); +void dircache_init(void) INIT_ATTR; int dircache_load(void); int dircache_save(void); int dircache_build(int last_size); diff --git a/firmware/target/arm/as3525/app.lds b/firmware/target/arm/as3525/app.lds index eb5b28f852..6e610d6e15 100644 --- a/firmware/target/arm/as3525/app.lds +++ b/firmware/target/arm/as3525/app.lds @@ -99,6 +99,8 @@ SECTIONS _iramend = .; } > IRAM AT> DRAM + _iramcopy = LOADADDR(.iram); + .ibss (NOLOAD) : { _iedata = .; @@ -108,9 +110,17 @@ SECTIONS _iend = .; } > IRAM - _iramcopy = LOADADDR(.iram); + .init ENDAUDIOADDR : + { + . = ALIGN(4); + _initstart = .; + *(.init) + _initend = .; + } AT> DRAM - .stack (NOLOAD) : + _initcopy = LOADADDR(.init); + + .stack _iramcopy (NOLOAD) : { *(.stack) stackbegin = .; diff --git a/firmware/target/arm/crt0-pp.S b/firmware/target/arm/crt0-pp.S index 9c996960cc..4e16df0f7a 100644 --- a/firmware/target/arm/crt0-pp.S +++ b/firmware/target/arm/crt0-pp.S @@ -213,6 +213,19 @@ cpu_init: strhi r5, [r3], #4 bhi 1b +#ifdef INIT_ATTR + /* copy init code to codec buffer */ + ldr r2, =_initstart + ldr r3, =_initend + ldr r4, =_initcopy + +1: + cmp r3, r2 + ldrhi r5, [r4], #4 + strhi r5, [r2], #4 + bhi 1b +#endif + /* Zero out IBSS */ ldr r2, =_iedata ldr r3, =_iend diff --git a/firmware/target/arm/crt0.S b/firmware/target/arm/crt0.S index 238cfdd65a..6284bcb16c 100644 --- a/firmware/target/arm/crt0.S +++ b/firmware/target/arm/crt0.S @@ -71,6 +71,7 @@ newstart: bhi 1b /* Copy the IRAM */ + /* must be done before bss is zeroed */ ldr r2, =_iramcopy ldr r3, =_iramstart ldr r4, =_iramend @@ -79,6 +80,23 @@ newstart: ldrhi r5, [r2], #4 strhi r5, [r3], #4 bhi 1b + +#endif + +#ifdef INIT_ATTR + /* copy init data to codec buffer */ + /* must be done before bss is zeroed */ + ldr r2, =_initcopy + ldr r3, =_initstart + ldr r4, =_initend +1: + cmp r4, r3 + ldrhi r5, [r2], #4 + strhi r5, [r3], #4 + bhi 1b + + mov r2, #0 + mcr p15, 0, r2, c7, c5, 0 @ Invalidate ICache #endif /* Initialise bss section to zero */ @@ -89,7 +107,7 @@ newstart: cmp r3, r2 strhi r4, [r2], #4 bhi 1b - + /* Set up some stack and munge it with 0xdeadbeef */ ldr sp, =stackend ldr r2, =stackbegin @@ -115,7 +133,6 @@ newstart: /* Switch back to supervisor mode */ msr cpsr_c, #0xd3 - bl main diff --git a/firmware/target/arm/sandisk/app.lds b/firmware/target/arm/sandisk/app.lds index 3010644b72..ec26fdbe38 100644 --- a/firmware/target/arm/sandisk/app.lds +++ b/firmware/target/arm/sandisk/app.lds @@ -37,8 +37,8 @@ STARTUP(target/arm/crt0-pp.o) MEMORY { - DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE - IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE + DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE + IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE } SECTIONS @@ -126,6 +126,17 @@ SECTIONS _iramcopy = LOADADDR(.iram); + + .init ENDAUDIOADDR : + { + . = ALIGN(4); + _initstart = .; + *(.init) + _initend = .; + } AT> DRAM + + _initcopy = LOADADDR(.init); + .idle_stacks (NOLOAD) : { *(.idle_stacks) @@ -175,6 +186,7 @@ SECTIONS .audiobuf (NOLOAD) : { _audiobuffer = .; + . = ALIGN(0x4); audiobuffer = .; } > DRAM diff --git a/firmware/thread.c b/firmware/thread.c index 6fa7073467..38933f623e 100644 --- a/firmware/thread.c +++ b/firmware/thread.c @@ -724,7 +724,8 @@ static void __attribute__((naked)) * initializations. *--------------------------------------------------------------------------- */ -static void core_thread_init(unsigned int core) +static void core_thread_init(unsigned int core) INIT_ATTR; +static void core_thread_init(unsigned int core) { if (core == CPU) {