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:
parent
e09dc8d513
commit
0aec12f3fd
6 changed files with 309 additions and 207 deletions
|
|
@ -78,8 +78,8 @@
|
|||
/*---------------------------------------------------*/
|
||||
extern char ata_device;
|
||||
extern int ata_io_address;
|
||||
extern int num_threads;
|
||||
extern const char *thread_name[];
|
||||
extern int num_threads[];
|
||||
extern const char *thread_name[][MAXTHREADS];
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
/* Test code!!! */
|
||||
|
|
@ -88,6 +88,8 @@ bool dbg_os(void)
|
|||
char buf[32];
|
||||
int i;
|
||||
int usage;
|
||||
unsigned int core;
|
||||
int line;
|
||||
|
||||
lcd_setmargins(0, 0);
|
||||
lcd_setfont(FONT_SYSFIXED);
|
||||
|
|
@ -95,12 +97,16 @@ bool dbg_os(void)
|
|||
|
||||
while(1)
|
||||
{
|
||||
lcd_puts(0, 0, "Stack usage:");
|
||||
for(i = 0; i < num_threads;i++)
|
||||
lcd_puts(0, 0, "Core and stack usage:");
|
||||
line = 0;
|
||||
for(core = 0; core < NUM_CORES; core++)
|
||||
{
|
||||
usage = thread_stack_usage(i);
|
||||
snprintf(buf, 32, "%s: %d%%", thread_name[i], usage);
|
||||
lcd_puts(0, 1+i, buf);
|
||||
for(i = 0; i < num_threads[core]; i++)
|
||||
{
|
||||
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();
|
||||
|
|
@ -124,10 +130,11 @@ bool dbg_os(void)
|
|||
{
|
||||
lcd_puts(0, 0, "Stack usage");
|
||||
|
||||
/* Only Archos Player uses this - so assume a single core */
|
||||
usage = thread_stack_usage(currval);
|
||||
snprintf(buf, 32, "%d: %d%% ", currval, usage);
|
||||
lcd_puts(0, 1, buf);
|
||||
|
||||
|
||||
button = get_action(CONTEXT_SETTINGS,HZ/10);
|
||||
|
||||
switch(button)
|
||||
|
|
@ -162,14 +169,14 @@ bool dbg_audio_thread(void)
|
|||
|
||||
lcd_setmargins(0, 0);
|
||||
lcd_setfont(FONT_SYSFIXED);
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
if (action_userabort(HZ/5))
|
||||
return false;
|
||||
|
||||
audio_get_debugdata(&d);
|
||||
|
||||
|
||||
lcd_clear_display();
|
||||
|
||||
snprintf(buf, sizeof(buf), "read: %x", d.audiobuf_read);
|
||||
|
|
@ -186,17 +193,17 @@ bool dbg_audio_thread(void)
|
|||
lcd_puts(0, 5, buf);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
snprintf(buf, sizeof(buf), "wm: %x - %x",
|
||||
d.low_watermark_level, d.lowest_watermark_level);
|
||||
lcd_puts(0, 7, buf);
|
||||
|
||||
|
||||
lcd_update();
|
||||
}
|
||||
return false;
|
||||
|
|
@ -229,7 +236,7 @@ bool dbg_audio_thread(void)
|
|||
ticks = boost_ticks = 0;
|
||||
|
||||
tick_add_task(dbg_audio_task);
|
||||
|
||||
|
||||
lcd_setmargins(0, 0);
|
||||
lcd_setfont(FONT_SYSFIXED);
|
||||
while(!done)
|
||||
|
|
@ -249,7 +256,7 @@ bool dbg_audio_thread(void)
|
|||
}
|
||||
action_signalscreenchange();
|
||||
line = 0;
|
||||
|
||||
|
||||
lcd_clear_display();
|
||||
|
||||
bufused = bufsize - pcmbuf_free();
|
||||
|
|
@ -283,12 +290,12 @@ bool dbg_audio_thread(void)
|
|||
snprintf(buf, sizeof(buf), "pcmbufdesc: %2d/%2d",
|
||||
pcmbuf_used_descs(), pcmbufdescs);
|
||||
lcd_puts(0, line++, buf);
|
||||
|
||||
|
||||
lcd_update();
|
||||
}
|
||||
|
||||
tick_remove_task(dbg_audio_task);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif /* CONFIG_CODEC */
|
||||
|
|
@ -303,7 +310,7 @@ static void flash_write_word(unsigned addr, unsigned value) {
|
|||
flash_word_temp = value;
|
||||
|
||||
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")));
|
||||
|
|
@ -324,7 +331,7 @@ bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
|
|||
__attribute__ ((section (".icode")));
|
||||
bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
|
||||
unsigned addr1, unsigned addr2)
|
||||
|
||||
|
||||
{
|
||||
#if (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020)
|
||||
/* 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 */
|
||||
|
||||
set_irq_level(old_level); /* enable interrupts again */
|
||||
|
||||
|
||||
/* 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. */
|
||||
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 */
|
||||
if (!got_id)
|
||||
got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
|
||||
|
||||
|
||||
/* check if the boot ROM area is a flash mirror */
|
||||
has_bootrom = (memcmp((char*)0, (char*)0x02000000, 64*1024) != 0);
|
||||
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);
|
||||
lcd_puts(0, 1, buf);
|
||||
|
||||
|
||||
snprintf(buf, 32, "Mask: 0x%04x", bitmask);
|
||||
lcd_puts(0, 2, buf);
|
||||
|
||||
|
||||
snprintf(buf, 32, "USB: %s", usb_polarity?"positive":"negative");
|
||||
lcd_puts(0, 3, buf);
|
||||
|
||||
|
||||
snprintf(buf, 32, "PR: %s", pr_polarity?"positive":"negative");
|
||||
lcd_puts(0, 4, buf);
|
||||
|
||||
|
||||
if (got_id)
|
||||
snprintf(buf, 32, "Flash: M=%02x D=%02x", manu, id);
|
||||
else
|
||||
|
|
@ -483,7 +490,7 @@ bool dbg_hw_info(void)
|
|||
snprintf(buf, 32, "ATA: 0x%x,%s", ata_io_address,
|
||||
ata_device ? "slave":"master");
|
||||
lcd_puts(0, 7, buf);
|
||||
#endif
|
||||
#endif
|
||||
lcd_update();
|
||||
|
||||
while(1)
|
||||
|
|
@ -503,7 +510,7 @@ bool dbg_hw_info(void)
|
|||
got_id = dbg_flash_id(&manu, &id, 0x5555, 0x2AAA); /* try SST, Atmel, NexFlash */
|
||||
if (!got_id)
|
||||
got_id = dbg_flash_id(&manu, &id, 0x555, 0x2AA); /* try AMD, Macronix */
|
||||
|
||||
|
||||
system_memory_guard(oldmode); /* re-enable memory guard */
|
||||
|
||||
lcd_setmargins(0, 0);
|
||||
|
|
@ -533,7 +540,7 @@ bool dbg_hw_info(void)
|
|||
lcd_clear_display();
|
||||
|
||||
lcd_puts(0, 0, "[Hardware info]");
|
||||
|
||||
|
||||
snprintf(buf, sizeof(buf), "HW rev: 0x%08x", ipod_hw_rev);
|
||||
lcd_puts(0, 1, buf);
|
||||
|
||||
|
|
@ -581,7 +588,7 @@ bool dbg_hw_info(void)
|
|||
/* calculate CRC16 checksum of boot ROM */
|
||||
rom_crc = crc_32((unsigned char*)0x0000, 64*1024, 0xffffffff);
|
||||
}
|
||||
|
||||
|
||||
system_memory_guard(oldmode); /* re-enable memory guard */
|
||||
|
||||
lcd_clear_display();
|
||||
|
|
@ -617,7 +624,7 @@ bool dbg_hw_info(void)
|
|||
{
|
||||
if (rom_crc == 0x56DBA4EE) /* known Version 1 */
|
||||
snprintf(buf, 32, "BootROM: V1");
|
||||
else if (rom_crc == 0x358099E8)
|
||||
else if (rom_crc == 0x358099E8)
|
||||
snprintf(buf, 32, "BootROM: V2");
|
||||
/* alternative boot ROM found in one single player so far */
|
||||
else
|
||||
|
|
@ -626,10 +633,10 @@ bool dbg_hw_info(void)
|
|||
else
|
||||
snprintf(buf, 32, "BootROM: no");
|
||||
}
|
||||
|
||||
|
||||
lcd_puts(0, 1, buf);
|
||||
lcd_update();
|
||||
|
||||
|
||||
button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
|
||||
|
||||
switch(button)
|
||||
|
|
@ -643,7 +650,7 @@ bool dbg_hw_info(void)
|
|||
if(currval < 0)
|
||||
currval = 5;
|
||||
break;
|
||||
|
||||
|
||||
case ACTION_SETTINGS_INC:
|
||||
currval++;
|
||||
if(currval > 5)
|
||||
|
|
@ -677,7 +684,7 @@ bool dbg_partitions(void)
|
|||
snprintf(buf, sizeof buf, "T:%x %ld MB", p->type, p->size / 2048);
|
||||
lcd_puts(0, 1, buf);
|
||||
lcd_update();
|
||||
|
||||
|
||||
button = get_action(CONTEXT_SETTINGS,TIMEOUT_BLOCK);
|
||||
|
||||
switch(button)
|
||||
|
|
@ -691,7 +698,7 @@ bool dbg_partitions(void)
|
|||
if (partition < 0)
|
||||
partition = 3;
|
||||
break;
|
||||
|
||||
|
||||
case ACTION_SETTINGS_INC:
|
||||
partition++;
|
||||
if (partition > 3)
|
||||
|
|
@ -751,22 +758,22 @@ bool dbg_spdif(void)
|
|||
lcd_puts(0, line++, buf);
|
||||
|
||||
line++;
|
||||
|
||||
|
||||
x = control >> 31;
|
||||
snprintf(buf, sizeof(buf), "PRO: %d (%s)",
|
||||
x, x?"Professional":"Consumer");
|
||||
lcd_puts(0, line++, buf);
|
||||
|
||||
|
||||
x = (control >> 30) & 1;
|
||||
snprintf(buf, sizeof(buf), "Audio: %d (%s)",
|
||||
x, x?"Non-PCM":"PCM");
|
||||
lcd_puts(0, line++, buf);
|
||||
|
||||
|
||||
x = (control >> 29) & 1;
|
||||
snprintf(buf, sizeof(buf), "Copy: %d (%s)",
|
||||
x, x?"Permitted":"Inhibited");
|
||||
lcd_puts(0, line++, buf);
|
||||
|
||||
|
||||
x = (control >> 27) & 7;
|
||||
switch(x)
|
||||
{
|
||||
|
|
@ -786,7 +793,7 @@ bool dbg_spdif(void)
|
|||
x = (control >> 24) & 3;
|
||||
snprintf(buf, sizeof(buf), "Mode: %d", x);
|
||||
lcd_puts(0, line++, buf);
|
||||
|
||||
|
||||
category = (control >> 17) & 127;
|
||||
switch(category)
|
||||
{
|
||||
|
|
@ -801,7 +808,7 @@ bool dbg_spdif(void)
|
|||
}
|
||||
snprintf(buf, sizeof(buf), "Category: 0x%02x (%s)", category, s);
|
||||
lcd_puts(0, line++, buf);
|
||||
|
||||
|
||||
x = (control >> 16) & 1;
|
||||
generation = x;
|
||||
if(((category & 0x70) == 0x10) ||
|
||||
|
|
@ -813,11 +820,11 @@ bool dbg_spdif(void)
|
|||
snprintf(buf, sizeof(buf), "Generation: %d (%s)",
|
||||
x, generation?"Original":"No ind.");
|
||||
lcd_puts(0, line++, buf);
|
||||
|
||||
|
||||
x = (control >> 12) & 15;
|
||||
snprintf(buf, sizeof(buf), "Source: %d", x);
|
||||
lcd_puts(0, line++, buf);
|
||||
|
||||
|
||||
x = (control >> 8) & 15;
|
||||
switch(x)
|
||||
{
|
||||
|
|
@ -836,7 +843,7 @@ bool dbg_spdif(void)
|
|||
}
|
||||
snprintf(buf, sizeof(buf), "Channel: %d (%s)", x, s);
|
||||
lcd_puts(0, line++, buf);
|
||||
|
||||
|
||||
x = (control >> 4) & 15;
|
||||
switch(x)
|
||||
{
|
||||
|
|
@ -857,7 +864,7 @@ bool dbg_spdif(void)
|
|||
snprintf(buf, sizeof(buf), "Clock accuracy: %d", x);
|
||||
lcd_puts(0, line++, buf);
|
||||
line++;
|
||||
|
||||
|
||||
snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
|
||||
(long)((long long)FREQMEAS*CPU_FREQ/((1 << 15)*3*(1 << 13))/128));
|
||||
lcd_puts(0, line++, buf);
|
||||
|
|
@ -914,7 +921,7 @@ bool dbg_ports(void)
|
|||
battery_voltage = (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) / 10000;
|
||||
batt_int = battery_voltage / 100;
|
||||
batt_frac = battery_voltage % 100;
|
||||
|
||||
|
||||
snprintf(buf, 32, "Batt: %d.%02dV %d%% ", batt_int, batt_frac,
|
||||
battery_level());
|
||||
lcd_puts(0, 6, buf);
|
||||
|
|
@ -960,7 +967,7 @@ bool dbg_ports(void)
|
|||
gpio1_function = GPIO1_FUNCTION;
|
||||
gpio_enable = GPIO_ENABLE;
|
||||
gpio1_enable = GPIO1_ENABLE;
|
||||
|
||||
|
||||
snprintf(buf, sizeof(buf), "GPIO_READ: %08x", gpio_read);
|
||||
lcd_puts(0, line++, buf);
|
||||
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)
|
||||
adc_remotedetect = adc_read(ADC_REMOTEDETECT);
|
||||
#endif
|
||||
|
||||
|
||||
snprintf(buf, sizeof(buf), "ADC_BUTTONS: %02x", adc_buttons);
|
||||
lcd_puts(0, line++, buf);
|
||||
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;
|
||||
batt_int = battery_voltage / 100;
|
||||
batt_frac = battery_voltage % 100;
|
||||
|
||||
|
||||
snprintf(buf, 32, "Batt: %d.%02dV %d%% ", batt_int, batt_frac,
|
||||
battery_level());
|
||||
lcd_puts(0, line++, buf);
|
||||
|
||||
|
||||
#if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
|
||||
snprintf(buf, sizeof(buf), "remotetype:: %d", remote_type());
|
||||
lcd_puts(0, line++, buf);
|
||||
#endif
|
||||
|
||||
|
||||
lcd_update();
|
||||
if (action_userabort(HZ/10))
|
||||
return false;
|
||||
|
|
@ -1128,15 +1135,15 @@ bool dbg_ports(void)
|
|||
break;
|
||||
}
|
||||
lcd_puts(0, 0, buf);
|
||||
|
||||
battery_voltage = (adc_read(ADC_UNREG_POWER) *
|
||||
|
||||
battery_voltage = (adc_read(ADC_UNREG_POWER) *
|
||||
BATTERY_SCALE_FACTOR) / 10000;
|
||||
batt_int = battery_voltage / 100;
|
||||
batt_frac = battery_voltage % 100;
|
||||
|
||||
|
||||
snprintf(buf, 32, "Batt: %d.%02dV", batt_int, batt_frac);
|
||||
lcd_puts(0, 1, buf);
|
||||
|
||||
|
||||
button = get_action(CONTEXT_SETTINGS,HZ/5);
|
||||
|
||||
switch(button)
|
||||
|
|
@ -1179,7 +1186,7 @@ bool dbg_cpufreq(void)
|
|||
while(1)
|
||||
{
|
||||
line = 0;
|
||||
|
||||
|
||||
snprintf(buf, sizeof(buf), "Frequency: %ld", FREQ);
|
||||
lcd_puts(0, line++, buf);
|
||||
|
||||
|
|
@ -1212,7 +1219,7 @@ bool dbg_cpufreq(void)
|
|||
return false;
|
||||
}
|
||||
#endif /* HAVE_ADJUSTABLE_CPU_FREQ */
|
||||
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
/*
|
||||
* view_battery() shows a automatically scaled graph of the battery voltage
|
||||
|
|
@ -1229,7 +1236,7 @@ bool view_battery(void)
|
|||
int i, x, y;
|
||||
unsigned short maxv, minv;
|
||||
char buf[32];
|
||||
|
||||
|
||||
lcd_setmargins(0, 0);
|
||||
lcd_setfont(FONT_SYSFIXED);
|
||||
|
||||
|
|
@ -1248,20 +1255,20 @@ bool view_battery(void)
|
|||
minv = power_history[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((minv < 1) || (minv >= 65535))
|
||||
minv = 1;
|
||||
if (maxv < 2)
|
||||
maxv = 2;
|
||||
|
||||
|
||||
lcd_clear_display();
|
||||
snprintf(buf, 30, "Battery %d.%02d", power_history[0] / 100,
|
||||
power_history[0] % 100);
|
||||
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);
|
||||
lcd_puts(0, 1, buf);
|
||||
|
||||
|
||||
x = 0;
|
||||
for (i = BAT_LAST_VAL - 1; i >= 0; i--) {
|
||||
y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv);
|
||||
|
|
@ -1274,7 +1281,7 @@ bool view_battery(void)
|
|||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case 1: /* status: */
|
||||
lcd_clear_display();
|
||||
lcd_puts(0, 0, "Power status:");
|
||||
|
|
@ -1289,7 +1296,7 @@ bool view_battery(void)
|
|||
#endif
|
||||
#ifdef CONFIG_CHARGING
|
||||
#if CONFIG_CHARGING == CHARGING_CONTROL
|
||||
snprintf(buf, 30, "Chgr: %s %s",
|
||||
snprintf(buf, 30, "Chgr: %s %s",
|
||||
charger_inserted() ? "present" : "absent",
|
||||
charger_enabled ? "on" : "off");
|
||||
lcd_puts(0, 3, buf);
|
||||
|
|
@ -1329,15 +1336,15 @@ bool view_battery(void)
|
|||
#endif /* CONFIG_CHARGING != CHARGING_CONTROL */
|
||||
#endif /* CONFIG_CHARGING */
|
||||
break;
|
||||
|
||||
|
||||
case 2: /* voltage deltas: */
|
||||
lcd_clear_display();
|
||||
lcd_puts(0, 0, "Voltage deltas:");
|
||||
|
||||
|
||||
for (i = 0; i <= 6; i++) {
|
||||
y = power_history[i] - power_history[i+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);
|
||||
lcd_puts(0, i+1, buf);
|
||||
}
|
||||
|
|
@ -1375,21 +1382,21 @@ bool view_battery(void)
|
|||
lcd_puts(0, 7, buf);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
lcd_update();
|
||||
|
||||
|
||||
switch(get_action(CONTEXT_SETTINGS,HZ/2))
|
||||
{
|
||||
case ACTION_SETTINGS_DEC:
|
||||
if (view)
|
||||
view--;
|
||||
break;
|
||||
|
||||
|
||||
case ACTION_SETTINGS_INC:
|
||||
if (view < 3)
|
||||
view++;
|
||||
break;
|
||||
|
||||
|
||||
case ACTION_STD_CANCEL:
|
||||
action_signalscreenchange();
|
||||
return false;
|
||||
|
|
@ -1399,7 +1406,7 @@ bool view_battery(void)
|
|||
}
|
||||
|
||||
#endif /* HAVE_LCD_BITMAP */
|
||||
|
||||
|
||||
static bool view_runtime(void)
|
||||
{
|
||||
char s[32];
|
||||
|
|
@ -1441,7 +1448,7 @@ static bool view_runtime(void)
|
|||
t = global_settings.topruntime;
|
||||
lcd_puts(0, y++, "Top time");
|
||||
}
|
||||
|
||||
|
||||
snprintf(s, sizeof(s), "%dh %dm %ds",
|
||||
t / 3600, (t % 3600) / 60, t % 60);
|
||||
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 *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
|
||||
static const unsigned char *nsec_units[] = { "ns", "µs", "ms" };
|
||||
|
||||
|
||||
card_name[6] = '\0';
|
||||
|
||||
lcd_setmargins(0, 0);
|
||||
|
|
@ -1574,7 +1581,7 @@ bool dbg_mmc_info(void)
|
|||
case ACTION_STD_CANCEL:
|
||||
done = true;
|
||||
break;
|
||||
|
||||
|
||||
case ACTION_SETTINGS_DEC:
|
||||
currval--;
|
||||
if (currval < 0)
|
||||
|
|
@ -1606,7 +1613,7 @@ static bool dbg_disk_info(void)
|
|||
#ifdef HAVE_LCD_BITMAP
|
||||
lcd_setmargins(0, 0);
|
||||
#endif
|
||||
|
||||
|
||||
while(!done)
|
||||
{
|
||||
int y=0;
|
||||
|
|
@ -1639,7 +1646,7 @@ static bool dbg_disk_info(void)
|
|||
|
||||
case 2:
|
||||
snprintf(buf, sizeof buf, "%ld MB",
|
||||
((unsigned long)identify_info[61] << 16 |
|
||||
((unsigned long)identify_info[61] << 16 |
|
||||
(unsigned long)identify_info[60]) / 2048 );
|
||||
lcd_puts(0, y++, "Size");
|
||||
lcd_puts(0, y++, buf);
|
||||
|
|
@ -1739,7 +1746,7 @@ static bool dbg_disk_info(void)
|
|||
if (--page < 0)
|
||||
page = max_page;
|
||||
break;
|
||||
|
||||
|
||||
case ACTION_SETTINGS_INC:
|
||||
if (++page > max_page)
|
||||
page = 0;
|
||||
|
|
@ -1765,9 +1772,9 @@ static bool dbg_dircache_info(void)
|
|||
while (!done)
|
||||
{
|
||||
line = 0;
|
||||
|
||||
|
||||
lcd_clear_display();
|
||||
snprintf(buf, sizeof(buf), "Cache initialized: %s",
|
||||
snprintf(buf, sizeof(buf), "Cache initialized: %s",
|
||||
dircache_is_enabled() ? "Yes" : "No");
|
||||
lcd_puts(0, line++, buf);
|
||||
|
||||
|
|
@ -1819,25 +1826,25 @@ static bool dbg_tagcache_info(void)
|
|||
while (!done)
|
||||
{
|
||||
line = 0;
|
||||
|
||||
|
||||
lcd_clear_display();
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
snprintf(buf, sizeof(buf), "RAM: %d/%d B",
|
||||
stat->ramcache_used, stat->ramcache_allocated);
|
||||
snprintf(buf, sizeof(buf), "RAM: %d/%d B",
|
||||
stat->ramcache_used, stat->ramcache_allocated);
|
||||
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);
|
||||
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);
|
||||
snprintf(buf, sizeof(buf), "Commit delayed: %s",
|
||||
stat->commit_delayed ? "Yes" : "No");
|
||||
snprintf(buf, sizeof(buf), "Commit delayed: %s",
|
||||
stat->commit_delayed ? "Yes" : "No");
|
||||
lcd_puts(0, line++, buf);
|
||||
|
||||
lcd_update();
|
||||
|
|
@ -1892,7 +1899,7 @@ bool dbg_save_roms(void)
|
|||
close(fd);
|
||||
}
|
||||
system_memory_guard(oldmode);
|
||||
|
||||
|
||||
#ifdef HAVE_EEPROM
|
||||
fd = creat("/internal_eeprom.bin", O_WRONLY);
|
||||
if (fd >= 0)
|
||||
|
|
@ -1916,7 +1923,7 @@ bool dbg_save_roms(void)
|
|||
close(fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif /* CPU */
|
||||
|
|
@ -1938,10 +1945,10 @@ bool dbg_fm_radio(void)
|
|||
|
||||
lcd_clear_display();
|
||||
fm_detected = radio_hardware_present();
|
||||
|
||||
|
||||
snprintf(buf, sizeof buf, "HW detected: %s", fm_detected?"yes":"no");
|
||||
lcd_puts(0, row++, buf);
|
||||
|
||||
|
||||
#if (CONFIG_TUNER & S1A0903X01)
|
||||
regs = samsung_get(RADIO_ALL);
|
||||
snprintf(buf, sizeof buf, "Samsung regs: %08lx", regs);
|
||||
|
|
@ -1954,7 +1961,7 @@ bool dbg_fm_radio(void)
|
|||
#endif
|
||||
|
||||
lcd_update();
|
||||
|
||||
|
||||
if (action_userabort(HZ))
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1983,7 +1990,7 @@ bool dbg_set_memory_guard(void)
|
|||
{ "Zero area (all)", -1 }
|
||||
};
|
||||
int mode = system_memory_guard(MEMGUARD_KEEP);
|
||||
|
||||
|
||||
set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
|
||||
system_memory_guard(mode);
|
||||
|
||||
|
|
@ -1999,7 +2006,7 @@ bool dbg_write_eeprom(void)
|
|||
int old_irq_level;
|
||||
char buf[EEPROM_SIZE];
|
||||
int err;
|
||||
|
||||
|
||||
fd = open("/internal_eeprom.bin", O_RDONLY);
|
||||
|
||||
if (fd >= 0)
|
||||
|
|
@ -2093,7 +2100,7 @@ bool debug_menu(void)
|
|||
NULL, NULL, NULL);
|
||||
result = menu_run(m);
|
||||
menu_exit(m);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -151,6 +151,10 @@
|
|||
#define USBOTG_ISP1362 1362
|
||||
#define USBOTG_M5636 5636
|
||||
|
||||
/* Multiple cores */
|
||||
#define CPU 0
|
||||
#define COP 1
|
||||
|
||||
/* now go and pick yours */
|
||||
#if defined(ARCHOS_PLAYER)
|
||||
#include "config-player.h"
|
||||
|
|
@ -219,6 +223,19 @@
|
|||
/* define for all cpus from PP family */
|
||||
#if (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020) || (CONFIG_CPU == PP5024)
|
||||
#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
|
||||
|
||||
/* define for all cpus from ARM family */
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ static inline void udelay(unsigned usecs)
|
|||
unsigned start = USEC_TIMER;
|
||||
while ((USEC_TIMER - start) < usecs);
|
||||
}
|
||||
|
||||
unsigned int current_core(void);
|
||||
#endif
|
||||
|
||||
struct flash_header {
|
||||
|
|
@ -88,7 +90,7 @@ void cpu_idle_mode(bool on_off);
|
|||
#define betoh32(x) swap32(x)
|
||||
#define htobe16(x) swap16(x)
|
||||
#define htobe32(x) swap32(x)
|
||||
#else
|
||||
#else
|
||||
#define letoh16(x) swap16(x)
|
||||
#define letoh32(x) swap32(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)
|
||||
{
|
||||
unsigned long m;
|
||||
|
||||
|
||||
asm volatile ("move.l %%macsr, %0" : "=r" (m));
|
||||
return m;
|
||||
}
|
||||
|
|
@ -301,7 +303,7 @@ static inline void invalidate_icache(void)
|
|||
"move.l #0x80000000,%d0\n"
|
||||
"movec.l %d0,%cacr");
|
||||
}
|
||||
|
||||
|
||||
#define CPUFREQ_DEFAULT_MULT 1
|
||||
#define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ)
|
||||
#define CPUFREQ_NORMAL_MULT 4
|
||||
|
|
@ -315,7 +317,7 @@ static inline void invalidate_icache(void)
|
|||
|
||||
#define CPUFREQ_DEFAULT_MULT 8
|
||||
#define CPUFREQ_DEFAULT 24000000
|
||||
#define CPUFREQ_NORMAL_MULT 10
|
||||
#define CPUFREQ_NORMAL_MULT 10
|
||||
#define CPUFREQ_NORMAL 30000000
|
||||
#define CPUFREQ_MAX_MULT 25
|
||||
#define CPUFREQ_MAX 75000000
|
||||
|
|
@ -336,7 +338,7 @@ static inline unsigned long swap32(unsigned long value)
|
|||
result[15.. 8] = value[23..16];
|
||||
result[ 7.. 0] = value[31..24];
|
||||
*/
|
||||
{
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
asm volatile (
|
||||
|
|
@ -418,7 +420,7 @@ static inline int set_irq_level(int level)
|
|||
__asm__ volatile ("clrsr ie");
|
||||
else
|
||||
__asm__ volatile ("setsr ie");
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,12 +31,16 @@
|
|||
|
||||
int create_thread(void (*function)(void), void* stack, int stack_size,
|
||||
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_on_core(unsigned int core, int threadnum);
|
||||
void switch_thread(void);
|
||||
void sleep_thread(void);
|
||||
void wake_up_thread(void);
|
||||
void init_threads(void);
|
||||
int thread_stack_usage(int threadnum);
|
||||
int thread_stack_usage_on_core(unsigned int core, int threadnum);
|
||||
#ifdef RB_PROFILE
|
||||
void profile_thread(void);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -91,21 +91,21 @@ bool detect_flashed_rockbox(void)
|
|||
{
|
||||
struct flash_header hdr;
|
||||
uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT;
|
||||
|
||||
|
||||
# ifndef BOOTLOADER
|
||||
int oldmode;
|
||||
oldmode = system_memory_guard(MEMGUARD_NONE);
|
||||
# endif
|
||||
|
||||
|
||||
memcpy(&hdr, src, sizeof(struct flash_header));
|
||||
|
||||
|
||||
# ifndef BOOTLOADER
|
||||
system_memory_guard(oldmode);
|
||||
# endif
|
||||
|
||||
|
||||
if (hdr.magic != FLASH_MAGIC)
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
#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. */
|
||||
num /= 2;
|
||||
externalAddress /= 2;
|
||||
|
||||
|
||||
DDMACFG = (dir << 1) | (mem << 2);
|
||||
DDMAIADR = internalAddress;
|
||||
DDMAEADR = externalAddress;
|
||||
DDMANUM = num;
|
||||
DDMACOM |= 0x4; /* start */
|
||||
|
||||
|
||||
ddma_wait_idle(); /* wait for completion */
|
||||
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. */
|
||||
num /= 2;
|
||||
externalAddress /= 2;
|
||||
|
||||
|
||||
DDMACFG = (dir << 1) | (mem << 2);
|
||||
DDMAIADR = internalAddress;
|
||||
DDMAEADR = externalAddress;
|
||||
DDMANUM = num;
|
||||
DDMACOM |= 0x4; /* start */
|
||||
|
||||
|
||||
ddma_wait_idle_noicode(); /* wait for completion */
|
||||
set_irq_level(irq);
|
||||
}
|
||||
|
|
@ -220,7 +220,7 @@ void smsc_delay() {
|
|||
Delay doesn't depend on CPU speed in Archos' firmware.
|
||||
*/
|
||||
for (i = 0; i < 100; i++) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -228,9 +228,9 @@ static void extra_init(void) {
|
|||
/* Power on stuff */
|
||||
P1 |= 0x07;
|
||||
P1CON |= 0x1f;
|
||||
|
||||
|
||||
/* P5 conf
|
||||
* lines 0, 1 & 4 are digital, other analog. :
|
||||
* lines 0, 1 & 4 are digital, other analog. :
|
||||
*/
|
||||
P5CON = 0xec;
|
||||
|
||||
|
|
@ -294,21 +294,21 @@ void system_init(void)
|
|||
/********
|
||||
* CPU
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/* PLL0 (cpu osc. frequency) */
|
||||
/* set_cpu_frequency(CPU_FREQ); */
|
||||
|
||||
|
||||
/*******************
|
||||
* configure S(D)RAM
|
||||
* configure S(D)RAM
|
||||
*/
|
||||
|
||||
/************************
|
||||
* Copy .icode section to icram
|
||||
*/
|
||||
ddma_transfer_noicode(0, 0, 0x40, (long)&icodecopy, (int)&icodesize);
|
||||
|
||||
|
||||
|
||||
/***************************
|
||||
* Interrupts
|
||||
|
|
@ -472,12 +472,12 @@ void UIE (void) /* Unexpected Interrupt or Exception */
|
|||
unsigned int format_vector, pc;
|
||||
int vector;
|
||||
char str[32];
|
||||
|
||||
|
||||
asm volatile ("move.l (52,%%sp),%0": "=r"(format_vector));
|
||||
asm volatile ("move.l (56,%%sp),%0": "=r"(pc));
|
||||
|
||||
vector = (format_vector >> 18) & 0xff;
|
||||
|
||||
|
||||
/* clear screen */
|
||||
lcd_clear_display ();
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
|
|
@ -488,7 +488,7 @@ void UIE (void) /* Unexpected Interrupt or Exception */
|
|||
snprintf(str,sizeof(str),"at %08x",pc);
|
||||
lcd_puts(0,1,str);
|
||||
lcd_update();
|
||||
|
||||
|
||||
/* set cpu frequency to 11mhz (to prevent overheating) */
|
||||
DCR = (DCR & ~0x01ff) | 1;
|
||||
PLLCR = 0x10800000;
|
||||
|
|
@ -510,7 +510,7 @@ void UIE (void) /* Unexpected Interrupt or Exception */
|
|||
}
|
||||
|
||||
/* 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,
|
||||
|
|
@ -520,7 +520,7 @@ void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) =
|
|||
|
||||
TRAP0,TRAP1,TRAP2,TRAP3,TRAP4,TRAP5,TRAP6,TRAP7,
|
||||
TRAP8,TRAP9,TRAP10,TRAP11,TRAP12,TRAP13,TRAP14,TRAP15,
|
||||
|
||||
|
||||
SWT,UIE,UIE,I2C,UART1,UART2,DMA0,DMA1,
|
||||
DMA2,DMA3,QSPI,UIE,UIE,UIE,UIE,UIE,
|
||||
PDIR1FULL,PDIR2FULL,EBUTXEMPTY,IIS2TXEMPTY,
|
||||
|
|
@ -741,7 +741,7 @@ static const char* const irqname[] = {
|
|||
|
||||
asm (
|
||||
|
||||
/* Vector table.
|
||||
/* Vector table.
|
||||
* Handled in asm because gcc 4.x doesn't allow weak aliases to symbols
|
||||
* defined in an asm block -- silly.
|
||||
* Reset vectors (0..3) are handled in crt0.S */
|
||||
|
|
@ -854,7 +854,7 @@ asm (
|
|||
RESERVE_INTERRUPT ( 108)
|
||||
DEFAULT_INTERRUPT (ADITI, 109)
|
||||
|
||||
/* UIE# block.
|
||||
/* UIE# block.
|
||||
* Must go into the same section as the UIE() handler */
|
||||
|
||||
"\t.text\n"
|
||||
|
|
@ -979,7 +979,7 @@ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
|
|||
char str[32];
|
||||
|
||||
asm volatile ("sts\tpr,%0" : "=r"(n));
|
||||
|
||||
|
||||
/* clear screen */
|
||||
lcd_clear_display ();
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
|
|
@ -1002,7 +1002,7 @@ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
|
|||
volatile int i;
|
||||
led (state);
|
||||
state = !state;
|
||||
|
||||
|
||||
for (i = 0; i < 240000; ++i);
|
||||
#endif
|
||||
|
||||
|
|
@ -1018,7 +1018,7 @@ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
|
|||
#elif CONFIG_KEYPAD == ONDIO_PAD
|
||||
if (!(PCDR & 0x0008))
|
||||
#endif
|
||||
{
|
||||
{
|
||||
/* enable the watchguard timer, but don't service it */
|
||||
RSTCSR_W = 0x5a40; /* Reset enabled, power-on reset */
|
||||
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 i;
|
||||
|
||||
|
||||
/* figure out the old mode from what is in the UBC regs. If the register
|
||||
values don't match any mode, assume MEMGUARD_NONE */
|
||||
for (i = MEMGUARD_NONE; i < MAXMEMGUARD; i++)
|
||||
|
|
@ -1098,7 +1098,7 @@ int system_memory_guard(int newmode)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (newmode == MEMGUARD_KEEP)
|
||||
newmode = oldmode;
|
||||
|
||||
|
|
@ -1109,7 +1109,7 @@ int system_memory_guard(int newmode)
|
|||
BAR = modes[newmode].addr;
|
||||
BAMR = modes[newmode].mask;
|
||||
BBR = modes[newmode].bbr;
|
||||
|
||||
|
||||
return oldmode;
|
||||
}
|
||||
#elif defined(CPU_ARM)
|
||||
|
|
@ -1124,7 +1124,7 @@ static const char* const uiename[] = {
|
|||
void UIE(unsigned int pc, unsigned int num)
|
||||
{
|
||||
char str[32];
|
||||
|
||||
|
||||
lcd_clear_display();
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
lcd_setfont(FONT_SYSFIXED);
|
||||
|
|
@ -1133,7 +1133,7 @@ void UIE(unsigned int pc, unsigned int num)
|
|||
snprintf(str, sizeof(str), "at %08x", pc);
|
||||
lcd_puts(0, 1, str);
|
||||
lcd_update();
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* 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)
|
||||
TIMER2();
|
||||
else if (CPU_HI_INT_STAT & GPIO_MASK)
|
||||
ipod_mini_button_int();
|
||||
ipod_mini_button_int();
|
||||
}
|
||||
#elif (defined IRIVER_H10) || (defined IRIVER_H10_5GB)
|
||||
/* 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)
|
||||
TIMER1();
|
||||
else if (CPU_INT_STAT & TIMER2_MASK)
|
||||
TIMER2();
|
||||
TIMER2();
|
||||
}
|
||||
#else
|
||||
extern void ipod_4g_button_int(void);
|
||||
|
||||
void irq(void)
|
||||
{
|
||||
if (CPU_INT_STAT & TIMER1_MASK)
|
||||
if (CPU_INT_STAT & TIMER1_MASK)
|
||||
TIMER1();
|
||||
else if (CPU_INT_STAT & TIMER2_MASK)
|
||||
TIMER2();
|
||||
|
|
@ -1187,11 +1187,21 @@ void irq(void)
|
|||
#endif
|
||||
#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
|
||||
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
|
||||
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. */
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
|
|
@ -1251,7 +1261,7 @@ void set_cpu_frequency(long frequency)
|
|||
#if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI)
|
||||
/* We don't know why the timer interrupt gets disabled on the PP5020
|
||||
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
|
||||
elsewhere to enable interrupts) doesn't work, we need "|=".
|
||||
|
|
@ -1321,19 +1331,29 @@ extern void TIMER2(void);
|
|||
|
||||
void irq(void)
|
||||
{
|
||||
if (CPU_INT_STAT & TIMER1_MASK)
|
||||
if (CPU_INT_STAT & TIMER1_MASK)
|
||||
TIMER1();
|
||||
else if (CPU_INT_STAT & TIMER2_MASK)
|
||||
else if (CPU_INT_STAT & TIMER2_MASK)
|
||||
TIMER2();
|
||||
}
|
||||
|
||||
#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
|
||||
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
|
||||
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. */
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
|
|
@ -1370,7 +1390,7 @@ void set_cpu_frequency(long frequency)
|
|||
else
|
||||
postmult = CPUFREQ_DEFAULT_MULT;
|
||||
cpu_frequency = frequency;
|
||||
|
||||
|
||||
outl(0x02, 0xcf005008);
|
||||
outl(0x55, 0xcf00500c);
|
||||
outl(0x6000, 0xcf005010);
|
||||
|
|
@ -1501,7 +1521,7 @@ void system_init(void)
|
|||
IRQ_WRITE_WAIT(0, 0, v == 0);
|
||||
IRQ_WRITE_WAIT(4, 0, v == 0);
|
||||
*/
|
||||
|
||||
|
||||
for (i = 0; i < 0x1c; i++)
|
||||
{
|
||||
IRQ_WRITE_WAIT(0x404 + i * 4, 0x1e000001, (v & 0x3010f) == 1);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ struct regs
|
|||
void *pr; /* Procedure register */
|
||||
void *start; /* Thread start address, or NULL when started */
|
||||
};
|
||||
#elif defined(CPU_ARM)
|
||||
#elif defined(CPU_ARM)
|
||||
struct regs
|
||||
{
|
||||
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. */
|
||||
|
||||
|
||||
int num_threads;
|
||||
static volatile int num_sleepers;
|
||||
static int current_thread;
|
||||
static struct regs thread_contexts[MAXTHREADS] IBSS_ATTR;
|
||||
const char *thread_name[MAXTHREADS];
|
||||
void *thread_stack[MAXTHREADS];
|
||||
int thread_stack_size[MAXTHREADS];
|
||||
int num_threads[NUM_CORES];
|
||||
static volatile int num_sleepers[NUM_CORES];
|
||||
static int current_thread[NUM_CORES];
|
||||
static struct regs thread_contexts[NUM_CORES][MAXTHREADS] IBSS_ATTR;
|
||||
const char *thread_name[NUM_CORES][MAXTHREADS];
|
||||
void *thread_stack[NUM_CORES][MAXTHREADS];
|
||||
int thread_stack_size[NUM_CORES][MAXTHREADS];
|
||||
static const char main_thread_name[] = "main";
|
||||
|
||||
extern int stackbegin[];
|
||||
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;
|
||||
static inline void store_context(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
|
||||
|
||||
#if defined(CPU_ARM)
|
||||
/*---------------------------------------------------------------------------
|
||||
/*---------------------------------------------------------------------------
|
||||
* Store non-volatile context.
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
|
@ -116,7 +129,7 @@ static inline void load_context(const void* addr)
|
|||
}
|
||||
|
||||
#elif defined(CPU_COLDFIRE)
|
||||
/*---------------------------------------------------------------------------
|
||||
/*---------------------------------------------------------------------------
|
||||
* Store non-volatile context.
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
|
@ -199,7 +212,7 @@ static inline void load_context(const void* addr)
|
|||
}
|
||||
|
||||
#elif CONFIG_CPU == TCC730
|
||||
/*---------------------------------------------------------------------------
|
||||
/*---------------------------------------------------------------------------
|
||||
* Store non-volatile context.
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
|
@ -215,7 +228,7 @@ static inline void load_context(const void* addr)
|
|||
"push a14\n\t" \
|
||||
"ldw @[%0+0], a15\n\t" : : "a" (addr) );
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
/*---------------------------------------------------------------------------
|
||||
* Load non-volatile context.
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
|
@ -260,7 +273,7 @@ void switch_thread(void)
|
|||
#ifdef SIMULATOR
|
||||
/* Do nothing */
|
||||
#else
|
||||
while (num_sleepers == num_threads)
|
||||
while (num_sleepers[CURRENT_CORE] == num_threads[CURRENT_CORE])
|
||||
{
|
||||
/* Enter sleep mode, woken up on interrupt */
|
||||
#ifdef CPU_COLDFIRE
|
||||
|
|
@ -284,21 +297,21 @@ void switch_thread(void)
|
|||
#endif
|
||||
}
|
||||
#endif
|
||||
current = current_thread;
|
||||
store_context(&thread_contexts[current]);
|
||||
|
||||
current = current_thread[CURRENT_CORE];
|
||||
store_context(&thread_contexts[CURRENT_CORE][current]);
|
||||
|
||||
#if CONFIG_CPU != TCC730
|
||||
/* Check if the current thread stack is overflown */
|
||||
stackptr = thread_stack[current];
|
||||
stackptr = thread_stack[CURRENT_CORE][current];
|
||||
if(stackptr[0] != DEADBEEF)
|
||||
panicf("Stkov %s", thread_name[current]);
|
||||
panicf("Stkov %s", thread_name[CURRENT_CORE][current]);
|
||||
#endif
|
||||
|
||||
if (++current >= num_threads)
|
||||
if (++current >= num_threads[CURRENT_CORE])
|
||||
current = 0;
|
||||
|
||||
current_thread = current;
|
||||
load_context(&thread_contexts[current]);
|
||||
current_thread[CURRENT_CORE] = current;
|
||||
load_context(&thread_contexts[CURRENT_CORE][current]);
|
||||
#ifdef RB_PROFILE
|
||||
profile_thread_started(current_thread);
|
||||
#endif
|
||||
|
|
@ -306,29 +319,42 @@ void switch_thread(void)
|
|||
|
||||
void sleep_thread(void)
|
||||
{
|
||||
++num_sleepers;
|
||||
++num_sleepers[CURRENT_CORE];
|
||||
switch_thread();
|
||||
}
|
||||
|
||||
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.
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
int create_thread(void (*function)(void), void* stack, int stack_size,
|
||||
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 stacklen;
|
||||
unsigned int *stackptr;
|
||||
struct regs *regs;
|
||||
|
||||
if (num_threads >= MAXTHREADS)
|
||||
if (num_threads[core] >= MAXTHREADS)
|
||||
return -1;
|
||||
|
||||
/* 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 */
|
||||
thread_name[num_threads] = name;
|
||||
thread_stack[num_threads] = stack;
|
||||
thread_stack_size[num_threads] = stack_size;
|
||||
regs = &thread_contexts[num_threads];
|
||||
thread_name[core][num_threads[core]] = name;
|
||||
thread_stack[core][num_threads[core]] = stack;
|
||||
thread_stack_size[core][num_threads[core]] = stack_size;
|
||||
regs = &thread_contexts[core][num_threads[core]];
|
||||
#if defined(CPU_COLDFIRE) || (CONFIG_CPU == SH7034) || defined(CPU_ARM)
|
||||
/* Align stack to an even 32 bit boundary */
|
||||
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;
|
||||
|
||||
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().
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
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;
|
||||
|
||||
if(threadnum >= num_threads)
|
||||
if(threadnum >= num_threads[core])
|
||||
return;
|
||||
|
||||
num_threads--;
|
||||
for (i=threadnum; i<num_threads-1; i++)
|
||||
num_threads[core]--;
|
||||
for (i=threadnum; i<num_threads[core]-1; i++)
|
||||
{ /* move all entries which are behind */
|
||||
thread_name[i] = thread_name[i+1];
|
||||
thread_stack[i] = thread_stack[i+1];
|
||||
thread_stack_size[i] = thread_stack_size[i+1];
|
||||
thread_contexts[i] = thread_contexts[i+1];
|
||||
thread_name[core][i] = thread_name[core][i+1];
|
||||
thread_stack[core][i] = thread_stack[core][i+1];
|
||||
thread_stack_size[core][i] = thread_stack_size[core][i+1];
|
||||
thread_contexts[core][i] = thread_contexts[core][i+1];
|
||||
}
|
||||
|
||||
if (current_thread == threadnum) /* deleting the current one? */
|
||||
current_thread = num_threads; /* set beyond last, avoid store harm */
|
||||
else if (current_thread > threadnum) /* within the moved positions? */
|
||||
current_thread--; /* adjust it, point to same context again */
|
||||
if (current_thread[core] == threadnum) /* deleting the current one? */
|
||||
current_thread[core] = num_threads[core]; /* set beyond last, avoid store harm */
|
||||
else if (current_thread[core] > threadnum) /* within the moved positions? */
|
||||
current_thread[core]--; /* adjust it, point to same context again */
|
||||
}
|
||||
|
||||
void init_threads(void)
|
||||
{
|
||||
num_threads = 1; /* We have 1 thread to begin with */
|
||||
current_thread = 0; /* The current thread is number 0 */
|
||||
thread_name[0] = main_thread_name;
|
||||
thread_stack[0] = stackbegin;
|
||||
thread_stack_size[0] = (int)stackend - (int)stackbegin;
|
||||
#if CONFIG_CPU == TCC730
|
||||
thread_contexts[0].started = 1;
|
||||
#else
|
||||
thread_contexts[0].start = 0; /* thread 0 already running */
|
||||
unsigned int core = CURRENT_CORE;
|
||||
|
||||
num_threads[core] = 1; /* We have 1 thread to begin with */
|
||||
current_thread[core] = 0; /* The current thread is number 0 */
|
||||
thread_name[core][0] = main_thread_name;
|
||||
/* In multiple core setups, each core has a different stack. There is probably
|
||||
a much better way to do this. */
|
||||
if(core == CPU)
|
||||
{
|
||||
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
|
||||
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 *stackptr = thread_stack[threadnum];
|
||||
unsigned int *stackptr = thread_stack[core][threadnum];
|
||||
|
||||
if(threadnum >= num_threads)
|
||||
if(threadnum >= num_threads[core])
|
||||
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)
|
||||
break;
|
||||
}
|
||||
|
||||
return ((thread_stack_size[threadnum] - i * sizeof(int)) * 100) /
|
||||
thread_stack_size[threadnum];
|
||||
}
|
||||
return ((thread_stack_size[core][threadnum] - i * sizeof(int)) * 100) /
|
||||
thread_stack_size[core][threadnum];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue