Don't check for external rbutil.ini anymore -- doing so didn't gave a real benefit...
[Rockbox.git] / firmware / system.c
blob0b5ae1719ef075dda5ac423d3b1f9afa9dac1671
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Alan Korr
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include <stdio.h>
20 #include "config.h"
21 #include <stdbool.h>
22 #include "lcd.h"
23 #include "font.h"
24 #include "system.h"
25 #include "kernel.h"
26 #include "thread.h"
27 #include "timer.h"
28 #include "inttypes.h"
29 #include "string.h"
31 #ifndef SIMULATOR
32 long cpu_frequency NOCACHEBSS_ATTR = CPU_FREQ;
33 #endif
35 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
36 static int boost_counter NOCACHEBSS_ATTR = 0;
37 static bool cpu_idle NOCACHEBSS_ATTR = false;
38 #if NUM_CORES > 1
39 struct spinlock boostctrl_spin NOCACHEBSS_ATTR;
40 void cpu_boost_init(void)
42 spinlock_init(&boostctrl_spin, SPINLOCK_NO_TASK_SWITCH);
44 #endif
46 int get_cpu_boost_counter(void)
48 return boost_counter;
50 #ifdef CPU_BOOST_LOGGING
51 #define MAX_BOOST_LOG 64
52 static char cpu_boost_calls[MAX_BOOST_LOG][MAX_PATH];
53 static int cpu_boost_first = 0;
54 static int cpu_boost_calls_count = 0;
55 static int cpu_boost_track_message = 0;
56 int cpu_boost_log_getcount(void)
58 return cpu_boost_calls_count;
60 char * cpu_boost_log_getlog_first(void)
62 char *first;
63 #if NUM_CORES > 1
64 spinlock_lock(&boostctrl_spin);
65 #endif
67 first = NULL;
69 if (cpu_boost_calls_count)
71 cpu_boost_track_message = 1;
72 first = cpu_boost_calls[cpu_boost_first];
75 #if NUM_CORES > 1
76 spinlock_unlock(&boostctrl_spin);
77 #endif
79 char * cpu_boost_log_getlog_next(void)
81 int message;
82 char *next;
84 #if NUM_CORES > 1
85 spinlock_lock(&boostctrl_spin);
86 #endif
88 message = (cpu_boost_track_message+cpu_boost_first)%MAX_BOOST_LOG;
89 next = NULL;
91 if (cpu_boost_track_message < cpu_boost_calls_count)
93 cpu_boost_track_message++;
94 next = cpu_boost_calls[message];
97 #if NUM_CORES > 1
98 spinlock_unlock(&boostctrl_spin);
99 #endif
101 void cpu_boost_(bool on_off, char* location, int line)
103 #if NUM_CORES > 1
104 spinlock_lock(&boostctrl_spin);
105 #endif
107 if (cpu_boost_calls_count == MAX_BOOST_LOG)
109 cpu_boost_first = (cpu_boost_first+1)%MAX_BOOST_LOG;
110 cpu_boost_calls_count--;
111 if (cpu_boost_calls_count < 0)
112 cpu_boost_calls_count = 0;
114 if (cpu_boost_calls_count < MAX_BOOST_LOG)
116 int message = (cpu_boost_first+cpu_boost_calls_count)%MAX_BOOST_LOG;
117 snprintf(cpu_boost_calls[message], MAX_PATH,
118 "%c %s:%d",on_off==true?'B':'U',location,line);
119 cpu_boost_calls_count++;
121 #else
122 void cpu_boost(bool on_off)
124 #if NUM_CORES > 1
125 spinlock_lock(&boostctrl_spin);
126 #endif
128 #endif /* CPU_BOOST_LOGGING */
129 if(on_off)
131 /* Boost the frequency if not already boosted */
132 if(++boost_counter == 1)
133 set_cpu_frequency(CPUFREQ_MAX);
135 else
137 /* Lower the frequency if the counter reaches 0 */
138 if(--boost_counter <= 0)
140 if(cpu_idle)
141 set_cpu_frequency(CPUFREQ_DEFAULT);
142 else
143 set_cpu_frequency(CPUFREQ_NORMAL);
145 /* Safety measure */
146 if (boost_counter < 0)
148 boost_counter = 0;
153 #if NUM_CORES > 1
154 spinlock_unlock(&boostctrl_spin);
155 #endif
158 void cpu_idle_mode(bool on_off)
160 #if NUM_CORES > 1
161 spinlock_lock(&boostctrl_spin);
162 #endif
164 cpu_idle = on_off;
166 /* We need to adjust the frequency immediately if the CPU
167 isn't boosted */
168 if(boost_counter == 0)
170 if(cpu_idle)
171 set_cpu_frequency(CPUFREQ_DEFAULT);
172 else
173 set_cpu_frequency(CPUFREQ_NORMAL);
176 #if NUM_CORES > 1
177 spinlock_unlock(&boostctrl_spin);
178 #endif
180 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
183 #ifdef HAVE_FLASHED_ROCKBOX
184 static bool detect_flash_header(uint8_t *addr)
186 #ifndef BOOTLOADER
187 int oldmode = system_memory_guard(MEMGUARD_NONE);
188 #endif
189 struct flash_header hdr;
190 memcpy(&hdr, addr, sizeof(struct flash_header));
191 #ifndef BOOTLOADER
192 system_memory_guard(oldmode);
193 #endif
194 return hdr.magic == FLASH_MAGIC;
196 #endif
198 bool detect_flashed_romimage(void)
200 #ifdef HAVE_FLASHED_ROCKBOX
201 return detect_flash_header((uint8_t *)FLASH_ROMIMAGE_ENTRY);
202 #else
203 return false;
204 #endif /* HAVE_FLASHED_ROCKBOX */
207 bool detect_flashed_ramimage(void)
209 #ifdef HAVE_FLASHED_ROCKBOX
210 return detect_flash_header((uint8_t *)FLASH_RAMIMAGE_ENTRY);
211 #else
212 return false;
213 #endif /* HAVE_FLASHED_ROCKBOX */
216 bool detect_original_firmware(void)
218 return !(detect_flashed_ramimage() || detect_flashed_romimage());
221 #if defined(CPU_ARM)
223 static const char* const uiename[] = {
224 "Undefined instruction",
225 "Prefetch abort",
226 "Data abort",
227 "Divide by zero"
230 /* Unexpected Interrupt or Exception handler. Currently only deals with
231 exceptions, but will deal with interrupts later.
233 void UIE(unsigned int pc, unsigned int num) __attribute__((noreturn));
234 void UIE(unsigned int pc, unsigned int num)
236 char str[32];
238 lcd_clear_display();
239 #ifdef HAVE_LCD_BITMAP
240 lcd_setfont(FONT_SYSFIXED);
241 #endif
242 lcd_puts(0, 0, uiename[num]);
243 snprintf(str, sizeof(str), "at %08x" IF_COP(" (%d)"), pc
244 IF_COP(, CURRENT_CORE));
245 lcd_puts(0, 1, str);
246 lcd_update();
248 while (1)
250 /* TODO: perhaps add button handling in here when we get a polling
251 driver some day.
253 core_idle();
257 #ifndef STUB
258 /* Needs to be here or gcc won't find it */
259 void __div0(void) __attribute__((naked));
260 void __div0(void)
262 asm volatile (
263 "ldr r0, [sp] \r\n"
264 "mov r1, #3 \r\n"
265 "b UIE \r\n"
268 #endif
270 #endif /* CPU_ARM */