summaryrefslogtreecommitdiff
path: root/firmware/system.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/system.c')
-rw-r--r--firmware/system.c102
1 files changed, 61 insertions, 41 deletions
diff --git a/firmware/system.c b/firmware/system.c
index c97b5233ec..6aee823205 100644
--- a/firmware/system.c
+++ b/firmware/system.c
@@ -91,21 +91,21 @@ bool detect_flashed_rockbox(void)
91{ 91{
92 struct flash_header hdr; 92 struct flash_header hdr;
93 uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT; 93 uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT;
94 94
95# ifndef BOOTLOADER 95# ifndef BOOTLOADER
96 int oldmode; 96 int oldmode;
97 oldmode = system_memory_guard(MEMGUARD_NONE); 97 oldmode = system_memory_guard(MEMGUARD_NONE);
98# endif 98# endif
99 99
100 memcpy(&hdr, src, sizeof(struct flash_header)); 100 memcpy(&hdr, src, sizeof(struct flash_header));
101 101
102# ifndef BOOTLOADER 102# ifndef BOOTLOADER
103 system_memory_guard(oldmode); 103 system_memory_guard(oldmode);
104# endif 104# endif
105 105
106 if (hdr.magic != FLASH_MAGIC) 106 if (hdr.magic != FLASH_MAGIC)
107 return false; 107 return false;
108 108
109 return true; 109 return true;
110} 110}
111#else 111#else
@@ -139,13 +139,13 @@ void ddma_transfer(int dir, int mem, void* intAddr, long extAddr, int num) {
139 /* HW wants those two in word units. */ 139 /* HW wants those two in word units. */
140 num /= 2; 140 num /= 2;
141 externalAddress /= 2; 141 externalAddress /= 2;
142 142
143 DDMACFG = (dir << 1) | (mem << 2); 143 DDMACFG = (dir << 1) | (mem << 2);
144 DDMAIADR = internalAddress; 144 DDMAIADR = internalAddress;
145 DDMAEADR = externalAddress; 145 DDMAEADR = externalAddress;
146 DDMANUM = num; 146 DDMANUM = num;
147 DDMACOM |= 0x4; /* start */ 147 DDMACOM |= 0x4; /* start */
148 148
149 ddma_wait_idle(); /* wait for completion */ 149 ddma_wait_idle(); /* wait for completion */
150 set_irq_level(irq); 150 set_irq_level(irq);
151} 151}
@@ -164,13 +164,13 @@ static void ddma_transfer_noicode(int dir, int mem, long intAddr, long extAddr,
164 /* HW wants those two in word units. */ 164 /* HW wants those two in word units. */
165 num /= 2; 165 num /= 2;
166 externalAddress /= 2; 166 externalAddress /= 2;
167 167
168 DDMACFG = (dir << 1) | (mem << 2); 168 DDMACFG = (dir << 1) | (mem << 2);
169 DDMAIADR = internalAddress; 169 DDMAIADR = internalAddress;
170 DDMAEADR = externalAddress; 170 DDMAEADR = externalAddress;
171 DDMANUM = num; 171 DDMANUM = num;
172 DDMACOM |= 0x4; /* start */ 172 DDMACOM |= 0x4; /* start */
173 173
174 ddma_wait_idle_noicode(); /* wait for completion */ 174 ddma_wait_idle_noicode(); /* wait for completion */
175 set_irq_level(irq); 175 set_irq_level(irq);
176} 176}
@@ -220,7 +220,7 @@ void smsc_delay() {
220 Delay doesn't depend on CPU speed in Archos' firmware. 220 Delay doesn't depend on CPU speed in Archos' firmware.
221 */ 221 */
222 for (i = 0; i < 100; i++) { 222 for (i = 0; i < 100; i++) {
223 223
224 } 224 }
225} 225}
226 226
@@ -228,9 +228,9 @@ static void extra_init(void) {
228 /* Power on stuff */ 228 /* Power on stuff */
229 P1 |= 0x07; 229 P1 |= 0x07;
230 P1CON |= 0x1f; 230 P1CON |= 0x1f;
231 231
232 /* P5 conf 232 /* P5 conf
233 * lines 0, 1 & 4 are digital, other analog. : 233 * lines 0, 1 & 4 are digital, other analog. :
234 */ 234 */
235 P5CON = 0xec; 235 P5CON = 0xec;
236 236
@@ -294,21 +294,21 @@ void system_init(void)
294 /******** 294 /********
295 * CPU 295 * CPU
296 */ 296 */
297 297
298 298
299 /* PLL0 (cpu osc. frequency) */ 299 /* PLL0 (cpu osc. frequency) */
300 /* set_cpu_frequency(CPU_FREQ); */ 300 /* set_cpu_frequency(CPU_FREQ); */
301 301
302 302
303 /******************* 303 /*******************
304 * configure S(D)RAM 304 * configure S(D)RAM
305 */ 305 */
306 306
307 /************************ 307 /************************
308 * Copy .icode section to icram 308 * Copy .icode section to icram
309 */ 309 */
310 ddma_transfer_noicode(0, 0, 0x40, (long)&icodecopy, (int)&icodesize); 310 ddma_transfer_noicode(0, 0, 0x40, (long)&icodecopy, (int)&icodesize);
311 311
312 312
313 /*************************** 313 /***************************
314 * Interrupts 314 * Interrupts
@@ -472,12 +472,12 @@ void UIE (void) /* Unexpected Interrupt or Exception */
472 unsigned int format_vector, pc; 472 unsigned int format_vector, pc;
473 int vector; 473 int vector;
474 char str[32]; 474 char str[32];
475 475
476 asm volatile ("move.l (52,%%sp),%0": "=r"(format_vector)); 476 asm volatile ("move.l (52,%%sp),%0": "=r"(format_vector));
477 asm volatile ("move.l (56,%%sp),%0": "=r"(pc)); 477 asm volatile ("move.l (56,%%sp),%0": "=r"(pc));
478 478
479 vector = (format_vector >> 18) & 0xff; 479 vector = (format_vector >> 18) & 0xff;
480 480
481 /* clear screen */ 481 /* clear screen */
482 lcd_clear_display (); 482 lcd_clear_display ();
483#ifdef HAVE_LCD_BITMAP 483#ifdef HAVE_LCD_BITMAP
@@ -488,7 +488,7 @@ void UIE (void) /* Unexpected Interrupt or Exception */
488 snprintf(str,sizeof(str),"at %08x",pc); 488 snprintf(str,sizeof(str),"at %08x",pc);
489 lcd_puts(0,1,str); 489 lcd_puts(0,1,str);
490 lcd_update(); 490 lcd_update();
491 491
492 /* set cpu frequency to 11mhz (to prevent overheating) */ 492 /* set cpu frequency to 11mhz (to prevent overheating) */
493 DCR = (DCR & ~0x01ff) | 1; 493 DCR = (DCR & ~0x01ff) | 1;
494 PLLCR = 0x10800000; 494 PLLCR = 0x10800000;
@@ -510,7 +510,7 @@ void UIE (void) /* Unexpected Interrupt or Exception */
510} 510}
511 511
512/* reset vectors are handled in crt0.S */ 512/* reset vectors are handled in crt0.S */
513void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) = 513void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) =
514{ 514{
515 UIE,UIE,UIE,UIE,UIE,UIE, 515 UIE,UIE,UIE,UIE,UIE,UIE,
516 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, 516 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
@@ -520,7 +520,7 @@ void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) =
520 520
521 TRAP0,TRAP1,TRAP2,TRAP3,TRAP4,TRAP5,TRAP6,TRAP7, 521 TRAP0,TRAP1,TRAP2,TRAP3,TRAP4,TRAP5,TRAP6,TRAP7,
522 TRAP8,TRAP9,TRAP10,TRAP11,TRAP12,TRAP13,TRAP14,TRAP15, 522 TRAP8,TRAP9,TRAP10,TRAP11,TRAP12,TRAP13,TRAP14,TRAP15,
523 523
524 SWT,UIE,UIE,I2C,UART1,UART2,DMA0,DMA1, 524 SWT,UIE,UIE,I2C,UART1,UART2,DMA0,DMA1,
525 DMA2,DMA3,QSPI,UIE,UIE,UIE,UIE,UIE, 525 DMA2,DMA3,QSPI,UIE,UIE,UIE,UIE,UIE,
526 PDIR1FULL,PDIR2FULL,EBUTXEMPTY,IIS2TXEMPTY, 526 PDIR1FULL,PDIR2FULL,EBUTXEMPTY,IIS2TXEMPTY,
@@ -741,7 +741,7 @@ static const char* const irqname[] = {
741 741
742asm ( 742asm (
743 743
744/* Vector table. 744/* Vector table.
745 * Handled in asm because gcc 4.x doesn't allow weak aliases to symbols 745 * Handled in asm because gcc 4.x doesn't allow weak aliases to symbols
746 * defined in an asm block -- silly. 746 * defined in an asm block -- silly.
747 * Reset vectors (0..3) are handled in crt0.S */ 747 * Reset vectors (0..3) are handled in crt0.S */
@@ -854,7 +854,7 @@ asm (
854 RESERVE_INTERRUPT ( 108) 854 RESERVE_INTERRUPT ( 108)
855 DEFAULT_INTERRUPT (ADITI, 109) 855 DEFAULT_INTERRUPT (ADITI, 109)
856 856
857/* UIE# block. 857/* UIE# block.
858 * Must go into the same section as the UIE() handler */ 858 * Must go into the same section as the UIE() handler */
859 859
860 "\t.text\n" 860 "\t.text\n"
@@ -979,7 +979,7 @@ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
979 char str[32]; 979 char str[32];
980 980
981 asm volatile ("sts\tpr,%0" : "=r"(n)); 981 asm volatile ("sts\tpr,%0" : "=r"(n));
982 982
983 /* clear screen */ 983 /* clear screen */
984 lcd_clear_display (); 984 lcd_clear_display ();
985#ifdef HAVE_LCD_BITMAP 985#ifdef HAVE_LCD_BITMAP
@@ -1002,7 +1002,7 @@ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
1002 volatile int i; 1002 volatile int i;
1003 led (state); 1003 led (state);
1004 state = !state; 1004 state = !state;
1005 1005
1006 for (i = 0; i < 240000; ++i); 1006 for (i = 0; i < 240000; ++i);
1007#endif 1007#endif
1008 1008
@@ -1018,7 +1018,7 @@ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
1018#elif CONFIG_KEYPAD == ONDIO_PAD 1018#elif CONFIG_KEYPAD == ONDIO_PAD
1019 if (!(PCDR & 0x0008)) 1019 if (!(PCDR & 0x0008))
1020#endif 1020#endif
1021 { 1021 {
1022 /* enable the watchguard timer, but don't service it */ 1022 /* enable the watchguard timer, but don't service it */
1023 RSTCSR_W = 0x5a40; /* Reset enabled, power-on reset */ 1023 RSTCSR_W = 0x5a40; /* Reset enabled, power-on reset */
1024 TCSR_W = 0xa560; /* Watchdog timer mode, timer enabled, sysclk/2 */ 1024 TCSR_W = 0xa560; /* Watchdog timer mode, timer enabled, sysclk/2 */
@@ -1086,7 +1086,7 @@ int system_memory_guard(int newmode)
1086 1086
1087 int oldmode = MEMGUARD_NONE; 1087 int oldmode = MEMGUARD_NONE;
1088 int i; 1088 int i;
1089 1089
1090 /* figure out the old mode from what is in the UBC regs. If the register 1090 /* figure out the old mode from what is in the UBC regs. If the register
1091 values don't match any mode, assume MEMGUARD_NONE */ 1091 values don't match any mode, assume MEMGUARD_NONE */
1092 for (i = MEMGUARD_NONE; i < MAXMEMGUARD; i++) 1092 for (i = MEMGUARD_NONE; i < MAXMEMGUARD; i++)
@@ -1098,7 +1098,7 @@ int system_memory_guard(int newmode)
1098 break; 1098 break;
1099 } 1099 }
1100 } 1100 }
1101 1101
1102 if (newmode == MEMGUARD_KEEP) 1102 if (newmode == MEMGUARD_KEEP)
1103 newmode = oldmode; 1103 newmode = oldmode;
1104 1104
@@ -1109,7 +1109,7 @@ int system_memory_guard(int newmode)
1109 BAR = modes[newmode].addr; 1109 BAR = modes[newmode].addr;
1110 BAMR = modes[newmode].mask; 1110 BAMR = modes[newmode].mask;
1111 BBR = modes[newmode].bbr; 1111 BBR = modes[newmode].bbr;
1112 1112
1113 return oldmode; 1113 return oldmode;
1114} 1114}
1115#elif defined(CPU_ARM) 1115#elif defined(CPU_ARM)
@@ -1124,7 +1124,7 @@ static const char* const uiename[] = {
1124void UIE(unsigned int pc, unsigned int num) 1124void UIE(unsigned int pc, unsigned int num)
1125{ 1125{
1126 char str[32]; 1126 char str[32];
1127 1127
1128 lcd_clear_display(); 1128 lcd_clear_display();
1129#ifdef HAVE_LCD_BITMAP 1129#ifdef HAVE_LCD_BITMAP
1130 lcd_setfont(FONT_SYSFIXED); 1130 lcd_setfont(FONT_SYSFIXED);
@@ -1133,7 +1133,7 @@ void UIE(unsigned int pc, unsigned int num)
1133 snprintf(str, sizeof(str), "at %08x", pc); 1133 snprintf(str, sizeof(str), "at %08x", pc);
1134 lcd_puts(0, 1, str); 1134 lcd_puts(0, 1, str);
1135 lcd_update(); 1135 lcd_update();
1136 1136
1137 while (1) 1137 while (1)
1138 { 1138 {
1139 /* TODO: perhaps add button handling in here when we get a polling 1139 /* TODO: perhaps add button handling in here when we get a polling
@@ -1160,7 +1160,7 @@ void irq(void)
1160 else if (CPU_INT_STAT & TIMER2_MASK) 1160 else if (CPU_INT_STAT & TIMER2_MASK)
1161 TIMER2(); 1161 TIMER2();
1162 else if (CPU_HI_INT_STAT & GPIO_MASK) 1162 else if (CPU_HI_INT_STAT & GPIO_MASK)
1163 ipod_mini_button_int(); 1163 ipod_mini_button_int();
1164} 1164}
1165#elif (defined IRIVER_H10) || (defined IRIVER_H10_5GB) 1165#elif (defined IRIVER_H10) || (defined IRIVER_H10_5GB)
1166/* TODO: this should really be in the target tree, but moving it there caused 1166/* TODO: this should really be in the target tree, but moving it there caused
@@ -1170,14 +1170,14 @@ void irq(void)
1170 if (CPU_INT_STAT & TIMER1_MASK) 1170 if (CPU_INT_STAT & TIMER1_MASK)
1171 TIMER1(); 1171 TIMER1();
1172 else if (CPU_INT_STAT & TIMER2_MASK) 1172 else if (CPU_INT_STAT & TIMER2_MASK)
1173 TIMER2(); 1173 TIMER2();
1174} 1174}
1175#else 1175#else
1176extern void ipod_4g_button_int(void); 1176extern void ipod_4g_button_int(void);
1177 1177
1178void irq(void) 1178void irq(void)
1179{ 1179{
1180 if (CPU_INT_STAT & TIMER1_MASK) 1180 if (CPU_INT_STAT & TIMER1_MASK)
1181 TIMER1(); 1181 TIMER1();
1182 else if (CPU_INT_STAT & TIMER2_MASK) 1182 else if (CPU_INT_STAT & TIMER2_MASK)
1183 TIMER2(); 1183 TIMER2();
@@ -1187,11 +1187,21 @@ void irq(void)
1187#endif 1187#endif
1188#endif /* BOOTLOADER */ 1188#endif /* BOOTLOADER */
1189 1189
1190unsigned int current_core(void)
1191{
1192 if(((*(volatile unsigned long *)(0x60000000)) & 0xff) == 0x55)
1193 {
1194 return CPU;
1195 }
1196 return COP;
1197}
1198
1199
1190/* TODO: The following two function have been lifted straight from IPL, and 1200/* TODO: The following two function have been lifted straight from IPL, and
1191 hence have a lot of numeric addresses used straight. I'd like to use 1201 hence have a lot of numeric addresses used straight. I'd like to use
1192 #defines for these, but don't know what most of them are for or even what 1202 #defines for these, but don't know what most of them are for or even what
1193 they should be named. Because of this I also have no way of knowing how 1203 they should be named. Because of this I also have no way of knowing how
1194 to extend the funtions to do alternate cache configurations and/or 1204 to extend the funtions to do alternate cache configurations and/or
1195 some other CPU frequency scaling. */ 1205 some other CPU frequency scaling. */
1196 1206
1197#ifndef BOOTLOADER 1207#ifndef BOOTLOADER
@@ -1251,7 +1261,7 @@ void set_cpu_frequency(long frequency)
1251#if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) 1261#if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI)
1252 /* We don't know why the timer interrupt gets disabled on the PP5020 1262 /* We don't know why the timer interrupt gets disabled on the PP5020
1253 based ipods, but without the following line, the 4Gs will freeze 1263 based ipods, but without the following line, the 4Gs will freeze
1254 when CPU frequency changing is enabled. 1264 when CPU frequency changing is enabled.
1255 1265
1256 Note also that a simple "CPU_INT_EN = TIMER1_MASK;" (as used 1266 Note also that a simple "CPU_INT_EN = TIMER1_MASK;" (as used
1257 elsewhere to enable interrupts) doesn't work, we need "|=". 1267 elsewhere to enable interrupts) doesn't work, we need "|=".
@@ -1321,19 +1331,29 @@ extern void TIMER2(void);
1321 1331
1322void irq(void) 1332void irq(void)
1323{ 1333{
1324 if (CPU_INT_STAT & TIMER1_MASK) 1334 if (CPU_INT_STAT & TIMER1_MASK)
1325 TIMER1(); 1335 TIMER1();
1326 else if (CPU_INT_STAT & TIMER2_MASK) 1336 else if (CPU_INT_STAT & TIMER2_MASK)
1327 TIMER2(); 1337 TIMER2();
1328} 1338}
1329 1339
1330#endif 1340#endif
1331 1341
1342unsigned int current_core(void)
1343{
1344 if(((*(volatile unsigned long *)(0xc4000000)) & 0xff) == 0x55)
1345 {
1346 return CPU;
1347 }
1348 return COP;
1349}
1350
1351
1332/* TODO: The following two function have been lifted straight from IPL, and 1352/* TODO: The following two function have been lifted straight from IPL, and
1333 hence have a lot of numeric addresses used straight. I'd like to use 1353 hence have a lot of numeric addresses used straight. I'd like to use
1334 #defines for these, but don't know what most of them are for or even what 1354 #defines for these, but don't know what most of them are for or even what
1335 they should be named. Because of this I also have no way of knowing how 1355 they should be named. Because of this I also have no way of knowing how
1336 to extend the funtions to do alternate cache configurations and/or 1356 to extend the funtions to do alternate cache configurations and/or
1337 some other CPU frequency scaling. */ 1357 some other CPU frequency scaling. */
1338 1358
1339#ifndef BOOTLOADER 1359#ifndef BOOTLOADER
@@ -1370,7 +1390,7 @@ void set_cpu_frequency(long frequency)
1370 else 1390 else
1371 postmult = CPUFREQ_DEFAULT_MULT; 1391 postmult = CPUFREQ_DEFAULT_MULT;
1372 cpu_frequency = frequency; 1392 cpu_frequency = frequency;
1373 1393
1374 outl(0x02, 0xcf005008); 1394 outl(0x02, 0xcf005008);
1375 outl(0x55, 0xcf00500c); 1395 outl(0x55, 0xcf00500c);
1376 outl(0x6000, 0xcf005010); 1396 outl(0x6000, 0xcf005010);
@@ -1501,7 +1521,7 @@ void system_init(void)
1501 IRQ_WRITE_WAIT(0, 0, v == 0); 1521 IRQ_WRITE_WAIT(0, 0, v == 0);
1502 IRQ_WRITE_WAIT(4, 0, v == 0); 1522 IRQ_WRITE_WAIT(4, 0, v == 0);
1503 */ 1523 */
1504 1524
1505 for (i = 0; i < 0x1c; i++) 1525 for (i = 0; i < 0x1c; i++)
1506 { 1526 {
1507 IRQ_WRITE_WAIT(0x404 + i * 4, 0x1e000001, (v & 0x3010f) == 1); 1527 IRQ_WRITE_WAIT(0x404 + i * 4, 0x1e000001, (v & 0x3010f) == 1);