summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorDaniel Ankers <dan@weirdo.org.uk>2007-03-04 20:06:41 +0000
committerDaniel Ankers <dan@weirdo.org.uk>2007-03-04 20:06:41 +0000
commit82f9056988331572e01231d70fadc64b7ab76c6f (patch)
tree9f1d33b904516fd5eeac2067e4afb32ce5e990df /apps
parent74e572c9d600247ee795b206da3715f6af442a25 (diff)
downloadrockbox-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.c2
-rw-r--r--apps/codecs.h5
-rw-r--r--apps/main.c14
-rw-r--r--apps/playback.c24
-rw-r--r--apps/playlist.c3
-rw-r--r--apps/plugin.c1
-rw-r--r--apps/plugin.h8
-rw-r--r--apps/plugins/alpine_cdc.c3
-rw-r--r--apps/plugins/battery_bench.c3
-rw-r--r--apps/plugins/mpegplayer/mpegplayer.c10
-rw-r--r--apps/tagcache.c3
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 &current_tick, 123 &current_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 */
197static volatile bool audio_codec_loaded; /* Is codec loaded? (C/A-) */ 197static volatile bool audio_codec_loaded NOCACHEBSS_ATTR;/* Codec loaded? (C/A-) */
198static volatile bool playing; /* Is audio playing? (A) */ 198static volatile bool playing NOCACHEBSS_ATTR; /* Is audio playing? (A) */
199static volatile bool paused; /* Is audio paused? (A/C-) */ 199static volatile bool paused NOCACHEBSS_ATTR; /* Is audio paused? (A/C-) */
200static volatile bool filling IDATA_ATTR; /* Is file buffer refilling? (A/C-) */ 200static 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 */
292extern struct codec_api ci; 292extern struct codec_api ci;
293static struct event_queue codec_queue; 293static struct event_queue codec_queue NOCACHEBSS_ATTR;
294static long codec_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)] 294static long codec_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)]
295IBSS_ATTR; 295IBSS_ATTR;
296static const char codec_thread_name[] = "codec"; 296static const char codec_thread_name[] = "codec";
@@ -304,7 +304,7 @@ static volatile int current_codec IDATA_ATTR; /* Current codec (normal/voice) */
304extern struct codec_api ci_voice; 304extern struct codec_api ci_voice;
305 305
306static struct thread_entry *voice_thread_p = NULL; 306static struct thread_entry *voice_thread_p = NULL;
307static struct event_queue voice_queue; 307static struct event_queue voice_queue NOCACHEBSS_ATTR;
308static long voice_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)] 308static long voice_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)]
309IBSS_ATTR_VOICE_STACK; 309IBSS_ATTR_VOICE_STACK;
310static const char voice_thread_name[] = "voice codec"; 310static 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 */
325static unsigned char *dram_buf[2] = { NULL, NULL }; 325static 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 */
327static struct mutex mutex_codecthread; 327static struct mutex mutex_codecthread NOCACHEBSS_ATTR;
328 328
329/* Voice state */ 329/* Voice state */
330static volatile bool voice_thread_start; /* Triggers voice playback (A/V) */ 330static volatile bool voice_thread_start; /* Triggers voice playback (A/V) */
331static volatile bool voice_is_playing; /* Is voice currently playing? (V) */ 331static volatile bool voice_is_playing NOCACHEBSS_ATTR; /* Is voice currently playing? (V) */
332static volatile bool voice_codec_loaded; /* Is voice codec loaded (V/A-) */ 332static volatile bool voice_codec_loaded NOCACHEBSS_ATTR; /* Is voice codec loaded (V/A-) */
333static char *voicebuf; 333static char *voicebuf;
334static size_t voice_remaining; 334static 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
869void audio_init(void) 870void 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();