diff options
author | Daniel Ankers <dan@weirdo.org.uk> | 2006-08-21 17:35:35 +0000 |
---|---|---|
committer | Daniel Ankers <dan@weirdo.org.uk> | 2006-08-21 17:35:35 +0000 |
commit | 0aec12f3fd801c5acc03a75818e06741957d51b9 (patch) | |
tree | d78b6d52c5962a00a5fefde97e977653a15c0428 | |
parent | e09dc8d51323bf0940b19ff8e12de7891fda2c52 (diff) | |
download | rockbox-0aec12f3fd801c5acc03a75818e06741957d51b9.tar.gz rockbox-0aec12f3fd801c5acc03a75818e06741957d51b9.zip |
Threading changes in preparation for multiple core support
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10681 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/debug_menu.c | 205 | ||||
-rw-r--r-- | firmware/export/config.h | 17 | ||||
-rw-r--r-- | firmware/export/system.h | 14 | ||||
-rw-r--r-- | firmware/export/thread.h | 4 | ||||
-rw-r--r-- | firmware/system.c | 102 | ||||
-rw-r--r-- | firmware/thread.c | 170 |
6 files changed, 307 insertions, 205 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c index c3a0d93dc6..69149767cc 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c | |||
@@ -78,8 +78,8 @@ | |||
78 | /*---------------------------------------------------*/ | 78 | /*---------------------------------------------------*/ |
79 | extern char ata_device; | 79 | extern char ata_device; |
80 | extern int ata_io_address; | 80 | extern int ata_io_address; |
81 | extern int num_threads; | 81 | extern int num_threads[]; |
82 | extern const char *thread_name[]; | 82 | extern const char *thread_name[][MAXTHREADS]; |
83 | 83 | ||
84 | #ifdef HAVE_LCD_BITMAP | 84 | #ifdef HAVE_LCD_BITMAP |
85 | /* Test code!!! */ | 85 | /* Test code!!! */ |
@@ -88,6 +88,8 @@ bool dbg_os(void) | |||
88 | char buf[32]; | 88 | char buf[32]; |
89 | int i; | 89 | int i; |
90 | int usage; | 90 | int usage; |
91 | unsigned int core; | ||
92 | int line; | ||
91 | 93 | ||
92 | lcd_setmargins(0, 0); | 94 | lcd_setmargins(0, 0); |
93 | lcd_setfont(FONT_SYSFIXED); | 95 | lcd_setfont(FONT_SYSFIXED); |
@@ -95,12 +97,16 @@ bool dbg_os(void) | |||
95 | 97 | ||
96 | while(1) | 98 | while(1) |
97 | { | 99 | { |
98 | lcd_puts(0, 0, "Stack usage:"); | 100 | lcd_puts(0, 0, "Core and stack usage:"); |
99 | for(i = 0; i < num_threads;i++) | 101 | line = 0; |
102 | for(core = 0; core < NUM_CORES; core++) | ||
100 | { | 103 | { |
101 | usage = thread_stack_usage(i); | 104 | for(i = 0; i < num_threads[core]; i++) |
102 | snprintf(buf, 32, "%s: %d%%", thread_name[i], usage); | 105 | { |
103 | lcd_puts(0, 1+i, buf); | 106 | usage = thread_stack_usage_on_core(core, i); |
107 | snprintf(buf, 32, "(%d) %s: %d%%", core, thread_name[core][i], usage); | ||
108 | lcd_puts(0, ++line, buf); | ||
109 | } | ||
104 | } | 110 | } |
105 | 111 | ||
106 | lcd_update(); | 112 | lcd_update(); |
@@ -124,10 +130,11 @@ bool dbg_os(void) | |||
124 | { | 130 | { |
125 | lcd_puts(0, 0, "Stack usage"); | 131 | lcd_puts(0, 0, "Stack usage"); |
126 | 132 | ||
133 | /* Only Archos Player uses this - so assume a single core */ | ||
127 | usage = thread_stack_usage(currval); | 134 | usage = thread_stack_usage(currval); |
128 | snprintf(buf, 32, "%d: %d%% ", currval, usage); | 135 | snprintf(buf, 32, "%d: %d%% ", currval, usage); |
129 | lcd_puts(0, 1, buf); | 136 | lcd_puts(0, 1, buf); |
130 | 137 | ||
131 | button = get_action(CONTEXT_SETTINGS,HZ/10); | 138 | button = get_action(CONTEXT_SETTINGS,HZ/10); |
132 | 139 | ||
133 | switch(button) | 140 | switch(button) |
@@ -162,14 +169,14 @@ bool dbg_audio_thread(void) | |||
162 | 169 | ||
163 | lcd_setmargins(0, 0); | 170 | lcd_setmargins(0, 0); |
164 | lcd_setfont(FONT_SYSFIXED); | 171 | lcd_setfont(FONT_SYSFIXED); |
165 | 172 | ||
166 | while(1) | 173 | while(1) |
167 | { | 174 | { |
168 | if (action_userabort(HZ/5)) | 175 | if (action_userabort(HZ/5)) |
169 | return false; | 176 | return false; |
170 | 177 | ||
171 | audio_get_debugdata(&d); | 178 | audio_get_debugdata(&d); |
172 | 179 | ||
173 | lcd_clear_display(); | 180 | lcd_clear_display(); |
174 | 181 | ||
175 | snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read); | 182 | snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read); |
@@ -186,17 +193,17 @@ bool dbg_audio_thread(void) | |||
186 | lcd_puts(0, 5, buf); | 193 | lcd_puts(0, 5, buf); |
187 | 194 | ||
188 | /* Playable space left */ | 195 | /* Playable space left */ |
189 | scrollbar(0, 6*8, 112, 4, d.audiobuflen, 0, | 196 | scrollbar(0, 6*8, 112, 4, d.audiobuflen, 0, |
190 | d.playable_space, HORIZONTAL); | 197 | d.playable_space, HORIZONTAL); |
191 | 198 | ||
192 | /* Show the watermark limit */ | 199 | /* Show the watermark limit */ |
193 | scrollbar(0, 6*8+4, 112, 4, d.audiobuflen, 0, | 200 | scrollbar(0, 6*8+4, 112, 4, d.audiobuflen, 0, |
194 | d.low_watermark_level, HORIZONTAL); | 201 | d.low_watermark_level, HORIZONTAL); |
195 | 202 | ||
196 | snprintf(buf, sizeof(buf), "wm: %x - %x", | 203 | snprintf(buf, sizeof(buf), "wm: %x - %x", |
197 | d.low_watermark_level, d.lowest_watermark_level); | 204 | d.low_watermark_level, d.lowest_watermark_level); |
198 | lcd_puts(0, 7, buf); | 205 | lcd_puts(0, 7, buf); |
199 | 206 | ||
200 | lcd_update(); | 207 | lcd_update(); |
201 | } | 208 | } |
202 | return false; | 209 | return false; |
@@ -229,7 +236,7 @@ bool dbg_audio_thread(void) | |||
229 | ticks = boost_ticks = 0; | 236 | ticks = boost_ticks = 0; |
230 | 237 | ||
231 | tick_add_task(dbg_audio_task); | 238 | tick_add_task(dbg_audio_task); |
232 | 239 | ||
233 | lcd_setmargins(0, 0); | 240 | lcd_setmargins(0, 0); |
234 | lcd_setfont(FONT_SYSFIXED); | 241 | lcd_setfont(FONT_SYSFIXED); |
235 | while(!done) | 242 | while(!done) |
@@ -249,7 +256,7 @@ bool dbg_audio_thread(void) | |||
249 | } | 256 | } |
250 | action_signalscreenchange(); | 257 | action_signalscreenchange(); |
251 | line = 0; | 258 | line = 0; |
252 | 259 | ||
253 | lcd_clear_display(); | 260 | lcd_clear_display(); |
254 | 261 | ||
255 | bufused = bufsize - pcmbuf_free(); | 262 | bufused = bufsize - pcmbuf_free(); |
@@ -283,12 +290,12 @@ bool dbg_audio_thread(void) | |||
283 | snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d", | 290 | snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d", |
284 | pcmbuf_used_descs(), pcmbufdescs); | 291 | pcmbuf_used_descs(), pcmbufdescs); |
285 | lcd_puts(0, line++, buf); | 292 | lcd_puts(0, line++, buf); |
286 | 293 | ||
287 | lcd_update(); | 294 | lcd_update(); |
288 | } | 295 | } |
289 | 296 | ||
290 | tick_remove_task(dbg_audio_task); | 297 | tick_remove_task(dbg_audio_task); |
291 | 298 | ||
292 | return false; | 299 | return false; |
293 | } | 300 | } |
294 | #endif /* CONFIG_CODEC */ | 301 | #endif /* CONFIG_CODEC */ |
@@ -303,7 +310,7 @@ static void flash_write_word(unsigned addr, unsigned value) { | |||
303 | flash_word_temp = value; | 310 | flash_word_temp = value; |
304 | 311 | ||
305 | long extAddr = (long)addr << 1; | 312 | long extAddr = (long)addr << 1; |
306 | ddma_transfer(1, 1, &flash_word_temp, extAddr, 2); | 313 | ddma_transfer(1, 1, &flash_word_temp, extAddr, 2); |
307 | } | 314 | } |
308 | 315 | ||
309 | static unsigned flash_read_word(unsigned addr) __attribute__ ((section(".icode"))); | 316 | static unsigned flash_read_word(unsigned addr) __attribute__ ((section(".icode"))); |
@@ -324,7 +331,7 @@ bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device, | |||
324 | __attribute__ ((section (".icode"))); | 331 | __attribute__ ((section (".icode"))); |
325 | bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device, | 332 | bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device, |
326 | unsigned addr1, unsigned addr2) | 333 | unsigned addr1, unsigned addr2) |
327 | 334 | ||
328 | { | 335 | { |
329 | #if (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020) | 336 | #if (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020) |
330 | /* TODO: Implement for iPod */ | 337 | /* TODO: Implement for iPod */ |
@@ -382,9 +389,9 @@ bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device, | |||
382 | /* sleep(HZ/50); no sleeping possible while interrupts are disabled */ | 389 | /* sleep(HZ/50); no sleeping possible while interrupts are disabled */ |
383 | 390 | ||
384 | set_irq_level(old_level); /* enable interrupts again */ | 391 | set_irq_level(old_level); /* enable interrupts again */ |
385 | 392 | ||
386 | /* I assume success if the obtained values are different from | 393 | /* I assume success if the obtained values are different from |
387 | the normal flash content. This is not perfectly bulletproof, they | 394 | the normal flash content. This is not perfectly bulletproof, they |
388 | could theoretically be the same by chance, causing us to fail. */ | 395 | could theoretically be the same by chance, causing us to fail. */ |
389 | if (not_manu != manu || not_id != id) /* a value has changed */ | 396 | if (not_manu != manu || not_id != id) /* a value has changed */ |
390 | { | 397 | { |
@@ -431,7 +438,7 @@ bool dbg_hw_info(void) | |||
431 | got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */ | 438 | got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */ |
432 | if (!got_id) | 439 | if (!got_id) |
433 | got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */ | 440 | got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */ |
434 | 441 | ||
435 | /* check if the boot ROM area is a flash mirror */ | 442 | /* check if the boot ROM area is a flash mirror */ |
436 | has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0); | 443 | has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0); |
437 | if (has_bootrom) /* if ROM and Flash different */ | 444 | if (has_bootrom) /* if ROM and Flash different */ |
@@ -450,16 +457,16 @@ bool dbg_hw_info(void) | |||
450 | 457 | ||
451 | snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100); | 458 | snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100); |
452 | lcd_puts(0, 1, buf); | 459 | lcd_puts(0, 1, buf); |
453 | 460 | ||
454 | snprintf(buf, 32, "Mask: 0x%04x", bitmask); | 461 | snprintf(buf, 32, "Mask: 0x%04x", bitmask); |
455 | lcd_puts(0, 2, buf); | 462 | lcd_puts(0, 2, buf); |
456 | 463 | ||
457 | snprintf(buf, 32, "USB: %s", usb_polarity?"positive":"negative"); | 464 | snprintf(buf, 32, "USB: %s", usb_polarity?"positive":"negative"); |
458 | lcd_puts(0, 3, buf); | 465 | lcd_puts(0, 3, buf); |
459 | 466 | ||
460 | snprintf(buf, 32, "PR: %s", pr_polarity?"positive":"negative"); | 467 | snprintf(buf, 32, "PR: %s", pr_polarity?"positive":"negative"); |
461 | lcd_puts(0, 4, buf); | 468 | lcd_puts(0, 4, buf); |
462 | 469 | ||
463 | if (got_id) | 470 | if (got_id) |
464 | snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id); | 471 | snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id); |
465 | else | 472 | else |
@@ -483,7 +490,7 @@ bool dbg_hw_info(void) | |||
483 | snprintf(buf, 32, "ATA: 0x%x,%s", ata_io_address, | 490 | snprintf(buf, 32, "ATA: 0x%x,%s", ata_io_address, |
484 | ata_device ? "slave":"master"); | 491 | ata_device ? "slave":"master"); |
485 | lcd_puts(0, 7, buf); | 492 | lcd_puts(0, 7, buf); |
486 | #endif | 493 | #endif |
487 | lcd_update(); | 494 | lcd_update(); |
488 | 495 | ||
489 | while(1) | 496 | while(1) |
@@ -503,7 +510,7 @@ bool dbg_hw_info(void) | |||
503 | got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */ | 510 | got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */ |
504 | if (!got_id) | 511 | if (!got_id) |
505 | got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */ | 512 | got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */ |
506 | 513 | ||
507 | system_memory_guard(oldmode); /* re-enable memory guard */ | 514 | system_memory_guard(oldmode); /* re-enable memory guard */ |
508 | 515 | ||
509 | lcd_setmargins(0, 0); | 516 | lcd_setmargins(0, 0); |
@@ -533,7 +540,7 @@ bool dbg_hw_info(void) | |||
533 | lcd_clear_display(); | 540 | lcd_clear_display(); |
534 | 541 | ||
535 | lcd_puts(0, 0, "[Hardware info]"); | 542 | lcd_puts(0, 0, "[Hardware info]"); |
536 | 543 | ||
537 | snprintf(buf, sizeof(buf), "HW rev: 0x%08x", ipod_hw_rev); | 544 | snprintf(buf, sizeof(buf), "HW rev: 0x%08x", ipod_hw_rev); |
538 | lcd_puts(0, 1, buf); | 545 | lcd_puts(0, 1, buf); |
539 | 546 | ||
@@ -581,7 +588,7 @@ bool dbg_hw_info(void) | |||
581 | /* calculate CRC16 checksum of boot ROM */ | 588 | /* calculate CRC16 checksum of boot ROM */ |
582 | rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff); | 589 | rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff); |
583 | } | 590 | } |
584 | 591 | ||
585 | system_memory_guard(oldmode); /* re-enable memory guard */ | 592 | system_memory_guard(oldmode); /* re-enable memory guard */ |
586 | 593 | ||
587 | lcd_clear_display(); | 594 | lcd_clear_display(); |
@@ -617,7 +624,7 @@ bool dbg_hw_info(void) | |||
617 | { | 624 | { |
618 | if (rom_crc == 0x56DBA4EE) /* known Version 1 */ | 625 | if (rom_crc == 0x56DBA4EE) /* known Version 1 */ |
619 | snprintf(buf, 32, "BootROM: V1"); | 626 | snprintf(buf, 32, "BootROM: V1"); |
620 | else if (rom_crc == 0x358099E8) | 627 | else if (rom_crc == 0x358099E8) |
621 | snprintf(buf, 32, "BootROM: V2"); | 628 | snprintf(buf, 32, "BootROM: V2"); |
622 | /* alternative boot ROM found in one single player so far */ | 629 | /* alternative boot ROM found in one single player so far */ |
623 | else | 630 | else |
@@ -626,10 +633,10 @@ bool dbg_hw_info(void) | |||
626 | else | 633 | else |
627 | snprintf(buf, 32, "BootROM: no"); | 634 | snprintf(buf, 32, "BootROM: no"); |
628 | } | 635 | } |
629 | 636 | ||
630 | lcd_puts(0, 1, buf); | 637 | lcd_puts(0, 1, buf); |
631 | lcd_update(); | 638 | lcd_update(); |
632 | 639 | ||
633 | button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK); | 640 | button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK); |
634 | 641 | ||
635 | switch(button) | 642 | switch(button) |
@@ -643,7 +650,7 @@ bool dbg_hw_info(void) | |||
643 | if(currval < 0) | 650 | if(currval < 0) |
644 | currval = 5; | 651 | currval = 5; |
645 | break; | 652 | break; |
646 | 653 | ||
647 | case ACTION_SETTINGS_INC: | 654 | case ACTION_SETTINGS_INC: |
648 | currval++; | 655 | currval++; |
649 | if(currval > 5) | 656 | if(currval > 5) |
@@ -677,7 +684,7 @@ bool dbg_partitions(void) | |||
677 | snprintf(buf, sizeof buf, "T:%x %ld MB", p->type, p->size / 2048); | 684 | snprintf(buf, sizeof buf, "T:%x %ld MB", p->type, p->size / 2048); |
678 | lcd_puts(0, 1, buf); | 685 | lcd_puts(0, 1, buf); |
679 | lcd_update(); | 686 | lcd_update(); |
680 | 687 | ||
681 | button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK); | 688 | button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK); |
682 | 689 | ||
683 | switch(button) | 690 | switch(button) |
@@ -691,7 +698,7 @@ bool dbg_partitions(void) | |||
691 | if (partition < 0) | 698 | if (partition < 0) |
692 | partition = 3; | 699 | partition = 3; |
693 | break; | 700 | break; |
694 | 701 | ||
695 | case ACTION_SETTINGS_INC: | 702 | case ACTION_SETTINGS_INC: |
696 | partition++; | 703 | partition++; |
697 | if (partition > 3) | 704 | if (partition > 3) |
@@ -751,22 +758,22 @@ bool dbg_spdif(void) | |||
751 | lcd_puts(0, line++, buf); | 758 | lcd_puts(0, line++, buf); |
752 | 759 | ||
753 | line++; | 760 | line++; |
754 | 761 | ||
755 | x = control >> 31; | 762 | x = control >> 31; |
756 | snprintf(buf, sizeof(buf), "PRO: %d (%s)", | 763 | snprintf(buf, sizeof(buf), "PRO: %d (%s)", |
757 | x, x?"Professional":"Consumer"); | 764 | x, x?"Professional":"Consumer"); |
758 | lcd_puts(0, line++, buf); | 765 | lcd_puts(0, line++, buf); |
759 | 766 | ||
760 | x = (control >> 30) & 1; | 767 | x = (control >> 30) & 1; |
761 | snprintf(buf, sizeof(buf), "Audio: %d (%s)", | 768 | snprintf(buf, sizeof(buf), "Audio: %d (%s)", |
762 | x, x?"Non-PCM":"PCM"); | 769 | x, x?"Non-PCM":"PCM"); |
763 | lcd_puts(0, line++, buf); | 770 | lcd_puts(0, line++, buf); |
764 | 771 | ||
765 | x = (control >> 29) & 1; | 772 | x = (control >> 29) & 1; |
766 | snprintf(buf, sizeof(buf), "Copy: %d (%s)", | 773 | snprintf(buf, sizeof(buf), "Copy: %d (%s)", |
767 | x, x?"Permitted":"Inhibited"); | 774 | x, x?"Permitted":"Inhibited"); |
768 | lcd_puts(0, line++, buf); | 775 | lcd_puts(0, line++, buf); |
769 | 776 | ||
770 | x = (control >> 27) & 7; | 777 | x = (control >> 27) & 7; |
771 | switch(x) | 778 | switch(x) |
772 | { | 779 | { |
@@ -786,7 +793,7 @@ bool dbg_spdif(void) | |||
786 | x = (control >> 24) & 3; | 793 | x = (control >> 24) & 3; |
787 | snprintf(buf, sizeof(buf), "Mode: %d", x); | 794 | snprintf(buf, sizeof(buf), "Mode: %d", x); |
788 | lcd_puts(0, line++, buf); | 795 | lcd_puts(0, line++, buf); |
789 | 796 | ||
790 | category = (control >> 17) & 127; | 797 | category = (control >> 17) & 127; |
791 | switch(category) | 798 | switch(category) |
792 | { | 799 | { |
@@ -801,7 +808,7 @@ bool dbg_spdif(void) | |||
801 | } | 808 | } |
802 | snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s); | 809 | snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s); |
803 | lcd_puts(0, line++, buf); | 810 | lcd_puts(0, line++, buf); |
804 | 811 | ||
805 | x = (control >> 16) & 1; | 812 | x = (control >> 16) & 1; |
806 | generation = x; | 813 | generation = x; |
807 | if(((category & 0x70) == 0x10) || | 814 | if(((category & 0x70) == 0x10) || |
@@ -813,11 +820,11 @@ bool dbg_spdif(void) | |||
813 | snprintf(buf, sizeof(buf), "Generation: %d (%s)", | 820 | snprintf(buf, sizeof(buf), "Generation: %d (%s)", |
814 | x, generation?"Original":"No ind."); | 821 | x, generation?"Original":"No ind."); |
815 | lcd_puts(0, line++, buf); | 822 | lcd_puts(0, line++, buf); |
816 | 823 | ||
817 | x = (control >> 12) & 15; | 824 | x = (control >> 12) & 15; |
818 | snprintf(buf, sizeof(buf), "Source: %d", x); | 825 | snprintf(buf, sizeof(buf), "Source: %d", x); |
819 | lcd_puts(0, line++, buf); | 826 | lcd_puts(0, line++, buf); |
820 | 827 | ||
821 | x = (control >> 8) & 15; | 828 | x = (control >> 8) & 15; |
822 | switch(x) | 829 | switch(x) |
823 | { | 830 | { |
@@ -836,7 +843,7 @@ bool dbg_spdif(void) | |||
836 | } | 843 | } |
837 | snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s); | 844 | snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s); |
838 | lcd_puts(0, line++, buf); | 845 | lcd_puts(0, line++, buf); |
839 | 846 | ||
840 | x = (control >> 4) & 15; | 847 | x = (control >> 4) & 15; |
841 | switch(x) | 848 | switch(x) |
842 | { | 849 | { |
@@ -857,7 +864,7 @@ bool dbg_spdif(void) | |||
857 | snprintf(buf, sizeof(buf), "Clock accuracy: %d", x); | 864 | snprintf(buf, sizeof(buf), "Clock accuracy: %d", x); |
858 | lcd_puts(0, line++, buf); | 865 | lcd_puts(0, line++, buf); |
859 | line++; | 866 | line++; |
860 | 867 | ||
861 | snprintf(buf, sizeof(buf), "Measured freq: %ldHz", | 868 | snprintf(buf, sizeof(buf), "Measured freq: %ldHz", |
862 | (long)((long long)FREQMEAS*CPU_FREQ/((1 << 15)*3*(1 << 13))/128)); | 869 | (long)((long long)FREQMEAS*CPU_FREQ/((1 << 15)*3*(1 << 13))/128)); |
863 | lcd_puts(0, line++, buf); | 870 | lcd_puts(0, line++, buf); |
@@ -914,7 +921,7 @@ bool dbg_ports(void) | |||
914 | battery_voltage = (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) / 10000; | 921 | battery_voltage = (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) / 10000; |
915 | batt_int = battery_voltage / 100; | 922 | batt_int = battery_voltage / 100; |
916 | batt_frac = battery_voltage % 100; | 923 | batt_frac = battery_voltage % 100; |
917 | 924 | ||
918 | snprintf(buf, 32, "Batt: %d.%02dV %d%% ", batt_int, batt_frac, | 925 | snprintf(buf, 32, "Batt: %d.%02dV %d%% ", batt_int, batt_frac, |
919 | battery_level()); | 926 | battery_level()); |
920 | lcd_puts(0, 6, buf); | 927 | lcd_puts(0, 6, buf); |
@@ -960,7 +967,7 @@ bool dbg_ports(void) | |||
960 | gpio1_function = GPIO1_FUNCTION; | 967 | gpio1_function = GPIO1_FUNCTION; |
961 | gpio_enable = GPIO_ENABLE; | 968 | gpio_enable = GPIO_ENABLE; |
962 | gpio1_enable = GPIO1_ENABLE; | 969 | gpio1_enable = GPIO1_ENABLE; |
963 | 970 | ||
964 | snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read); | 971 | snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read); |
965 | lcd_puts(0, line++, buf); | 972 | lcd_puts(0, line++, buf); |
966 | snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out); | 973 | snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out); |
@@ -985,7 +992,7 @@ bool dbg_ports(void) | |||
985 | #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) | 992 | #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) |
986 | adc_remotedetect = adc_read(ADC_REMOTEDETECT); | 993 | adc_remotedetect = adc_read(ADC_REMOTEDETECT); |
987 | #endif | 994 | #endif |
988 | 995 | ||
989 | snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons); | 996 | snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons); |
990 | lcd_puts(0, line++, buf); | 997 | lcd_puts(0, line++, buf); |
991 | snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote); | 998 | snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote); |
@@ -1000,16 +1007,16 @@ bool dbg_ports(void) | |||
1000 | battery_voltage = (adc_battery * BATTERY_SCALE_FACTOR) / 10000; | 1007 | battery_voltage = (adc_battery * BATTERY_SCALE_FACTOR) / 10000; |
1001 | batt_int = battery_voltage / 100; | 1008 | batt_int = battery_voltage / 100; |
1002 | batt_frac = battery_voltage % 100; | 1009 | batt_frac = battery_voltage % 100; |
1003 | 1010 | ||
1004 | snprintf(buf, 32, "Batt: %d.%02dV %d%% ", batt_int, batt_frac, | 1011 | snprintf(buf, 32, "Batt: %d.%02dV %d%% ", batt_int, batt_frac, |
1005 | battery_level()); | 1012 | battery_level()); |
1006 | lcd_puts(0, line++, buf); | 1013 | lcd_puts(0, line++, buf); |
1007 | 1014 | ||
1008 | #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) | 1015 | #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) |
1009 | snprintf(buf, sizeof(buf), "remotetype:: %d", remote_type()); | 1016 | snprintf(buf, sizeof(buf), "remotetype:: %d", remote_type()); |
1010 | lcd_puts(0, line++, buf); | 1017 | lcd_puts(0, line++, buf); |
1011 | #endif | 1018 | #endif |
1012 | 1019 | ||
1013 | lcd_update(); | 1020 | lcd_update(); |
1014 | if (action_userabort(HZ/10)) | 1021 | if (action_userabort(HZ/10)) |
1015 | return false; | 1022 | return false; |
@@ -1128,15 +1135,15 @@ bool dbg_ports(void) | |||
1128 | break; | 1135 | break; |
1129 | } | 1136 | } |
1130 | lcd_puts(0, 0, buf); | 1137 | lcd_puts(0, 0, buf); |
1131 | 1138 | ||
1132 | battery_voltage = (adc_read(ADC_UNREG_POWER) * | 1139 | battery_voltage = (adc_read(ADC_UNREG_POWER) * |
1133 | BATTERY_SCALE_FACTOR) / 10000; | 1140 | BATTERY_SCALE_FACTOR) / 10000; |
1134 | batt_int = battery_voltage / 100; | 1141 | batt_int = battery_voltage / 100; |
1135 | batt_frac = battery_voltage % 100; | 1142 | batt_frac = battery_voltage % 100; |
1136 | 1143 | ||
1137 | snprintf(buf, 32, "Batt: %d.%02dV", batt_int, batt_frac); | 1144 | snprintf(buf, 32, "Batt: %d.%02dV", batt_int, batt_frac); |
1138 | lcd_puts(0, 1, buf); | 1145 | lcd_puts(0, 1, buf); |
1139 | 1146 | ||
1140 | button = get_action(CONTEXT_SETTINGS,HZ/5); | 1147 | button = get_action(CONTEXT_SETTINGS,HZ/5); |
1141 | 1148 | ||
1142 | switch(button) | 1149 | switch(button) |
@@ -1179,7 +1186,7 @@ bool dbg_cpufreq(void) | |||
1179 | while(1) | 1186 | while(1) |
1180 | { | 1187 | { |
1181 | line = 0; | 1188 | line = 0; |
1182 | 1189 | ||
1183 | snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ); | 1190 | snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ); |
1184 | lcd_puts(0, line++, buf); | 1191 | lcd_puts(0, line++, buf); |
1185 | 1192 | ||
@@ -1212,7 +1219,7 @@ bool dbg_cpufreq(void) | |||
1212 | return false; | 1219 | return false; |
1213 | } | 1220 | } |
1214 | #endif /* HAVE_ADJUSTABLE_CPU_FREQ */ | 1221 | #endif /* HAVE_ADJUSTABLE_CPU_FREQ */ |
1215 | 1222 | ||
1216 | #ifdef HAVE_LCD_BITMAP | 1223 | #ifdef HAVE_LCD_BITMAP |
1217 | /* | 1224 | /* |
1218 | * view_battery() shows a automatically scaled graph of the battery voltage | 1225 | * view_battery() shows a automatically scaled graph of the battery voltage |
@@ -1229,7 +1236,7 @@ bool view_battery(void) | |||
1229 | int i, x, y; | 1236 | int i, x, y; |
1230 | unsigned short maxv, minv; | 1237 | unsigned short maxv, minv; |
1231 | char buf[32]; | 1238 | char buf[32]; |
1232 | 1239 | ||
1233 | lcd_setmargins(0, 0); | 1240 | lcd_setmargins(0, 0); |
1234 | lcd_setfont(FONT_SYSFIXED); | 1241 | lcd_setfont(FONT_SYSFIXED); |
1235 | 1242 | ||
@@ -1248,20 +1255,20 @@ bool view_battery(void) | |||
1248 | minv = power_history[i]; | 1255 | minv = power_history[i]; |
1249 | } | 1256 | } |
1250 | } | 1257 | } |
1251 | 1258 | ||
1252 | if ((minv < 1) || (minv >= 65535)) | 1259 | if ((minv < 1) || (minv >= 65535)) |
1253 | minv = 1; | 1260 | minv = 1; |
1254 | if (maxv < 2) | 1261 | if (maxv < 2) |
1255 | maxv = 2; | 1262 | maxv = 2; |
1256 | 1263 | ||
1257 | lcd_clear_display(); | 1264 | lcd_clear_display(); |
1258 | snprintf(buf, 30, "Battery %d.%02d", power_history[0] / 100, | 1265 | snprintf(buf, 30, "Battery %d.%02d", power_history[0] / 100, |
1259 | power_history[0] % 100); | 1266 | power_history[0] % 100); |
1260 | lcd_puts(0, 0, buf); | 1267 | lcd_puts(0, 0, buf); |
1261 | snprintf(buf, 30, "scale %d.%02d-%d.%02d V", | 1268 | snprintf(buf, 30, "scale %d.%02d-%d.%02d V", |
1262 | minv / 100, minv % 100, maxv / 100, maxv % 100); | 1269 | minv / 100, minv % 100, maxv / 100, maxv % 100); |
1263 | lcd_puts(0, 1, buf); | 1270 | lcd_puts(0, 1, buf); |
1264 | 1271 | ||
1265 | x = 0; | 1272 | x = 0; |
1266 | for (i = BAT_LAST_VAL - 1; i >= 0; i--) { | 1273 | for (i = BAT_LAST_VAL - 1; i >= 0; i--) { |
1267 | y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv); | 1274 | y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv); |
@@ -1274,7 +1281,7 @@ bool view_battery(void) | |||
1274 | } | 1281 | } |
1275 | 1282 | ||
1276 | break; | 1283 | break; |
1277 | 1284 | ||
1278 | case 1: /* status: */ | 1285 | case 1: /* status: */ |
1279 | lcd_clear_display(); | 1286 | lcd_clear_display(); |
1280 | lcd_puts(0, 0, "Power status:"); | 1287 | lcd_puts(0, 0, "Power status:"); |
@@ -1289,7 +1296,7 @@ bool view_battery(void) | |||
1289 | #endif | 1296 | #endif |
1290 | #ifdef CONFIG_CHARGING | 1297 | #ifdef CONFIG_CHARGING |
1291 | #if CONFIG_CHARGING == CHARGING_CONTROL | 1298 | #if CONFIG_CHARGING == CHARGING_CONTROL |
1292 | snprintf(buf, 30, "Chgr: %s %s", | 1299 | snprintf(buf, 30, "Chgr: %s %s", |
1293 | charger_inserted() ? "present" : "absent", | 1300 | charger_inserted() ? "present" : "absent", |
1294 | charger_enabled ? "on" : "off"); | 1301 | charger_enabled ? "on" : "off"); |
1295 | lcd_puts(0, 3, buf); | 1302 | lcd_puts(0, 3, buf); |
@@ -1329,15 +1336,15 @@ bool view_battery(void) | |||
1329 | #endif /* CONFIG_CHARGING != CHARGING_CONTROL */ | 1336 | #endif /* CONFIG_CHARGING != CHARGING_CONTROL */ |
1330 | #endif /* CONFIG_CHARGING */ | 1337 | #endif /* CONFIG_CHARGING */ |
1331 | break; | 1338 | break; |
1332 | 1339 | ||
1333 | case 2: /* voltage deltas: */ | 1340 | case 2: /* voltage deltas: */ |
1334 | lcd_clear_display(); | 1341 | lcd_clear_display(); |
1335 | lcd_puts(0, 0, "Voltage deltas:"); | 1342 | lcd_puts(0, 0, "Voltage deltas:"); |
1336 | 1343 | ||
1337 | for (i = 0; i <= 6; i++) { | 1344 | for (i = 0; i <= 6; i++) { |
1338 | y = power_history[i] - power_history[i+i]; | 1345 | y = power_history[i] - power_history[i+i]; |
1339 | snprintf(buf, 30, "-%d min: %s%d.%02d V", i, | 1346 | snprintf(buf, 30, "-%d min: %s%d.%02d V", i, |
1340 | (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 100, | 1347 | (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 100, |
1341 | ((y < 0) ? y * -1 : y ) % 100); | 1348 | ((y < 0) ? y * -1 : y ) % 100); |
1342 | lcd_puts(0, i+1, buf); | 1349 | lcd_puts(0, i+1, buf); |
1343 | } | 1350 | } |
@@ -1375,21 +1382,21 @@ bool view_battery(void) | |||
1375 | lcd_puts(0, 7, buf); | 1382 | lcd_puts(0, 7, buf); |
1376 | break; | 1383 | break; |
1377 | } | 1384 | } |
1378 | 1385 | ||
1379 | lcd_update(); | 1386 | lcd_update(); |
1380 | 1387 | ||
1381 | switch(get_action(CONTEXT_SETTINGS,HZ/2)) | 1388 | switch(get_action(CONTEXT_SETTINGS,HZ/2)) |
1382 | { | 1389 | { |
1383 | case ACTION_SETTINGS_DEC: | 1390 | case ACTION_SETTINGS_DEC: |
1384 | if (view) | 1391 | if (view) |
1385 | view--; | 1392 | view--; |
1386 | break; | 1393 | break; |
1387 | 1394 | ||
1388 | case ACTION_SETTINGS_INC: | 1395 | case ACTION_SETTINGS_INC: |
1389 | if (view < 3) | 1396 | if (view < 3) |
1390 | view++; | 1397 | view++; |
1391 | break; | 1398 | break; |
1392 | 1399 | ||
1393 | case ACTION_STD_CANCEL: | 1400 | case ACTION_STD_CANCEL: |
1394 | action_signalscreenchange(); | 1401 | action_signalscreenchange(); |
1395 | return false; | 1402 | return false; |
@@ -1399,7 +1406,7 @@ bool view_battery(void) | |||
1399 | } | 1406 | } |
1400 | 1407 | ||
1401 | #endif /* HAVE_LCD_BITMAP */ | 1408 | #endif /* HAVE_LCD_BITMAP */ |
1402 | 1409 | ||
1403 | static bool view_runtime(void) | 1410 | static bool view_runtime(void) |
1404 | { | 1411 | { |
1405 | char s[32]; | 1412 | char s[32]; |
@@ -1441,7 +1448,7 @@ static bool view_runtime(void) | |||
1441 | t = global_settings.topruntime; | 1448 | t = global_settings.topruntime; |
1442 | lcd_puts(0, y++, "Top time"); | 1449 | lcd_puts(0, y++, "Top time"); |
1443 | } | 1450 | } |
1444 | 1451 | ||
1445 | snprintf(s, sizeof(s), "%dh %dm %ds", | 1452 | snprintf(s, sizeof(s), "%dh %dm %ds", |
1446 | t / 3600, (t % 3600) / 60, t % 60); | 1453 | t / 3600, (t % 3600) / 60, t % 60); |
1447 | lcd_puts(0, y++, s); | 1454 | lcd_puts(0, y++, s); |
@@ -1498,7 +1505,7 @@ bool dbg_mmc_info(void) | |||
1498 | static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 }; | 1505 | static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 }; |
1499 | static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" }; | 1506 | static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" }; |
1500 | static const unsigned char *nsec_units[] = { "ns", "µs", "ms" }; | 1507 | static const unsigned char *nsec_units[] = { "ns", "µs", "ms" }; |
1501 | 1508 | ||
1502 | card_name[6] = '\0'; | 1509 | card_name[6] = '\0'; |
1503 | 1510 | ||
1504 | lcd_setmargins(0, 0); | 1511 | lcd_setmargins(0, 0); |
@@ -1574,7 +1581,7 @@ bool dbg_mmc_info(void) | |||
1574 | case ACTION_STD_CANCEL: | 1581 | case ACTION_STD_CANCEL: |
1575 | done = true; | 1582 | done = true; |
1576 | break; | 1583 | break; |
1577 | 1584 | ||
1578 | case ACTION_SETTINGS_DEC: | 1585 | case ACTION_SETTINGS_DEC: |
1579 | currval--; | 1586 | currval--; |
1580 | if (currval < 0) | 1587 | if (currval < 0) |
@@ -1606,7 +1613,7 @@ static bool dbg_disk_info(void) | |||
1606 | #ifdef HAVE_LCD_BITMAP | 1613 | #ifdef HAVE_LCD_BITMAP |
1607 | lcd_setmargins(0, 0); | 1614 | lcd_setmargins(0, 0); |
1608 | #endif | 1615 | #endif |
1609 | 1616 | ||
1610 | while(!done) | 1617 | while(!done) |
1611 | { | 1618 | { |
1612 | int y=0; | 1619 | int y=0; |
@@ -1639,7 +1646,7 @@ static bool dbg_disk_info(void) | |||
1639 | 1646 | ||
1640 | case 2: | 1647 | case 2: |
1641 | snprintf(buf, sizeof buf, "%ld MB", | 1648 | snprintf(buf, sizeof buf, "%ld MB", |
1642 | ((unsigned long)identify_info[61] << 16 | | 1649 | ((unsigned long)identify_info[61] << 16 | |
1643 | (unsigned long)identify_info[60]) / 2048 ); | 1650 | (unsigned long)identify_info[60]) / 2048 ); |
1644 | lcd_puts(0, y++, "Size"); | 1651 | lcd_puts(0, y++, "Size"); |
1645 | lcd_puts(0, y++, buf); | 1652 | lcd_puts(0, y++, buf); |
@@ -1739,7 +1746,7 @@ static bool dbg_disk_info(void) | |||
1739 | if (--page < 0) | 1746 | if (--page < 0) |
1740 | page = max_page; | 1747 | page = max_page; |
1741 | break; | 1748 | break; |
1742 | 1749 | ||
1743 | case ACTION_SETTINGS_INC: | 1750 | case ACTION_SETTINGS_INC: |
1744 | if (++page > max_page) | 1751 | if (++page > max_page) |
1745 | page = 0; | 1752 | page = 0; |
@@ -1765,9 +1772,9 @@ static bool dbg_dircache_info(void) | |||
1765 | while (!done) | 1772 | while (!done) |
1766 | { | 1773 | { |
1767 | line = 0; | 1774 | line = 0; |
1768 | 1775 | ||
1769 | lcd_clear_display(); | 1776 | lcd_clear_display(); |
1770 | snprintf(buf, sizeof(buf), "Cache initialized: %s", | 1777 | snprintf(buf, sizeof(buf), "Cache initialized: %s", |
1771 | dircache_is_enabled() ? "Yes" : "No"); | 1778 | dircache_is_enabled() ? "Yes" : "No"); |
1772 | lcd_puts(0, line++, buf); | 1779 | lcd_puts(0, line++, buf); |
1773 | 1780 | ||
@@ -1819,25 +1826,25 @@ static bool dbg_tagcache_info(void) | |||
1819 | while (!done) | 1826 | while (!done) |
1820 | { | 1827 | { |
1821 | line = 0; | 1828 | line = 0; |
1822 | 1829 | ||
1823 | lcd_clear_display(); | 1830 | lcd_clear_display(); |
1824 | stat = tagcache_get_stat(); | 1831 | stat = tagcache_get_stat(); |
1825 | snprintf(buf, sizeof(buf), "Initialized: %s", stat->initialized ? "Yes" : "No"); | 1832 | snprintf(buf, sizeof(buf), "Initialized: %s", stat->initialized ? "Yes" : "No"); |
1826 | lcd_puts(0, line++, buf); | 1833 | lcd_puts(0, line++, buf); |
1827 | snprintf(buf, sizeof(buf), "DB Ready: %s", stat->ready ? "Yes" : "No"); | 1834 | snprintf(buf, sizeof(buf), "DB Ready: %s", stat->ready ? "Yes" : "No"); |
1828 | lcd_puts(0, line++, buf); | 1835 | lcd_puts(0, line++, buf); |
1829 | snprintf(buf, sizeof(buf), "RAM Cache: %s", stat->ramcache ? "Yes" : "No"); | 1836 | snprintf(buf, sizeof(buf), "RAM Cache: %s", stat->ramcache ? "Yes" : "No"); |
1830 | lcd_puts(0, line++, buf); | 1837 | lcd_puts(0, line++, buf); |
1831 | snprintf(buf, sizeof(buf), "RAM: %d/%d B", | 1838 | snprintf(buf, sizeof(buf), "RAM: %d/%d B", |
1832 | stat->ramcache_used, stat->ramcache_allocated); | 1839 | stat->ramcache_used, stat->ramcache_allocated); |
1833 | lcd_puts(0, line++, buf); | 1840 | lcd_puts(0, line++, buf); |
1834 | snprintf(buf, sizeof(buf), "Progress: %d%% (%d entries)", | 1841 | snprintf(buf, sizeof(buf), "Progress: %d%% (%d entries)", |
1835 | stat->progress, stat->processed_entries); | 1842 | stat->progress, stat->processed_entries); |
1836 | lcd_puts(0, line++, buf); | 1843 | lcd_puts(0, line++, buf); |
1837 | snprintf(buf, sizeof(buf), "Commit step: %d", stat->commit_step); | 1844 | snprintf(buf, sizeof(buf), "Commit step: %d", stat->commit_step); |
1838 | lcd_puts(0, line++, buf); | 1845 | lcd_puts(0, line++, buf); |
1839 | snprintf(buf, sizeof(buf), "Commit delayed: %s", | 1846 | snprintf(buf, sizeof(buf), "Commit delayed: %s", |
1840 | stat->commit_delayed ? "Yes" : "No"); | 1847 | stat->commit_delayed ? "Yes" : "No"); |
1841 | lcd_puts(0, line++, buf); | 1848 | lcd_puts(0, line++, buf); |
1842 | 1849 | ||
1843 | lcd_update(); | 1850 | lcd_update(); |
@@ -1892,7 +1899,7 @@ bool dbg_save_roms(void) | |||
1892 | close(fd); | 1899 | close(fd); |
1893 | } | 1900 | } |
1894 | system_memory_guard(oldmode); | 1901 | system_memory_guard(oldmode); |
1895 | 1902 | ||
1896 | #ifdef HAVE_EEPROM | 1903 | #ifdef HAVE_EEPROM |
1897 | fd = creat("/internal_eeprom.bin", O_WRONLY); | 1904 | fd = creat("/internal_eeprom.bin", O_WRONLY); |
1898 | if (fd >= 0) | 1905 | if (fd >= 0) |
@@ -1916,7 +1923,7 @@ bool dbg_save_roms(void) | |||
1916 | close(fd); | 1923 | close(fd); |
1917 | } | 1924 | } |
1918 | #endif | 1925 | #endif |
1919 | 1926 | ||
1920 | return false; | 1927 | return false; |
1921 | } | 1928 | } |
1922 | #endif /* CPU */ | 1929 | #endif /* CPU */ |
@@ -1938,10 +1945,10 @@ bool dbg_fm_radio(void) | |||
1938 | 1945 | ||
1939 | lcd_clear_display(); | 1946 | lcd_clear_display(); |
1940 | fm_detected = radio_hardware_present(); | 1947 | fm_detected = radio_hardware_present(); |
1941 | 1948 | ||
1942 | snprintf(buf, sizeof buf, "HW detected: %s", fm_detected?"yes":"no"); | 1949 | snprintf(buf, sizeof buf, "HW detected: %s", fm_detected?"yes":"no"); |
1943 | lcd_puts(0, row++, buf); | 1950 | lcd_puts(0, row++, buf); |
1944 | 1951 | ||
1945 | #if (CONFIG_TUNER & S1A0903X01) | 1952 | #if (CONFIG_TUNER & S1A0903X01) |
1946 | regs = samsung_get(RADIO_ALL); | 1953 | regs = samsung_get(RADIO_ALL); |
1947 | snprintf(buf, sizeof buf, "Samsung regs: %08lx", regs); | 1954 | snprintf(buf, sizeof buf, "Samsung regs: %08lx", regs); |
@@ -1954,7 +1961,7 @@ bool dbg_fm_radio(void) | |||
1954 | #endif | 1961 | #endif |
1955 | 1962 | ||
1956 | lcd_update(); | 1963 | lcd_update(); |
1957 | 1964 | ||
1958 | if (action_userabort(HZ)) | 1965 | if (action_userabort(HZ)) |
1959 | return false; | 1966 | return false; |
1960 | } | 1967 | } |
@@ -1983,7 +1990,7 @@ bool dbg_set_memory_guard(void) | |||
1983 | { "Zero area (all)", -1 } | 1990 | { "Zero area (all)", -1 } |
1984 | }; | 1991 | }; |
1985 | int mode = system_memory_guard(MEMGUARD_KEEP); | 1992 | int mode = system_memory_guard(MEMGUARD_KEEP); |
1986 | 1993 | ||
1987 | set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL); | 1994 | set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL); |
1988 | system_memory_guard(mode); | 1995 | system_memory_guard(mode); |
1989 | 1996 | ||
@@ -1999,7 +2006,7 @@ bool dbg_write_eeprom(void) | |||
1999 | int old_irq_level; | 2006 | int old_irq_level; |
2000 | char buf[EEPROM_SIZE]; | 2007 | char buf[EEPROM_SIZE]; |
2001 | int err; | 2008 | int err; |
2002 | 2009 | ||
2003 | fd = open("/internal_eeprom.bin", O_RDONLY); | 2010 | fd = open("/internal_eeprom.bin", O_RDONLY); |
2004 | 2011 | ||
2005 | if (fd >= 0) | 2012 | if (fd >= 0) |
@@ -2093,7 +2100,7 @@ bool debug_menu(void) | |||
2093 | NULL, NULL, NULL); | 2100 | NULL, NULL, NULL); |
2094 | result = menu_run(m); | 2101 | result = menu_run(m); |
2095 | menu_exit(m); | 2102 | menu_exit(m); |
2096 | 2103 | ||
2097 | return result; | 2104 | return result; |
2098 | } | 2105 | } |
2099 | 2106 | ||
diff --git a/firmware/export/config.h b/firmware/export/config.h index 8f1a5e65cc..cd674b63f8 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h | |||
@@ -151,6 +151,10 @@ | |||
151 | #define USBOTG_ISP1362 1362 | 151 | #define USBOTG_ISP1362 1362 |
152 | #define USBOTG_M5636 5636 | 152 | #define USBOTG_M5636 5636 |
153 | 153 | ||
154 | /* Multiple cores */ | ||
155 | #define CPU 0 | ||
156 | #define COP 1 | ||
157 | |||
154 | /* now go and pick yours */ | 158 | /* now go and pick yours */ |
155 | #if defined(ARCHOS_PLAYER) | 159 | #if defined(ARCHOS_PLAYER) |
156 | #include "config-player.h" | 160 | #include "config-player.h" |
@@ -219,6 +223,19 @@ | |||
219 | /* define for all cpus from PP family */ | 223 | /* define for all cpus from PP family */ |
220 | #if (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020) || (CONFIG_CPU == PP5024) | 224 | #if (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020) || (CONFIG_CPU == PP5024) |
221 | #define CPU_PP | 225 | #define CPU_PP |
226 | |||
227 | /* PP family has dual cores */ | ||
228 | #if 0 | ||
229 | /* Keep it as single core until dual core support is ready */ | ||
230 | #define NUM_CORES 2 | ||
231 | #define CURRENT_CORE current_core() | ||
232 | #endif | ||
233 | |||
234 | #define NUM_CORES 1 | ||
235 | #define CURRENT_CORE 0 | ||
236 | #else | ||
237 | #define NUM_CORES 1 | ||
238 | #define CURRENT_CORE 0 | ||
222 | #endif | 239 | #endif |
223 | 240 | ||
224 | /* define for all cpus from ARM family */ | 241 | /* define for all cpus from ARM family */ |
diff --git a/firmware/export/system.h b/firmware/export/system.h index 1b326e1b8b..d13b27c529 100644 --- a/firmware/export/system.h +++ b/firmware/export/system.h | |||
@@ -43,6 +43,8 @@ static inline void udelay(unsigned usecs) | |||
43 | unsigned start = USEC_TIMER; | 43 | unsigned start = USEC_TIMER; |
44 | while ((USEC_TIMER - start) < usecs); | 44 | while ((USEC_TIMER - start) < usecs); |
45 | } | 45 | } |
46 | |||
47 | unsigned int current_core(void); | ||
46 | #endif | 48 | #endif |
47 | 49 | ||
48 | struct flash_header { | 50 | struct flash_header { |
@@ -88,7 +90,7 @@ void cpu_idle_mode(bool on_off); | |||
88 | #define betoh32(x) swap32(x) | 90 | #define betoh32(x) swap32(x) |
89 | #define htobe16(x) swap16(x) | 91 | #define htobe16(x) swap16(x) |
90 | #define htobe32(x) swap32(x) | 92 | #define htobe32(x) swap32(x) |
91 | #else | 93 | #else |
92 | #define letoh16(x) swap16(x) | 94 | #define letoh16(x) swap16(x) |
93 | #define letoh32(x) swap32(x) | 95 | #define letoh32(x) swap32(x) |
94 | #define htole16(x) swap16(x) | 96 | #define htole16(x) swap16(x) |
@@ -178,7 +180,7 @@ static inline void coldfire_set_macsr(unsigned long flags) | |||
178 | static inline unsigned long coldfire_get_macsr(void) | 180 | static inline unsigned long coldfire_get_macsr(void) |
179 | { | 181 | { |
180 | unsigned long m; | 182 | unsigned long m; |
181 | 183 | ||
182 | asm volatile ("move.l %%macsr, %0" : "=r" (m)); | 184 | asm volatile ("move.l %%macsr, %0" : "=r" (m)); |
183 | return m; | 185 | return m; |
184 | } | 186 | } |
@@ -301,7 +303,7 @@ static inline void invalidate_icache(void) | |||
301 | "move.l #0x80000000,%d0\n" | 303 | "move.l #0x80000000,%d0\n" |
302 | "movec.l %d0,%cacr"); | 304 | "movec.l %d0,%cacr"); |
303 | } | 305 | } |
304 | 306 | ||
305 | #define CPUFREQ_DEFAULT_MULT 1 | 307 | #define CPUFREQ_DEFAULT_MULT 1 |
306 | #define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ) | 308 | #define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ) |
307 | #define CPUFREQ_NORMAL_MULT 4 | 309 | #define CPUFREQ_NORMAL_MULT 4 |
@@ -315,7 +317,7 @@ static inline void invalidate_icache(void) | |||
315 | 317 | ||
316 | #define CPUFREQ_DEFAULT_MULT 8 | 318 | #define CPUFREQ_DEFAULT_MULT 8 |
317 | #define CPUFREQ_DEFAULT 24000000 | 319 | #define CPUFREQ_DEFAULT 24000000 |
318 | #define CPUFREQ_NORMAL_MULT 10 | 320 | #define CPUFREQ_NORMAL_MULT 10 |
319 | #define CPUFREQ_NORMAL 30000000 | 321 | #define CPUFREQ_NORMAL 30000000 |
320 | #define CPUFREQ_MAX_MULT 25 | 322 | #define CPUFREQ_MAX_MULT 25 |
321 | #define CPUFREQ_MAX 75000000 | 323 | #define CPUFREQ_MAX 75000000 |
@@ -336,7 +338,7 @@ static inline unsigned long swap32(unsigned long value) | |||
336 | result[15.. 8] = value[23..16]; | 338 | result[15.. 8] = value[23..16]; |
337 | result[ 7.. 0] = value[31..24]; | 339 | result[ 7.. 0] = value[31..24]; |
338 | */ | 340 | */ |
339 | { | 341 | { |
340 | unsigned int tmp; | 342 | unsigned int tmp; |
341 | 343 | ||
342 | asm volatile ( | 344 | asm volatile ( |
@@ -418,7 +420,7 @@ static inline int set_irq_level(int level) | |||
418 | __asm__ volatile ("clrsr ie"); | 420 | __asm__ volatile ("clrsr ie"); |
419 | else | 421 | else |
420 | __asm__ volatile ("setsr ie"); | 422 | __asm__ volatile ("setsr ie"); |
421 | 423 | ||
422 | return result; | 424 | return result; |
423 | } | 425 | } |
424 | 426 | ||
diff --git a/firmware/export/thread.h b/firmware/export/thread.h index 762e315a4c..a5034aedab 100644 --- a/firmware/export/thread.h +++ b/firmware/export/thread.h | |||
@@ -31,12 +31,16 @@ | |||
31 | 31 | ||
32 | int create_thread(void (*function)(void), void* stack, int stack_size, | 32 | int create_thread(void (*function)(void), void* stack, int stack_size, |
33 | const char *name); | 33 | const char *name); |
34 | int create_thread_on_core(unsigned int core, void (*function)(void), void* stack, int stack_size, | ||
35 | const char *name); | ||
34 | void remove_thread(int threadnum); | 36 | void remove_thread(int threadnum); |
37 | void remove_thread_on_core(unsigned int core, int threadnum); | ||
35 | void switch_thread(void); | 38 | void switch_thread(void); |
36 | void sleep_thread(void); | 39 | void sleep_thread(void); |
37 | void wake_up_thread(void); | 40 | void wake_up_thread(void); |
38 | void init_threads(void); | 41 | void init_threads(void); |
39 | int thread_stack_usage(int threadnum); | 42 | int thread_stack_usage(int threadnum); |
43 | int thread_stack_usage_on_core(unsigned int core, int threadnum); | ||
40 | #ifdef RB_PROFILE | 44 | #ifdef RB_PROFILE |
41 | void profile_thread(void); | 45 | void profile_thread(void); |
42 | #endif | 46 | #endif |
diff --git a/firmware/system.c b/firmware/system.c index c97b5233ec..6aee823205 100644 --- a/firmware/system.c +++ b/firmware/system.c | |||
@@ -91,21 +91,21 @@ bool detect_flashed_rockbox(void) | |||
91 | { | 91 | { |
92 | struct flash_header hdr; | 92 | struct flash_header hdr; |
93 | uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT; | 93 | uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT; |
94 | 94 | ||
95 | # ifndef BOOTLOADER | 95 | # ifndef BOOTLOADER |
96 | int oldmode; | 96 | int oldmode; |
97 | oldmode = system_memory_guard(MEMGUARD_NONE); | 97 | oldmode = system_memory_guard(MEMGUARD_NONE); |
98 | # endif | 98 | # endif |
99 | 99 | ||
100 | memcpy(&hdr, src, sizeof(struct flash_header)); | 100 | memcpy(&hdr, src, sizeof(struct flash_header)); |
101 | 101 | ||
102 | # ifndef BOOTLOADER | 102 | # ifndef BOOTLOADER |
103 | system_memory_guard(oldmode); | 103 | system_memory_guard(oldmode); |
104 | # endif | 104 | # endif |
105 | 105 | ||
106 | if (hdr.magic != FLASH_MAGIC) | 106 | if (hdr.magic != FLASH_MAGIC) |
107 | return false; | 107 | return false; |
108 | 108 | ||
109 | return true; | 109 | return true; |
110 | } | 110 | } |
111 | #else | 111 | #else |
@@ -139,13 +139,13 @@ void ddma_transfer(int dir, int mem, void* intAddr, long extAddr, int num) { | |||
139 | /* HW wants those two in word units. */ | 139 | /* HW wants those two in word units. */ |
140 | num /= 2; | 140 | num /= 2; |
141 | externalAddress /= 2; | 141 | externalAddress /= 2; |
142 | 142 | ||
143 | DDMACFG = (dir << 1) | (mem << 2); | 143 | DDMACFG = (dir << 1) | (mem << 2); |
144 | DDMAIADR = internalAddress; | 144 | DDMAIADR = internalAddress; |
145 | DDMAEADR = externalAddress; | 145 | DDMAEADR = externalAddress; |
146 | DDMANUM = num; | 146 | DDMANUM = num; |
147 | DDMACOM |= 0x4; /* start */ | 147 | DDMACOM |= 0x4; /* start */ |
148 | 148 | ||
149 | ddma_wait_idle(); /* wait for completion */ | 149 | ddma_wait_idle(); /* wait for completion */ |
150 | set_irq_level(irq); | 150 | set_irq_level(irq); |
151 | } | 151 | } |
@@ -164,13 +164,13 @@ static void ddma_transfer_noicode(int dir, int mem, long intAddr, long extAddr, | |||
164 | /* HW wants those two in word units. */ | 164 | /* HW wants those two in word units. */ |
165 | num /= 2; | 165 | num /= 2; |
166 | externalAddress /= 2; | 166 | externalAddress /= 2; |
167 | 167 | ||
168 | DDMACFG = (dir << 1) | (mem << 2); | 168 | DDMACFG = (dir << 1) | (mem << 2); |
169 | DDMAIADR = internalAddress; | 169 | DDMAIADR = internalAddress; |
170 | DDMAEADR = externalAddress; | 170 | DDMAEADR = externalAddress; |
171 | DDMANUM = num; | 171 | DDMANUM = num; |
172 | DDMACOM |= 0x4; /* start */ | 172 | DDMACOM |= 0x4; /* start */ |
173 | 173 | ||
174 | ddma_wait_idle_noicode(); /* wait for completion */ | 174 | ddma_wait_idle_noicode(); /* wait for completion */ |
175 | set_irq_level(irq); | 175 | set_irq_level(irq); |
176 | } | 176 | } |
@@ -220,7 +220,7 @@ void smsc_delay() { | |||
220 | Delay doesn't depend on CPU speed in Archos' firmware. | 220 | Delay doesn't depend on CPU speed in Archos' firmware. |
221 | */ | 221 | */ |
222 | for (i = 0; i < 100; i++) { | 222 | for (i = 0; i < 100; i++) { |
223 | 223 | ||
224 | } | 224 | } |
225 | } | 225 | } |
226 | 226 | ||
@@ -228,9 +228,9 @@ static void extra_init(void) { | |||
228 | /* Power on stuff */ | 228 | /* Power on stuff */ |
229 | P1 |= 0x07; | 229 | P1 |= 0x07; |
230 | P1CON |= 0x1f; | 230 | P1CON |= 0x1f; |
231 | 231 | ||
232 | /* P5 conf | 232 | /* P5 conf |
233 | * lines 0, 1 & 4 are digital, other analog. : | 233 | * lines 0, 1 & 4 are digital, other analog. : |
234 | */ | 234 | */ |
235 | P5CON = 0xec; | 235 | P5CON = 0xec; |
236 | 236 | ||
@@ -294,21 +294,21 @@ void system_init(void) | |||
294 | /******** | 294 | /******** |
295 | * CPU | 295 | * CPU |
296 | */ | 296 | */ |
297 | 297 | ||
298 | 298 | ||
299 | /* PLL0 (cpu osc. frequency) */ | 299 | /* PLL0 (cpu osc. frequency) */ |
300 | /* set_cpu_frequency(CPU_FREQ); */ | 300 | /* set_cpu_frequency(CPU_FREQ); */ |
301 | 301 | ||
302 | 302 | ||
303 | /******************* | 303 | /******************* |
304 | * configure S(D)RAM | 304 | * configure S(D)RAM |
305 | */ | 305 | */ |
306 | 306 | ||
307 | /************************ | 307 | /************************ |
308 | * Copy .icode section to icram | 308 | * Copy .icode section to icram |
309 | */ | 309 | */ |
310 | ddma_transfer_noicode(0, 0, 0x40, (long)&icodecopy, (int)&icodesize); | 310 | ddma_transfer_noicode(0, 0, 0x40, (long)&icodecopy, (int)&icodesize); |
311 | 311 | ||
312 | 312 | ||
313 | /*************************** | 313 | /*************************** |
314 | * Interrupts | 314 | * Interrupts |
@@ -472,12 +472,12 @@ void UIE (void) /* Unexpected Interrupt or Exception */ | |||
472 | unsigned int format_vector, pc; | 472 | unsigned int format_vector, pc; |
473 | int vector; | 473 | int vector; |
474 | char str[32]; | 474 | char str[32]; |
475 | 475 | ||
476 | asm volatile ("move.l (52,%%sp),%0": "=r"(format_vector)); | 476 | asm volatile ("move.l (52,%%sp),%0": "=r"(format_vector)); |
477 | asm volatile ("move.l (56,%%sp),%0": "=r"(pc)); | 477 | asm volatile ("move.l (56,%%sp),%0": "=r"(pc)); |
478 | 478 | ||
479 | vector = (format_vector >> 18) & 0xff; | 479 | vector = (format_vector >> 18) & 0xff; |
480 | 480 | ||
481 | /* clear screen */ | 481 | /* clear screen */ |
482 | lcd_clear_display (); | 482 | lcd_clear_display (); |
483 | #ifdef HAVE_LCD_BITMAP | 483 | #ifdef HAVE_LCD_BITMAP |
@@ -488,7 +488,7 @@ void UIE (void) /* Unexpected Interrupt or Exception */ | |||
488 | snprintf(str,sizeof(str),"at %08x",pc); | 488 | snprintf(str,sizeof(str),"at %08x",pc); |
489 | lcd_puts(0,1,str); | 489 | lcd_puts(0,1,str); |
490 | lcd_update(); | 490 | lcd_update(); |
491 | 491 | ||
492 | /* set cpu frequency to 11mhz (to prevent overheating) */ | 492 | /* set cpu frequency to 11mhz (to prevent overheating) */ |
493 | DCR = (DCR & ~0x01ff) | 1; | 493 | DCR = (DCR & ~0x01ff) | 1; |
494 | PLLCR = 0x10800000; | 494 | PLLCR = 0x10800000; |
@@ -510,7 +510,7 @@ void UIE (void) /* Unexpected Interrupt or Exception */ | |||
510 | } | 510 | } |
511 | 511 | ||
512 | /* reset vectors are handled in crt0.S */ | 512 | /* reset vectors are handled in crt0.S */ |
513 | void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) = | 513 | void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) = |
514 | { | 514 | { |
515 | UIE,UIE,UIE,UIE,UIE,UIE, | 515 | UIE,UIE,UIE,UIE,UIE,UIE, |
516 | UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, | 516 | UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, |
@@ -520,7 +520,7 @@ void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) = | |||
520 | 520 | ||
521 | TRAP0,TRAP1,TRAP2,TRAP3,TRAP4,TRAP5,TRAP6,TRAP7, | 521 | TRAP0,TRAP1,TRAP2,TRAP3,TRAP4,TRAP5,TRAP6,TRAP7, |
522 | TRAP8,TRAP9,TRAP10,TRAP11,TRAP12,TRAP13,TRAP14,TRAP15, | 522 | TRAP8,TRAP9,TRAP10,TRAP11,TRAP12,TRAP13,TRAP14,TRAP15, |
523 | 523 | ||
524 | SWT,UIE,UIE,I2C,UART1,UART2,DMA0,DMA1, | 524 | SWT,UIE,UIE,I2C,UART1,UART2,DMA0,DMA1, |
525 | DMA2,DMA3,QSPI,UIE,UIE,UIE,UIE,UIE, | 525 | DMA2,DMA3,QSPI,UIE,UIE,UIE,UIE,UIE, |
526 | PDIR1FULL,PDIR2FULL,EBUTXEMPTY,IIS2TXEMPTY, | 526 | PDIR1FULL,PDIR2FULL,EBUTXEMPTY,IIS2TXEMPTY, |
@@ -741,7 +741,7 @@ static const char* const irqname[] = { | |||
741 | 741 | ||
742 | asm ( | 742 | asm ( |
743 | 743 | ||
744 | /* Vector table. | 744 | /* Vector table. |
745 | * Handled in asm because gcc 4.x doesn't allow weak aliases to symbols | 745 | * Handled in asm because gcc 4.x doesn't allow weak aliases to symbols |
746 | * defined in an asm block -- silly. | 746 | * defined in an asm block -- silly. |
747 | * Reset vectors (0..3) are handled in crt0.S */ | 747 | * Reset vectors (0..3) are handled in crt0.S */ |
@@ -854,7 +854,7 @@ asm ( | |||
854 | RESERVE_INTERRUPT ( 108) | 854 | RESERVE_INTERRUPT ( 108) |
855 | DEFAULT_INTERRUPT (ADITI, 109) | 855 | DEFAULT_INTERRUPT (ADITI, 109) |
856 | 856 | ||
857 | /* UIE# block. | 857 | /* UIE# block. |
858 | * Must go into the same section as the UIE() handler */ | 858 | * Must go into the same section as the UIE() handler */ |
859 | 859 | ||
860 | "\t.text\n" | 860 | "\t.text\n" |
@@ -979,7 +979,7 @@ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */ | |||
979 | char str[32]; | 979 | char str[32]; |
980 | 980 | ||
981 | asm volatile ("sts\tpr,%0" : "=r"(n)); | 981 | asm volatile ("sts\tpr,%0" : "=r"(n)); |
982 | 982 | ||
983 | /* clear screen */ | 983 | /* clear screen */ |
984 | lcd_clear_display (); | 984 | lcd_clear_display (); |
985 | #ifdef HAVE_LCD_BITMAP | 985 | #ifdef HAVE_LCD_BITMAP |
@@ -1002,7 +1002,7 @@ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */ | |||
1002 | volatile int i; | 1002 | volatile int i; |
1003 | led (state); | 1003 | led (state); |
1004 | state = !state; | 1004 | state = !state; |
1005 | 1005 | ||
1006 | for (i = 0; i < 240000; ++i); | 1006 | for (i = 0; i < 240000; ++i); |
1007 | #endif | 1007 | #endif |
1008 | 1008 | ||
@@ -1018,7 +1018,7 @@ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */ | |||
1018 | #elif CONFIG_KEYPAD == ONDIO_PAD | 1018 | #elif CONFIG_KEYPAD == ONDIO_PAD |
1019 | if (!(PCDR & 0x0008)) | 1019 | if (!(PCDR & 0x0008)) |
1020 | #endif | 1020 | #endif |
1021 | { | 1021 | { |
1022 | /* enable the watchguard timer, but don't service it */ | 1022 | /* enable the watchguard timer, but don't service it */ |
1023 | RSTCSR_W = 0x5a40; /* Reset enabled, power-on reset */ | 1023 | RSTCSR_W = 0x5a40; /* Reset enabled, power-on reset */ |
1024 | TCSR_W = 0xa560; /* Watchdog timer mode, timer enabled, sysclk/2 */ | 1024 | TCSR_W = 0xa560; /* Watchdog timer mode, timer enabled, sysclk/2 */ |
@@ -1086,7 +1086,7 @@ int system_memory_guard(int newmode) | |||
1086 | 1086 | ||
1087 | int oldmode = MEMGUARD_NONE; | 1087 | int oldmode = MEMGUARD_NONE; |
1088 | int i; | 1088 | int i; |
1089 | 1089 | ||
1090 | /* figure out the old mode from what is in the UBC regs. If the register | 1090 | /* figure out the old mode from what is in the UBC regs. If the register |
1091 | values don't match any mode, assume MEMGUARD_NONE */ | 1091 | values don't match any mode, assume MEMGUARD_NONE */ |
1092 | for (i = MEMGUARD_NONE; i < MAXMEMGUARD; i++) | 1092 | for (i = MEMGUARD_NONE; i < MAXMEMGUARD; i++) |
@@ -1098,7 +1098,7 @@ int system_memory_guard(int newmode) | |||
1098 | break; | 1098 | break; |
1099 | } | 1099 | } |
1100 | } | 1100 | } |
1101 | 1101 | ||
1102 | if (newmode == MEMGUARD_KEEP) | 1102 | if (newmode == MEMGUARD_KEEP) |
1103 | newmode = oldmode; | 1103 | newmode = oldmode; |
1104 | 1104 | ||
@@ -1109,7 +1109,7 @@ int system_memory_guard(int newmode) | |||
1109 | BAR = modes[newmode].addr; | 1109 | BAR = modes[newmode].addr; |
1110 | BAMR = modes[newmode].mask; | 1110 | BAMR = modes[newmode].mask; |
1111 | BBR = modes[newmode].bbr; | 1111 | BBR = modes[newmode].bbr; |
1112 | 1112 | ||
1113 | return oldmode; | 1113 | return oldmode; |
1114 | } | 1114 | } |
1115 | #elif defined(CPU_ARM) | 1115 | #elif defined(CPU_ARM) |
@@ -1124,7 +1124,7 @@ static const char* const uiename[] = { | |||
1124 | void UIE(unsigned int pc, unsigned int num) | 1124 | void UIE(unsigned int pc, unsigned int num) |
1125 | { | 1125 | { |
1126 | char str[32]; | 1126 | char str[32]; |
1127 | 1127 | ||
1128 | lcd_clear_display(); | 1128 | lcd_clear_display(); |
1129 | #ifdef HAVE_LCD_BITMAP | 1129 | #ifdef HAVE_LCD_BITMAP |
1130 | lcd_setfont(FONT_SYSFIXED); | 1130 | lcd_setfont(FONT_SYSFIXED); |
@@ -1133,7 +1133,7 @@ void UIE(unsigned int pc, unsigned int num) | |||
1133 | snprintf(str, sizeof(str), "at %08x", pc); | 1133 | snprintf(str, sizeof(str), "at %08x", pc); |
1134 | lcd_puts(0, 1, str); | 1134 | lcd_puts(0, 1, str); |
1135 | lcd_update(); | 1135 | lcd_update(); |
1136 | 1136 | ||
1137 | while (1) | 1137 | while (1) |
1138 | { | 1138 | { |
1139 | /* TODO: perhaps add button handling in here when we get a polling | 1139 | /* TODO: perhaps add button handling in here when we get a polling |
@@ -1160,7 +1160,7 @@ void irq(void) | |||
1160 | else if (CPU_INT_STAT & TIMER2_MASK) | 1160 | else if (CPU_INT_STAT & TIMER2_MASK) |
1161 | TIMER2(); | 1161 | TIMER2(); |
1162 | else if (CPU_HI_INT_STAT & GPIO_MASK) | 1162 | else if (CPU_HI_INT_STAT & GPIO_MASK) |
1163 | ipod_mini_button_int(); | 1163 | ipod_mini_button_int(); |
1164 | } | 1164 | } |
1165 | #elif (defined IRIVER_H10) || (defined IRIVER_H10_5GB) | 1165 | #elif (defined IRIVER_H10) || (defined IRIVER_H10_5GB) |
1166 | /* TODO: this should really be in the target tree, but moving it there caused | 1166 | /* TODO: this should really be in the target tree, but moving it there caused |
@@ -1170,14 +1170,14 @@ void irq(void) | |||
1170 | if (CPU_INT_STAT & TIMER1_MASK) | 1170 | if (CPU_INT_STAT & TIMER1_MASK) |
1171 | TIMER1(); | 1171 | TIMER1(); |
1172 | else if (CPU_INT_STAT & TIMER2_MASK) | 1172 | else if (CPU_INT_STAT & TIMER2_MASK) |
1173 | TIMER2(); | 1173 | TIMER2(); |
1174 | } | 1174 | } |
1175 | #else | 1175 | #else |
1176 | extern void ipod_4g_button_int(void); | 1176 | extern void ipod_4g_button_int(void); |
1177 | 1177 | ||
1178 | void irq(void) | 1178 | void irq(void) |
1179 | { | 1179 | { |
1180 | if (CPU_INT_STAT & TIMER1_MASK) | 1180 | if (CPU_INT_STAT & TIMER1_MASK) |
1181 | TIMER1(); | 1181 | TIMER1(); |
1182 | else if (CPU_INT_STAT & TIMER2_MASK) | 1182 | else if (CPU_INT_STAT & TIMER2_MASK) |
1183 | TIMER2(); | 1183 | TIMER2(); |
@@ -1187,11 +1187,21 @@ void irq(void) | |||
1187 | #endif | 1187 | #endif |
1188 | #endif /* BOOTLOADER */ | 1188 | #endif /* BOOTLOADER */ |
1189 | 1189 | ||
1190 | unsigned int current_core(void) | ||
1191 | { | ||
1192 | if(((*(volatile unsigned long *)(0x60000000)) & 0xff) == 0x55) | ||
1193 | { | ||
1194 | return CPU; | ||
1195 | } | ||
1196 | return COP; | ||
1197 | } | ||
1198 | |||
1199 | |||
1190 | /* TODO: The following two function have been lifted straight from IPL, and | 1200 | /* TODO: The following two function have been lifted straight from IPL, and |
1191 | hence have a lot of numeric addresses used straight. I'd like to use | 1201 | hence have a lot of numeric addresses used straight. I'd like to use |
1192 | #defines for these, but don't know what most of them are for or even what | 1202 | #defines for these, but don't know what most of them are for or even what |
1193 | they should be named. Because of this I also have no way of knowing how | 1203 | they should be named. Because of this I also have no way of knowing how |
1194 | to extend the funtions to do alternate cache configurations and/or | 1204 | to extend the funtions to do alternate cache configurations and/or |
1195 | some other CPU frequency scaling. */ | 1205 | some other CPU frequency scaling. */ |
1196 | 1206 | ||
1197 | #ifndef BOOTLOADER | 1207 | #ifndef BOOTLOADER |
@@ -1251,7 +1261,7 @@ void set_cpu_frequency(long frequency) | |||
1251 | #if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) | 1261 | #if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) |
1252 | /* We don't know why the timer interrupt gets disabled on the PP5020 | 1262 | /* We don't know why the timer interrupt gets disabled on the PP5020 |
1253 | based ipods, but without the following line, the 4Gs will freeze | 1263 | based ipods, but without the following line, the 4Gs will freeze |
1254 | when CPU frequency changing is enabled. | 1264 | when CPU frequency changing is enabled. |
1255 | 1265 | ||
1256 | Note also that a simple "CPU_INT_EN = TIMER1_MASK;" (as used | 1266 | Note also that a simple "CPU_INT_EN = TIMER1_MASK;" (as used |
1257 | elsewhere to enable interrupts) doesn't work, we need "|=". | 1267 | elsewhere to enable interrupts) doesn't work, we need "|=". |
@@ -1321,19 +1331,29 @@ extern void TIMER2(void); | |||
1321 | 1331 | ||
1322 | void irq(void) | 1332 | void irq(void) |
1323 | { | 1333 | { |
1324 | if (CPU_INT_STAT & TIMER1_MASK) | 1334 | if (CPU_INT_STAT & TIMER1_MASK) |
1325 | TIMER1(); | 1335 | TIMER1(); |
1326 | else if (CPU_INT_STAT & TIMER2_MASK) | 1336 | else if (CPU_INT_STAT & TIMER2_MASK) |
1327 | TIMER2(); | 1337 | TIMER2(); |
1328 | } | 1338 | } |
1329 | 1339 | ||
1330 | #endif | 1340 | #endif |
1331 | 1341 | ||
1342 | unsigned int current_core(void) | ||
1343 | { | ||
1344 | if(((*(volatile unsigned long *)(0xc4000000)) & 0xff) == 0x55) | ||
1345 | { | ||
1346 | return CPU; | ||
1347 | } | ||
1348 | return COP; | ||
1349 | } | ||
1350 | |||
1351 | |||
1332 | /* TODO: The following two function have been lifted straight from IPL, and | 1352 | /* TODO: The following two function have been lifted straight from IPL, and |
1333 | hence have a lot of numeric addresses used straight. I'd like to use | 1353 | hence have a lot of numeric addresses used straight. I'd like to use |
1334 | #defines for these, but don't know what most of them are for or even what | 1354 | #defines for these, but don't know what most of them are for or even what |
1335 | they should be named. Because of this I also have no way of knowing how | 1355 | they should be named. Because of this I also have no way of knowing how |
1336 | to extend the funtions to do alternate cache configurations and/or | 1356 | to extend the funtions to do alternate cache configurations and/or |
1337 | some other CPU frequency scaling. */ | 1357 | some other CPU frequency scaling. */ |
1338 | 1358 | ||
1339 | #ifndef BOOTLOADER | 1359 | #ifndef BOOTLOADER |
@@ -1370,7 +1390,7 @@ void set_cpu_frequency(long frequency) | |||
1370 | else | 1390 | else |
1371 | postmult = CPUFREQ_DEFAULT_MULT; | 1391 | postmult = CPUFREQ_DEFAULT_MULT; |
1372 | cpu_frequency = frequency; | 1392 | cpu_frequency = frequency; |
1373 | 1393 | ||
1374 | outl(0x02, 0xcf005008); | 1394 | outl(0x02, 0xcf005008); |
1375 | outl(0x55, 0xcf00500c); | 1395 | outl(0x55, 0xcf00500c); |
1376 | outl(0x6000, 0xcf005010); | 1396 | outl(0x6000, 0xcf005010); |
@@ -1501,7 +1521,7 @@ void system_init(void) | |||
1501 | IRQ_WRITE_WAIT(0, 0, v == 0); | 1521 | IRQ_WRITE_WAIT(0, 0, v == 0); |
1502 | IRQ_WRITE_WAIT(4, 0, v == 0); | 1522 | IRQ_WRITE_WAIT(4, 0, v == 0); |
1503 | */ | 1523 | */ |
1504 | 1524 | ||
1505 | for (i = 0; i < 0x1c; i++) | 1525 | for (i = 0; i < 0x1c; i++) |
1506 | { | 1526 | { |
1507 | IRQ_WRITE_WAIT(0x404 + i * 4, 0x1e000001, (v & 0x3010f) == 1); | 1527 | IRQ_WRITE_WAIT(0x404 + i * 4, 0x1e000001, (v & 0x3010f) == 1); |
diff --git a/firmware/thread.c b/firmware/thread.c index 0013d49519..c194b2694d 100644 --- a/firmware/thread.c +++ b/firmware/thread.c | |||
@@ -41,7 +41,7 @@ struct regs | |||
41 | void *pr; /* Procedure register */ | 41 | void *pr; /* Procedure register */ |
42 | void *start; /* Thread start address, or NULL when started */ | 42 | void *start; /* Thread start address, or NULL when started */ |
43 | }; | 43 | }; |
44 | #elif defined(CPU_ARM) | 44 | #elif defined(CPU_ARM) |
45 | struct regs | 45 | struct regs |
46 | { | 46 | { |
47 | unsigned int r[8]; /* Registers r4-r11 */ | 47 | unsigned int r[8]; /* Registers r4-r11 */ |
@@ -62,18 +62,31 @@ struct regs | |||
62 | /* Cast to the the machine int type, whose size could be < 4. */ | 62 | /* Cast to the the machine int type, whose size could be < 4. */ |
63 | 63 | ||
64 | 64 | ||
65 | int num_threads; | 65 | int num_threads[NUM_CORES]; |
66 | static volatile int num_sleepers; | 66 | static volatile int num_sleepers[NUM_CORES]; |
67 | static int current_thread; | 67 | static int current_thread[NUM_CORES]; |
68 | static struct regs thread_contexts[MAXTHREADS] IBSS_ATTR; | 68 | static struct regs thread_contexts[NUM_CORES][MAXTHREADS] IBSS_ATTR; |
69 | const char *thread_name[MAXTHREADS]; | 69 | const char *thread_name[NUM_CORES][MAXTHREADS]; |
70 | void *thread_stack[MAXTHREADS]; | 70 | void *thread_stack[NUM_CORES][MAXTHREADS]; |
71 | int thread_stack_size[MAXTHREADS]; | 71 | int thread_stack_size[NUM_CORES][MAXTHREADS]; |
72 | static const char main_thread_name[] = "main"; | 72 | static const char main_thread_name[] = "main"; |
73 | 73 | ||
74 | extern int stackbegin[]; | 74 | extern int stackbegin[]; |
75 | extern int stackend[]; | 75 | extern int stackend[]; |
76 | 76 | ||
77 | #ifdef CPU_PP | ||
78 | #ifndef BOOTLOADER | ||
79 | extern int cop_stackbegin[]; | ||
80 | extern int cop_stackend[]; | ||
81 | #else | ||
82 | /* The coprocessor stack is not set up in the bootloader code, but the | ||
83 | threading is. No threads are run on the coprocessor, so set up some dummy | ||
84 | stack */ | ||
85 | int *cop_stackbegin = stackbegin; | ||
86 | int *cop_stackend = stackend; | ||
87 | #endif | ||
88 | #endif | ||
89 | |||
77 | void switch_thread(void) ICODE_ATTR; | 90 | void switch_thread(void) ICODE_ATTR; |
78 | static inline void store_context(void* addr) __attribute__ ((always_inline)); | 91 | static inline void store_context(void* addr) __attribute__ ((always_inline)); |
79 | static inline void load_context(const void* addr) __attribute__ ((always_inline)); | 92 | static inline void load_context(const void* addr) __attribute__ ((always_inline)); |
@@ -86,7 +99,7 @@ void profile_thread(void) { | |||
86 | #endif | 99 | #endif |
87 | 100 | ||
88 | #if defined(CPU_ARM) | 101 | #if defined(CPU_ARM) |
89 | /*--------------------------------------------------------------------------- | 102 | /*--------------------------------------------------------------------------- |
90 | * Store non-volatile context. | 103 | * Store non-volatile context. |
91 | *--------------------------------------------------------------------------- | 104 | *--------------------------------------------------------------------------- |
92 | */ | 105 | */ |
@@ -116,7 +129,7 @@ static inline void load_context(const void* addr) | |||
116 | } | 129 | } |
117 | 130 | ||
118 | #elif defined(CPU_COLDFIRE) | 131 | #elif defined(CPU_COLDFIRE) |
119 | /*--------------------------------------------------------------------------- | 132 | /*--------------------------------------------------------------------------- |
120 | * Store non-volatile context. | 133 | * Store non-volatile context. |
121 | *--------------------------------------------------------------------------- | 134 | *--------------------------------------------------------------------------- |
122 | */ | 135 | */ |
@@ -199,7 +212,7 @@ static inline void load_context(const void* addr) | |||
199 | } | 212 | } |
200 | 213 | ||
201 | #elif CONFIG_CPU == TCC730 | 214 | #elif CONFIG_CPU == TCC730 |
202 | /*--------------------------------------------------------------------------- | 215 | /*--------------------------------------------------------------------------- |
203 | * Store non-volatile context. | 216 | * Store non-volatile context. |
204 | *--------------------------------------------------------------------------- | 217 | *--------------------------------------------------------------------------- |
205 | */ | 218 | */ |
@@ -215,7 +228,7 @@ static inline void load_context(const void* addr) | |||
215 | "push a14\n\t" \ | 228 | "push a14\n\t" \ |
216 | "ldw @[%0+0], a15\n\t" : : "a" (addr) ); | 229 | "ldw @[%0+0], a15\n\t" : : "a" (addr) ); |
217 | 230 | ||
218 | /*--------------------------------------------------------------------------- | 231 | /*--------------------------------------------------------------------------- |
219 | * Load non-volatile context. | 232 | * Load non-volatile context. |
220 | *--------------------------------------------------------------------------- | 233 | *--------------------------------------------------------------------------- |
221 | */ | 234 | */ |
@@ -260,7 +273,7 @@ void switch_thread(void) | |||
260 | #ifdef SIMULATOR | 273 | #ifdef SIMULATOR |
261 | /* Do nothing */ | 274 | /* Do nothing */ |
262 | #else | 275 | #else |
263 | while (num_sleepers == num_threads) | 276 | while (num_sleepers[CURRENT_CORE] == num_threads[CURRENT_CORE]) |
264 | { | 277 | { |
265 | /* Enter sleep mode, woken up on interrupt */ | 278 | /* Enter sleep mode, woken up on interrupt */ |
266 | #ifdef CPU_COLDFIRE | 279 | #ifdef CPU_COLDFIRE |
@@ -284,21 +297,21 @@ void switch_thread(void) | |||
284 | #endif | 297 | #endif |
285 | } | 298 | } |
286 | #endif | 299 | #endif |
287 | current = current_thread; | 300 | current = current_thread[CURRENT_CORE]; |
288 | store_context(&thread_contexts[current]); | 301 | store_context(&thread_contexts[CURRENT_CORE][current]); |
289 | 302 | ||
290 | #if CONFIG_CPU != TCC730 | 303 | #if CONFIG_CPU != TCC730 |
291 | /* Check if the current thread stack is overflown */ | 304 | /* Check if the current thread stack is overflown */ |
292 | stackptr = thread_stack[current]; | 305 | stackptr = thread_stack[CURRENT_CORE][current]; |
293 | if(stackptr[0] != DEADBEEF) | 306 | if(stackptr[0] != DEADBEEF) |
294 | panicf("Stkov %s", thread_name[current]); | 307 | panicf("Stkov %s", thread_name[CURRENT_CORE][current]); |
295 | #endif | 308 | #endif |
296 | 309 | ||
297 | if (++current >= num_threads) | 310 | if (++current >= num_threads[CURRENT_CORE]) |
298 | current = 0; | 311 | current = 0; |
299 | 312 | ||
300 | current_thread = current; | 313 | current_thread[CURRENT_CORE] = current; |
301 | load_context(&thread_contexts[current]); | 314 | load_context(&thread_contexts[CURRENT_CORE][current]); |
302 | #ifdef RB_PROFILE | 315 | #ifdef RB_PROFILE |
303 | profile_thread_started(current_thread); | 316 | profile_thread_started(current_thread); |
304 | #endif | 317 | #endif |
@@ -306,29 +319,42 @@ void switch_thread(void) | |||
306 | 319 | ||
307 | void sleep_thread(void) | 320 | void sleep_thread(void) |
308 | { | 321 | { |
309 | ++num_sleepers; | 322 | ++num_sleepers[CURRENT_CORE]; |
310 | switch_thread(); | 323 | switch_thread(); |
311 | } | 324 | } |
312 | 325 | ||
313 | void wake_up_thread(void) | 326 | void wake_up_thread(void) |
314 | { | 327 | { |
315 | num_sleepers = 0; | 328 | num_sleepers[CURRENT_CORE] = 0; |
316 | } | 329 | } |
317 | 330 | ||
318 | /*--------------------------------------------------------------------------- | 331 | |
319 | * Create thread. | 332 | /*--------------------------------------------------------------------------- |
333 | * Create thread on the current core. | ||
320 | * Return ID if context area could be allocated, else -1. | 334 | * Return ID if context area could be allocated, else -1. |
321 | *--------------------------------------------------------------------------- | 335 | *--------------------------------------------------------------------------- |
322 | */ | 336 | */ |
323 | int create_thread(void (*function)(void), void* stack, int stack_size, | 337 | int create_thread(void (*function)(void), void* stack, int stack_size, |
324 | const char *name) | 338 | const char *name) |
325 | { | 339 | { |
340 | return create_thread_on_core(CURRENT_CORE, function, stack, stack_size, | ||
341 | name); | ||
342 | } | ||
343 | |||
344 | /*--------------------------------------------------------------------------- | ||
345 | * Create thread on a specific core. | ||
346 | * Return ID if context area could be allocated, else -1. | ||
347 | *--------------------------------------------------------------------------- | ||
348 | */ | ||
349 | int create_thread_on_core(unsigned int core, void (*function)(void), void* stack, int stack_size, | ||
350 | const char *name) | ||
351 | { | ||
326 | unsigned int i; | 352 | unsigned int i; |
327 | unsigned int stacklen; | 353 | unsigned int stacklen; |
328 | unsigned int *stackptr; | 354 | unsigned int *stackptr; |
329 | struct regs *regs; | 355 | struct regs *regs; |
330 | 356 | ||
331 | if (num_threads >= MAXTHREADS) | 357 | if (num_threads[core] >= MAXTHREADS) |
332 | return -1; | 358 | return -1; |
333 | 359 | ||
334 | /* Munge the stack to make it easy to spot stack overflows */ | 360 | /* Munge the stack to make it easy to spot stack overflows */ |
@@ -340,10 +366,10 @@ int create_thread(void (*function)(void), void* stack, int stack_size, | |||
340 | } | 366 | } |
341 | 367 | ||
342 | /* Store interesting information */ | 368 | /* Store interesting information */ |
343 | thread_name[num_threads] = name; | 369 | thread_name[core][num_threads[core]] = name; |
344 | thread_stack[num_threads] = stack; | 370 | thread_stack[core][num_threads[core]] = stack; |
345 | thread_stack_size[num_threads] = stack_size; | 371 | thread_stack_size[core][num_threads[core]] = stack_size; |
346 | regs = &thread_contexts[num_threads]; | 372 | regs = &thread_contexts[core][num_threads[core]]; |
347 | #if defined(CPU_COLDFIRE) || (CONFIG_CPU == SH7034) || defined(CPU_ARM) | 373 | #if defined(CPU_COLDFIRE) || (CONFIG_CPU == SH7034) || defined(CPU_ARM) |
348 | /* Align stack to an even 32 bit boundary */ | 374 | /* Align stack to an even 32 bit boundary */ |
349 | regs->sp = (void*)(((unsigned int)stack + stack_size) & ~3); | 375 | regs->sp = (void*)(((unsigned int)stack + stack_size) & ~3); |
@@ -355,65 +381,91 @@ int create_thread(void (*function)(void), void* stack, int stack_size, | |||
355 | regs->start = (void*)function; | 381 | regs->start = (void*)function; |
356 | 382 | ||
357 | wake_up_thread(); | 383 | wake_up_thread(); |
358 | return num_threads++; /* return the current ID, e.g for remove_thread() */ | 384 | return num_threads[core]++; /* return the current ID, e.g for remove_thread() */ |
359 | } | 385 | } |
360 | 386 | ||
361 | /*--------------------------------------------------------------------------- | 387 | /*--------------------------------------------------------------------------- |
362 | * Remove a thread from the scheduler. | 388 | * Remove a thread on the current core from the scheduler. |
363 | * Parameter is the ID as returned from create_thread(). | 389 | * Parameter is the ID as returned from create_thread(). |
364 | *--------------------------------------------------------------------------- | 390 | *--------------------------------------------------------------------------- |
365 | */ | 391 | */ |
366 | void remove_thread(int threadnum) | 392 | void remove_thread(int threadnum) |
367 | { | 393 | { |
394 | remove_thread_on_core(CURRENT_CORE, threadnum); | ||
395 | } | ||
396 | |||
397 | /*--------------------------------------------------------------------------- | ||
398 | * Remove a thread on the specified core from the scheduler. | ||
399 | * Parameters are the core and the ID as returned from create_thread(). | ||
400 | *--------------------------------------------------------------------------- | ||
401 | */ | ||
402 | void remove_thread_on_core(unsigned int core, int threadnum) | ||
403 | { | ||
368 | int i; | 404 | int i; |
369 | 405 | ||
370 | if(threadnum >= num_threads) | 406 | if(threadnum >= num_threads[core]) |
371 | return; | 407 | return; |
372 | 408 | ||
373 | num_threads--; | 409 | num_threads[core]--; |
374 | for (i=threadnum; i<num_threads-1; i++) | 410 | for (i=threadnum; i<num_threads[core]-1; i++) |
375 | { /* move all entries which are behind */ | 411 | { /* move all entries which are behind */ |
376 | thread_name[i] = thread_name[i+1]; | 412 | thread_name[core][i] = thread_name[core][i+1]; |
377 | thread_stack[i] = thread_stack[i+1]; | 413 | thread_stack[core][i] = thread_stack[core][i+1]; |
378 | thread_stack_size[i] = thread_stack_size[i+1]; | 414 | thread_stack_size[core][i] = thread_stack_size[core][i+1]; |
379 | thread_contexts[i] = thread_contexts[i+1]; | 415 | thread_contexts[core][i] = thread_contexts[core][i+1]; |
380 | } | 416 | } |
381 | 417 | ||
382 | if (current_thread == threadnum) /* deleting the current one? */ | 418 | if (current_thread[core] == threadnum) /* deleting the current one? */ |
383 | current_thread = num_threads; /* set beyond last, avoid store harm */ | 419 | current_thread[core] = num_threads[core]; /* set beyond last, avoid store harm */ |
384 | else if (current_thread > threadnum) /* within the moved positions? */ | 420 | else if (current_thread[core] > threadnum) /* within the moved positions? */ |
385 | current_thread--; /* adjust it, point to same context again */ | 421 | current_thread[core]--; /* adjust it, point to same context again */ |
386 | } | 422 | } |
387 | 423 | ||
388 | void init_threads(void) | 424 | void init_threads(void) |
389 | { | 425 | { |
390 | num_threads = 1; /* We have 1 thread to begin with */ | 426 | unsigned int core = CURRENT_CORE; |
391 | current_thread = 0; /* The current thread is number 0 */ | 427 | |
392 | thread_name[0] = main_thread_name; | 428 | num_threads[core] = 1; /* We have 1 thread to begin with */ |
393 | thread_stack[0] = stackbegin; | 429 | current_thread[core] = 0; /* The current thread is number 0 */ |
394 | thread_stack_size[0] = (int)stackend - (int)stackbegin; | 430 | thread_name[core][0] = main_thread_name; |
431 | /* In multiple core setups, each core has a different stack. There is probably | ||
432 | a much better way to do this. */ | ||
433 | if(core == CPU) | ||
434 | { | ||
435 | thread_stack[CPU][0] = stackbegin; | ||
436 | thread_stack_size[CPU][0] = (int)stackend - (int)stackbegin; | ||
437 | } else { | ||
438 | #if NUM_CORES > 1 /* This code path will not be run on single core targets */ | ||
439 | thread_stack[COP][0] = cop_stackbegin; | ||
440 | thread_stack_size[COP][0] = (int)cop_stackend - (int)cop_stackbegin; | ||
441 | #endif | ||
442 | } | ||
395 | #if CONFIG_CPU == TCC730 | 443 | #if CONFIG_CPU == TCC730 |
396 | thread_contexts[0].started = 1; | 444 | thread_contexts[core][0].started = 1; |
397 | #else | 445 | #else |
398 | thread_contexts[0].start = 0; /* thread 0 already running */ | 446 | thread_contexts[core][0].start = 0; /* thread 0 already running */ |
399 | #endif | 447 | #endif |
400 | num_sleepers = 0; | 448 | num_sleepers[core] = 0; |
449 | } | ||
450 | |||
451 | int thread_stack_usage(int threadnum){ | ||
452 | return thread_stack_usage_on_core(CURRENT_CORE, threadnum); | ||
401 | } | 453 | } |
402 | 454 | ||
403 | int thread_stack_usage(int threadnum) | 455 | int thread_stack_usage_on_core(unsigned int core, int threadnum) |
404 | { | 456 | { |
405 | unsigned int i; | 457 | unsigned int i; |
406 | unsigned int *stackptr = thread_stack[threadnum]; | 458 | unsigned int *stackptr = thread_stack[core][threadnum]; |
407 | 459 | ||
408 | if(threadnum >= num_threads) | 460 | if(threadnum >= num_threads[core]) |
409 | return -1; | 461 | return -1; |
410 | 462 | ||
411 | for(i = 0;i < thread_stack_size[threadnum]/sizeof(int);i++) | 463 | for(i = 0;i < thread_stack_size[core][threadnum]/sizeof(int);i++) |
412 | { | 464 | { |
413 | if(stackptr[i] != DEADBEEF) | 465 | if(stackptr[i] != DEADBEEF) |
414 | break; | 466 | break; |
415 | } | 467 | } |
416 | 468 | ||
417 | return ((thread_stack_size[threadnum] - i * sizeof(int)) * 100) / | 469 | return ((thread_stack_size[core][threadnum] - i * sizeof(int)) * 100) / |
418 | thread_stack_size[threadnum]; | 470 | thread_stack_size[core][threadnum]; |
419 | } | 471 | } |