1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
32 long cpu_frequency NOCACHEBSS_ATTR
= CPU_FREQ
;
35 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
36 static int boost_counter NOCACHEBSS_ATTR
= 0;
37 static bool cpu_idle NOCACHEBSS_ATTR
= false;
39 struct spinlock boostctrl_spin NOCACHEBSS_ATTR
;
40 void cpu_boost_init(void)
42 spinlock_init(&boostctrl_spin
, SPINLOCK_NO_TASK_SWITCH
);
46 int get_cpu_boost_counter(void)
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)
64 spinlock_lock(&boostctrl_spin
);
69 if (cpu_boost_calls_count
)
71 cpu_boost_track_message
= 1;
72 first
= cpu_boost_calls
[cpu_boost_first
];
76 spinlock_unlock(&boostctrl_spin
);
79 char * cpu_boost_log_getlog_next(void)
85 spinlock_lock(&boostctrl_spin
);
88 message
= (cpu_boost_track_message
+cpu_boost_first
)%MAX_BOOST_LOG
;
91 if (cpu_boost_track_message
< cpu_boost_calls_count
)
93 cpu_boost_track_message
++;
94 next
= cpu_boost_calls
[message
];
98 spinlock_unlock(&boostctrl_spin
);
101 void cpu_boost_(bool on_off
, char* location
, int line
)
104 spinlock_lock(&boostctrl_spin
);
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
++;
122 void cpu_boost(bool on_off
)
125 spinlock_lock(&boostctrl_spin
);
128 #endif /* CPU_BOOST_LOGGING */
131 /* Boost the frequency if not already boosted */
132 if(++boost_counter
== 1)
133 set_cpu_frequency(CPUFREQ_MAX
);
137 /* Lower the frequency if the counter reaches 0 */
138 if(--boost_counter
<= 0)
141 set_cpu_frequency(CPUFREQ_DEFAULT
);
143 set_cpu_frequency(CPUFREQ_NORMAL
);
146 if (boost_counter
< 0)
154 spinlock_unlock(&boostctrl_spin
);
158 void cpu_idle_mode(bool on_off
)
161 spinlock_lock(&boostctrl_spin
);
166 /* We need to adjust the frequency immediately if the CPU
168 if(boost_counter
== 0)
171 set_cpu_frequency(CPUFREQ_DEFAULT
);
173 set_cpu_frequency(CPUFREQ_NORMAL
);
177 spinlock_unlock(&boostctrl_spin
);
180 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
183 #ifdef HAVE_FLASHED_ROCKBOX
184 static bool detect_flash_header(uint8_t *addr
)
187 int oldmode
= system_memory_guard(MEMGUARD_NONE
);
189 struct flash_header hdr
;
190 memcpy(&hdr
, addr
, sizeof(struct flash_header
));
192 system_memory_guard(oldmode
);
194 return hdr
.magic
== FLASH_MAGIC
;
198 bool detect_flashed_romimage(void)
200 #ifdef HAVE_FLASHED_ROCKBOX
201 return detect_flash_header((uint8_t *)FLASH_ROMIMAGE_ENTRY
);
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
);
213 #endif /* HAVE_FLASHED_ROCKBOX */
216 bool detect_original_firmware(void)
218 return !(detect_flashed_ramimage() || detect_flashed_romimage());
223 static const char* const uiename
[] = {
224 "Undefined instruction",
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
)
239 #ifdef HAVE_LCD_BITMAP
240 lcd_setfont(FONT_SYSFIXED
);
242 lcd_puts(0, 0, uiename
[num
]);
243 snprintf(str
, sizeof(str
), "at %08x" IF_COP(" (%d)"), pc
244 IF_COP(, CURRENT_CORE
));
250 /* TODO: perhaps add button handling in here when we get a polling
258 /* Needs to be here or gcc won't find it */
259 void __div0(void) __attribute__((naked
));