From 7914e90738ff37e6378b37632eb1f05bab7354d5 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Fri, 28 Sep 2007 10:20:02 +0000 Subject: Commit a subset of the dual core changes that have to do with cache handling, stacks, firmware startup and thread startup. Tested on e200, H10-20GB, iPod Color and 5.5G. Thread function return implemented for all targets. Some changes to plugins to follow shortly. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14879 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs.c | 4 +++ apps/codecs.h | 24 +++++++++++++++++- apps/codecs/codec_crt0.c | 2 ++ apps/debug_menu.c | 66 +++++++++++++++++++++++++++++------------------- apps/main.c | 26 +++++++------------ apps/plugin.c | 5 ++++ apps/plugin.h | 25 +++++++++++++++++- 7 files changed, 107 insertions(+), 45 deletions(-) (limited to 'apps') diff --git a/apps/codecs.c b/apps/codecs.c index ba9d7392b1..35cce6a861 100644 --- a/apps/codecs.c +++ b/apps/codecs.c @@ -157,6 +157,10 @@ struct codec_api ci = { /* new stuff at the end, sort into place next time the API gets incompatible */ +#ifdef CACHE_FUNCTIONS_AS_CALL + flush_icache, + invalidate_icache, +#endif }; void codec_get_full_path(char *path, const char *codec_root_fn) diff --git a/apps/codecs.h b/apps/codecs.h index 652ae7451a..50bc36baa2 100644 --- a/apps/codecs.h +++ b/apps/codecs.h @@ -80,7 +80,7 @@ #define CODEC_ENC_MAGIC 0x52454E43 /* RENC */ /* increase this every time the api struct changes */ -#define CODEC_API_VERSION 18 +#define CODEC_API_VERSION 19 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any @@ -230,6 +230,10 @@ struct codec_api { /* new stuff at the end, sort into place next time the API gets incompatible */ +#ifdef CACHE_FUNCTIONS_AS_CALL + void (*flush_icache)(void); + void (*invalidate_icache)(void); +#endif }; /* codec header */ @@ -286,4 +290,22 @@ int codec_load_file(const char* codec, struct codec_api *api); /* defined by the codec */ enum codec_status codec_start(struct codec_api* rockbox); +#ifndef CACHE_FUNCTION_WRAPPERS + +#ifdef CACHE_FUNCTIONS_AS_CALL +#define CACHE_FUNCTION_WRAPPERS(api) \ + void flush_icache(void) \ + { \ + (api)->flush_icache(); \ + } \ + void invalidate_icache(void) \ + { \ + (api)->invalidate_icache(); \ + } +#else +#define CACHE_FUNCTION_WRAPPERS(api) +#endif /* CACHE_FUNCTIONS_AS_CALL */ + +#endif /* CACHE_FUNCTION_WRAPPERS */ + #endif diff --git a/apps/codecs/codec_crt0.c b/apps/codecs/codec_crt0.c index c9c2cba370..1c61d84b47 100644 --- a/apps/codecs/codec_crt0.c +++ b/apps/codecs/codec_crt0.c @@ -32,6 +32,8 @@ extern unsigned char plugin_end_addr[]; extern enum codec_status codec_main(void); +CACHE_FUNCTION_WRAPPERS(ci); + enum codec_status codec_start(struct codec_api *api) { #ifndef SIMULATOR diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 40c0fcc9b0..15c2c93d62 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -180,7 +180,6 @@ static bool dbg_list(struct action_callback_info *info) /*---------------------------------------------------*/ extern struct thread_entry threads[MAXTHREADS]; - static char thread_status_char(int status) { switch (status) @@ -193,42 +192,48 @@ static char thread_status_char(int status) return '?'; } -#if NUM_CORES > 1 -#define IF_COP2(...) __VA_ARGS__ -#else -#define IF_COP2(...) -#endif + static char* threads_getname(int selected_item, void * data, char *buffer) { (void)data; + char name[32]; struct thread_entry *thread = NULL; - int status, usage; + unsigned status; + int usage; + +#if NUM_CORES > 1 + if (selected_item < (int)NUM_CORES) + { + usage = idle_stack_usage(selected_item); + snprintf(buffer, MAX_PATH, "Idle (%d): %2d%%", selected_item, usage); + return buffer; + } + + selected_item -= NUM_CORES; +#endif + thread = &threads[selected_item]; + status = thread_get_status(thread); if (thread->name == NULL) { snprintf(buffer, MAX_PATH, "%2d: ---", selected_item); return buffer; } - + + thread_get_name(name, 32, thread); usage = thread_stack_usage(thread); status = thread_get_status(thread); -#ifdef HAVE_PRIORITY_SCHEDULING - snprintf(buffer, MAX_PATH, "%2d: " IF_COP2("(%d) ") "%c%c %d %2d%% %s", - selected_item, - IF_COP2(thread->core,) - (status == STATE_RUNNING) ? '*' : ' ', - thread_status_char(status), - thread->priority, - usage, thread->name); -#else - snprintf(buffer, MAX_PATH, "%2d: " IF_COP2("(%d) ") "%c%c %2d%% %s", + + snprintf(buffer, MAX_PATH, + "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d ") "%2d%% %s", selected_item, - IF_COP2(thread->core,) + IF_COP(thread->core,) (status == STATE_RUNNING) ? '*' : ' ', thread_status_char(status), - usage, thread->name); -#endif + IF_PRIO(thread->priority,) + usage, name); + return buffer; } static int dbg_threads_action_callback(int action, struct action_callback_info *info) @@ -236,11 +241,16 @@ static int dbg_threads_action_callback(int action, struct action_callback_info * #ifdef ROCKBOX_HAS_LOGF if (action == ACTION_STD_OK) { - struct thread_entry *thread = &threads[gui_synclist_get_sel_pos(info->lists)]; - if (thread->name != NULL) - remove_thread(thread); - } + int selpos = gui_synclist_get_sel_pos(info->lists); +#if NUM_CORES > 1 + if (selpos >= NUM_CORES) + remove_thread(&threads[selpos - NUM_CORES]); +#else + remove_thread(&threads[selpos]); #endif + } + gui_synclist_hide_selection_marker(info->lists, false); +#endif /* ROCKBOX_HAS_LOGF */ gui_synclist_draw(info->lists); return action; } @@ -248,8 +258,12 @@ static int dbg_threads_action_callback(int action, struct action_callback_info * static bool dbg_os(void) { struct action_callback_info info; - info.title = IF_COP2("Core and ") "Stack usage:"; + info.title = IF_COP("Core and ") "Stack usage:"; +#if NUM_CORES == 1 info.count = MAXTHREADS; +#else + info.count = MAXTHREADS+NUM_CORES; +#endif info.selection_size = 1; info.action_callback = dbg_threads_action_callback; info.dbg_getname = threads_getname; diff --git a/apps/main.c b/apps/main.c index a27998168c..bc8a12dd4e 100644 --- a/apps/main.c +++ b/apps/main.c @@ -334,9 +334,7 @@ static void init(void) /* if nobody initialized ATA before, I consider this a cold start */ bool coldstart = (PACR2 & 0x4000) != 0; /* starting from Flash */ #endif -#ifdef CPU_PP - COP_CTL = PROC_WAKE; -#endif + system_init(); kernel_init(); @@ -591,25 +589,19 @@ void cop_main(void) so it should not be assumed that the coprocessor be usable even on platforms which support it. - A kernel thread runs on the coprocessor which waits for other threads to be - added, and gracefully handles RoLo */ + A kernel thread is initially setup on the coprocessor and immediately + destroyed for purposes of continuity. The cop sits idle until at least + one thread exists on it. */ -#if CONFIG_CPU == PP5002 /* 3G doesn't have Rolo or dual core support yet */ - while(1) { - COP_CTL = PROC_SLEEP; - } -#else - extern volatile unsigned char cpu_message; - +#if NUM_CORES > 1 system_init(); kernel_init(); - - while(cpu_message != COP_REBOOT) { - sleep(HZ); + /* This should never be reached */ +#endif + while(1) { + COP_CTL = PROC_SLEEP; } - rolo_restart_cop(); -#endif /* PP5002 */ } #endif /* CPU_PP */ diff --git a/apps/plugin.c b/apps/plugin.c index f56d532537..f0b86c08cb 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -509,6 +509,11 @@ static const struct plugin_api rockbox_api = { #if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) lcd_yuv_set_options, #endif + +#ifdef CACHE_FUNCTIONS_AS_CALL + flush_icache, + invalidate_icache, +#endif }; int plugin_load(const char* plugin, void* parameter) diff --git a/apps/plugin.h b/apps/plugin.h index a2e24f88d9..5f868e5654 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -112,7 +112,7 @@ #define PLUGIN_MAGIC 0x526F634B /* RocK */ /* increase this every time the api struct changes */ -#define PLUGIN_API_VERSION 77 +#define PLUGIN_API_VERSION 78 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any @@ -627,6 +627,11 @@ struct plugin_api { #if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) void (*lcd_yuv_set_options)(unsigned options); #endif + +#ifdef CACHE_FUNCTIONS_AS_CALL + void (*flush_icache)(void); + void (*invalidate_icache)(void); +#endif }; /* plugin header */ @@ -710,4 +715,22 @@ enum plugin_status plugin_start(struct plugin_api* rockbox, void* parameter) return (api)->memcmp(s1, s2, n); \ } +#ifndef CACHE_FUNCTION_WRAPPERS + +#ifdef CACHE_FUNCTIONS_AS_CALL +#define CACHE_FUNCTION_WRAPPERS(api) \ + void flush_icache(void) \ + { \ + (api)->flush_icache(); \ + } \ + void invalidate_icache(void) \ + { \ + (api)->invalidate_icache(); \ + } +#else +#define CACHE_FUNCTION_WRAPPERS(api) +#endif /* CACHE_FUNCTIONS_AS_CALL */ + +#endif /* CACHE_FUNCTION_WRAPPERS */ + #endif -- cgit v1.2.3