2002-03-28 15:09:10 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* Copyright (C) 2002 by Alan Korr
|
|
|
|
*
|
2008-06-28 18:10:04 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
2002-03-28 15:09:10 +00:00
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
2002-04-16 14:02:26 +00:00
|
|
|
#include "config.h"
|
2005-01-24 00:01:37 +00:00
|
|
|
#include "system.h"
|
2009-01-08 10:15:32 +00:00
|
|
|
#include <stdio.h>
|
2005-03-01 14:35:10 +00:00
|
|
|
#include "kernel.h"
|
2007-03-26 16:55:17 +00:00
|
|
|
#include "thread.h"
|
2006-08-05 20:19:10 +00:00
|
|
|
#include "string.h"
|
2005-03-01 14:35:10 +00:00
|
|
|
|
|
|
|
#ifndef SIMULATOR
|
2008-04-06 04:34:57 +00:00
|
|
|
long cpu_frequency SHAREDBSS_ATTR = CPU_FREQ;
|
2005-03-01 14:35:10 +00:00
|
|
|
#endif
|
2002-04-16 14:02:26 +00:00
|
|
|
|
2005-03-03 16:29:02 +00:00
|
|
|
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
2008-04-06 04:34:57 +00:00
|
|
|
static int boost_counter SHAREDBSS_ATTR = 0;
|
|
|
|
static bool cpu_idle SHAREDBSS_ATTR = false;
|
2007-10-16 01:25:17 +00:00
|
|
|
#if NUM_CORES > 1
|
2008-04-06 04:34:57 +00:00
|
|
|
struct spinlock boostctrl_spin SHAREDBSS_ATTR;
|
2007-10-16 01:25:17 +00:00
|
|
|
void cpu_boost_init(void)
|
|
|
|
{
|
2008-01-18 13:12:33 +00:00
|
|
|
spinlock_init(&boostctrl_spin);
|
2007-10-16 01:25:17 +00:00
|
|
|
}
|
|
|
|
#endif
|
2007-03-26 16:55:17 +00:00
|
|
|
|
2006-10-05 10:07:03 +00:00
|
|
|
int get_cpu_boost_counter(void)
|
|
|
|
{
|
|
|
|
return boost_counter;
|
|
|
|
}
|
2007-01-22 10:41:25 +00:00
|
|
|
#ifdef CPU_BOOST_LOGGING
|
|
|
|
#define MAX_BOOST_LOG 64
|
|
|
|
static char cpu_boost_calls[MAX_BOOST_LOG][MAX_PATH];
|
|
|
|
static int cpu_boost_first = 0;
|
|
|
|
static int cpu_boost_calls_count = 0;
|
|
|
|
static int cpu_boost_track_message = 0;
|
|
|
|
int cpu_boost_log_getcount(void)
|
|
|
|
{
|
|
|
|
return cpu_boost_calls_count;
|
|
|
|
}
|
|
|
|
char * cpu_boost_log_getlog_first(void)
|
|
|
|
{
|
2007-10-16 01:25:17 +00:00
|
|
|
char *first;
|
|
|
|
#if NUM_CORES > 1
|
|
|
|
spinlock_lock(&boostctrl_spin);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
first = NULL;
|
|
|
|
|
2007-01-22 10:41:25 +00:00
|
|
|
if (cpu_boost_calls_count)
|
|
|
|
{
|
|
|
|
cpu_boost_track_message = 1;
|
2007-10-16 01:25:17 +00:00
|
|
|
first = cpu_boost_calls[cpu_boost_first];
|
2007-01-22 10:41:25 +00:00
|
|
|
}
|
2007-10-16 01:25:17 +00:00
|
|
|
|
|
|
|
#if NUM_CORES > 1
|
|
|
|
spinlock_unlock(&boostctrl_spin);
|
|
|
|
#endif
|
2007-10-21 11:02:51 +00:00
|
|
|
|
|
|
|
return first;
|
2007-01-22 10:41:25 +00:00
|
|
|
}
|
2007-10-21 11:02:51 +00:00
|
|
|
|
2007-01-22 10:41:25 +00:00
|
|
|
char * cpu_boost_log_getlog_next(void)
|
|
|
|
{
|
2007-10-16 01:25:17 +00:00
|
|
|
int message;
|
|
|
|
char *next;
|
|
|
|
|
|
|
|
#if NUM_CORES > 1
|
|
|
|
spinlock_lock(&boostctrl_spin);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
message = (cpu_boost_track_message+cpu_boost_first)%MAX_BOOST_LOG;
|
|
|
|
next = NULL;
|
|
|
|
|
2007-01-22 10:41:25 +00:00
|
|
|
if (cpu_boost_track_message < cpu_boost_calls_count)
|
|
|
|
{
|
|
|
|
cpu_boost_track_message++;
|
2007-10-16 01:25:17 +00:00
|
|
|
next = cpu_boost_calls[message];
|
2007-01-22 10:41:25 +00:00
|
|
|
}
|
2007-10-16 01:25:17 +00:00
|
|
|
|
|
|
|
#if NUM_CORES > 1
|
|
|
|
spinlock_unlock(&boostctrl_spin);
|
|
|
|
#endif
|
2007-10-21 11:02:51 +00:00
|
|
|
|
|
|
|
return next;
|
2007-01-22 10:41:25 +00:00
|
|
|
}
|
2007-10-21 11:02:51 +00:00
|
|
|
|
2007-01-22 10:41:25 +00:00
|
|
|
void cpu_boost_(bool on_off, char* location, int line)
|
|
|
|
{
|
2007-10-16 01:25:17 +00:00
|
|
|
#if NUM_CORES > 1
|
|
|
|
spinlock_lock(&boostctrl_spin);
|
|
|
|
#endif
|
|
|
|
|
2007-01-22 10:41:25 +00:00
|
|
|
if (cpu_boost_calls_count == MAX_BOOST_LOG)
|
|
|
|
{
|
|
|
|
cpu_boost_first = (cpu_boost_first+1)%MAX_BOOST_LOG;
|
|
|
|
cpu_boost_calls_count--;
|
|
|
|
if (cpu_boost_calls_count < 0)
|
|
|
|
cpu_boost_calls_count = 0;
|
|
|
|
}
|
|
|
|
if (cpu_boost_calls_count < MAX_BOOST_LOG)
|
|
|
|
{
|
|
|
|
int message = (cpu_boost_first+cpu_boost_calls_count)%MAX_BOOST_LOG;
|
|
|
|
snprintf(cpu_boost_calls[message], MAX_PATH,
|
|
|
|
"%c %s:%d",on_off==true?'B':'U',location,line);
|
|
|
|
cpu_boost_calls_count++;
|
|
|
|
}
|
|
|
|
#else
|
2006-12-05 20:01:48 +00:00
|
|
|
void cpu_boost(bool on_off)
|
2005-03-03 16:29:02 +00:00
|
|
|
{
|
2007-10-16 01:25:17 +00:00
|
|
|
#if NUM_CORES > 1
|
|
|
|
spinlock_lock(&boostctrl_spin);
|
2007-01-22 10:41:25 +00:00
|
|
|
#endif
|
2007-10-16 01:25:17 +00:00
|
|
|
|
|
|
|
#endif /* CPU_BOOST_LOGGING */
|
2005-03-03 16:29:02 +00:00
|
|
|
if(on_off)
|
|
|
|
{
|
|
|
|
/* Boost the frequency if not already boosted */
|
2007-10-16 01:25:17 +00:00
|
|
|
if(++boost_counter == 1)
|
2005-03-03 16:29:02 +00:00
|
|
|
set_cpu_frequency(CPUFREQ_MAX);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Lower the frequency if the counter reaches 0 */
|
2007-10-16 01:25:17 +00:00
|
|
|
if(--boost_counter <= 0)
|
2005-03-03 16:29:02 +00:00
|
|
|
{
|
2005-07-05 07:58:19 +00:00
|
|
|
if(cpu_idle)
|
|
|
|
set_cpu_frequency(CPUFREQ_DEFAULT);
|
|
|
|
else
|
|
|
|
set_cpu_frequency(CPUFREQ_NORMAL);
|
2005-03-03 16:29:02 +00:00
|
|
|
|
2007-10-16 01:25:17 +00:00
|
|
|
/* Safety measure */
|
|
|
|
if (boost_counter < 0)
|
|
|
|
{
|
|
|
|
boost_counter = 0;
|
|
|
|
}
|
|
|
|
}
|
2005-03-03 16:29:02 +00:00
|
|
|
}
|
2007-10-16 01:25:17 +00:00
|
|
|
|
|
|
|
#if NUM_CORES > 1
|
|
|
|
spinlock_unlock(&boostctrl_spin);
|
|
|
|
#endif
|
2005-03-03 16:29:02 +00:00
|
|
|
}
|
2005-07-05 07:58:19 +00:00
|
|
|
|
|
|
|
void cpu_idle_mode(bool on_off)
|
|
|
|
{
|
2007-10-16 01:25:17 +00:00
|
|
|
#if NUM_CORES > 1
|
|
|
|
spinlock_lock(&boostctrl_spin);
|
|
|
|
#endif
|
|
|
|
|
2005-07-05 07:58:19 +00:00
|
|
|
cpu_idle = on_off;
|
|
|
|
|
|
|
|
/* We need to adjust the frequency immediately if the CPU
|
|
|
|
isn't boosted */
|
|
|
|
if(boost_counter == 0)
|
|
|
|
{
|
|
|
|
if(cpu_idle)
|
|
|
|
set_cpu_frequency(CPUFREQ_DEFAULT);
|
|
|
|
else
|
|
|
|
set_cpu_frequency(CPUFREQ_NORMAL);
|
|
|
|
}
|
2007-10-16 01:25:17 +00:00
|
|
|
|
|
|
|
#if NUM_CORES > 1
|
|
|
|
spinlock_unlock(&boostctrl_spin);
|
|
|
|
#endif
|
2005-07-05 07:58:19 +00:00
|
|
|
}
|
2006-12-05 20:01:48 +00:00
|
|
|
#endif /* HAVE_ADJUSTABLE_CPU_FREQ */
|
2005-07-05 07:58:19 +00:00
|
|
|
|
2006-11-08 18:33:06 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_FLASHED_ROCKBOX
|
2007-01-12 18:34:00 +00:00
|
|
|
static bool detect_flash_header(uint8_t *addr)
|
|
|
|
{
|
2006-11-08 18:33:06 +00:00
|
|
|
#ifndef BOOTLOADER
|
|
|
|
int oldmode = system_memory_guard(MEMGUARD_NONE);
|
|
|
|
#endif
|
2007-01-12 18:34:00 +00:00
|
|
|
struct flash_header hdr;
|
|
|
|
memcpy(&hdr, addr, sizeof(struct flash_header));
|
2006-11-08 18:33:06 +00:00
|
|
|
#ifndef BOOTLOADER
|
2006-08-11 10:13:16 +00:00
|
|
|
system_memory_guard(oldmode);
|
2007-01-12 18:34:00 +00:00
|
|
|
#endif
|
|
|
|
return hdr.magic == FLASH_MAGIC;
|
|
|
|
}
|
2006-11-08 18:33:06 +00:00
|
|
|
#endif
|
2006-08-21 17:35:35 +00:00
|
|
|
|
2007-01-12 18:34:00 +00:00
|
|
|
bool detect_flashed_romimage(void)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_FLASHED_ROCKBOX
|
|
|
|
return detect_flash_header((uint8_t *)FLASH_ROMIMAGE_ENTRY);
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif /* HAVE_FLASHED_ROCKBOX */
|
|
|
|
}
|
2006-08-21 17:35:35 +00:00
|
|
|
|
2007-01-12 18:34:00 +00:00
|
|
|
bool detect_flashed_ramimage(void)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_FLASHED_ROCKBOX
|
|
|
|
return detect_flash_header((uint8_t *)FLASH_RAMIMAGE_ENTRY);
|
2006-08-05 20:19:10 +00:00
|
|
|
#else
|
|
|
|
return false;
|
2006-11-08 18:33:06 +00:00
|
|
|
#endif /* HAVE_FLASHED_ROCKBOX */
|
2006-08-05 20:19:10 +00:00
|
|
|
}
|
|
|
|
|
2007-01-12 18:34:00 +00:00
|
|
|
bool detect_original_firmware(void)
|
|
|
|
{
|
|
|
|
return !(detect_flashed_ramimage() || detect_flashed_romimage());
|
|
|
|
}
|
|
|
|
|