Manual: make sure that there won't be any additional spaces in the \opt{}. This shoul...
[Rockbox.git] / firmware / system.c
blob65478e724b412380de70bf30a751a5335a2baf71
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);
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 return first;
82 char * cpu_boost_log_getlog_next(void)
84 int message;
85 char *next;
87 #if NUM_CORES > 1
88 spinlock_lock(&boostctrl_spin);
89 #endif
91 message = (cpu_boost_track_message+cpu_boost_first)%MAX_BOOST_LOG;
92 next = NULL;
94 if (cpu_boost_track_message < cpu_boost_calls_count)
96 cpu_boost_track_message++;
97 next = cpu_boost_calls[message];
100 #if NUM_CORES > 1
101 spinlock_unlock(&boostctrl_spin);
102 #endif
104 return next;
107 void cpu_boost_(bool on_off, char* location, int line)
109 #if NUM_CORES > 1
110 spinlock_lock(&boostctrl_spin);
111 #endif
113 if (cpu_boost_calls_count == MAX_BOOST_LOG)
115 cpu_boost_first = (cpu_boost_first+1)%MAX_BOOST_LOG;
116 cpu_boost_calls_count--;
117 if (cpu_boost_calls_count < 0)
118 cpu_boost_calls_count = 0;
120 if (cpu_boost_calls_count < MAX_BOOST_LOG)
122 int message = (cpu_boost_first+cpu_boost_calls_count)%MAX_BOOST_LOG;
123 snprintf(cpu_boost_calls[message], MAX_PATH,
124 "%c %s:%d",on_off==true?'B':'U',location,line);
125 cpu_boost_calls_count++;
127 #else
128 void cpu_boost(bool on_off)
130 #if NUM_CORES > 1
131 spinlock_lock(&boostctrl_spin);
132 #endif
134 #endif /* CPU_BOOST_LOGGING */
135 if(on_off)
137 /* Boost the frequency if not already boosted */
138 if(++boost_counter == 1)
139 set_cpu_frequency(CPUFREQ_MAX);
141 else
143 /* Lower the frequency if the counter reaches 0 */
144 if(--boost_counter <= 0)
146 if(cpu_idle)
147 set_cpu_frequency(CPUFREQ_DEFAULT);
148 else
149 set_cpu_frequency(CPUFREQ_NORMAL);
151 /* Safety measure */
152 if (boost_counter < 0)
154 boost_counter = 0;
159 #if NUM_CORES > 1
160 spinlock_unlock(&boostctrl_spin);
161 #endif
164 void cpu_idle_mode(bool on_off)
166 #if NUM_CORES > 1
167 spinlock_lock(&boostctrl_spin);
168 #endif
170 cpu_idle = on_off;
172 /* We need to adjust the frequency immediately if the CPU
173 isn't boosted */
174 if(boost_counter == 0)
176 if(cpu_idle)
177 set_cpu_frequency(CPUFREQ_DEFAULT);
178 else
179 set_cpu_frequency(CPUFREQ_NORMAL);
182 #if NUM_CORES > 1
183 spinlock_unlock(&boostctrl_spin);
184 #endif
186 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
189 #ifdef HAVE_FLASHED_ROCKBOX
190 static bool detect_flash_header(uint8_t *addr)
192 #ifndef BOOTLOADER
193 int oldmode = system_memory_guard(MEMGUARD_NONE);
194 #endif
195 struct flash_header hdr;
196 memcpy(&hdr, addr, sizeof(struct flash_header));
197 #ifndef BOOTLOADER
198 system_memory_guard(oldmode);
199 #endif
200 return hdr.magic == FLASH_MAGIC;
202 #endif
204 bool detect_flashed_romimage(void)
206 #ifdef HAVE_FLASHED_ROCKBOX
207 return detect_flash_header((uint8_t *)FLASH_ROMIMAGE_ENTRY);
208 #else
209 return false;
210 #endif /* HAVE_FLASHED_ROCKBOX */
213 bool detect_flashed_ramimage(void)
215 #ifdef HAVE_FLASHED_ROCKBOX
216 return detect_flash_header((uint8_t *)FLASH_RAMIMAGE_ENTRY);
217 #else
218 return false;
219 #endif /* HAVE_FLASHED_ROCKBOX */
222 bool detect_original_firmware(void)
224 return !(detect_flashed_ramimage() || detect_flashed_romimage());
227 #if defined(CPU_ARM)
229 static const char* const uiename[] = {
230 "Undefined instruction",
231 "Prefetch abort",
232 "Data abort",
233 "Divide by zero"
236 /* Unexpected Interrupt or Exception handler. Currently only deals with
237 exceptions, but will deal with interrupts later.
239 void UIE(unsigned int pc, unsigned int num) __attribute__((noreturn));
240 void UIE(unsigned int pc, unsigned int num)
242 char str[32];
244 lcd_clear_display();
245 #ifdef HAVE_LCD_BITMAP
246 lcd_setfont(FONT_SYSFIXED);
247 #endif
248 lcd_puts(0, 0, uiename[num]);
249 snprintf(str, sizeof(str), "at %08x" IF_COP(" (%d)"), pc
250 IF_COP(, CURRENT_CORE));
251 lcd_puts(0, 1, str);
252 lcd_update();
254 while (1)
256 /* TODO: perhaps add button handling in here when we get a polling
257 driver some day.
259 core_idle();
263 #ifndef STUB
264 /* Needs to be here or gcc won't find it */
265 void __div0(void) __attribute__((naked));
266 void __div0(void)
268 asm volatile (
269 "ldr r0, [sp] \r\n"
270 "mov r1, #3 \r\n"
271 "b UIE \r\n"
274 #endif
276 #ifdef BOOTLOADER
277 void reference_system_c(void)
280 #endif
282 #endif /* CPU_ARM */