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 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;
}

View file

@ -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 */

View file

@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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];
}