diff options
38 files changed, 383 insertions, 215 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(); |
diff --git a/docs/PLUGIN_API b/docs/PLUGIN_API index e24d70fece..feba0868fb 100644 --- a/docs/PLUGIN_API +++ b/docs/PLUGIN_API | |||
@@ -431,7 +431,8 @@ Kernel | |||
431 | SYS_USB_CONNECTED. Else do nothing and return 0. | 431 | SYS_USB_CONNECTED. Else do nothing and return 0. |
432 | 432 | ||
433 | int create_thread(void* function, void* stack, int stack_size, | 433 | int create_thread(void* function, void* stack, int stack_size, |
434 | const char *name); | 434 | const char *name IF_PRIO(int priority) |
435 | IF_COP(, unsigned int core, bool fallback)); | ||
435 | 436 | ||
436 | Create a thread. | 437 | Create a thread. |
437 | ??? (see firmware/thread.c:145) | 438 | ??? (see firmware/thread.c:145) |
diff --git a/firmware/backlight.c b/firmware/backlight.c index a273b94a38..1e8dd46b2d 100644 --- a/firmware/backlight.c +++ b/firmware/backlight.c | |||
@@ -582,7 +582,8 @@ void backlight_init(void) | |||
582 | 582 | ||
583 | create_thread(backlight_thread, backlight_stack, | 583 | create_thread(backlight_thread, backlight_stack, |
584 | sizeof(backlight_stack), backlight_thread_name | 584 | sizeof(backlight_stack), backlight_thread_name |
585 | IF_PRIO(, PRIORITY_SYSTEM)); | 585 | IF_PRIO(, PRIORITY_SYSTEM) |
586 | IF_COP(, CPU, false)); | ||
586 | tick_add_task(backlight_tick); | 587 | tick_add_task(backlight_tick); |
587 | } | 588 | } |
588 | 589 | ||
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index fd9796c0d8..f78fa2d0cf 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c | |||
@@ -701,7 +701,8 @@ void dircache_init(void) | |||
701 | 701 | ||
702 | queue_init(&dircache_queue, true); | 702 | queue_init(&dircache_queue, true); |
703 | create_thread(dircache_thread, dircache_stack, | 703 | create_thread(dircache_thread, dircache_stack, |
704 | sizeof(dircache_stack), dircache_thread_name IF_PRIO(, PRIORITY_BACKGROUND)); | 704 | sizeof(dircache_stack), dircache_thread_name IF_PRIO(, PRIORITY_BACKGROUND) |
705 | IF_COP(, CPU, false)); | ||
705 | } | 706 | } |
706 | 707 | ||
707 | /** | 708 | /** |
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index 21376ab9a7..76c0090a12 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c | |||
@@ -991,7 +991,8 @@ int ata_init(void) | |||
991 | last_disk_activity = current_tick; | 991 | last_disk_activity = current_tick; |
992 | create_thread(ata_thread, ata_stack, | 992 | create_thread(ata_thread, ata_stack, |
993 | sizeof(ata_stack), ata_thread_name | 993 | sizeof(ata_stack), ata_thread_name |
994 | IF_PRIO(, PRIORITY_SYSTEM)); | 994 | IF_PRIO(, PRIORITY_SYSTEM) |
995 | IF_COP(, CPU, false)); | ||
995 | initialized = true; | 996 | initialized = true; |
996 | 997 | ||
997 | } | 998 | } |
diff --git a/firmware/drivers/ata_mmc.c b/firmware/drivers/ata_mmc.c index a549624b2c..377d2444bf 100644 --- a/firmware/drivers/ata_mmc.c +++ b/firmware/drivers/ata_mmc.c | |||
@@ -1173,7 +1173,8 @@ int ata_init(void) | |||
1173 | 1173 | ||
1174 | queue_init(&mmc_queue, true); | 1174 | queue_init(&mmc_queue, true); |
1175 | create_thread(mmc_thread, mmc_stack, | 1175 | create_thread(mmc_thread, mmc_stack, |
1176 | sizeof(mmc_stack), mmc_thread_name IF_PRIO(, PRIORITY_SYSTEM)); | 1176 | sizeof(mmc_stack), mmc_thread_name IF_PRIO(, PRIORITY_SYSTEM) |
1177 | IF_COP(, CPU, false)); | ||
1177 | tick_add_task(mmc_tick); | 1178 | tick_add_task(mmc_tick); |
1178 | initialized = true; | 1179 | initialized = true; |
1179 | } | 1180 | } |
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c index d545bf3fe4..7269e54dcd 100644 --- a/firmware/drivers/lcd-16bit.c +++ b/firmware/drivers/lcd-16bit.c | |||
@@ -89,7 +89,8 @@ void lcd_init(void) | |||
89 | 89 | ||
90 | create_thread(scroll_thread, scroll_stack, | 90 | create_thread(scroll_thread, scroll_stack, |
91 | sizeof(scroll_stack), scroll_name | 91 | sizeof(scroll_stack), scroll_name |
92 | IF_PRIO(, PRIORITY_USER_INTERFACE)); | 92 | IF_PRIO(, PRIORITY_USER_INTERFACE) |
93 | IF_COP(, CPU, false)); | ||
93 | } | 94 | } |
94 | 95 | ||
95 | /*** parameter handling ***/ | 96 | /*** parameter handling ***/ |
diff --git a/firmware/drivers/lcd-1bit-vert.c b/firmware/drivers/lcd-1bit-vert.c index 62dfab0180..64c1ace292 100644 --- a/firmware/drivers/lcd-1bit-vert.c +++ b/firmware/drivers/lcd-1bit-vert.c | |||
@@ -68,7 +68,8 @@ void lcd_init(void) | |||
68 | /* Call device specific init */ | 68 | /* Call device specific init */ |
69 | lcd_init_device(); | 69 | lcd_init_device(); |
70 | create_thread(scroll_thread, scroll_stack, | 70 | create_thread(scroll_thread, scroll_stack, |
71 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE)); | 71 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE) |
72 | IF_COP(, CPU, false)); | ||
72 | } | 73 | } |
73 | 74 | ||
74 | /*** parameter handling ***/ | 75 | /*** parameter handling ***/ |
diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c index 9ba52e1ba9..475e466c42 100644 --- a/firmware/drivers/lcd-2bit-horz.c +++ b/firmware/drivers/lcd-2bit-horz.c | |||
@@ -79,7 +79,8 @@ void lcd_init(void) | |||
79 | /* Call device specific init */ | 79 | /* Call device specific init */ |
80 | lcd_init_device(); | 80 | lcd_init_device(); |
81 | create_thread(scroll_thread, scroll_stack, | 81 | create_thread(scroll_thread, scroll_stack, |
82 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE)); | 82 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE) |
83 | IF_COP(, CPU, false)); | ||
83 | } | 84 | } |
84 | 85 | ||
85 | /*** parameter handling ***/ | 86 | /*** parameter handling ***/ |
diff --git a/firmware/drivers/lcd-2bit-vert.c b/firmware/drivers/lcd-2bit-vert.c index 7b3352b9d6..7a49f35312 100644 --- a/firmware/drivers/lcd-2bit-vert.c +++ b/firmware/drivers/lcd-2bit-vert.c | |||
@@ -82,7 +82,8 @@ void lcd_init(void) | |||
82 | /* Call device specific init */ | 82 | /* Call device specific init */ |
83 | lcd_init_device(); | 83 | lcd_init_device(); |
84 | create_thread(scroll_thread, scroll_stack, | 84 | create_thread(scroll_thread, scroll_stack, |
85 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE)); | 85 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE) |
86 | IF_COP(, CPU, false)); | ||
86 | } | 87 | } |
87 | 88 | ||
88 | /*** parameter handling ***/ | 89 | /*** parameter handling ***/ |
diff --git a/firmware/drivers/lcd-player.c b/firmware/drivers/lcd-player.c index 8ca81473fc..c863c9f188 100644 --- a/firmware/drivers/lcd-player.c +++ b/firmware/drivers/lcd-player.c | |||
@@ -610,7 +610,8 @@ void lcd_init (void) | |||
610 | lcd_set_contrast(lcd_default_contrast()); | 610 | lcd_set_contrast(lcd_default_contrast()); |
611 | 611 | ||
612 | create_thread(scroll_thread, scroll_stack, | 612 | create_thread(scroll_thread, scroll_stack, |
613 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE)); | 613 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE) |
614 | IF_COP(, CPU, false)); | ||
614 | } | 615 | } |
615 | 616 | ||
616 | void lcd_jump_scroll (int mode) /* 0=off, 1=once, ..., JUMP_SCROLL_ALWAYS */ | 617 | void lcd_jump_scroll (int mode) /* 0=off, 1=once, ..., JUMP_SCROLL_ALWAYS */ |
diff --git a/firmware/drivers/lcd-remote-1bit-v.c b/firmware/drivers/lcd-remote-1bit-v.c index c81ccc83c9..0aa3d890f7 100644 --- a/firmware/drivers/lcd-remote-1bit-v.c +++ b/firmware/drivers/lcd-remote-1bit-v.c | |||
@@ -903,5 +903,6 @@ void lcd_remote_init(void) | |||
903 | queue_init(&remote_scroll_queue, false); | 903 | queue_init(&remote_scroll_queue, false); |
904 | #endif | 904 | #endif |
905 | create_thread(scroll_thread, scroll_stack, | 905 | create_thread(scroll_thread, scroll_stack, |
906 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE)); | 906 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE) |
907 | IF_COP(, CPU, false)); | ||
907 | } | 908 | } |
diff --git a/firmware/drivers/lcd-remote-2bit-vi.c b/firmware/drivers/lcd-remote-2bit-vi.c index 281cbc2189..e0f6b35004 100644 --- a/firmware/drivers/lcd-remote-2bit-vi.c +++ b/firmware/drivers/lcd-remote-2bit-vi.c | |||
@@ -1241,5 +1241,6 @@ void lcd_remote_init(void) | |||
1241 | queue_init(&remote_scroll_queue, false); | 1241 | queue_init(&remote_scroll_queue, false); |
1242 | #endif | 1242 | #endif |
1243 | create_thread(scroll_thread, scroll_stack, | 1243 | create_thread(scroll_thread, scroll_stack, |
1244 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE)); | 1244 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE) |
1245 | IF_COP(, CPU, false)); | ||
1245 | } | 1246 | } |
diff --git a/firmware/export/config.h b/firmware/export/config.h index d848d16155..13fb77661d 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h | |||
@@ -273,21 +273,6 @@ | |||
273 | /* define for all cpus from PP family */ | 273 | /* define for all cpus from PP family */ |
274 | #if (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020) || (CONFIG_CPU == PP5024) | 274 | #if (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020) || (CONFIG_CPU == PP5024) |
275 | #define CPU_PP | 275 | #define CPU_PP |
276 | |||
277 | /* PP family has dual cores */ | ||
278 | #if 0 | ||
279 | /* Keep it as single core until dual core support is ready */ | ||
280 | #define NUM_CORES 2 | ||
281 | #define CURRENT_CORE current_core() | ||
282 | #endif | ||
283 | |||
284 | #define NUM_CORES 1 | ||
285 | #define CURRENT_CORE 0 | ||
286 | |||
287 | #define COP_REBOOT 0x00000001 | ||
288 | #else | ||
289 | #define NUM_CORES 1 | ||
290 | #define CURRENT_CORE 0 | ||
291 | #endif | 276 | #endif |
292 | 277 | ||
293 | /* define for all cpus from ARM family */ | 278 | /* define for all cpus from ARM family */ |
@@ -348,4 +333,28 @@ | |||
348 | #define IRAM_LCDFRAMEBUFFER | 333 | #define IRAM_LCDFRAMEBUFFER |
349 | #endif | 334 | #endif |
350 | 335 | ||
336 | /* Dual core support - not yet working on the 3G iPod */ | ||
337 | #if defined(CPU_PP) && CONFIG_CPU != PP5002 | ||
338 | #define NUM_CORES 2 | ||
339 | #define CURRENT_CORE current_core() | ||
340 | /* Hopefully at some point we will learn how to mark areas of main memory as | ||
341 | * not to be cached. Until then, use IRAM for variables shared across cores */ | ||
342 | #define NOCACHEBSS_ATTR IBSS_ATTR | ||
343 | #define NOCACHEDATA_ATTR IDATA_ATTR | ||
344 | |||
345 | #define IF_COP(empty, x, y) , x, y | ||
346 | |||
347 | /* Defines for inter-core messaging */ | ||
348 | #define COP_REBOOT 1 | ||
349 | |||
350 | #else | ||
351 | #define NUM_CORES 1 | ||
352 | #define CURRENT_CORE CPU | ||
353 | #define NOCACHEBSS_ATTR | ||
354 | #define NOCACHEDATA_ATTR | ||
355 | |||
356 | #define IF_COP(empty, x, y) | ||
357 | |||
358 | #endif /* Processor specific */ | ||
359 | |||
351 | #endif | 360 | #endif |
diff --git a/firmware/export/pp5002.h b/firmware/export/pp5002.h index ef131fe6d6..9636313390 100644 --- a/firmware/export/pp5002.h +++ b/firmware/export/pp5002.h | |||
@@ -73,6 +73,9 @@ | |||
73 | #define CPU_INT_STAT (*(volatile unsigned long*)(0xcf001000)) | 73 | #define CPU_INT_STAT (*(volatile unsigned long*)(0xcf001000)) |
74 | #define CPU_INT_EN (*(volatile unsigned long*)(0xcf001024)) | 74 | #define CPU_INT_EN (*(volatile unsigned long*)(0xcf001024)) |
75 | #define CPU_INT_CLR (*(volatile unsigned long*)(0xcf001028)) | 75 | #define CPU_INT_CLR (*(volatile unsigned long*)(0xcf001028)) |
76 | #define COP_INT_STAT (*(volatile unsigned long*)(0xcf001010)) /* A guess */ | ||
77 | #define COP_INT_EN (*(volatile unsigned long*)(0xcf001034)) | ||
78 | #define COP_INT_CLR (*(volatile unsigned long*)(0xcf001038)) | ||
76 | 79 | ||
77 | #define USB2D_IDENT (*(volatile unsigned long*)(0xc5000000)) | 80 | #define USB2D_IDENT (*(volatile unsigned long*)(0xc5000000)) |
78 | #define USB_STATUS (*(volatile unsigned long*)(0xc50001a4)) | 81 | #define USB_STATUS (*(volatile unsigned long*)(0xc50001a4)) |
diff --git a/firmware/export/pp5020.h b/firmware/export/pp5020.h index 3d205a0ea1..a34f1251c9 100644 --- a/firmware/export/pp5020.h +++ b/firmware/export/pp5020.h | |||
@@ -30,6 +30,15 @@ | |||
30 | #define PROC_ID_CPU 0x55 | 30 | #define PROC_ID_CPU 0x55 |
31 | #define PROC_ID_COP 0xaa | 31 | #define PROC_ID_COP 0xaa |
32 | 32 | ||
33 | /* Mailboxes */ | ||
34 | /* Each processor has two mailboxes it can write to and two which | ||
35 | it can read from. We define the first to be for sending messages | ||
36 | and the second for replying to messages */ | ||
37 | #define CPU_MESSAGE (*(volatile unsigned long *)(0x60001000)) | ||
38 | #define COP_MESSAGE (*(volatile unsigned long *)(0x60001004)) | ||
39 | #define CPU_REPLY (*(volatile unsigned long *)(0x60001008)) | ||
40 | #define COP_REPLY (*(volatile unsigned long *)(0x6000100c)) | ||
41 | |||
33 | /* Interrupts */ | 42 | /* Interrupts */ |
34 | #define CPU_INT_STAT (*(volatile unsigned long*)(0x64004000)) | 43 | #define CPU_INT_STAT (*(volatile unsigned long*)(0x64004000)) |
35 | #define COP_INT_STAT (*(volatile unsigned long*)(0x60004004)) | 44 | #define COP_INT_STAT (*(volatile unsigned long*)(0x60004004)) |
diff --git a/firmware/export/thread.h b/firmware/export/thread.h index bced98ea23..2ff4694159 100644 --- a/firmware/export/thread.h +++ b/firmware/export/thread.h | |||
@@ -124,13 +124,8 @@ struct core_entry { | |||
124 | 124 | ||
125 | struct thread_entry* | 125 | struct thread_entry* |
126 | create_thread(void (*function)(void), void* stack, int stack_size, | 126 | create_thread(void (*function)(void), void* stack, int stack_size, |
127 | const char *name IF_PRIO(, int priority)); | 127 | const char *name IF_PRIO(, int priority) |
128 | 128 | IF_COP(, unsigned int core, bool fallback)); | |
129 | struct thread_entry* | ||
130 | create_thread_on_core(unsigned int core, void (*function)(void), | ||
131 | void* stack, int stack_size, | ||
132 | const char *name | ||
133 | IF_PRIO(, int priority)); | ||
134 | 129 | ||
135 | #ifdef HAVE_SCHEDULER_BOOSTCTRL | 130 | #ifdef HAVE_SCHEDULER_BOOSTCTRL |
136 | void trigger_cpu_boost(void); | 131 | void trigger_cpu_boost(void); |
diff --git a/firmware/kernel.c b/firmware/kernel.c index 75c6604682..313530ffba 100644 --- a/firmware/kernel.c +++ b/firmware/kernel.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include "panic.h" | 26 | #include "panic.h" |
27 | 27 | ||
28 | #if !defined(CPU_PP) || !defined(BOOTLOADER) | 28 | #if !defined(CPU_PP) || !defined(BOOTLOADER) |
29 | long current_tick = 0; | 29 | long current_tick NOCACHEDATA_ATTR = 0; |
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | static void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); | 32 | static void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); |
@@ -45,10 +45,13 @@ void kernel_init(void) | |||
45 | /* Init the threading API */ | 45 | /* Init the threading API */ |
46 | init_threads(); | 46 | init_threads(); |
47 | 47 | ||
48 | memset(tick_funcs, 0, sizeof(tick_funcs)); | 48 | if(CURRENT_CORE == CPU) |
49 | { | ||
50 | memset(tick_funcs, 0, sizeof(tick_funcs)); | ||
49 | 51 | ||
50 | num_queues = 0; | 52 | num_queues = 0; |
51 | memset(all_queues, 0, sizeof(all_queues)); | 53 | memset(all_queues, 0, sizeof(all_queues)); |
54 | } | ||
52 | 55 | ||
53 | tick_start(1000/HZ); | 56 | tick_start(1000/HZ); |
54 | } | 57 | } |
@@ -496,28 +499,36 @@ void TIMER1(void) | |||
496 | int i; | 499 | int i; |
497 | 500 | ||
498 | TIMER1_VAL; /* Read value to ack IRQ */ | 501 | TIMER1_VAL; /* Read value to ack IRQ */ |
499 | /* Run through the list of tick tasks */ | 502 | /* Run through the list of tick tasks (using main core) */ |
500 | for (i = 0;i < MAX_NUM_TICK_TASKS;i++) | 503 | if (CURRENT_CORE == CPU) |
501 | { | 504 | { |
502 | if (tick_funcs[i]) | 505 | for (i = 0;i < MAX_NUM_TICK_TASKS;i++) |
503 | { | 506 | { |
504 | tick_funcs[i](); | 507 | if (tick_funcs[i]) |
508 | { | ||
509 | tick_funcs[i](); | ||
510 | } | ||
505 | } | 511 | } |
506 | } | ||
507 | 512 | ||
508 | current_tick++; | 513 | current_tick++; |
514 | } | ||
509 | } | 515 | } |
510 | #endif | 516 | #endif |
511 | 517 | ||
512 | void tick_start(unsigned int interval_in_ms) | 518 | void tick_start(unsigned int interval_in_ms) |
513 | { | 519 | { |
514 | #ifndef BOOTLOADER | 520 | #ifndef BOOTLOADER |
515 | TIMER1_CFG = 0x0; | 521 | if(CURRENT_CORE == CPU) |
516 | TIMER1_VAL; | 522 | { |
517 | /* enable timer */ | 523 | TIMER1_CFG = 0x0; |
518 | TIMER1_CFG = 0xc0000000 | (interval_in_ms*1000 - 1); | 524 | TIMER1_VAL; |
519 | /* unmask interrupt source */ | 525 | /* enable timer */ |
520 | CPU_INT_EN = TIMER1_MASK; | 526 | TIMER1_CFG = 0xc0000000 | (interval_in_ms*1000 - 1); |
527 | /* unmask interrupt source */ | ||
528 | CPU_INT_EN = TIMER1_MASK; | ||
529 | } else { | ||
530 | COP_INT_EN = TIMER1_MASK; | ||
531 | } | ||
521 | #else | 532 | #else |
522 | /* We don't enable interrupts in the bootloader */ | 533 | /* We don't enable interrupts in the bootloader */ |
523 | (void)interval_in_ms; | 534 | (void)interval_in_ms; |
@@ -645,6 +656,29 @@ void mutex_init(struct mutex *m) | |||
645 | m->thread = NULL; | 656 | m->thread = NULL; |
646 | } | 657 | } |
647 | 658 | ||
659 | #ifdef CPU_PP | ||
660 | /* PortalPlayer chips have 2 cores, therefore need atomic mutexes */ | ||
661 | |||
662 | static inline bool test_and_set(bool *x, bool v) | ||
663 | { | ||
664 | asm volatile ( | ||
665 | "swpb %0, %0, [%1]\n" | ||
666 | : "+r"(v) | ||
667 | : "r"(x) | ||
668 | ); | ||
669 | return v; | ||
670 | } | ||
671 | |||
672 | void mutex_lock(struct mutex *m) | ||
673 | { | ||
674 | if (test_and_set(&m->locked,true)) | ||
675 | { | ||
676 | /* Wait until the lock is open... */ | ||
677 | block_thread(&m->thread); | ||
678 | } | ||
679 | } | ||
680 | |||
681 | #else | ||
648 | void mutex_lock(struct mutex *m) | 682 | void mutex_lock(struct mutex *m) |
649 | { | 683 | { |
650 | if (m->locked) | 684 | if (m->locked) |
@@ -656,6 +690,7 @@ void mutex_lock(struct mutex *m) | |||
656 | /* ...and lock it */ | 690 | /* ...and lock it */ |
657 | m->locked = true; | 691 | m->locked = true; |
658 | } | 692 | } |
693 | #endif | ||
659 | 694 | ||
660 | void mutex_unlock(struct mutex *m) | 695 | void mutex_unlock(struct mutex *m) |
661 | { | 696 | { |
diff --git a/firmware/mpeg.c b/firmware/mpeg.c index 9afa8a20bd..909a21dcda 100644 --- a/firmware/mpeg.c +++ b/firmware/mpeg.c | |||
@@ -2905,7 +2905,8 @@ void audio_init(void) | |||
2905 | queue_init(&mpeg_queue, true); | 2905 | queue_init(&mpeg_queue, true); |
2906 | #endif /* !SIMULATOR */ | 2906 | #endif /* !SIMULATOR */ |
2907 | create_thread(mpeg_thread, mpeg_stack, | 2907 | create_thread(mpeg_thread, mpeg_stack, |
2908 | sizeof(mpeg_stack), mpeg_thread_name IF_PRIO(, PRIORITY_SYSTEM)); | 2908 | sizeof(mpeg_stack), mpeg_thread_name IF_PRIO(, PRIORITY_SYSTEM) |
2909 | IF_COP(, CPU, false)); | ||
2909 | 2910 | ||
2910 | memset(trackdata, sizeof(trackdata), 0); | 2911 | memset(trackdata, sizeof(trackdata), 0); |
2911 | 2912 | ||
diff --git a/firmware/pcm_record.c b/firmware/pcm_record.c index 270bb354d2..3f4abc7be3 100644 --- a/firmware/pcm_record.c +++ b/firmware/pcm_record.c | |||
@@ -418,7 +418,8 @@ void pcm_rec_init(void) | |||
418 | queue_enable_queue_send(&pcmrec_queue, &pcmrec_queue_send); | 418 | queue_enable_queue_send(&pcmrec_queue, &pcmrec_queue_send); |
419 | pcmrec_thread_p = | 419 | pcmrec_thread_p = |
420 | create_thread(pcmrec_thread, pcmrec_stack, sizeof(pcmrec_stack), | 420 | create_thread(pcmrec_thread, pcmrec_stack, sizeof(pcmrec_stack), |
421 | pcmrec_thread_name IF_PRIO(, PRIORITY_RECORDING)); | 421 | pcmrec_thread_name IF_PRIO(, PRIORITY_RECORDING) |
422 | IF_COP(, CPU, false)); | ||
422 | } /* pcm_rec_init */ | 423 | } /* pcm_rec_init */ |
423 | 424 | ||
424 | /** audio_* group **/ | 425 | /** audio_* group **/ |
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index c2f9ca0bca..1492c80bc4 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c | |||
@@ -1245,7 +1245,8 @@ void powermgmt_init(void) | |||
1245 | /* init history to 0 */ | 1245 | /* init history to 0 */ |
1246 | memset(power_history, 0x00, sizeof(power_history)); | 1246 | memset(power_history, 0x00, sizeof(power_history)); |
1247 | create_thread(power_thread, power_stack, sizeof(power_stack), | 1247 | create_thread(power_thread, power_stack, sizeof(power_stack), |
1248 | power_thread_name IF_PRIO(, PRIORITY_SYSTEM)); | 1248 | power_thread_name IF_PRIO(, PRIORITY_SYSTEM) |
1249 | IF_COP(, CPU, false)); | ||
1249 | } | 1250 | } |
1250 | 1251 | ||
1251 | #endif /* SIMULATOR */ | 1252 | #endif /* SIMULATOR */ |
diff --git a/firmware/system.c b/firmware/system.c index a86d945093..a9c9d9e350 100644 --- a/firmware/system.c +++ b/firmware/system.c | |||
@@ -612,12 +612,22 @@ extern void ipod_mini_button_int(void); | |||
612 | 612 | ||
613 | void irq(void) | 613 | void irq(void) |
614 | { | 614 | { |
615 | if (CPU_INT_STAT & TIMER1_MASK) | 615 | if(CURRENT_CORE == CPU) |
616 | TIMER1(); | 616 | { |
617 | else if (CPU_INT_STAT & TIMER2_MASK) | 617 | if (CPU_INT_STAT & TIMER1_MASK) |
618 | TIMER2(); | 618 | TIMER1(); |
619 | else if (CPU_HI_INT_STAT & GPIO_MASK) | 619 | else if (CPU_INT_STAT & TIMER2_MASK) |
620 | ipod_mini_button_int(); | 620 | TIMER2(); |
621 | else if (CPU_HI_INT_STAT & GPIO_MASK) | ||
622 | ipod_mini_button_int(); | ||
623 | } else { | ||
624 | if (COP_INT_STAT & TIMER1_MASK) | ||
625 | TIMER1(); | ||
626 | else if (COP_INT_STAT & TIMER2_MASK) | ||
627 | TIMER2(); | ||
628 | else if (COP_HI_INT_STAT & GPIO_MASK) | ||
629 | ipod_mini_button_int(); | ||
630 | } | ||
621 | } | 631 | } |
622 | #elif (defined IRIVER_H10) || (defined IRIVER_H10_5GB) || defined(ELIO_TPJ1022) \ | 632 | #elif (defined IRIVER_H10) || (defined IRIVER_H10_5GB) || defined(ELIO_TPJ1022) \ |
623 | || (defined SANSA_E200) | 633 | || (defined SANSA_E200) |
@@ -626,22 +636,40 @@ void irq(void) | |||
626 | /* TODO: Even if it isn't in the target tree, this should be the default case */ | 636 | /* TODO: Even if it isn't in the target tree, this should be the default case */ |
627 | void irq(void) | 637 | void irq(void) |
628 | { | 638 | { |
629 | if (CPU_INT_STAT & TIMER1_MASK) | 639 | if(CURRENT_CORE == CPU) |
630 | TIMER1(); | 640 | { |
631 | else if (CPU_INT_STAT & TIMER2_MASK) | 641 | if (CPU_INT_STAT & TIMER1_MASK) |
632 | TIMER2(); | 642 | TIMER1(); |
643 | else if (CPU_INT_STAT & TIMER2_MASK) | ||
644 | TIMER2(); | ||
645 | } else { | ||
646 | if (COP_INT_STAT & TIMER1_MASK) | ||
647 | TIMER1(); | ||
648 | else if (COP_INT_STAT & TIMER2_MASK) | ||
649 | TIMER2(); | ||
650 | } | ||
633 | } | 651 | } |
634 | #else | 652 | #else |
635 | extern void ipod_4g_button_int(void); | 653 | extern void ipod_4g_button_int(void); |
636 | 654 | ||
637 | void irq(void) | 655 | void irq(void) |
638 | { | 656 | { |
639 | if (CPU_INT_STAT & TIMER1_MASK) | 657 | if(CURRENT_CORE == CPU) |
640 | TIMER1(); | 658 | { |
641 | else if (CPU_INT_STAT & TIMER2_MASK) | 659 | if (CPU_INT_STAT & TIMER1_MASK) |
642 | TIMER2(); | 660 | TIMER1(); |
643 | else if (CPU_HI_INT_STAT & I2C_MASK) | 661 | else if (CPU_INT_STAT & TIMER2_MASK) |
644 | ipod_4g_button_int(); | 662 | TIMER2(); |
663 | else if (CPU_HI_INT_STAT & I2C_MASK) | ||
664 | ipod_4g_button_int(); | ||
665 | } else { | ||
666 | if (COP_INT_STAT & TIMER1_MASK) | ||
667 | TIMER1(); | ||
668 | else if (COP_INT_STAT & TIMER2_MASK) | ||
669 | TIMER2(); | ||
670 | else if (COP_HI_INT_STAT & I2C_MASK) | ||
671 | ipod_4g_button_int(); | ||
672 | } | ||
645 | } | 673 | } |
646 | #endif | 674 | #endif |
647 | #endif /* BOOTLOADER */ | 675 | #endif /* BOOTLOADER */ |
@@ -694,43 +722,47 @@ void set_cpu_frequency(long frequency) | |||
694 | { | 722 | { |
695 | unsigned long postmult; | 723 | unsigned long postmult; |
696 | 724 | ||
697 | if (frequency == CPUFREQ_NORMAL) | 725 | if (CURRENT_CORE == CPU) |
698 | postmult = CPUFREQ_NORMAL_MULT; | 726 | { |
699 | else if (frequency == CPUFREQ_MAX) | 727 | if (frequency == CPUFREQ_NORMAL) |
700 | postmult = CPUFREQ_MAX_MULT; | 728 | postmult = CPUFREQ_NORMAL_MULT; |
701 | else | 729 | else if (frequency == CPUFREQ_MAX) |
702 | postmult = CPUFREQ_DEFAULT_MULT; | 730 | postmult = CPUFREQ_MAX_MULT; |
703 | cpu_frequency = frequency; | 731 | else |
732 | postmult = CPUFREQ_DEFAULT_MULT; | ||
733 | cpu_frequency = frequency; | ||
704 | 734 | ||
705 | /* Enable PLL? */ | 735 | /* Enable PLL? */ |
706 | outl(inl(0x70000020) | (1<<30), 0x70000020); | 736 | outl(inl(0x70000020) | (1<<30), 0x70000020); |
707 | 737 | ||
708 | /* Select 24MHz crystal as clock source? */ | 738 | /* Select 24MHz crystal as clock source? */ |
709 | outl((inl(0x60006020) & 0x0fffff0f) | 0x20000020, 0x60006020); | 739 | outl((inl(0x60006020) & 0x0fffff0f) | 0x20000020, 0x60006020); |
710 | 740 | ||
711 | /* Clock frequency = (24/8)*postmult */ | 741 | /* Clock frequency = (24/8)*postmult */ |
712 | outl(0xaa020000 | 8 | (postmult << 8), 0x60006034); | 742 | outl(0xaa020000 | 8 | (postmult << 8), 0x60006034); |
713 | 743 | ||
714 | /* Wait for PLL relock? */ | 744 | /* Wait for PLL relock? */ |
715 | udelay(2000); | 745 | udelay(2000); |
716 | 746 | ||
717 | /* Select PLL as clock source? */ | 747 | /* Select PLL as clock source? */ |
718 | outl((inl(0x60006020) & 0x0fffff0f) | 0x20000070, 0x60006020); | 748 | outl((inl(0x60006020) & 0x0fffff0f) | 0x20000070, 0x60006020); |
719 | 749 | ||
720 | #if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IRIVER_H10) || defined(IRIVER_H10_5GB) | 750 | #if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IRIVER_H10) || defined(IRIVER_H10_5GB) |
721 | /* We don't know why the timer interrupt gets disabled on the PP5020 | 751 | /* We don't know why the timer interrupt gets disabled on the PP5020 |
722 | based ipods, but without the following line, the 4Gs will freeze | 752 | based ipods, but without the following line, the 4Gs will freeze |
723 | when CPU frequency changing is enabled. | 753 | when CPU frequency changing is enabled. |
724 | 754 | ||
725 | Note also that a simple "CPU_INT_EN = TIMER1_MASK;" (as used | 755 | Note also that a simple "CPU_INT_EN = TIMER1_MASK;" (as used |
726 | elsewhere to enable interrupts) doesn't work, we need "|=". | 756 | elsewhere to enable interrupts) doesn't work, we need "|=". |
727 | 757 | ||
728 | It's not needed on the PP5021 and PP5022 ipods. | 758 | It's not needed on the PP5021 and PP5022 ipods. |
729 | */ | 759 | */ |
730 | 760 | ||
731 | /* unmask interrupt source */ | 761 | /* unmask interrupt source */ |
732 | CPU_INT_EN |= TIMER1_MASK; | 762 | CPU_INT_EN |= TIMER1_MASK; |
763 | COP_INT_EN |= TIMER1_MASK; | ||
733 | #endif | 764 | #endif |
765 | } | ||
734 | } | 766 | } |
735 | #elif !defined(BOOTLOADER) | 767 | #elif !defined(BOOTLOADER) |
736 | void ipod_set_cpu_frequency(void) | 768 | void ipod_set_cpu_frequency(void) |
@@ -754,24 +786,33 @@ void ipod_set_cpu_frequency(void) | |||
754 | void system_init(void) | 786 | void system_init(void) |
755 | { | 787 | { |
756 | #ifndef BOOTLOADER | 788 | #ifndef BOOTLOADER |
757 | /* Remap the flash ROM from 0x00000000 to 0x20000000. */ | 789 | if (CURRENT_CORE == CPU) |
758 | MMAP3_LOGICAL = 0x20000000 | 0x3a00; | 790 | { |
759 | MMAP3_PHYSICAL = 0x00000000 | 0x3f84; | 791 | /* Remap the flash ROM from 0x00000000 to 0x20000000. */ |
760 | 792 | MMAP3_LOGICAL = 0x20000000 | 0x3a00; | |
761 | /* The hw revision is written to the last 4 bytes of SDRAM by the | 793 | MMAP3_PHYSICAL = 0x00000000 | 0x3f84; |
762 | bootloader - we save it before Rockbox overwrites it. */ | 794 | |
763 | ipod_hw_rev = (*((volatile unsigned long*)(0x01fffffc))); | 795 | /* The hw revision is written to the last 4 bytes of SDRAM by the |
764 | 796 | bootloader - we save it before Rockbox overwrites it. */ | |
765 | /* disable all irqs */ | 797 | ipod_hw_rev = (*((volatile unsigned long*)(0x01fffffc))); |
766 | outl(-1, 0x60001138); | 798 | |
767 | outl(-1, 0x60001128); | 799 | /* disable all irqs */ |
768 | outl(-1, 0x6000111c); | 800 | outl(-1, 0x60001138); |
769 | 801 | outl(-1, 0x60001128); | |
770 | outl(-1, 0x60001038); | 802 | outl(-1, 0x6000111c); |
771 | outl(-1, 0x60001028); | 803 | |
772 | outl(-1, 0x6000101c); | 804 | outl(-1, 0x60001038); |
773 | #ifndef HAVE_ADJUSTABLE_CPU_FREQ | 805 | outl(-1, 0x60001028); |
774 | ipod_set_cpu_frequency(); | 806 | outl(-1, 0x6000101c); |
807 | #if (!defined HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES == 1) | ||
808 | ipod_set_cpu_frequency(); | ||
809 | #endif | ||
810 | } | ||
811 | #if (!defined HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1) | ||
812 | else | ||
813 | { | ||
814 | ipod_set_cpu_frequency(); | ||
815 | } | ||
775 | #endif | 816 | #endif |
776 | ipod_init_cache(); | 817 | ipod_init_cache(); |
777 | #endif | 818 | #endif |
@@ -796,10 +837,18 @@ extern void TIMER2(void); | |||
796 | 837 | ||
797 | void irq(void) | 838 | void irq(void) |
798 | { | 839 | { |
799 | if (CPU_INT_STAT & TIMER1_MASK) | 840 | if(CURRENT_CORE == CPU) |
800 | TIMER1(); | 841 | { |
801 | else if (CPU_INT_STAT & TIMER2_MASK) | 842 | if (CPU_INT_STAT & TIMER1_MASK) |
802 | TIMER2(); | 843 | TIMER1(); |
844 | else if (CPU_INT_STAT & TIMER2_MASK) | ||
845 | TIMER2(); | ||
846 | } else { | ||
847 | if (COP_INT_STAT & TIMER1_MASK) | ||
848 | TIMER1(); | ||
849 | else if (COP_INT_STAT & TIMER2_MASK) | ||
850 | TIMER2(); | ||
851 | } | ||
803 | } | 852 | } |
804 | 853 | ||
805 | #endif | 854 | #endif |
@@ -848,29 +897,32 @@ void set_cpu_frequency(long frequency) | |||
848 | { | 897 | { |
849 | unsigned long postmult; | 898 | unsigned long postmult; |
850 | 899 | ||
851 | if (frequency == CPUFREQ_NORMAL) | 900 | if (CURRENT_CORE == CPU) |
852 | postmult = CPUFREQ_NORMAL_MULT; | 901 | { |
853 | else if (frequency == CPUFREQ_MAX) | 902 | if (frequency == CPUFREQ_NORMAL) |
854 | postmult = CPUFREQ_MAX_MULT; | 903 | postmult = CPUFREQ_NORMAL_MULT; |
855 | else | 904 | else if (frequency == CPUFREQ_MAX) |
856 | postmult = CPUFREQ_DEFAULT_MULT; | 905 | postmult = CPUFREQ_MAX_MULT; |
857 | cpu_frequency = frequency; | 906 | else |
907 | postmult = CPUFREQ_DEFAULT_MULT; | ||
908 | cpu_frequency = frequency; | ||
858 | 909 | ||
859 | outl(0x02, 0xcf005008); | 910 | outl(0x02, 0xcf005008); |
860 | outl(0x55, 0xcf00500c); | 911 | outl(0x55, 0xcf00500c); |
861 | outl(0x6000, 0xcf005010); | 912 | outl(0x6000, 0xcf005010); |
862 | 913 | ||
863 | /* Clock frequency = (24/8)*postmult */ | 914 | /* Clock frequency = (24/8)*postmult */ |
864 | outl(8, 0xcf005018); | 915 | outl(8, 0xcf005018); |
865 | outl(postmult, 0xcf00501c); | 916 | outl(postmult, 0xcf00501c); |
866 | 917 | ||
867 | outl(0xe000, 0xcf005010); | 918 | outl(0xe000, 0xcf005010); |
868 | 919 | ||
869 | /* Wait for PLL relock? */ | 920 | /* Wait for PLL relock? */ |
870 | udelay(2000); | 921 | udelay(2000); |
871 | 922 | ||
872 | /* Select PLL as clock source? */ | 923 | /* Select PLL as clock source? */ |
873 | outl(0xa8, 0xcf00500c); | 924 | outl(0xa8, 0xcf00500c); |
925 | } | ||
874 | } | 926 | } |
875 | #elif !defined(BOOTLOADER) | 927 | #elif !defined(BOOTLOADER) |
876 | static void ipod_set_cpu_speed(void) | 928 | static void ipod_set_cpu_speed(void) |
@@ -901,17 +953,20 @@ static void ipod_set_cpu_speed(void) | |||
901 | void system_init(void) | 953 | void system_init(void) |
902 | { | 954 | { |
903 | #ifndef BOOTLOADER | 955 | #ifndef BOOTLOADER |
904 | /* Remap the flash ROM from 0x00000000 to 0x20000000. */ | 956 | if (CURRENT_CORE == CPU) |
905 | MMAP3_LOGICAL = 0x20000000 | 0x3a00; | 957 | { |
906 | MMAP3_PHYSICAL = 0x00000000 | 0x3f84; | 958 | /* Remap the flash ROM from 0x00000000 to 0x20000000. */ |
907 | 959 | MMAP3_LOGICAL = 0x20000000 | 0x3a00; | |
908 | ipod_hw_rev = (*((volatile unsigned long*)(0x01fffffc))); | 960 | MMAP3_PHYSICAL = 0x00000000 | 0x3f84; |
909 | outl(-1, 0xcf00101c); | 961 | |
910 | outl(-1, 0xcf001028); | 962 | ipod_hw_rev = (*((volatile unsigned long*)(0x01fffffc))); |
911 | outl(-1, 0xcf001038); | 963 | outl(-1, 0xcf00101c); |
964 | outl(-1, 0xcf001028); | ||
965 | outl(-1, 0xcf001038); | ||
912 | #ifndef HAVE_ADJUSTABLE_CPU_FREQ | 966 | #ifndef HAVE_ADJUSTABLE_CPU_FREQ |
913 | ipod_set_cpu_speed(); | 967 | ipod_set_cpu_speed(); |
914 | #endif | 968 | #endif |
969 | } | ||
915 | ipod_init_cache(); | 970 | ipod_init_cache(); |
916 | #endif | 971 | #endif |
917 | } | 972 | } |
diff --git a/firmware/target/arm/crt0-pp.S b/firmware/target/arm/crt0-pp.S index e0d1034f74..bbeace1b60 100644 --- a/firmware/target/arm/crt0-pp.S +++ b/firmware/target/arm/crt0-pp.S | |||
@@ -222,6 +222,19 @@ cop_init: | |||
222 | strhi r4, [r2], #4 | 222 | strhi r4, [r2], #4 |
223 | bhi 2b | 223 | bhi 2b |
224 | 224 | ||
225 | /* Set up stack for IRQ mode */ | ||
226 | msr cpsr_c, #0xd2 | ||
227 | ldr sp, =cop_irq_stack | ||
228 | /* Set up stack for FIQ mode */ | ||
229 | msr cpsr_c, #0xd1 | ||
230 | ldr sp, =fiq_stack | ||
231 | |||
232 | /* Let abort and undefined modes use IRQ stack */ | ||
233 | msr cpsr_c, #0xd7 | ||
234 | ldr sp, =cop_irq_stack | ||
235 | msr cpsr_c, #0xdb | ||
236 | ldr sp, =cop_irq_stack | ||
237 | |||
225 | ldr sp, =cop_stackend | 238 | ldr sp, =cop_stackend |
226 | 239 | ||
227 | /* Run cop_main() in apps/main.c */ | 240 | /* Run cop_main() in apps/main.c */ |
@@ -307,6 +320,10 @@ UIE: | |||
307 | .space 256*4 | 320 | .space 256*4 |
308 | irq_stack: | 321 | irq_stack: |
309 | 322 | ||
323 | /* 256 words of COP IRQ stack */ | ||
324 | .space 256*4 | ||
325 | cop_irq_stack: | ||
326 | |||
310 | /* 256 words of FIQ stack */ | 327 | /* 256 words of FIQ stack */ |
311 | .space 256*4 | 328 | .space 256*4 |
312 | fiq_stack: | 329 | fiq_stack: |
diff --git a/firmware/target/arm/sandisk/sansa-e200/ata-e200.c b/firmware/target/arm/sandisk/sansa-e200/ata-e200.c index cf05397a78..73a67d1ee6 100644 --- a/firmware/target/arm/sandisk/sansa-e200/ata-e200.c +++ b/firmware/target/arm/sandisk/sansa-e200/ata-e200.c | |||
@@ -687,7 +687,8 @@ int ata_init(void) | |||
687 | { | 687 | { |
688 | queue_init(&sd_queue, true); | 688 | queue_init(&sd_queue, true); |
689 | create_thread(sd_thread, sd_stack, | 689 | create_thread(sd_thread, sd_stack, |
690 | sizeof(sd_stack), sd_thread_name IF_PRIO(, PRIORITY_SYSTEM)); | 690 | sizeof(sd_stack), sd_thread_name IF_PRIO(, PRIORITY_SYSTEM) |
691 | IF_COP(, CPU, false)); | ||
691 | initialized = true; | 692 | initialized = true; |
692 | } | 693 | } |
693 | 694 | ||
diff --git a/firmware/thread.c b/firmware/thread.c index 2281f43e53..281ab0fa54 100644 --- a/firmware/thread.c +++ b/firmware/thread.c | |||
@@ -64,6 +64,10 @@ int *cop_stackend = stackend; | |||
64 | #endif | 64 | #endif |
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | #if (NUM_CORES > 1) | ||
68 | bool IDATA_ATTR kernel_running_on_cop = false; | ||
69 | #endif | ||
70 | |||
67 | /* Conserve IRAM | 71 | /* Conserve IRAM |
68 | static void add_to_list(struct thread_entry **list, | 72 | static void add_to_list(struct thread_entry **list, |
69 | struct thread_entry *thread) ICODE_ATTR; | 73 | struct thread_entry *thread) ICODE_ATTR; |
@@ -316,10 +320,13 @@ static inline void sleep_core(void) | |||
316 | #elif CONFIG_CPU == SH7034 | 320 | #elif CONFIG_CPU == SH7034 |
317 | and_b(0x7F, &SBYCR); | 321 | and_b(0x7F, &SBYCR); |
318 | asm volatile ("sleep"); | 322 | asm volatile ("sleep"); |
319 | #elif CONFIG_CPU == PP5020 | 323 | #elif defined (CPU_PP) |
320 | /* This should sleep the CPU. It appears to wake by itself on | 324 | /* This should sleep the CPU. It appears to wake by itself on |
321 | interrupts */ | 325 | interrupts */ |
322 | CPU_CTL = 0x80000000; | 326 | if (CURRENT_CORE == CPU) |
327 | CPU_CTL = PROC_SLEEP; | ||
328 | else | ||
329 | COP_CTL = PROC_SLEEP; | ||
323 | #elif CONFIG_CPU == S3C2440 | 330 | #elif CONFIG_CPU == S3C2440 |
324 | CLKCON |= (1 << 2); /* set IDLE bit */ | 331 | CLKCON |= (1 << 2); /* set IDLE bit */ |
325 | for(i=0; i<10; i++); /* wait for IDLE */ | 332 | for(i=0; i<10; i++); /* wait for IDLE */ |
@@ -608,27 +615,16 @@ void wakeup_thread(struct thread_entry **list) | |||
608 | } | 615 | } |
609 | 616 | ||
610 | /*--------------------------------------------------------------------------- | 617 | /*--------------------------------------------------------------------------- |
611 | * Create thread on the current core. | 618 | * Create a thread |
612 | * Return ID if context area could be allocated, else -1. | 619 | * If using a dual core architecture, specify which core to start the thread |
620 | * on, and whether to fall back to the other core if it can't be created | ||
621 | * Return ID if context area could be allocated, else NULL. | ||
613 | *--------------------------------------------------------------------------- | 622 | *--------------------------------------------------------------------------- |
614 | */ | 623 | */ |
615 | struct thread_entry* | 624 | struct thread_entry* |
616 | create_thread(void (*function)(void), void* stack, int stack_size, | 625 | create_thread(void (*function)(void), void* stack, int stack_size, |
617 | const char *name IF_PRIO(, int priority)) | 626 | const char *name IF_PRIO(, int priority) |
618 | { | 627 | IF_COP(, unsigned int core, bool fallback)) |
619 | return create_thread_on_core(CURRENT_CORE, function, stack, stack_size, | ||
620 | name IF_PRIO(, priority)); | ||
621 | } | ||
622 | |||
623 | /*--------------------------------------------------------------------------- | ||
624 | * Create thread on a specific core. | ||
625 | * Return ID if context area could be allocated, else -1. | ||
626 | *--------------------------------------------------------------------------- | ||
627 | */ | ||
628 | struct thread_entry* | ||
629 | create_thread_on_core(unsigned int core, void (*function)(void), | ||
630 | void* stack, int stack_size, | ||
631 | const char *name IF_PRIO(, int priority)) | ||
632 | { | 628 | { |
633 | unsigned int i; | 629 | unsigned int i; |
634 | unsigned int stacklen; | 630 | unsigned int stacklen; |
@@ -637,6 +633,29 @@ struct thread_entry* | |||
637 | struct regs *regs; | 633 | struct regs *regs; |
638 | struct thread_entry *thread; | 634 | struct thread_entry *thread; |
639 | 635 | ||
636 | /***** | ||
637 | * Ugly code alert! | ||
638 | * To prevent ifdef hell while keeping the binary size down, we define | ||
639 | * core here if it hasn't been passed as a parameter | ||
640 | *****/ | ||
641 | #if NUM_CORES == 1 | ||
642 | #define core CPU | ||
643 | #endif | ||
644 | |||
645 | #if NUM_CORES > 1 | ||
646 | /* If the kernel hasn't initialised on the COP (most likely due to an old | ||
647 | * bootloader) then refuse to start threads on the COP | ||
648 | */ | ||
649 | if((core == COP) && !kernel_running_on_cop) | ||
650 | { | ||
651 | if (fallback) | ||
652 | return create_thread(function, stack, stack_size, name | ||
653 | IF_PRIO(, priority) IF_COP(, CPU, false)); | ||
654 | else | ||
655 | return NULL; | ||
656 | } | ||
657 | #endif | ||
658 | |||
640 | for (n = 0; n < MAXTHREADS; n++) | 659 | for (n = 0; n < MAXTHREADS; n++) |
641 | { | 660 | { |
642 | if (cores[core].threads[n].name == NULL) | 661 | if (cores[core].threads[n].name == NULL) |
@@ -644,8 +663,15 @@ struct thread_entry* | |||
644 | } | 663 | } |
645 | 664 | ||
646 | if (n == MAXTHREADS) | 665 | if (n == MAXTHREADS) |
647 | return NULL; | 666 | { |
648 | 667 | #if NUM_CORES > 1 | |
668 | if (fallback) | ||
669 | return create_thread(function, stack, stack_size, name | ||
670 | IF_PRIO(, priority) IF_COP(, 1 - core, fallback)); | ||
671 | else | ||
672 | #endif | ||
673 | return NULL; | ||
674 | } | ||
649 | 675 | ||
650 | /* Munge the stack to make it easy to spot stack overflows */ | 676 | /* Munge the stack to make it easy to spot stack overflows */ |
651 | stacklen = stack_size / sizeof(int); | 677 | stacklen = stack_size / sizeof(int); |
@@ -677,6 +703,9 @@ struct thread_entry* | |||
677 | THREAD_CPU_INIT(core, thread); | 703 | THREAD_CPU_INIT(core, thread); |
678 | 704 | ||
679 | return thread; | 705 | return thread; |
706 | #if NUM_CORES == 1 | ||
707 | #undef core | ||
708 | #endif | ||
680 | } | 709 | } |
681 | 710 | ||
682 | #ifdef HAVE_SCHEDULER_BOOSTCTRL | 711 | #ifdef HAVE_SCHEDULER_BOOSTCTRL |
@@ -751,7 +780,8 @@ void init_threads(void) | |||
751 | { | 780 | { |
752 | unsigned int core = CURRENT_CORE; | 781 | unsigned int core = CURRENT_CORE; |
753 | 782 | ||
754 | memset(cores, 0, sizeof cores); | 783 | if (core == CPU) |
784 | memset(cores, 0, sizeof cores); | ||
755 | cores[core].sleeping = NULL; | 785 | cores[core].sleeping = NULL; |
756 | cores[core].running = NULL; | 786 | cores[core].running = NULL; |
757 | cores[core].threads[0].name = main_thread_name; | 787 | cores[core].threads[0].name = main_thread_name; |
@@ -779,6 +809,10 @@ void init_threads(void) | |||
779 | #endif | 809 | #endif |
780 | } | 810 | } |
781 | cores[core].threads[0].context.start = 0; /* thread 0 already running */ | 811 | cores[core].threads[0].context.start = 0; /* thread 0 already running */ |
812 | #if NUM_CORES > 1 | ||
813 | if(core == COP) | ||
814 | kernel_running_on_cop = true; /* can we use context.start for this? */ | ||
815 | #endif | ||
782 | } | 816 | } |
783 | 817 | ||
784 | int thread_stack_usage(const struct thread_entry *thread) | 818 | int thread_stack_usage(const struct thread_entry *thread) |
diff --git a/firmware/usb.c b/firmware/usb.c index ee08b04caa..cf4641950e 100644 --- a/firmware/usb.c +++ b/firmware/usb.c | |||
@@ -428,7 +428,8 @@ void usb_init(void) | |||
428 | #ifndef BOOTLOADER | 428 | #ifndef BOOTLOADER |
429 | queue_init(&usb_queue, true); | 429 | queue_init(&usb_queue, true); |
430 | create_thread(usb_thread, usb_stack, sizeof(usb_stack), | 430 | create_thread(usb_thread, usb_stack, sizeof(usb_stack), |
431 | usb_thread_name IF_PRIO(, PRIORITY_SYSTEM)); | 431 | usb_thread_name IF_PRIO(, PRIORITY_SYSTEM) |
432 | IF_COP(, CPU, false)); | ||
432 | 433 | ||
433 | tick_add_task(usb_tick); | 434 | tick_add_task(usb_tick); |
434 | #endif | 435 | #endif |
diff --git a/uisimulator/common/stubs.c b/uisimulator/common/stubs.c index a993a9e0e8..8ea46824ce 100644 --- a/uisimulator/common/stubs.c +++ b/uisimulator/common/stubs.c | |||
@@ -258,12 +258,6 @@ void remove_thread(int threadnum) | |||
258 | (void)threadnum; | 258 | (void)threadnum; |
259 | } | 259 | } |
260 | 260 | ||
261 | void remove_thread_on_core(unsigned int core, int threadnum) | ||
262 | { | ||
263 | (void)core; | ||
264 | (void)threadnum; | ||
265 | } | ||
266 | |||
267 | /* assure an unused place to direct virtual pointers to */ | 261 | /* assure an unused place to direct virtual pointers to */ |
268 | #define VIRT_SIZE 0xFFFF /* more than enough for our string ID range */ | 262 | #define VIRT_SIZE 0xFFFF /* more than enough for our string ID range */ |
269 | unsigned char vp_dummy[VIRT_SIZE]; | 263 | unsigned char vp_dummy[VIRT_SIZE]; |
diff --git a/uisimulator/sdl/thread-sdl.c b/uisimulator/sdl/thread-sdl.c index 041ca3153d..21697699a5 100644 --- a/uisimulator/sdl/thread-sdl.c +++ b/uisimulator/sdl/thread-sdl.c | |||
@@ -75,12 +75,6 @@ int create_thread(void (*fp)(void), void* sp, int stk_size) | |||
75 | return 0; | 75 | return 0; |
76 | } | 76 | } |
77 | 77 | ||
78 | int create_thread_on_core(void (*core)(void), void (*fp)(void), void* sp, int stk_size) | ||
79 | { | ||
80 | (void)core; | ||
81 | return create_thread(fp, sp, stk_size); | ||
82 | } | ||
83 | |||
84 | void init_threads(void) | 78 | void init_threads(void) |
85 | { | 79 | { |
86 | m = SDL_CreateMutex(); | 80 | m = SDL_CreateMutex(); |