diff options
author | Daniel Ankers <dan@weirdo.org.uk> | 2007-03-04 20:06:41 +0000 |
---|---|---|
committer | Daniel Ankers <dan@weirdo.org.uk> | 2007-03-04 20:06:41 +0000 |
commit | 82f9056988331572e01231d70fadc64b7ab76c6f (patch) | |
tree | 9f1d33b904516fd5eeac2067e4afb32ce5e990df /apps | |
parent | 74e572c9d600247ee795b206da3715f6af442a25 (diff) | |
download | rockbox-82f9056988331572e01231d70fadc64b7ab76c6f.tar.gz rockbox-82f9056988331572e01231d70fadc64b7ab76c6f.zip |
Dual core support for PP502x players (iPod G4 and later, iriver h10, Sansa - iPod G3 will be coming soon.) This allows threads to be run on either core provided that all communications between the cores is done using uncached memory. There should be no significant change in battery life from doing this. Documentation (on the RockboxKernel wiki page) will follow shortly.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12601 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codecs.c | 2 | ||||
-rw-r--r-- | apps/codecs.h | 5 | ||||
-rw-r--r-- | apps/main.c | 14 | ||||
-rw-r--r-- | apps/playback.c | 24 | ||||
-rw-r--r-- | apps/playlist.c | 3 | ||||
-rw-r--r-- | apps/plugin.c | 1 | ||||
-rw-r--r-- | apps/plugin.h | 8 | ||||
-rw-r--r-- | apps/plugins/alpine_cdc.c | 3 | ||||
-rw-r--r-- | apps/plugins/battery_bench.c | 3 | ||||
-rw-r--r-- | apps/plugins/mpegplayer/mpegplayer.c | 10 | ||||
-rw-r--r-- | apps/tagcache.c | 3 |
11 files changed, 41 insertions, 35 deletions
diff --git a/apps/codecs.c b/apps/codecs.c index 0c6ddd0422..ccfa449d51 100644 --- a/apps/codecs.c +++ b/apps/codecs.c | |||
@@ -123,7 +123,7 @@ struct codec_api ci = { | |||
123 | ¤t_tick, | 123 | ¤t_tick, |
124 | default_event_handler, | 124 | default_event_handler, |
125 | default_event_handler_ex, | 125 | default_event_handler_ex, |
126 | create_thread_on_core, | 126 | create_thread, |
127 | remove_thread, | 127 | remove_thread, |
128 | reset_poweroff_timer, | 128 | reset_poweroff_timer, |
129 | #ifndef SIMULATOR | 129 | #ifndef SIMULATOR |
diff --git a/apps/codecs.h b/apps/codecs.h index 6710afdc8e..3c2b754dac 100644 --- a/apps/codecs.h +++ b/apps/codecs.h | |||
@@ -199,9 +199,10 @@ struct codec_api { | |||
199 | long* current_tick; | 199 | long* current_tick; |
200 | long (*default_event_handler)(long event); | 200 | long (*default_event_handler)(long event); |
201 | long (*default_event_handler_ex)(long event, void (*callback)(void *), void *parameter); | 201 | long (*default_event_handler_ex)(long event, void (*callback)(void *), void *parameter); |
202 | struct thread_entry* (*create_thread)(unsigned int core, void (*function)(void), | 202 | struct thread_entry* (*create_thread)(void (*function)(void), |
203 | void* stack, int stack_size, const char *name | 203 | void* stack, int stack_size, const char *name |
204 | IF_PRIO(, int priority)); | 204 | IF_PRIO(, int priority) |
205 | IF_COP(, unsigned int core, bool fallback)); | ||
205 | void (*remove_thread)(struct thread_entry *thread); | 206 | void (*remove_thread)(struct thread_entry *thread); |
206 | void (*reset_poweroff_timer)(void); | 207 | void (*reset_poweroff_timer)(void); |
207 | #ifndef SIMULATOR | 208 | #ifndef SIMULATOR |
diff --git a/apps/main.c b/apps/main.c index 6286b68ed1..e4d90bce61 100644 --- a/apps/main.c +++ b/apps/main.c | |||
@@ -297,6 +297,9 @@ static void init(void) | |||
297 | /* if nobody initialized ATA before, I consider this a cold start */ | 297 | /* if nobody initialized ATA before, I consider this a cold start */ |
298 | bool coldstart = (PACR2 & 0x4000) != 0; /* starting from Flash */ | 298 | bool coldstart = (PACR2 & 0x4000) != 0; /* starting from Flash */ |
299 | #endif | 299 | #endif |
300 | #ifdef CPU_PP | ||
301 | COP_CTL = PROC_WAKE; | ||
302 | #endif | ||
300 | system_init(); | 303 | system_init(); |
301 | kernel_init(); | 304 | kernel_init(); |
302 | 305 | ||
@@ -549,19 +552,22 @@ void cop_main(void) | |||
549 | so it should not be assumed that the coprocessor be usable even on | 552 | so it should not be assumed that the coprocessor be usable even on |
550 | platforms which support it. | 553 | platforms which support it. |
551 | 554 | ||
552 | At present the COP sleeps unless it receives a message from the CPU telling | 555 | A kernel thread runs on the coprocessor which waits for other threads to be |
553 | it that we are loading a new kernel, so must reboot */ | 556 | added, and gracefully handles RoLo */ |
554 | 557 | ||
555 | #if CONFIG_CPU == PP5002 | 558 | #if CONFIG_CPU == PP5002 |
556 | /* 3G doesn't have Rolo support yet */ | 559 | /* 3G doesn't have Rolo or dual core support yet */ |
557 | while(1) { | 560 | while(1) { |
558 | COP_CTL = PROC_SLEEP; | 561 | COP_CTL = PROC_SLEEP; |
559 | } | 562 | } |
560 | #else | 563 | #else |
561 | extern volatile unsigned char cpu_message; | 564 | extern volatile unsigned char cpu_message; |
562 | 565 | ||
566 | system_init(); | ||
567 | kernel_init(); | ||
568 | |||
563 | while(cpu_message != COP_REBOOT) { | 569 | while(cpu_message != COP_REBOOT) { |
564 | COP_CTL = PROC_SLEEP; | 570 | sleep(HZ); |
565 | } | 571 | } |
566 | rolo_restart_cop(); | 572 | rolo_restart_cop(); |
567 | #endif /* PP5002 */ | 573 | #endif /* PP5002 */ |
diff --git a/apps/playback.c b/apps/playback.c index fe7a9f6ab1..89caec92aa 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -194,9 +194,9 @@ static bool audio_is_initialized = false; | |||
194 | /* TBD: Split out "audio" and "playback" (ie. calling) threads */ | 194 | /* TBD: Split out "audio" and "playback" (ie. calling) threads */ |
195 | 195 | ||
196 | /* Main state control */ | 196 | /* Main state control */ |
197 | static volatile bool audio_codec_loaded; /* Is codec loaded? (C/A-) */ | 197 | static volatile bool audio_codec_loaded NOCACHEBSS_ATTR;/* Codec loaded? (C/A-) */ |
198 | static volatile bool playing; /* Is audio playing? (A) */ | 198 | static volatile bool playing NOCACHEBSS_ATTR; /* Is audio playing? (A) */ |
199 | static volatile bool paused; /* Is audio paused? (A/C-) */ | 199 | static volatile bool paused NOCACHEBSS_ATTR; /* Is audio paused? (A/C-) */ |
200 | static volatile bool filling IDATA_ATTR; /* Is file buffer refilling? (A/C-) */ | 200 | static volatile bool filling IDATA_ATTR; /* Is file buffer refilling? (A/C-) */ |
201 | 201 | ||
202 | /* Ring buffer where compressed audio and codecs are loaded */ | 202 | /* Ring buffer where compressed audio and codecs are loaded */ |
@@ -290,7 +290,7 @@ static void audio_reset_buffer(size_t pcmbufsize); | |||
290 | 290 | ||
291 | /* Codec thread */ | 291 | /* Codec thread */ |
292 | extern struct codec_api ci; | 292 | extern struct codec_api ci; |
293 | static struct event_queue codec_queue; | 293 | static struct event_queue codec_queue NOCACHEBSS_ATTR; |
294 | static long codec_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)] | 294 | static long codec_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)] |
295 | IBSS_ATTR; | 295 | IBSS_ATTR; |
296 | static const char codec_thread_name[] = "codec"; | 296 | static const char codec_thread_name[] = "codec"; |
@@ -304,7 +304,7 @@ static volatile int current_codec IDATA_ATTR; /* Current codec (normal/voice) */ | |||
304 | extern struct codec_api ci_voice; | 304 | extern struct codec_api ci_voice; |
305 | 305 | ||
306 | static struct thread_entry *voice_thread_p = NULL; | 306 | static struct thread_entry *voice_thread_p = NULL; |
307 | static struct event_queue voice_queue; | 307 | static struct event_queue voice_queue NOCACHEBSS_ATTR; |
308 | static long voice_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)] | 308 | static long voice_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)] |
309 | IBSS_ATTR_VOICE_STACK; | 309 | IBSS_ATTR_VOICE_STACK; |
310 | static const char voice_thread_name[] = "voice codec"; | 310 | static const char voice_thread_name[] = "voice codec"; |
@@ -324,12 +324,12 @@ static unsigned char *iram_buf[2] = { NULL, NULL }; | |||
324 | /* Pointer to DRAM buffers for normal/voice codecs */ | 324 | /* Pointer to DRAM buffers for normal/voice codecs */ |
325 | static unsigned char *dram_buf[2] = { NULL, NULL }; | 325 | static unsigned char *dram_buf[2] = { NULL, NULL }; |
326 | /* Mutex to control which codec (normal/voice) is running */ | 326 | /* Mutex to control which codec (normal/voice) is running */ |
327 | static struct mutex mutex_codecthread; | 327 | static struct mutex mutex_codecthread NOCACHEBSS_ATTR; |
328 | 328 | ||
329 | /* Voice state */ | 329 | /* Voice state */ |
330 | static volatile bool voice_thread_start; /* Triggers voice playback (A/V) */ | 330 | static volatile bool voice_thread_start; /* Triggers voice playback (A/V) */ |
331 | static volatile bool voice_is_playing; /* Is voice currently playing? (V) */ | 331 | static volatile bool voice_is_playing NOCACHEBSS_ATTR; /* Is voice currently playing? (V) */ |
332 | static volatile bool voice_codec_loaded; /* Is voice codec loaded (V/A-) */ | 332 | static volatile bool voice_codec_loaded NOCACHEBSS_ATTR; /* Is voice codec loaded (V/A-) */ |
333 | static char *voicebuf; | 333 | static char *voicebuf; |
334 | static size_t voice_remaining; | 334 | static size_t voice_remaining; |
335 | 335 | ||
@@ -863,7 +863,8 @@ void audio_preinit(void) | |||
863 | queue_init(&codec_queue, true); | 863 | queue_init(&codec_queue, true); |
864 | 864 | ||
865 | create_thread(audio_thread, audio_stack, sizeof(audio_stack), | 865 | create_thread(audio_thread, audio_stack, sizeof(audio_stack), |
866 | audio_thread_name IF_PRIO(, PRIORITY_BUFFERING)); | 866 | audio_thread_name IF_PRIO(, PRIORITY_BUFFERING) |
867 | IF_COP(, CPU, false)); | ||
867 | } | 868 | } |
868 | 869 | ||
869 | void audio_init(void) | 870 | void audio_init(void) |
@@ -888,7 +889,7 @@ void voice_init(void) | |||
888 | queue_init(&voice_queue, true); | 889 | queue_init(&voice_queue, true); |
889 | voice_thread_p = create_thread(voice_thread, voice_stack, | 890 | voice_thread_p = create_thread(voice_thread, voice_stack, |
890 | sizeof(voice_stack), voice_thread_name | 891 | sizeof(voice_stack), voice_thread_name |
891 | IF_PRIO(, PRIORITY_PLAYBACK)); | 892 | IF_PRIO(, PRIORITY_PLAYBACK) IF_COP(, CPU, false)); |
892 | 893 | ||
893 | while (!voice_codec_loaded) | 894 | while (!voice_codec_loaded) |
894 | yield(); | 895 | yield(); |
@@ -3533,7 +3534,8 @@ static void audio_playback_init(void) | |||
3533 | 3534 | ||
3534 | codec_thread_p = create_thread( | 3535 | codec_thread_p = create_thread( |
3535 | codec_thread, codec_stack, sizeof(codec_stack), | 3536 | codec_thread, codec_stack, sizeof(codec_stack), |
3536 | codec_thread_name IF_PRIO(, PRIORITY_PLAYBACK)); | 3537 | codec_thread_name IF_PRIO(, PRIORITY_PLAYBACK) |
3538 | IF_COP(, COP, true)); | ||
3537 | 3539 | ||
3538 | while (1) | 3540 | while (1) |
3539 | { | 3541 | { |
diff --git a/apps/playlist.c b/apps/playlist.c index 6997b12675..0358b6adc4 100644 --- a/apps/playlist.c +++ b/apps/playlist.c | |||
@@ -1873,7 +1873,8 @@ void playlist_init(void) | |||
1873 | memset(playlist->filenames, 0, | 1873 | memset(playlist->filenames, 0, |
1874 | playlist->max_playlist_size * sizeof(int)); | 1874 | playlist->max_playlist_size * sizeof(int)); |
1875 | create_thread(playlist_thread, playlist_stack, sizeof(playlist_stack), | 1875 | create_thread(playlist_thread, playlist_stack, sizeof(playlist_stack), |
1876 | playlist_thread_name IF_PRIO(, PRIORITY_BACKGROUND)); | 1876 | playlist_thread_name IF_PRIO(, PRIORITY_BACKGROUND) |
1877 | IF_COP(, CPU, false)); | ||
1877 | queue_init(&playlist_queue, true); | 1878 | queue_init(&playlist_queue, true); |
1878 | #endif | 1879 | #endif |
1879 | } | 1880 | } |
diff --git a/apps/plugin.c b/apps/plugin.c index 5bbff96b04..230b62b819 100644 --- a/apps/plugin.c +++ b/apps/plugin.c | |||
@@ -481,7 +481,6 @@ static const struct plugin_api rockbox_api = { | |||
481 | sound_default, | 481 | sound_default, |
482 | pcm_record_more, | 482 | pcm_record_more, |
483 | #endif | 483 | #endif |
484 | create_thread_on_core, | ||
485 | 484 | ||
486 | #ifdef IRIVER_H100_SERIES | 485 | #ifdef IRIVER_H100_SERIES |
487 | /* Routines for the iriver_flash -plugin. */ | 486 | /* Routines for the iriver_flash -plugin. */ |
diff --git a/apps/plugin.h b/apps/plugin.h index 48e9c40196..1d161783a1 100644 --- a/apps/plugin.h +++ b/apps/plugin.h | |||
@@ -327,7 +327,8 @@ struct plugin_api { | |||
327 | long (*default_event_handler_ex)(long event, void (*callback)(void *), void *parameter); | 327 | long (*default_event_handler_ex)(long event, void (*callback)(void *), void *parameter); |
328 | struct thread_entry* (*create_thread)(void (*function)(void), void* stack, | 328 | struct thread_entry* (*create_thread)(void (*function)(void), void* stack, |
329 | int stack_size, const char *name | 329 | int stack_size, const char *name |
330 | IF_PRIO(, int priority)); | 330 | IF_PRIO(, int priority) |
331 | IF_COP(, unsigned int core, bool fallback)); | ||
331 | void (*remove_thread)(struct thread_entry *thread); | 332 | void (*remove_thread)(struct thread_entry *thread); |
332 | void (*reset_poweroff_timer)(void); | 333 | void (*reset_poweroff_timer)(void); |
333 | #ifndef SIMULATOR | 334 | #ifndef SIMULATOR |
@@ -595,11 +596,6 @@ struct plugin_api { | |||
595 | void (*pcm_record_more)(void *start, size_t size); | 596 | void (*pcm_record_more)(void *start, size_t size); |
596 | #endif | 597 | #endif |
597 | 598 | ||
598 | struct thread_entry*(*create_thread_on_core)( | ||
599 | unsigned int core, void (*function)(void), | ||
600 | void* stack, int stack_size, | ||
601 | const char *name IF_PRIO(, int priority)); | ||
602 | |||
603 | #ifdef IRIVER_H100_SERIES | 599 | #ifdef IRIVER_H100_SERIES |
604 | /* Routines for the iriver_flash -plugin. */ | 600 | /* Routines for the iriver_flash -plugin. */ |
605 | bool (*detect_original_firmware)(void); | 601 | bool (*detect_original_firmware)(void); |
diff --git a/apps/plugins/alpine_cdc.c b/apps/plugins/alpine_cdc.c index 9c1bc8bd0b..9cc1f9cde4 100644 --- a/apps/plugins/alpine_cdc.c +++ b/apps/plugins/alpine_cdc.c | |||
@@ -1171,7 +1171,8 @@ int main(void* parameter) | |||
1171 | rb->memset(&gTread, 0, sizeof(gTread)); | 1171 | rb->memset(&gTread, 0, sizeof(gTread)); |
1172 | gTread.foreground = true; | 1172 | gTread.foreground = true; |
1173 | rb->create_thread(thread, stack, stacksize, "CDC" | 1173 | rb->create_thread(thread, stack, stacksize, "CDC" |
1174 | IF_PRIO(, PRIORITY_BACKGROUND)); | 1174 | IF_PRIO(, PRIORITY_BACKGROUND) |
1175 | IF_COP(, CPU, false)); | ||
1175 | 1176 | ||
1176 | #ifdef DEBUG | 1177 | #ifdef DEBUG |
1177 | do | 1178 | do |
diff --git a/apps/plugins/battery_bench.c b/apps/plugins/battery_bench.c index fff3c2fa57..6e3178237f 100644 --- a/apps/plugins/battery_bench.c +++ b/apps/plugins/battery_bench.c | |||
@@ -479,7 +479,8 @@ int main(void) | |||
479 | rb->queue_init(&thread_q, true); /* put the thread's queue in the bcast list */ | 479 | rb->queue_init(&thread_q, true); /* put the thread's queue in the bcast list */ |
480 | if(rb->create_thread(thread, thread_stack, | 480 | if(rb->create_thread(thread, thread_stack, |
481 | sizeof(thread_stack), "Battery Benchmark" | 481 | sizeof(thread_stack), "Battery Benchmark" |
482 | IF_PRIO(, PRIORITY_BACKGROUND)) == NULL) | 482 | IF_PRIO(, PRIORITY_BACKGROUND) |
483 | IF_COP(, CPU, false)) == NULL) | ||
483 | { | 484 | { |
484 | rb->splash(HZ,true,"Cannot create thread!"); | 485 | rb->splash(HZ,true,"Cannot create thread!"); |
485 | return PLUGIN_ERROR; | 486 | return PLUGIN_ERROR; |
diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c index 36f54dc224..684a491872 100644 --- a/apps/plugins/mpegplayer/mpegplayer.c +++ b/apps/plugins/mpegplayer/mpegplayer.c | |||
@@ -909,19 +909,17 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | |||
909 | videostatus = STREAM_PLAYING; | 909 | videostatus = STREAM_PLAYING; |
910 | 910 | ||
911 | /* We put the video thread on the second processor for multi-core targets. */ | 911 | /* We put the video thread on the second processor for multi-core targets. */ |
912 | #if NUM_CORES > 1 | ||
913 | if ((videothread_id = rb->create_thread_on_core(COP,decode_mpeg2, | ||
914 | #else | ||
915 | if ((videothread_id = rb->create_thread(decode_mpeg2, | 912 | if ((videothread_id = rb->create_thread(decode_mpeg2, |
916 | #endif | 913 | (uint8_t*)video_stack,VIDEO_STACKSIZE,"mpgvideo" IF_PRIO(,PRIORITY_PLAYBACK) |
917 | (uint8_t*)video_stack,VIDEO_STACKSIZE,"mpgvideo" IF_PRIO(,PRIORITY_PLAYBACK))) == NULL) | 914 | IF_COP(, COP, true))) == NULL) |
918 | { | 915 | { |
919 | rb->splash(HZ,true,"Cannot create video thread!"); | 916 | rb->splash(HZ,true,"Cannot create video thread!"); |
920 | return PLUGIN_ERROR; | 917 | return PLUGIN_ERROR; |
921 | } | 918 | } |
922 | 919 | ||
923 | if ((audiothread_id = rb->create_thread(mad_decode, | 920 | if ((audiothread_id = rb->create_thread(mad_decode, |
924 | (uint8_t*)audio_stack,AUDIO_STACKSIZE,"mpgaudio" IF_PRIO(,PRIORITY_PLAYBACK))) == NULL) | 921 | (uint8_t*)audio_stack,AUDIO_STACKSIZE,"mpgaudio" IF_PRIO(,PRIORITY_PLAYBACK) |
922 | IF_COP(, CPU, false))) == NULL) | ||
925 | { | 923 | { |
926 | rb->splash(HZ,true,"Cannot create audio thread!"); | 924 | rb->splash(HZ,true,"Cannot create audio thread!"); |
927 | rb->remove_thread(videothread_id); | 925 | rb->remove_thread(videothread_id); |
diff --git a/apps/tagcache.c b/apps/tagcache.c index a6a0168353..6b891f1011 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c | |||
@@ -3941,7 +3941,8 @@ void tagcache_init(void) | |||
3941 | queue_init(&tagcache_queue, true); | 3941 | queue_init(&tagcache_queue, true); |
3942 | create_thread(tagcache_thread, tagcache_stack, | 3942 | create_thread(tagcache_thread, tagcache_stack, |
3943 | sizeof(tagcache_stack), tagcache_thread_name | 3943 | sizeof(tagcache_stack), tagcache_thread_name |
3944 | IF_PRIO(, PRIORITY_BACKGROUND)); | 3944 | IF_PRIO(, PRIORITY_BACKGROUND) |
3945 | IF_COP(, CPU, false)); | ||
3945 | #else | 3946 | #else |
3946 | tc_stat.initialized = true; | 3947 | tc_stat.initialized = true; |
3947 | allocate_tempbuf(); | 3948 | allocate_tempbuf(); |