1
0
Fork 0
forked from len0rd/rockbox

Threading changes in preparation for multiple core support

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10681 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Daniel Ankers 2006-08-21 17:35:35 +00:00
parent e09dc8d513
commit 0aec12f3fd
6 changed files with 309 additions and 207 deletions

View file

@ -78,8 +78,8 @@
/*---------------------------------------------------*/ /*---------------------------------------------------*/
extern char ata_device; extern char ata_device;
extern int ata_io_address; extern int ata_io_address;
extern int num_threads; extern int num_threads[];
extern const char *thread_name[]; extern const char *thread_name[][MAXTHREADS];
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
/* Test code!!! */ /* Test code!!! */
@ -88,6 +88,8 @@ bool dbg_os(void)
char buf[32]; char buf[32];
int i; int i;
int usage; int usage;
unsigned int core;
int line;
lcd_setmargins(0, 0); lcd_setmargins(0, 0);
lcd_setfont(FONT_SYSFIXED); lcd_setfont(FONT_SYSFIXED);
@ -95,12 +97,16 @@ bool dbg_os(void)
while(1) while(1)
{ {
lcd_puts(0, 0, "Stack usage:"); lcd_puts(0, 0, "Core and stack usage:");
for(i = 0; i < num_threads;i++) line = 0;
for(core = 0; core < NUM_CORES; core++)
{ {
usage = thread_stack_usage(i); for(i = 0; i < num_threads[core]; i++)
snprintf(buf, 32, "%s: %d%%", thread_name[i], usage); {
lcd_puts(0, 1+i, buf); usage = thread_stack_usage_on_core(core, i);
snprintf(buf, 32, "(%d) %s: %d%%", core, thread_name[core][i], usage);
lcd_puts(0, ++line, buf);
}
} }
lcd_update(); lcd_update();
@ -124,10 +130,11 @@ bool dbg_os(void)
{ {
lcd_puts(0, 0, "Stack usage"); lcd_puts(0, 0, "Stack usage");
/* Only Archos Player uses this - so assume a single core */
usage = thread_stack_usage(currval); usage = thread_stack_usage(currval);
snprintf(buf, 32, "%d: %d%% ", currval, usage); snprintf(buf, 32, "%d: %d%% ", currval, usage);
lcd_puts(0, 1, buf); lcd_puts(0, 1, buf);
button = get_action(CONTEXT_SETTINGS,HZ/10); button = get_action(CONTEXT_SETTINGS,HZ/10);
switch(button) switch(button)
@ -162,14 +169,14 @@ bool dbg_audio_thread(void)
lcd_setmargins(0, 0); lcd_setmargins(0, 0);
lcd_setfont(FONT_SYSFIXED); lcd_setfont(FONT_SYSFIXED);
while(1) while(1)
{ {
if (action_userabort(HZ/5)) if (action_userabort(HZ/5))
return false; return false;
audio_get_debugdata(&d); audio_get_debugdata(&d);
lcd_clear_display(); lcd_clear_display();
snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read); snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
@ -186,17 +193,17 @@ bool dbg_audio_thread(void)
lcd_puts(0, 5, buf); lcd_puts(0, 5, buf);
/* Playable space left */ /* Playable space left */
scrollbar(0, 6*8, 112, 4, d.audiobuflen, 0, scrollbar(0, 6*8, 112, 4, d.audiobuflen, 0,
d.playable_space, HORIZONTAL); d.playable_space, HORIZONTAL);
/* Show the watermark limit */ /* Show the watermark limit */
scrollbar(0, 6*8+4, 112, 4, d.audiobuflen, 0, scrollbar(0, 6*8+4, 112, 4, d.audiobuflen, 0,
d.low_watermark_level, HORIZONTAL); d.low_watermark_level, HORIZONTAL);
snprintf(buf, sizeof(buf), "wm: %x - %x", snprintf(buf, sizeof(buf), "wm: %x - %x",
d.low_watermark_level, d.lowest_watermark_level); d.low_watermark_level, d.lowest_watermark_level);
lcd_puts(0, 7, buf); lcd_puts(0, 7, buf);
lcd_update(); lcd_update();
} }
return false; return false;
@ -229,7 +236,7 @@ bool dbg_audio_thread(void)
ticks = boost_ticks = 0; ticks = boost_ticks = 0;
tick_add_task(dbg_audio_task); tick_add_task(dbg_audio_task);
lcd_setmargins(0, 0); lcd_setmargins(0, 0);
lcd_setfont(FONT_SYSFIXED); lcd_setfont(FONT_SYSFIXED);
while(!done) while(!done)
@ -249,7 +256,7 @@ bool dbg_audio_thread(void)
} }
action_signalscreenchange(); action_signalscreenchange();
line = 0; line = 0;
lcd_clear_display(); lcd_clear_display();
bufused = bufsize - pcmbuf_free(); bufused = bufsize - pcmbuf_free();
@ -283,12 +290,12 @@ bool dbg_audio_thread(void)
snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d", snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
pcmbuf_used_descs(), pcmbufdescs); pcmbuf_used_descs(), pcmbufdescs);
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
lcd_update(); lcd_update();
} }
tick_remove_task(dbg_audio_task); tick_remove_task(dbg_audio_task);
return false; return false;
} }
#endif /* CONFIG_CODEC */ #endif /* CONFIG_CODEC */
@ -303,7 +310,7 @@ static void flash_write_word(unsigned addr, unsigned value) {
flash_word_temp = value; flash_word_temp = value;
long extAddr = (long)addr << 1; long extAddr = (long)addr << 1;
ddma_transfer(1, 1, &flash_word_temp, extAddr, 2); ddma_transfer(1, 1, &flash_word_temp, extAddr, 2);
} }
static unsigned flash_read_word(unsigned addr) __attribute__ ((section(".icode"))); static unsigned flash_read_word(unsigned addr) __attribute__ ((section(".icode")));
@ -324,7 +331,7 @@ bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
__attribute__ ((section (".icode"))); __attribute__ ((section (".icode")));
bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device, bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
unsigned addr1, unsigned addr2) unsigned addr1, unsigned addr2)
{ {
#if (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020) #if (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020)
/* TODO: Implement for iPod */ /* TODO: Implement for iPod */
@ -382,9 +389,9 @@ bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
/* sleep(HZ/50); no sleeping possible while interrupts are disabled */ /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
set_irq_level(old_level); /* enable interrupts again */ set_irq_level(old_level); /* enable interrupts again */
/* I assume success if the obtained values are different from /* I assume success if the obtained values are different from
the normal flash content. This is not perfectly bulletproof, they the normal flash content. This is not perfectly bulletproof, they
could theoretically be the same by chance, causing us to fail. */ could theoretically be the same by chance, causing us to fail. */
if (not_manu != manu || not_id != id) /* a value has changed */ if (not_manu != manu || not_id != id) /* a value has changed */
{ {
@ -431,7 +438,7 @@ bool dbg_hw_info(void)
got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */ got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
if (!got_id) if (!got_id)
got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */ got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
/* check if the boot ROM area is a flash mirror */ /* check if the boot ROM area is a flash mirror */
has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0); has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
if (has_bootrom) /* if ROM and Flash different */ if (has_bootrom) /* if ROM and Flash different */
@ -450,16 +457,16 @@ bool dbg_hw_info(void)
snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100); snprintf(buf, 32, "ROM: %d.%02d", rom_version/100, rom_version%100);
lcd_puts(0, 1, buf); lcd_puts(0, 1, buf);
snprintf(buf, 32, "Mask: 0x%04x", bitmask); snprintf(buf, 32, "Mask: 0x%04x", bitmask);
lcd_puts(0, 2, buf); lcd_puts(0, 2, buf);
snprintf(buf, 32, "USB: %s", usb_polarity?"positive":"negative"); snprintf(buf, 32, "USB: %s", usb_polarity?"positive":"negative");
lcd_puts(0, 3, buf); lcd_puts(0, 3, buf);
snprintf(buf, 32, "PR: %s", pr_polarity?"positive":"negative"); snprintf(buf, 32, "PR: %s", pr_polarity?"positive":"negative");
lcd_puts(0, 4, buf); lcd_puts(0, 4, buf);
if (got_id) if (got_id)
snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id); snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
else else
@ -483,7 +490,7 @@ bool dbg_hw_info(void)
snprintf(buf, 32, "ATA: 0x%x,%s", ata_io_address, snprintf(buf, 32, "ATA: 0x%x,%s", ata_io_address,
ata_device ? "slave":"master"); ata_device ? "slave":"master");
lcd_puts(0, 7, buf); lcd_puts(0, 7, buf);
#endif #endif
lcd_update(); lcd_update();
while(1) while(1)
@ -503,7 +510,7 @@ bool dbg_hw_info(void)
got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */ got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
if (!got_id) if (!got_id)
got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */ got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
system_memory_guard(oldmode); /* re-enable memory guard */ system_memory_guard(oldmode); /* re-enable memory guard */
lcd_setmargins(0, 0); lcd_setmargins(0, 0);
@ -533,7 +540,7 @@ bool dbg_hw_info(void)
lcd_clear_display(); lcd_clear_display();
lcd_puts(0, 0, "[Hardware info]"); lcd_puts(0, 0, "[Hardware info]");
snprintf(buf, sizeof(buf), "HW rev: 0x%08x", ipod_hw_rev); snprintf(buf, sizeof(buf), "HW rev: 0x%08x", ipod_hw_rev);
lcd_puts(0, 1, buf); lcd_puts(0, 1, buf);
@ -581,7 +588,7 @@ bool dbg_hw_info(void)
/* calculate CRC16 checksum of boot ROM */ /* calculate CRC16 checksum of boot ROM */
rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff); rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
} }
system_memory_guard(oldmode); /* re-enable memory guard */ system_memory_guard(oldmode); /* re-enable memory guard */
lcd_clear_display(); lcd_clear_display();
@ -617,7 +624,7 @@ bool dbg_hw_info(void)
{ {
if (rom_crc == 0x56DBA4EE) /* known Version 1 */ if (rom_crc == 0x56DBA4EE) /* known Version 1 */
snprintf(buf, 32, "BootROM: V1"); snprintf(buf, 32, "BootROM: V1");
else if (rom_crc == 0x358099E8) else if (rom_crc == 0x358099E8)
snprintf(buf, 32, "BootROM: V2"); snprintf(buf, 32, "BootROM: V2");
/* alternative boot ROM found in one single player so far */ /* alternative boot ROM found in one single player so far */
else else
@ -626,10 +633,10 @@ bool dbg_hw_info(void)
else else
snprintf(buf, 32, "BootROM: no"); snprintf(buf, 32, "BootROM: no");
} }
lcd_puts(0, 1, buf); lcd_puts(0, 1, buf);
lcd_update(); lcd_update();
button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK); button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
switch(button) switch(button)
@ -643,7 +650,7 @@ bool dbg_hw_info(void)
if(currval < 0) if(currval < 0)
currval = 5; currval = 5;
break; break;
case ACTION_SETTINGS_INC: case ACTION_SETTINGS_INC:
currval++; currval++;
if(currval > 5) if(currval > 5)
@ -677,7 +684,7 @@ bool dbg_partitions(void)
snprintf(buf, sizeof buf, "T:%x %ld MB", p->type, p->size / 2048); snprintf(buf, sizeof buf, "T:%x %ld MB", p->type, p->size / 2048);
lcd_puts(0, 1, buf); lcd_puts(0, 1, buf);
lcd_update(); lcd_update();
button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK); button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
switch(button) switch(button)
@ -691,7 +698,7 @@ bool dbg_partitions(void)
if (partition < 0) if (partition < 0)
partition = 3; partition = 3;
break; break;
case ACTION_SETTINGS_INC: case ACTION_SETTINGS_INC:
partition++; partition++;
if (partition > 3) if (partition > 3)
@ -751,22 +758,22 @@ bool dbg_spdif(void)
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
line++; line++;
x = control >> 31; x = control >> 31;
snprintf(buf, sizeof(buf), "PRO: %d (%s)", snprintf(buf, sizeof(buf), "PRO: %d (%s)",
x, x?"Professional":"Consumer"); x, x?"Professional":"Consumer");
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
x = (control >> 30) & 1; x = (control >> 30) & 1;
snprintf(buf, sizeof(buf), "Audio: %d (%s)", snprintf(buf, sizeof(buf), "Audio: %d (%s)",
x, x?"Non-PCM":"PCM"); x, x?"Non-PCM":"PCM");
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
x = (control >> 29) & 1; x = (control >> 29) & 1;
snprintf(buf, sizeof(buf), "Copy: %d (%s)", snprintf(buf, sizeof(buf), "Copy: %d (%s)",
x, x?"Permitted":"Inhibited"); x, x?"Permitted":"Inhibited");
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
x = (control >> 27) & 7; x = (control >> 27) & 7;
switch(x) switch(x)
{ {
@ -786,7 +793,7 @@ bool dbg_spdif(void)
x = (control >> 24) & 3; x = (control >> 24) & 3;
snprintf(buf, sizeof(buf), "Mode: %d", x); snprintf(buf, sizeof(buf), "Mode: %d", x);
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
category = (control >> 17) & 127; category = (control >> 17) & 127;
switch(category) switch(category)
{ {
@ -801,7 +808,7 @@ bool dbg_spdif(void)
} }
snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s); snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
x = (control >> 16) & 1; x = (control >> 16) & 1;
generation = x; generation = x;
if(((category & 0x70) == 0x10) || if(((category & 0x70) == 0x10) ||
@ -813,11 +820,11 @@ bool dbg_spdif(void)
snprintf(buf, sizeof(buf), "Generation: %d (%s)", snprintf(buf, sizeof(buf), "Generation: %d (%s)",
x, generation?"Original":"No ind."); x, generation?"Original":"No ind.");
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
x = (control >> 12) & 15; x = (control >> 12) & 15;
snprintf(buf, sizeof(buf), "Source: %d", x); snprintf(buf, sizeof(buf), "Source: %d", x);
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
x = (control >> 8) & 15; x = (control >> 8) & 15;
switch(x) switch(x)
{ {
@ -836,7 +843,7 @@ bool dbg_spdif(void)
} }
snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s); snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
x = (control >> 4) & 15; x = (control >> 4) & 15;
switch(x) switch(x)
{ {
@ -857,7 +864,7 @@ bool dbg_spdif(void)
snprintf(buf, sizeof(buf), "Clock accuracy: %d", x); snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
line++; line++;
snprintf(buf, sizeof(buf), "Measured freq: %ldHz", snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
(long)((long long)FREQMEAS*CPU_FREQ/((1 << 15)*3*(1 << 13))/128)); (long)((long long)FREQMEAS*CPU_FREQ/((1 << 15)*3*(1 << 13))/128));
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
@ -914,7 +921,7 @@ bool dbg_ports(void)
battery_voltage = (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) / 10000; battery_voltage = (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) / 10000;
batt_int = battery_voltage / 100; batt_int = battery_voltage / 100;
batt_frac = battery_voltage % 100; batt_frac = battery_voltage % 100;
snprintf(buf, 32, "Batt: %d.%02dV %d%% ", batt_int, batt_frac, snprintf(buf, 32, "Batt: %d.%02dV %d%% ", batt_int, batt_frac,
battery_level()); battery_level());
lcd_puts(0, 6, buf); lcd_puts(0, 6, buf);
@ -960,7 +967,7 @@ bool dbg_ports(void)
gpio1_function = GPIO1_FUNCTION; gpio1_function = GPIO1_FUNCTION;
gpio_enable = GPIO_ENABLE; gpio_enable = GPIO_ENABLE;
gpio1_enable = GPIO1_ENABLE; gpio1_enable = GPIO1_ENABLE;
snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read); snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out); snprintf(buf, sizeof(buf), "GPIO_OUT: %08x", gpio_out);
@ -985,7 +992,7 @@ bool dbg_ports(void)
#if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
adc_remotedetect = adc_read(ADC_REMOTEDETECT); adc_remotedetect = adc_read(ADC_REMOTEDETECT);
#endif #endif
snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons); snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote); snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote);
@ -1000,16 +1007,16 @@ bool dbg_ports(void)
battery_voltage = (adc_battery * BATTERY_SCALE_FACTOR) / 10000; battery_voltage = (adc_battery * BATTERY_SCALE_FACTOR) / 10000;
batt_int = battery_voltage / 100; batt_int = battery_voltage / 100;
batt_frac = battery_voltage % 100; batt_frac = battery_voltage % 100;
snprintf(buf, 32, "Batt: %d.%02dV %d%% ", batt_int, batt_frac, snprintf(buf, 32, "Batt: %d.%02dV %d%% ", batt_int, batt_frac,
battery_level()); battery_level());
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
#if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
snprintf(buf, sizeof(buf), "remotetype:: %d", remote_type()); snprintf(buf, sizeof(buf), "remotetype:: %d", remote_type());
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
#endif #endif
lcd_update(); lcd_update();
if (action_userabort(HZ/10)) if (action_userabort(HZ/10))
return false; return false;
@ -1128,15 +1135,15 @@ bool dbg_ports(void)
break; break;
} }
lcd_puts(0, 0, buf); lcd_puts(0, 0, buf);
battery_voltage = (adc_read(ADC_UNREG_POWER) * battery_voltage = (adc_read(ADC_UNREG_POWER) *
BATTERY_SCALE_FACTOR) / 10000; BATTERY_SCALE_FACTOR) / 10000;
batt_int = battery_voltage / 100; batt_int = battery_voltage / 100;
batt_frac = battery_voltage % 100; batt_frac = battery_voltage % 100;
snprintf(buf, 32, "Batt: %d.%02dV", batt_int, batt_frac); snprintf(buf, 32, "Batt: %d.%02dV", batt_int, batt_frac);
lcd_puts(0, 1, buf); lcd_puts(0, 1, buf);
button = get_action(CONTEXT_SETTINGS,HZ/5); button = get_action(CONTEXT_SETTINGS,HZ/5);
switch(button) switch(button)
@ -1179,7 +1186,7 @@ bool dbg_cpufreq(void)
while(1) while(1)
{ {
line = 0; line = 0;
snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ); snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
@ -1212,7 +1219,7 @@ bool dbg_cpufreq(void)
return false; return false;
} }
#endif /* HAVE_ADJUSTABLE_CPU_FREQ */ #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
/* /*
* view_battery() shows a automatically scaled graph of the battery voltage * view_battery() shows a automatically scaled graph of the battery voltage
@ -1229,7 +1236,7 @@ bool view_battery(void)
int i, x, y; int i, x, y;
unsigned short maxv, minv; unsigned short maxv, minv;
char buf[32]; char buf[32];
lcd_setmargins(0, 0); lcd_setmargins(0, 0);
lcd_setfont(FONT_SYSFIXED); lcd_setfont(FONT_SYSFIXED);
@ -1248,20 +1255,20 @@ bool view_battery(void)
minv = power_history[i]; minv = power_history[i];
} }
} }
if ((minv < 1) || (minv >= 65535)) if ((minv < 1) || (minv >= 65535))
minv = 1; minv = 1;
if (maxv < 2) if (maxv < 2)
maxv = 2; maxv = 2;
lcd_clear_display(); lcd_clear_display();
snprintf(buf, 30, "Battery %d.%02d", power_history[0] / 100, snprintf(buf, 30, "Battery %d.%02d", power_history[0] / 100,
power_history[0] % 100); power_history[0] % 100);
lcd_puts(0, 0, buf); lcd_puts(0, 0, buf);
snprintf(buf, 30, "scale %d.%02d-%d.%02d V", snprintf(buf, 30, "scale %d.%02d-%d.%02d V",
minv / 100, minv % 100, maxv / 100, maxv % 100); minv / 100, minv % 100, maxv / 100, maxv % 100);
lcd_puts(0, 1, buf); lcd_puts(0, 1, buf);
x = 0; x = 0;
for (i = BAT_LAST_VAL - 1; i >= 0; i--) { for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv); y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
@ -1274,7 +1281,7 @@ bool view_battery(void)
} }
break; break;
case 1: /* status: */ case 1: /* status: */
lcd_clear_display(); lcd_clear_display();
lcd_puts(0, 0, "Power status:"); lcd_puts(0, 0, "Power status:");
@ -1289,7 +1296,7 @@ bool view_battery(void)
#endif #endif
#ifdef CONFIG_CHARGING #ifdef CONFIG_CHARGING
#if CONFIG_CHARGING == CHARGING_CONTROL #if CONFIG_CHARGING == CHARGING_CONTROL
snprintf(buf, 30, "Chgr: %s %s", snprintf(buf, 30, "Chgr: %s %s",
charger_inserted() ? "present" : "absent", charger_inserted() ? "present" : "absent",
charger_enabled ? "on" : "off"); charger_enabled ? "on" : "off");
lcd_puts(0, 3, buf); lcd_puts(0, 3, buf);
@ -1329,15 +1336,15 @@ bool view_battery(void)
#endif /* CONFIG_CHARGING != CHARGING_CONTROL */ #endif /* CONFIG_CHARGING != CHARGING_CONTROL */
#endif /* CONFIG_CHARGING */ #endif /* CONFIG_CHARGING */
break; break;
case 2: /* voltage deltas: */ case 2: /* voltage deltas: */
lcd_clear_display(); lcd_clear_display();
lcd_puts(0, 0, "Voltage deltas:"); lcd_puts(0, 0, "Voltage deltas:");
for (i = 0; i <= 6; i++) { for (i = 0; i <= 6; i++) {
y = power_history[i] - power_history[i+i]; y = power_history[i] - power_history[i+i];
snprintf(buf, 30, "-%d min: %s%d.%02d V", i, snprintf(buf, 30, "-%d min: %s%d.%02d V", i,
(y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 100, (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 100,
((y < 0) ? y * -1 : y ) % 100); ((y < 0) ? y * -1 : y ) % 100);
lcd_puts(0, i+1, buf); lcd_puts(0, i+1, buf);
} }
@ -1375,21 +1382,21 @@ bool view_battery(void)
lcd_puts(0, 7, buf); lcd_puts(0, 7, buf);
break; break;
} }
lcd_update(); lcd_update();
switch(get_action(CONTEXT_SETTINGS,HZ/2)) switch(get_action(CONTEXT_SETTINGS,HZ/2))
{ {
case ACTION_SETTINGS_DEC: case ACTION_SETTINGS_DEC:
if (view) if (view)
view--; view--;
break; break;
case ACTION_SETTINGS_INC: case ACTION_SETTINGS_INC:
if (view < 3) if (view < 3)
view++; view++;
break; break;
case ACTION_STD_CANCEL: case ACTION_STD_CANCEL:
action_signalscreenchange(); action_signalscreenchange();
return false; return false;
@ -1399,7 +1406,7 @@ bool view_battery(void)
} }
#endif /* HAVE_LCD_BITMAP */ #endif /* HAVE_LCD_BITMAP */
static bool view_runtime(void) static bool view_runtime(void)
{ {
char s[32]; char s[32];
@ -1441,7 +1448,7 @@ static bool view_runtime(void)
t = global_settings.topruntime; t = global_settings.topruntime;
lcd_puts(0, y++, "Top time"); lcd_puts(0, y++, "Top time");
} }
snprintf(s, sizeof(s), "%dh %dm %ds", snprintf(s, sizeof(s), "%dh %dm %ds",
t / 3600, (t % 3600) / 60, t % 60); t / 3600, (t % 3600) / 60, t % 60);
lcd_puts(0, y++, s); lcd_puts(0, y++, s);
@ -1498,7 +1505,7 @@ bool dbg_mmc_info(void)
static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 }; static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" }; static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
static const unsigned char *nsec_units[] = { "ns", "µs", "ms" }; static const unsigned char *nsec_units[] = { "ns", "µs", "ms" };
card_name[6] = '\0'; card_name[6] = '\0';
lcd_setmargins(0, 0); lcd_setmargins(0, 0);
@ -1574,7 +1581,7 @@ bool dbg_mmc_info(void)
case ACTION_STD_CANCEL: case ACTION_STD_CANCEL:
done = true; done = true;
break; break;
case ACTION_SETTINGS_DEC: case ACTION_SETTINGS_DEC:
currval--; currval--;
if (currval < 0) if (currval < 0)
@ -1606,7 +1613,7 @@ static bool dbg_disk_info(void)
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
lcd_setmargins(0, 0); lcd_setmargins(0, 0);
#endif #endif
while(!done) while(!done)
{ {
int y=0; int y=0;
@ -1639,7 +1646,7 @@ static bool dbg_disk_info(void)
case 2: case 2:
snprintf(buf, sizeof buf, "%ld MB", snprintf(buf, sizeof buf, "%ld MB",
((unsigned long)identify_info[61] << 16 | ((unsigned long)identify_info[61] << 16 |
(unsigned long)identify_info[60]) / 2048 ); (unsigned long)identify_info[60]) / 2048 );
lcd_puts(0, y++, "Size"); lcd_puts(0, y++, "Size");
lcd_puts(0, y++, buf); lcd_puts(0, y++, buf);
@ -1739,7 +1746,7 @@ static bool dbg_disk_info(void)
if (--page < 0) if (--page < 0)
page = max_page; page = max_page;
break; break;
case ACTION_SETTINGS_INC: case ACTION_SETTINGS_INC:
if (++page > max_page) if (++page > max_page)
page = 0; page = 0;
@ -1765,9 +1772,9 @@ static bool dbg_dircache_info(void)
while (!done) while (!done)
{ {
line = 0; line = 0;
lcd_clear_display(); lcd_clear_display();
snprintf(buf, sizeof(buf), "Cache initialized: %s", snprintf(buf, sizeof(buf), "Cache initialized: %s",
dircache_is_enabled() ? "Yes" : "No"); dircache_is_enabled() ? "Yes" : "No");
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
@ -1819,25 +1826,25 @@ static bool dbg_tagcache_info(void)
while (!done) while (!done)
{ {
line = 0; line = 0;
lcd_clear_display(); lcd_clear_display();
stat = tagcache_get_stat(); stat = tagcache_get_stat();
snprintf(buf, sizeof(buf), "Initialized: %s", stat->initialized ? "Yes" : "No"); snprintf(buf, sizeof(buf), "Initialized: %s", stat->initialized ? "Yes" : "No");
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "DB Ready: %s", stat->ready ? "Yes" : "No"); snprintf(buf, sizeof(buf), "DB Ready: %s", stat->ready ? "Yes" : "No");
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "RAM Cache: %s", stat->ramcache ? "Yes" : "No"); snprintf(buf, sizeof(buf), "RAM Cache: %s", stat->ramcache ? "Yes" : "No");
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "RAM: %d/%d B", snprintf(buf, sizeof(buf), "RAM: %d/%d B",
stat->ramcache_used, stat->ramcache_allocated); stat->ramcache_used, stat->ramcache_allocated);
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "Progress: %d%% (%d entries)", snprintf(buf, sizeof(buf), "Progress: %d%% (%d entries)",
stat->progress, stat->processed_entries); stat->progress, stat->processed_entries);
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "Commit step: %d", stat->commit_step); snprintf(buf, sizeof(buf), "Commit step: %d", stat->commit_step);
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "Commit delayed: %s", snprintf(buf, sizeof(buf), "Commit delayed: %s",
stat->commit_delayed ? "Yes" : "No"); stat->commit_delayed ? "Yes" : "No");
lcd_puts(0, line++, buf); lcd_puts(0, line++, buf);
lcd_update(); lcd_update();
@ -1892,7 +1899,7 @@ bool dbg_save_roms(void)
close(fd); close(fd);
} }
system_memory_guard(oldmode); system_memory_guard(oldmode);
#ifdef HAVE_EEPROM #ifdef HAVE_EEPROM
fd = creat("/internal_eeprom.bin", O_WRONLY); fd = creat("/internal_eeprom.bin", O_WRONLY);
if (fd >= 0) if (fd >= 0)
@ -1916,7 +1923,7 @@ bool dbg_save_roms(void)
close(fd); close(fd);
} }
#endif #endif
return false; return false;
} }
#endif /* CPU */ #endif /* CPU */
@ -1938,10 +1945,10 @@ bool dbg_fm_radio(void)
lcd_clear_display(); lcd_clear_display();
fm_detected = radio_hardware_present(); fm_detected = radio_hardware_present();
snprintf(buf, sizeof buf, "HW detected: %s", fm_detected?"yes":"no"); snprintf(buf, sizeof buf, "HW detected: %s", fm_detected?"yes":"no");
lcd_puts(0, row++, buf); lcd_puts(0, row++, buf);
#if (CONFIG_TUNER & S1A0903X01) #if (CONFIG_TUNER & S1A0903X01)
regs = samsung_get(RADIO_ALL); regs = samsung_get(RADIO_ALL);
snprintf(buf, sizeof buf, "Samsung regs: %08lx", regs); snprintf(buf, sizeof buf, "Samsung regs: %08lx", regs);
@ -1954,7 +1961,7 @@ bool dbg_fm_radio(void)
#endif #endif
lcd_update(); lcd_update();
if (action_userabort(HZ)) if (action_userabort(HZ))
return false; return false;
} }
@ -1983,7 +1990,7 @@ bool dbg_set_memory_guard(void)
{ "Zero area (all)", -1 } { "Zero area (all)", -1 }
}; };
int mode = system_memory_guard(MEMGUARD_KEEP); int mode = system_memory_guard(MEMGUARD_KEEP);
set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL); set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
system_memory_guard(mode); system_memory_guard(mode);
@ -1999,7 +2006,7 @@ bool dbg_write_eeprom(void)
int old_irq_level; int old_irq_level;
char buf[EEPROM_SIZE]; char buf[EEPROM_SIZE];
int err; int err;
fd = open("/internal_eeprom.bin", O_RDONLY); fd = open("/internal_eeprom.bin", O_RDONLY);
if (fd >= 0) if (fd >= 0)
@ -2093,7 +2100,7 @@ bool debug_menu(void)
NULL, NULL, NULL); NULL, NULL, NULL);
result = menu_run(m); result = menu_run(m);
menu_exit(m); menu_exit(m);
return result; return result;
} }

