Fix FS #7594 _again_ --- please stop re-introducing the typo ;)
[Rockbox.git] / firmware / system.c
blob3fcf37d297fe8c227211147597e37f0dda246eef
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;
39 int get_cpu_boost_counter(void)
41 return boost_counter;
43 #ifdef CPU_BOOST_LOGGING
44 #define MAX_BOOST_LOG 64
45 static char cpu_boost_calls[MAX_BOOST_LOG][MAX_PATH];
46 static int cpu_boost_first = 0;
47 static int cpu_boost_calls_count = 0;
48 static int cpu_boost_track_message = 0;
49 int cpu_boost_log_getcount(void)
51 return cpu_boost_calls_count;
53 char * cpu_boost_log_getlog_first(void)
55 if (cpu_boost_calls_count)
57 cpu_boost_track_message = 1;
58 return cpu_boost_calls[cpu_boost_first];
60 else return NULL;
62 char * cpu_boost_log_getlog_next(void)
64 int message = (cpu_boost_track_message+cpu_boost_first)%MAX_BOOST_LOG;
65 if (cpu_boost_track_message < cpu_boost_calls_count)
67 cpu_boost_track_message++;
68 return cpu_boost_calls[message];
70 else return NULL;
72 void cpu_boost_(bool on_off, char* location, int line)
74 if (cpu_boost_calls_count == MAX_BOOST_LOG)
76 cpu_boost_first = (cpu_boost_first+1)%MAX_BOOST_LOG;
77 cpu_boost_calls_count--;
78 if (cpu_boost_calls_count < 0)
79 cpu_boost_calls_count = 0;
81 if (cpu_boost_calls_count < MAX_BOOST_LOG)
83 int message = (cpu_boost_first+cpu_boost_calls_count)%MAX_BOOST_LOG;
84 snprintf(cpu_boost_calls[message], MAX_PATH,
85 "%c %s:%d",on_off==true?'B':'U',location,line);
86 cpu_boost_calls_count++;
88 #else
89 void cpu_boost(bool on_off)
91 #endif
92 if(on_off)
94 /* Boost the frequency if not already boosted */
95 if(boost_counter++ == 0)
96 set_cpu_frequency(CPUFREQ_MAX);
98 else
100 /* Lower the frequency if the counter reaches 0 */
101 if(--boost_counter == 0)
103 if(cpu_idle)
104 set_cpu_frequency(CPUFREQ_DEFAULT);
105 else
106 set_cpu_frequency(CPUFREQ_NORMAL);
109 /* Safety measure */
110 if(boost_counter < 0)
111 boost_counter = 0;
115 void cpu_idle_mode(bool on_off)
117 cpu_idle = on_off;
119 /* We need to adjust the frequency immediately if the CPU
120 isn't boosted */
121 if(boost_counter == 0)
123 if(cpu_idle)
124 set_cpu_frequency(CPUFREQ_DEFAULT);
125 else
126 set_cpu_frequency(CPUFREQ_NORMAL);
129 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
132 #ifdef HAVE_FLASHED_ROCKBOX
133 static bool detect_flash_header(uint8_t *addr)
135 #ifndef BOOTLOADER
136 int oldmode = system_memory_guard(MEMGUARD_NONE);
137 #endif
138 struct flash_header hdr;
139 memcpy(&hdr, addr, sizeof(struct flash_header));
140 #ifndef BOOTLOADER
141 system_memory_guard(oldmode);
142 #endif
143 return hdr.magic == FLASH_MAGIC;
145 #endif
147 bool detect_flashed_romimage(void)
149 #ifdef HAVE_FLASHED_ROCKBOX
150 return detect_flash_header((uint8_t *)FLASH_ROMIMAGE_ENTRY);
151 #else
152 return false;
153 #endif /* HAVE_FLASHED_ROCKBOX */
156 bool detect_flashed_ramimage(void)
158 #ifdef HAVE_FLASHED_ROCKBOX
159 return detect_flash_header((uint8_t *)FLASH_RAMIMAGE_ENTRY);
160 #else
161 return false;
162 #endif /* HAVE_FLASHED_ROCKBOX */
165 bool detect_original_firmware(void)
167 return !(detect_flashed_ramimage() || detect_flashed_romimage());
170 #if defined(CPU_ARM)
172 static const char* const uiename[] = {
173 "Undefined instruction",
174 "Prefetch abort",
175 "Data abort",
176 "Divide by zero"
179 /* Unexpected Interrupt or Exception handler. Currently only deals with
180 exceptions, but will deal with interrupts later.
182 void UIE(unsigned int pc, unsigned int num)
184 char str[32];
186 lcd_clear_display();
187 #ifdef HAVE_LCD_BITMAP
188 lcd_setfont(FONT_SYSFIXED);
189 #endif
190 lcd_puts(0, 0, uiename[num]);
191 snprintf(str, sizeof(str), "at %08x", pc);
192 lcd_puts(0, 1, str);
193 lcd_update();
195 while (1)
197 /* TODO: perhaps add button handling in here when we get a polling
198 driver some day.
203 #ifndef STUB
204 /* Needs to be here or gcc won't find it */
205 void __div0(void) __attribute__((naked));
206 void __div0(void)
208 asm volatile (
209 "ldr r0, [sp] \r\n"
210 "mov r1, #3 \r\n"
211 "b UIE \r\n"
214 #endif
216 #endif /* CPU_ARM */