1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Alan Korr
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
34 long cpu_frequency SHAREDBSS_ATTR
= CPU_FREQ
;
37 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
38 static int boost_counter SHAREDBSS_ATTR
= 0;
39 static bool cpu_idle SHAREDBSS_ATTR
= false;
41 struct spinlock boostctrl_spin SHAREDBSS_ATTR
;
42 void cpu_boost_init(void)
44 spinlock_init(&boostctrl_spin
);
48 int get_cpu_boost_counter(void)
52 #ifdef CPU_BOOST_LOGGING
53 #define MAX_BOOST_LOG 64
54 static char cpu_boost_calls
[MAX_BOOST_LOG
][MAX_PATH
];
55 static int cpu_boost_first
= 0;
56 static int cpu_boost_calls_count
= 0;
57 static int cpu_boost_track_message
= 0;
58 int cpu_boost_log_getcount(void)
60 return cpu_boost_calls_count
;
62 char * cpu_boost_log_getlog_first(void)
66 spinlock_lock(&boostctrl_spin
);
71 if (cpu_boost_calls_count
)
73 cpu_boost_track_message
= 1;
74 first
= cpu_boost_calls
[cpu_boost_first
];
78 spinlock_unlock(&boostctrl_spin
);
84 char * cpu_boost_log_getlog_next(void)
90 spinlock_lock(&boostctrl_spin
);
93 message
= (cpu_boost_track_message
+cpu_boost_first
)%MAX_BOOST_LOG
;
96 if (cpu_boost_track_message
< cpu_boost_calls_count
)
98 cpu_boost_track_message
++;
99 next
= cpu_boost_calls
[message
];
103 spinlock_unlock(&boostctrl_spin
);
109 void cpu_boost_(bool on_off
, char* location
, int line
)
112 spinlock_lock(&boostctrl_spin
);
115 if (cpu_boost_calls_count
== MAX_BOOST_LOG
)
117 cpu_boost_first
= (cpu_boost_first
+1)%MAX_BOOST_LOG
;
118 cpu_boost_calls_count
--;
119 if (cpu_boost_calls_count
< 0)
120 cpu_boost_calls_count
= 0;
122 if (cpu_boost_calls_count
< MAX_BOOST_LOG
)
124 int message
= (cpu_boost_first
+cpu_boost_calls_count
)%MAX_BOOST_LOG
;
125 snprintf(cpu_boost_calls
[message
], MAX_PATH
,
126 "%c %s:%d",on_off
==true?'B':'U',location
,line
);
127 cpu_boost_calls_count
++;
130 void cpu_boost(bool on_off
)
133 spinlock_lock(&boostctrl_spin
);
136 #endif /* CPU_BOOST_LOGGING */
139 /* Boost the frequency if not already boosted */
140 if(++boost_counter
== 1)
141 set_cpu_frequency(CPUFREQ_MAX
);
145 /* Lower the frequency if the counter reaches 0 */
146 if(--boost_counter
<= 0)
149 set_cpu_frequency(CPUFREQ_DEFAULT
);
151 set_cpu_frequency(CPUFREQ_NORMAL
);
154 if (boost_counter
< 0)
162 spinlock_unlock(&boostctrl_spin
);
166 void cpu_idle_mode(bool on_off
)
169 spinlock_lock(&boostctrl_spin
);
174 /* We need to adjust the frequency immediately if the CPU
176 if(boost_counter
== 0)
179 set_cpu_frequency(CPUFREQ_DEFAULT
);
181 set_cpu_frequency(CPUFREQ_NORMAL
);
185 spinlock_unlock(&boostctrl_spin
);
188 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
191 #ifdef HAVE_FLASHED_ROCKBOX
192 static bool detect_flash_header(uint8_t *addr
)
195 int oldmode
= system_memory_guard(MEMGUARD_NONE
);
197 struct flash_header hdr
;
198 memcpy(&hdr
, addr
, sizeof(struct flash_header
));
200 system_memory_guard(oldmode
);
202 return hdr
.magic
== FLASH_MAGIC
;
206 bool detect_flashed_romimage(void)
208 #ifdef HAVE_FLASHED_ROCKBOX
209 return detect_flash_header((uint8_t *)FLASH_ROMIMAGE_ENTRY
);
212 #endif /* HAVE_FLASHED_ROCKBOX */
215 bool detect_flashed_ramimage(void)
217 #ifdef HAVE_FLASHED_ROCKBOX
218 return detect_flash_header((uint8_t *)FLASH_RAMIMAGE_ENTRY
);
221 #endif /* HAVE_FLASHED_ROCKBOX */
224 bool detect_original_firmware(void)
226 return !(detect_flashed_ramimage() || detect_flashed_romimage());
231 static const char* const uiename
[] = {
232 "Undefined instruction",
238 /* Unexpected Interrupt or Exception handler. Currently only deals with
239 exceptions, but will deal with interrupts later.
241 void UIE(unsigned int pc
, unsigned int num
) __attribute__((noreturn
));
242 void UIE(unsigned int pc
, unsigned int num
)
247 #ifdef HAVE_LCD_BITMAP
248 lcd_setfont(FONT_SYSFIXED
);
250 lcd_puts(0, 0, uiename
[num
]);
251 snprintf(str
, sizeof(str
), "at %08x" IF_COP(" (%d)"), pc
252 IF_COP(, CURRENT_CORE
));
258 /* TODO: perhaps add button handling in here when we get a polling
266 /* Needs to be here or gcc won't find it */
267 void __div0(void) __attribute__((naked
));