View file

@ -151,6 +151,10 @@
#define USBOTG_ISP1362 1362 #define USBOTG_ISP1362 1362
#define USBOTG_M5636 5636 #define USBOTG_M5636 5636
/* Multiple cores */
#define CPU 0
#define COP 1
/* now go and pick yours */ /* now go and pick yours */
#if defined(ARCHOS_PLAYER) #if defined(ARCHOS_PLAYER)
#include "config-player.h" #include "config-player.h"
@ -219,6 +223,19 @@
/* define for all cpus from PP family */ /* define for all cpus from PP family */
#if (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020) || (CONFIG_CPU == PP5024) #if (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020) || (CONFIG_CPU == PP5024)
#define CPU_PP #define CPU_PP
/* PP family has dual cores */
#if 0
/* Keep it as single core until dual core support is ready */
#define NUM_CORES 2
#define CURRENT_CORE current_core()
#endif
#define NUM_CORES 1
#define CURRENT_CORE 0
#else
#define NUM_CORES 1
#define CURRENT_CORE 0
#endif #endif
/* define for all cpus from ARM family */ /* define for all cpus from ARM family */

View file

@ -43,6 +43,8 @@ static inline void udelay(unsigned usecs)
unsigned start = USEC_TIMER; unsigned start = USEC_TIMER;
while ((USEC_TIMER - start) < usecs); while ((USEC_TIMER - start) < usecs);
} }
unsigned int current_core(void);
#endif #endif
struct flash_header { struct flash_header {
@ -88,7 +90,7 @@ void cpu_idle_mode(bool on_off);
#define betoh32(x) swap32(x) #define betoh32(x) swap32(x)
#define htobe16(x) swap16(x) #define htobe16(x) swap16(x)
#define htobe32(x) swap32(x) #define htobe32(x) swap32(x)
#else #else
#define letoh16(x) swap16(x) #define letoh16(x) swap16(x)
#define letoh32(x) swap32(x) #define letoh32(x) swap32(x)
#define htole16(x) swap16(x) #define htole16(x) swap16(x)
@ -178,7 +180,7 @@ static inline void coldfire_set_macsr(unsigned long flags)
static inline unsigned long coldfire_get_macsr(void) static inline unsigned long coldfire_get_macsr(void)
{ {
unsigned long m; unsigned long m;
asm volatile ("move.l %%macsr, %0" : "=r" (m)); asm volatile ("move.l %%macsr, %0" : "=r" (m));
return m; return m;
} }
@ -301,7 +303,7 @@ static inline void invalidate_icache(void)
"move.l #0x80000000,%d0\n" "move.l #0x80000000,%d0\n"
"movec.l %d0,%cacr"); "movec.l %d0,%cacr");
} }
#define CPUFREQ_DEFAULT_MULT 1 #define CPUFREQ_DEFAULT_MULT 1
#define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ) #define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ)
#define CPUFREQ_NORMAL_MULT 4 #define CPUFREQ_NORMAL_MULT 4
@ -315,7 +317,7 @@ static inline void invalidate_icache(void)
#define CPUFREQ_DEFAULT_MULT 8 #define CPUFREQ_DEFAULT_MULT 8
#define CPUFREQ_DEFAULT 24000000 #define CPUFREQ_DEFAULT 24000000
#define CPUFREQ_NORMAL_MULT 10 #define CPUFREQ_NORMAL_MULT 10
#define CPUFREQ_NORMAL 30000000 #define CPUFREQ_NORMAL 30000000
#define CPUFREQ_MAX_MULT 25 #define CPUFREQ_MAX_MULT 25
#define CPUFREQ_MAX 75000000 #define CPUFREQ_MAX 75000000
@ -336,7 +338,7 @@ static inline unsigned long swap32(unsigned long value)
result[15.. 8] = value[23..16]; result[15.. 8] = value[23..16];
result[ 7.. 0] = value[31..24]; result[ 7.. 0] = value[31..24];
*/ */
{ {
unsigned int tmp; unsigned int tmp;
asm volatile ( asm volatile (
@ -418,7 +420,7 @@ static inline int set_irq_level(int level)
__asm__ volatile ("clrsr ie"); __asm__ volatile ("clrsr ie");
else else
__asm__ volatile ("setsr ie"); __asm__ volatile ("setsr ie");
return result; return result;
} }

View file

@ -31,12 +31,16 @@
int create_thread(void (*function)(void), void* stack, int stack_size, int create_thread(void (*function)(void), void* stack, int stack_size,
const char *name); const char *name);
int create_thread_on_core(unsigned int core, void (*function)(void), void* stack, int stack_size,
const char *name);
void remove_thread(int threadnum); void remove_thread(int threadnum);
void remove_thread_on_core(unsigned int core, int threadnum);
void switch_thread(void); void switch_thread(void);
void sleep_thread(void); void sleep_thread(void);
void wake_up_thread(void); void wake_up_thread(void);
void init_threads(void); void init_threads(void);
int thread_stack_usage(int threadnum); int thread_stack_usage(int threadnum);
int thread_stack_usage_on_core(unsigned int core, int threadnum);
#ifdef RB_PROFILE #ifdef RB_PROFILE
void profile_thread(void); void profile_thread(void);
#endif #endif

View file

@ -91,21 +91,21 @@ bool detect_flashed_rockbox(void)
{ {
struct flash_header hdr; struct flash_header hdr;
uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT; uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT;
# ifndef BOOTLOADER # ifndef BOOTLOADER
int oldmode; int oldmode;
oldmode = system_memory_guard(MEMGUARD_NONE); oldmode = system_memory_guard(MEMGUARD_NONE);
# endif # endif
memcpy(&hdr, src, sizeof(struct flash_header)); memcpy(&hdr, src, sizeof(struct flash_header));
# ifndef BOOTLOADER # ifndef BOOTLOADER
system_memory_guard(oldmode); system_memory_guard(oldmode);
# endif # endif
if (hdr.magic != FLASH_MAGIC) if (hdr.magic != FLASH_MAGIC)
return false; return false;
return true; return true;
} }
#else #else
@ -139,13 +139,13 @@ void ddma_transfer(int dir, int mem, void* intAddr, long extAddr, int num) {
/* HW wants those two in word units. */ /* HW wants those two in word units. */
num /= 2; num /= 2;
externalAddress /= 2; externalAddress /= 2;
DDMACFG = (dir << 1) | (mem << 2); DDMACFG = (dir << 1) | (mem << 2);
DDMAIADR = internalAddress; DDMAIADR = internalAddress;
DDMAEADR = externalAddress; DDMAEADR = externalAddress;
DDMANUM = num; DDMANUM = num;
DDMACOM |= 0x4; /* start */ DDMACOM |= 0x4; /* start */
ddma_wait_idle(); /* wait for completion */ ddma_wait_idle(); /* wait for completion */
set_irq_level(irq); set_irq_level(irq);
} }
@ -164,13 +164,13 @@ static void ddma_transfer_noicode(int dir, int mem, long intAddr, long extAddr,
/* HW wants those two in word units. */ /* HW wants those two in word units. */
num /= 2; num /= 2;
externalAddress /= 2; externalAddress /= 2;
DDMACFG = (dir << 1) | (mem << 2); DDMACFG = (dir << 1) | (mem << 2);
DDMAIADR = internalAddress; DDMAIADR = internalAddress;
DDMAEADR = externalAddress; DDMAEADR = externalAddress;
DDMANUM = num; DDMANUM = num;
DDMACOM |= 0x4; /* start */ DDMACOM |= 0x4; /* start */
ddma_wait_idle_noicode(); /* wait for completion */ ddma_wait_idle_noicode(); /* wait for completion */
set_irq_level(irq); set_irq_level(irq);
} }
@ -220,7 +220,7 @@ void smsc_delay() {
Delay doesn't depend on CPU speed in Archos' firmware. Delay doesn't depend on CPU speed in Archos' firmware.
*/ */
for (i = 0; i < 100; i++) { for (i = 0; i < 100; i++) {
} }
} }
@ -228,9 +228,9 @@ static void extra_init(void) {
/* Power on stuff */ /* Power on stuff */
P1 |= 0x07; P1 |= 0x07;
P1CON |= 0x1f; P1CON |= 0x1f;
/* P5 conf /* P5 conf
* lines 0, 1 & 4 are digital, other analog. : * lines 0, 1 & 4 are digital, other analog. :
*/ */
P5CON = 0xec; P5CON = 0xec;
@ -294,21 +294,21 @@ void system_init(void)
/******** /********
* CPU * CPU
*/ */
/* PLL0 (cpu osc. frequency) */ /* PLL0 (cpu osc. frequency) */
/* set_cpu_frequency(CPU_FREQ); */ /* set_cpu_frequency(CPU_FREQ); */
/******************* /*******************
* configure S(D)RAM * configure S(D)RAM
*/ */
/************************ /************************
* Copy .icode section to icram * Copy .icode section to icram
*/ */
ddma_transfer_noicode(0, 0, 0x40, (long)&icodecopy, (int)&icodesize); ddma_transfer_noicode(0, 0, 0x40, (long)&icodecopy, (int)&icodesize);
/*************************** /***************************
* Interrupts * Interrupts
@ -472,12 +472,12 @@ void UIE (void) /* Unexpected Interrupt or Exception */
unsigned int format_vector, pc; unsigned int format_vector, pc;
int vector; int vector;
char str[32]; char str[32];
asm volatile ("move.l (52,%%sp),%0": "=r"(format_vector)); asm volatile ("move.l (52,%%sp),%0": "=r"(format_vector));
asm volatile ("move.l (56,%%sp),%0": "=r"(pc)); asm volatile ("move.l (56,%%sp),%0": "=r"(pc));
vector = (format_vector >> 18) & 0xff; vector = (format_vector >> 18) & 0xff;
/* clear screen */ /* clear screen */
lcd_clear_display (); lcd_clear_display ();
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
@ -488,7 +488,7 @@ void UIE (void) /* Unexpected Interrupt or Exception */
snprintf(str,sizeof(str),"at %08x",pc); snprintf(str,sizeof(str),"at %08x",pc);
lcd_puts(0,1,str); lcd_puts(0,1,str);
lcd_update(); lcd_update();
/* set cpu frequency to 11mhz (to prevent overheating) */ /* set cpu frequency to 11mhz (to prevent overheating) */
DCR = (DCR & ~0x01ff) | 1; DCR = (DCR & ~0x01ff) | 1;
PLLCR = 0x10800000; PLLCR = 0x10800000;
@ -510,7 +510,7 @@ void UIE (void) /* Unexpected Interrupt or Exception */
} }
/* reset vectors are handled in crt0.S */ /* reset vectors are handled in crt0.S */
void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) = void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) =
{ {
UIE,UIE,UIE,UIE,UIE,UIE, UIE,UIE,UIE,UIE,UIE,UIE,
UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
@ -520,7 +520,7 @@ void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) =
TRAP0,TRAP1,TRAP2,TRAP3,TRAP4,TRAP5,TRAP6,TRAP7, TRAP0,TRAP1,TRAP2,TRAP3,TRAP4,TRAP5,TRAP6,TRAP7,
TRAP8,TRAP9,TRAP10,TRAP11,TRAP12,TRAP13,TRAP14,TRAP15, TRAP8,TRAP9,TRAP10,TRAP11,TRAP12,TRAP13,TRAP14,TRAP15,
SWT,UIE,UIE,I2C,UART1,UART2,DMA0,DMA1, SWT,UIE,UIE,I2C,UART1,UART2,DMA0,DMA1,
DMA2,DMA3,QSPI,UIE,UIE,UIE,UIE,UIE, DMA2,DMA3,QSPI,UIE,UIE,UIE,UIE,UIE,
PDIR1FULL,PDIR2FULL,EBUTXEMPTY,IIS2TXEMPTY, PDIR1FULL,PDIR2FULL,EBUTXEMPTY,IIS2TXEMPTY,
@ -741,7 +741,7 @@ static const char* const irqname[] = {
asm ( asm (
/* Vector table. /* Vector table.
* Handled in asm because gcc 4.x doesn't allow weak aliases to symbols * Handled in asm because gcc 4.x doesn't allow weak aliases to symbols
* defined in an asm block -- silly. * defined in an asm block -- silly.
* Reset vectors (0..3) are handled in crt0.S */ * Reset vectors (0..3) are handled in crt0.S */
@ -854,7 +854,7 @@ asm (
RESERVE_INTERRUPT ( 108) RESERVE_INTERRUPT ( 108)
DEFAULT_INTERRUPT (ADITI, 109) DEFAULT_INTERRUPT (ADITI, 109)
/* UIE# block. /* UIE# block.
* Must go into the same section as the UIE() handler */ * Must go into the same section as the UIE() handler */
"\t.text\n" "\t.text\n"
@ -979,7 +979,7 @@ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
char str[32]; char str[32];
asm volatile ("sts\tpr,%0" : "=r"(n)); asm volatile ("sts\tpr,%0" : "=r"(n));
/* clear screen */ /* clear screen */
lcd_clear_display (); lcd_clear_display ();
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
@ -1002,7 +1002,7 @@ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
volatile int i; volatile int i;
led (state); led (state);
state = !state; state = !state;
for (i = 0; i < 240000; ++i); for (i = 0; i < 240000; ++i);
#endif #endif
@ -1018,7 +1018,7 @@ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
#elif CONFIG_KEYPAD == ONDIO_PAD #elif CONFIG_KEYPAD == ONDIO_PAD
if (!(PCDR & 0x0008)) if (!(PCDR & 0x0008))
#endif #endif
{ {
/* enable the watchguard timer, but don't service it */ /* enable the watchguard timer, but don't service it */
RSTCSR_W = 0x5a40; /* Reset enabled, power-on reset */ RSTCSR_W = 0x5a40; /* Reset enabled, power-on reset */
TCSR_W = 0xa560; /* Watchdog timer mode, timer enabled, sysclk/2 */ TCSR_W = 0xa560; /* Watchdog timer mode, timer enabled, sysclk/2 */
@ -1086,7 +1086,7 @@ int system_memory_guard(int newmode)
int oldmode = MEMGUARD_NONE; int oldmode = MEMGUARD_NONE;
int i; int i;
/* figure out the old mode from what is in the UBC regs. If the register /* figure out the old mode from what is in the UBC regs. If the register
values don't match any mode, assume MEMGUARD_NONE */ values don't match any mode, assume MEMGUARD_NONE */
for (i = MEMGUARD_NONE; i < MAXMEMGUARD; i++) for (i = MEMGUARD_NONE; i < MAXMEMGUARD; i++)
@ -1098,7 +1098,7 @@ int system_memory_guard(int newmode)
break; break;
} }
} }
if (newmode == MEMGUARD_KEEP) if (newmode == MEMGUARD_KEEP)
newmode = oldmode; newmode = oldmode;
@ -1109,7 +1109,7 @@ int system_memory_guard(int newmode)
BAR = modes[newmode].addr; BAR = modes[newmode].addr;
BAMR = modes[newmode].mask; BAMR = modes[newmode].mask;
BBR = modes[newmode].bbr; BBR = modes[newmode].bbr;
return oldmode; return oldmode;
} }
#elif defined(CPU_ARM) #elif defined(CPU_ARM)
@ -1124,7 +1124,7 @@ static const char* const uiename[] = {
void UIE(unsigned int pc, unsigned int num) void UIE(unsigned int pc, unsigned int num)
{ {
char str[32]; char str[32];
lcd_clear_display(); lcd_clear_display();
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
lcd_setfont(FONT_SYSFIXED); lcd_setfont(FONT_SYSFIXED);
@ -1133,7 +1133,7 @@ void UIE(unsigned int pc, unsigned int num)
snprintf(str, sizeof(str), "at %08x", pc); snprintf(str, sizeof(str), "at %08x", pc);
lcd_puts(0, 1, str); lcd_puts(0, 1, str);
lcd_update(); lcd_update();
while (1) while (1)
{ {
/* TODO: perhaps add button handling in here when we get a polling /* TODO: perhaps add button handling in here when we get a polling
@ -1160,7 +1160,7 @@ void irq(void)
else if (CPU_INT_STAT & TIMER2_MASK) else if (CPU_INT_STAT & TIMER2_MASK)
TIMER2(); TIMER2();
else if (CPU_HI_INT_STAT & GPIO_MASK) else if (CPU_HI_INT_STAT & GPIO_MASK)
ipod_mini_button_int(); ipod_mini_button_int();
} }
#elif (defined IRIVER_H10) || (defined IRIVER_H10_5GB) #elif (defined IRIVER_H10) || (defined IRIVER_H10_5GB)
/* TODO: this should really be in the target tree, but moving it there caused /* TODO: this should really be in the target tree, but moving it there caused
@ -1170,14 +1170,14 @@ void irq(void)
if (CPU_INT_STAT & TIMER1_MASK) if (CPU_INT_STAT & TIMER1_MASK)
TIMER1(); TIMER1();
else if (CPU_INT_STAT & TIMER2_MASK) else if (CPU_INT_STAT & TIMER2_MASK)
TIMER2(); TIMER2();
} }
#else #else
extern void ipod_4g_button_int(void); extern void ipod_4g_button_int(void);
void irq(void) void irq(void)
{ {
if (CPU_INT_STAT & TIMER1_MASK) if (CPU_INT_STAT & TIMER1_MASK)
TIMER1(); TIMER1();
else if (CPU_INT_STAT & TIMER2_MASK) else if (CPU_INT_STAT & TIMER2_MASK)
TIMER2(); TIMER2();
@ -1187,11 +1187,21 @@ void irq(void)
#endif #endif
#endif /* BOOTLOADER */ #endif /* BOOTLOADER */
unsigned int current_core(void)
{
if(((*(volatile unsigned long *)(0x60000000)) & 0xff) == 0x55)
{
return CPU;
}
return COP;
}
/* TODO: The following two function have been lifted straight from IPL, and /* TODO: The following two function have been lifted straight from IPL, and
hence have a lot of numeric addresses used straight. I'd like to use hence have a lot of numeric addresses used straight. I'd like to use
#defines for these, but don't know what most of them are for or even what #defines for these, but don't know what most of them are for or even what
they should be named. Because of this I also have no way of knowing how they should be named. Because of this I also have no way of knowing how
to extend the funtions to do alternate cache configurations and/or to extend the funtions to do alternate cache configurations and/or
some other CPU frequency scaling. */ some other CPU frequency scaling. */
#ifndef BOOTLOADER #ifndef BOOTLOADER
@ -1251,7 +1261,7 @@ void set_cpu_frequency(long frequency)
#if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) #if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI)
/* We don't know why the timer interrupt gets disabled on the PP5020 /* We don't know why the timer interrupt gets disabled on the PP5020
based ipods, but without the following line, the 4Gs will freeze based ipods, but without the following line, the 4Gs will freeze
when CPU frequency changing is enabled. when CPU frequency changing is enabled.
Note also that a simple "CPU_INT_EN = TIMER1_MASK;" (as used Note also that a simple "CPU_INT_EN = TIMER1_MASK;" (as used
elsewhere to enable interrupts) doesn't work, we need "|=". elsewhere to enable interrupts) doesn't work, we need "|=".
@ -1321,19 +1331,29 @@ extern void TIMER2(void);
void irq(void) void irq(void)
{ {
if (CPU_INT_STAT & TIMER1_MASK) if (CPU_INT_STAT & TIMER1_MASK)
TIMER1(); TIMER1();
else if (CPU_INT_STAT & TIMER2_MASK) else if (CPU_INT_STAT & TIMER2_MASK)
TIMER2(); TIMER2();
} }
#endif #endif
unsigned int current_core(void)
{
if(((*(volatile unsigned long *)(0xc4000000)) & 0xff) == 0x55)
{
return CPU;
}
return COP;
}
/* TODO: The following two function have been lifted straight from IPL, and /* TODO: The following two function have been lifted straight from IPL, and
hence have a lot of numeric addresses used straight. I'd like to use hence have a lot of numeric addresses used straight. I'd like to use
#defines for these, but don't know what most of them are for or even what #defines for these, but don't know what most of them are for or even what
they should be named. Because of this I also have no way of knowing how they should be named. Because of this I also have no way of knowing how
to extend the funtions to do alternate cache configurations and/or to extend the funtions to do alternate cache configurations and/or
some other CPU frequency scaling. */ some other CPU frequency scaling. */
#ifndef BOOTLOADER #ifndef BOOTLOADER
@ -1370,7 +1390,7 @@ void set_cpu_frequency(long frequency)
else else
postmult = CPUFREQ_DEFAULT_MULT; postmult = CPUFREQ_DEFAULT_MULT;
cpu_frequency = frequency; cpu_frequency = frequency;
outl(0x02, 0xcf005008); outl(0x02, 0xcf005008);
outl(0x55, 0xcf00500c); outl(0x55, 0xcf00500c);
outl(0x6000, 0xcf005010); outl(0x6000, 0xcf005010);
@ -1501,7 +1521,7 @@ void system_init(void)
IRQ_WRITE_WAIT(0, 0, v == 0); IRQ_WRITE_WAIT(0, 0, v == 0);
IRQ_WRITE_WAIT(4, 0, v == 0); IRQ_WRITE_WAIT(4, 0, v == 0);
*/ */
for (i = 0; i < 0x1c; i++) for (i = 0; i < 0x1c; i++)
{ {
IRQ_WRITE_WAIT(0x404 + i * 4, 0x1e000001, (v & 0x3010f) == 1); IRQ_WRITE_WAIT(0x404 + i * 4, 0x1e000001, (v & 0x3010f) == 1);

View file

@ -41,7 +41,7 @@ struct regs
void *pr; /* Procedure register */ void *pr; /* Procedure register */
void *start; /* Thread start address, or NULL when started */ void *start; /* Thread start address, or NULL when started */
}; };
#elif defined(CPU_ARM) #elif defined(CPU_ARM)
struct regs struct regs
{ {
unsigned int r[8]; /* Registers r4-r11 */ unsigned int r[8]; /* Registers r4-r11 */
@ -62,18 +62,31 @@ struct regs
/* Cast to the the machine int type, whose size could be < 4. */ /* Cast to the the machine int type, whose size could be < 4. */
int num_threads; int num_threads[NUM_CORES];
static volatile int num_sleepers; static volatile int num_sleepers[NUM_CORES];
static int current_thread; static int current_thread[NUM_CORES];
static struct regs thread_contexts[MAXTHREADS] IBSS_ATTR; static struct regs thread_contexts[NUM_CORES][MAXTHREADS] IBSS_ATTR;
const char *thread_name[MAXTHREADS]; const char *thread_name[NUM_CORES][MAXTHREADS];
void *thread_stack[MAXTHREADS]; void *thread_stack[NUM_CORES][MAXTHREADS];
int thread_stack_size[MAXTHREADS]; int thread_stack_size[NUM_CORES][MAXTHREADS];
static const char main_thread_name[] = "main"; static const char main_thread_name[] = "main";
extern int stackbegin[]; extern int stackbegin[];
extern int stackend[]; extern int stackend[];
#ifdef CPU_PP
#ifndef BOOTLOADER
extern int cop_stackbegin[];
extern int cop_stackend[];
#else
/* The coprocessor stack is not set up in the bootloader code, but the
threading is. No threads are run on the coprocessor, so set up some dummy
stack */
int *cop_stackbegin = stackbegin;
int *cop_stackend = stackend;
#endif
#endif
void switch_thread(void) ICODE_ATTR; void switch_thread(void) ICODE_ATTR;
static inline void store_context(void* addr) __attribute__ ((always_inline)); static inline void store_context(void* addr) __attribute__ ((always_inline));
static inline void load_context(const void* addr) __attribute__ ((always_inline)); static inline void load_context(const void* addr) __attribute__ ((always_inline));
@ -86,7 +99,7 @@ void profile_thread(void) {
#endif #endif
#if defined(CPU_ARM) #if defined(CPU_ARM)
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
* Store non-volatile context. * Store non-volatile context.
*--------------------------------------------------------------------------- *---------------------------------------------------------------------------
*/ */
@ -116,7 +129,7 @@ static inline void load_context(const void* addr)
} }
#elif defined(CPU_COLDFIRE) #elif defined(CPU_COLDFIRE)
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
* Store non-volatile context. * Store non-volatile context.
*--------------------------------------------------------------------------- *---------------------------------------------------------------------------
*/ */
@ -199,7 +212,7 @@ static inline void load_context(const void* addr)
} }
#elif CONFIG_CPU == TCC730 #elif CONFIG_CPU == TCC730
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
* Store non-volatile context. * Store non-volatile context.
*--------------------------------------------------------------------------- *---------------------------------------------------------------------------
*/ */
@ -215,7 +228,7 @@ static inline void load_context(const void* addr)
"push a14\n\t" \ "push a14\n\t" \
"ldw @[%0+0], a15\n\t" : : "a" (addr) ); "ldw @[%0+0], a15\n\t" : : "a" (addr) );
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
* Load non-volatile context. * Load non-volatile context.
*--------------------------------------------------------------------------- *---------------------------------------------------------------------------
*/ */
@ -260,7 +273,7 @@ void switch_thread(void)
#ifdef SIMULATOR #ifdef SIMULATOR
/* Do nothing */ /* Do nothing */
#else #else
while (num_sleepers == num_threads) while (num_sleepers[CURRENT_CORE] == num_threads[CURRENT_CORE])
{ {
/* Enter sleep mode, woken up on interrupt */ /* Enter sleep mode, woken up on interrupt */
#ifdef CPU_COLDFIRE #ifdef CPU_COLDFIRE
@ -284,21 +297,21 @@ void switch_thread(void)
#endif #endif
} }
#endif #endif
current = current_thread; current = current_thread[CURRENT_CORE];
store_context(&thread_contexts[current]); store_context(&thread_contexts[CURRENT_CORE][current]);
#if CONFIG_CPU != TCC730 #if CONFIG_CPU != TCC730
/* Check if the current thread stack is overflown */ /* Check if the current thread stack is overflown */
stackptr = thread_stack[current]; stackptr = thread_stack[CURRENT_CORE][current];
if(stackptr[0] != DEADBEEF) if(stackptr[0] != DEADBEEF)
panicf("Stkov %s", thread_name[current]); panicf("Stkov %s", thread_name[CURRENT_CORE][current]);
#endif #endif
if (++current >= num_threads) if (++current >= num_threads[CURRENT_CORE])
current = 0; current = 0;
current_thread = current; current_thread[CURRENT_CORE] = current;
load_context(&thread_contexts[current]); load_context(&thread_contexts[CURRENT_CORE][current]);
#ifdef RB_PROFILE #ifdef RB_PROFILE
profile_thread_started(current_thread); profile_thread_started(current_thread);
#endif #endif
@ -306,29 +319,42 @@ void switch_thread(void)
void sleep_thread(void) void sleep_thread(void)
{ {
++num_sleepers; ++num_sleepers[CURRENT_CORE];
switch_thread(); switch_thread();
} }
void wake_up_thread(void) void wake_up_thread(void)
{ {
num_sleepers = 0; num_sleepers[CURRENT_CORE] = 0;
} }
/*---------------------------------------------------------------------------
* Create thread. /*---------------------------------------------------------------------------
* Create thread on the current core.
* Return ID if context area could be allocated, else -1. * Return ID if context area could be allocated, else -1.
*--------------------------------------------------------------------------- *---------------------------------------------------------------------------
*/ */
int create_thread(void (*function)(void), void* stack, int stack_size, int create_thread(void (*function)(void), void* stack, int stack_size,
const char *name) const char *name)
{
return create_thread_on_core(CURRENT_CORE, function, stack, stack_size,
name);
}
/*---------------------------------------------------------------------------
* Create thread on a specific core.
* Return ID if context area could be allocated, else -1.
*---------------------------------------------------------------------------
*/
int create_thread_on_core(unsigned int core, void (*function)(void), void* stack, int stack_size,
const char *name)
{ {
unsigned int i; unsigned int i;
unsigned int stacklen; unsigned int stacklen;
unsigned int *stackptr; unsigned int *stackptr;
struct regs *regs; struct regs *regs;
if (num_threads >= MAXTHREADS) if (num_threads[core] >= MAXTHREADS)
return -1; return -1;
/* Munge the stack to make it easy to spot stack overflows */ /* 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,
} }
/* Store interesting information */ /* Store interesting information */
thread_name[num_threads] = name; thread_name[core][num_threads[core]] = name;
thread_stack[num_threads] = stack; thread_stack[core][num_threads[core]] = stack;
thread_stack_size[num_threads] = stack_size; thread_stack_size[core][num_threads[core]] = stack_size;
regs = &thread_contexts[num_threads]; regs = &thread_contexts[core][num_threads[core]];
#if defined(CPU_COLDFIRE) || (CONFIG_CPU == SH7034) || defined(CPU_ARM) #if defined(CPU_COLDFIRE) || (CONFIG_CPU == SH7034) || defined(CPU_ARM)
/* Align stack to an even 32 bit boundary */ /* Align stack to an even 32 bit boundary */
regs->sp = (void*)(((unsigned int)stack + stack_size) & ~3); regs->sp = (void*)(((unsigned int)stack + stack_size) & ~3);
@ -355,65 +381,91 @@ int create_thread(void (*function)(void), void* stack, int stack_size,
regs->start = (void*)function; regs->start = (void*)function;
wake_up_thread(); wake_up_thread();
return num_threads++; /* return the current ID, e.g for remove_thread() */ return num_threads[core]++; /* return the current ID, e.g for remove_thread() */
} }
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
* Remove a thread from the scheduler. * Remove a thread on the current core from the scheduler.
* Parameter is the ID as returned from create_thread(). * Parameter is the ID as returned from create_thread().
*--------------------------------------------------------------------------- *---------------------------------------------------------------------------
*/ */
void remove_thread(int threadnum) void remove_thread(int threadnum)
{
remove_thread_on_core(CURRENT_CORE, threadnum);
}
/*---------------------------------------------------------------------------
* Remove a thread on the specified core from the scheduler.
* Parameters are the core and the ID as returned from create_thread().
*---------------------------------------------------------------------------
*/
void remove_thread_on_core(unsigned int core, int threadnum)
{ {
int i; int i;
if(threadnum >= num_threads) if(threadnum >= num_threads[core])
return; return;
num_threads--; num_threads[core]--;
for (i=threadnum; i<num_threads-1; i++) for (i=threadnum; i<num_threads[core]-1; i++)
{ /* move all entries which are behind */ { /* move all entries which are behind */
thread_name[i] = thread_name[i+1]; thread_name[core][i] = thread_name[core][i+1];
thread_stack[i] = thread_stack[i+1]; thread_stack[core][i] = thread_stack[core][i+1];
thread_stack_size[i] = thread_stack_size[i+1]; thread_stack_size[core][i] = thread_stack_size[core][i+1];
thread_contexts[i] = thread_contexts[i+1]; thread_contexts[core][i] = thread_contexts[core][i+1];
} }
if (current_thread == threadnum) /* deleting the current one? */ if (current_thread[core] == threadnum) /* deleting the current one? */
current_thread = num_threads; /* set beyond last, avoid store harm */ current_thread[core] = num_threads[core]; /* set beyond last, avoid store harm */
else if (current_thread > threadnum) /* within the moved positions? */ else if (current_thread[core] > threadnum) /* within the moved positions? */
current_thread--; /* adjust it, point to same context again */ current_thread[core]--; /* adjust it, point to same context again */
} }
void init_threads(void) void init_threads(void)
{ {
num_threads = 1; /* We have 1 thread to begin with */ unsigned int core = CURRENT_CORE;
current_thread = 0; /* The current thread is number 0 */
thread_name[0] = main_thread_name; num_threads[core] = 1; /* We have 1 thread to begin with */
thread_stack[0] = stackbegin; current_thread[core] = 0; /* The current thread is number 0 */
thread_stack_size[0] = (int)stackend - (int)stackbegin; thread_name[core][0] = main_thread_name;
#if CONFIG_CPU == TCC730 /* In multiple core setups, each core has a different stack. There is probably
thread_contexts[0].started = 1; a much better way to do this. */
#else if(core == CPU)
thread_contexts[0].start = 0; /* thread 0 already running */ {
thread_stack[CPU][0] = stackbegin;
thread_stack_size[CPU][0] = (int)stackend - (int)stackbegin;
} else {
#if NUM_CORES > 1 /* This code path will not be run on single core targets */
thread_stack[COP][0] = cop_stackbegin;
thread_stack_size[COP][0] = (int)cop_stackend - (int)cop_stackbegin;
#endif #endif
num_sleepers = 0; }
#if CONFIG_CPU == TCC730
thread_contexts[core][0].started = 1;
#else
thread_contexts[core][0].start = 0; /* thread 0 already running */
#endif
num_sleepers[core] = 0;
} }
int thread_stack_usage(int threadnum) int thread_stack_usage(int threadnum){
return thread_stack_usage_on_core(CURRENT_CORE, threadnum);
}
int thread_stack_usage_on_core(unsigned int core, int threadnum)
{ {
unsigned int i; unsigned int i;
unsigned int *stackptr = thread_stack[threadnum]; unsigned int *stackptr = thread_stack[core][threadnum];
if(threadnum >= num_threads) if(threadnum >= num_threads[core])
return -1; return -1;
for(i = 0;i < thread_stack_size[threadnum]/sizeof(int);i++) for(i = 0;i < thread_stack_size[core][threadnum]/sizeof(int);i++)
{ {
if(stackptr[i] != DEADBEEF) if(stackptr[i] != DEADBEEF)
break; break;
} }
return ((thread_stack_size[threadnum] - i * sizeof(int)) * 100) / return ((thread_stack_size[core][threadnum] - i * sizeof(int)) * 100) /
thread_stack_size[threadnum]; thread_stack_size[core][threadnum];
} }