+++ /dev/null
-//==========================================================================
-//
-// redboot_cmds.c
-//
-// TRITON [platform] specific RedBoot commands
-//
-//==========================================================================
-//#####ECOSGPLCOPYRIGHTBEGIN####
-//## -------------------------------------------
-//## This file is part of eCos, the Embedded Configurable Operating System.
-//## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-//##
-//## eCos 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 or (at your option) any later version.
-//##
-//## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
-//## WARRANTY; without even the implied warranty of MERCHANTABILITY or
-//## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-//## for more details.
-//##
-//## You should have received a copy of the GNU General Public License along
-//## with eCos; if not, write to the Free Software Foundation, Inc.,
-//## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-//##
-//## As a special exception, if other files instantiate templates or use macros
-//## or inline functions from this file, or you compile this file and link it
-//## with other works to produce a work based on this file, this file does not
-//## by itself cause the resulting work to be covered by the GNU General Public
-//## License. However the source code for this file must still be made available
-//## in accordance with section (3) of the GNU General Public License.
-//##
-//## This exception does not invalidate any other reasons why a work based on
-//## this file might be covered by the GNU General Public License.
-//##
-//## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-//## at http://sources.redhat.com/ecos/ecos-license/
-//## -------------------------------------------
-//#####ECOSGPLCOPYRIGHTEND####
-//==========================================================================
-//#####DESCRIPTIONBEGIN####
-//
-// Author(s): gthomas
-// Contributors: gthomas
-// Richard Panton <richard.panton@3glab.com>
-// Date: 2001-02-24
-// Purpose:
-// Description:
-//
-// This code is part of RedBoot (tm).
-//
-//####DESCRIPTIONEND####
-//
-//==========================================================================
-
-#include <redboot.h>
-
-#include <cyg/hal/hal_triton.h>
-#include <cyg/hal/hal_intr.h>
-#include <cyg/hal/hal_cache.h>
-
-// Exported CLI function(s)
-
-
-
-#define CCCR_MEMCLK_99 0x00000001
-#define CCCR_MEMCLK_117 0x00000002
-#define CCCR_MEMCLK_132 0x00000003
-#define CCCR_MEMCLK_147 0x00000004
-#define CCCR_MEMCLK_165 0x00000005
-
-#define CCCR_RUN_EQ_MEM 0x00000020
-#define CCCR_RUN_2T_MEM 0x00000040
-
-#define CCCR_TURBO_10 0x00000100
-#define CCCR_TURBO_15 0x00000180
-#define CCCR_TURBO_20 0x00000200
-#define CCCR_TURBO_30 0x00000300
-
-
-
-RedBoot_cmd("mem",
- "Set a memory location",
- "[-h|-b] [-a <address>] <data>",
- do_mem
- );
-
-void do_mem(int argc, char *argv[])
-{
- struct option_info opts[3];
- bool mem_half_word, mem_byte;
- volatile cyg_uint32 *address = NULL;
- cyg_uint32 value;
-
- init_opts(&opts[0], 'b', false, OPTION_ARG_TYPE_FLG,
- (void *)&mem_byte, 0, "write a byte");
- init_opts(&opts[1], 'h', false, OPTION_ARG_TYPE_FLG,
- (void *)&mem_half_word, 0, "write a half-word");
- init_opts(&opts[2], 'a', true, OPTION_ARG_TYPE_NUM,
- (void *)&address, NULL, "address to write at");
- if (!scan_opts(argc, argv, 1, opts, 3, (void *)&value, OPTION_ARG_TYPE_NUM, "address to set"))
- return;
- if (mem_byte && mem_half_word) {
- diag_printf("*ERR: Should not specify both byte and half-word access\n");
- } else if (mem_byte) {
- *(cyg_uint8*)address = (cyg_uint8)(value & 255);
- diag_printf(" Set 0x%08X to 0x%02X (result 0x%02X)\n", address, value & 255, (int)*(cyg_uint8*)address);
- } else if (mem_half_word) {
- if ((unsigned long)address & 1) {
- diag_printf("*ERR: Badly aligned address 0x%08X for half-word store\n", address);
- } else {
- *(cyg_uint16*)address = (cyg_uint16)(value & 0xffff);
- diag_printf(" Set 0x%08X to 0x%04X (result 0x%04X)\n", address, value & 0xffff, (int)*(cyg_uint16*)address);
- }
- } else {
- if ((unsigned long)address & 3) {
- diag_printf("*ERR: Badly aligned address 0x%08X for word store\n", address);
- } else {
- *address = value;
- diag_printf(" Set 0x%08X to 0x%08X (result 0x%08X)\n", address, value,
- *address);
- }
- }
-}
-
-RedBoot_cmd("clock",
- "Set/Query the system clock speed",
- "[-s <clock>]",
- do_clock
- );
-
-int get_clock_rate(void) {
-
- unsigned long CCCR_reg, CCLKCFG_reg;
-
-
- asm volatile (
- "ldr r1, =0x41300000;" // Core Clock Config Reg
- "ldr %0, [r1];"
- "mrc p14, 0, %1, c6, c0, 0;" // read CCLKCFG register
- : "=r"(CCCR_reg), "=r"(CCLKCFG_reg)
- :
- : "r1"
- );
-
- CCCR_reg &= 0x3ff; // blank reserved bits
-
- if (!(CCLKCFG_reg & 1)) { // we do not stay in turbo mode
- CCCR_reg &= 0x7f; // delete turbo information
- switch (CCCR_reg) {
- case (CCCR_MEMCLK_99 | CCCR_RUN_EQ_MEM):
- return 100;
- break;
- case (CCCR_MEMCLK_99 | CCCR_RUN_2T_MEM):
- return 200;
- break;
- default:
- return 0;
- }
- } else { // we stay in turbo mode
- switch (CCCR_reg) {
- case (CCCR_MEMCLK_99 | CCCR_RUN_2T_MEM | CCCR_TURBO_15):
- return 300;
- break;
- case (CCCR_MEMCLK_99 | CCCR_RUN_2T_MEM | CCCR_TURBO_20):
- return 400;
- break;
- default:
- return 0;
- }
- }
-}
-void do_clock(int argc, char *argv[])
-{
- int new_clock, ret;
- bool new_clock_set, clock_ok;
- struct option_info opts[1];
-//#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
-// struct config_option opt;
-//#endif
- unsigned long reg;
-
- init_opts(&opts[0], 's', true, OPTION_ARG_TYPE_NUM,
- (void *)&new_clock, (bool *)&new_clock_set, "new clock speed");
- if (!scan_opts(argc, argv, 1, opts, 1, 0, 0, "")) {
- return;
- }
-
- if (new_clock_set) {
- diag_printf("Clock speed will be changed to %d MHz\n", new_clock);
-
- clock_ok = 1;
-
- switch (new_clock) {
- case 100:
- reg = CCCR_MEMCLK_99 | CCCR_RUN_EQ_MEM | CCCR_TURBO_10;
- asm volatile (
- "mov r1, %0;"
- "ldr r2, =0x41300000;" // Core Clock Config Reg
- "str r1, [r2];" // set speed
- "mov r1, #0x2;" // no turbo mode
- "mcr p14, 0, r1, c6, c0, 0;" // frequency change sequence
- :
- : "r"(reg)
- : "r1", "r2"
- );
- break;
- case 200:
- reg = CCCR_MEMCLK_99 | CCCR_RUN_2T_MEM | CCCR_TURBO_10;
- asm volatile (
- "mov r1, %0;"
- "ldr r2, =0x41300000;" // Core Clock Config Reg
- "str r1, [r2];" // set speed
- "mov r1, #0x2;" // no turbo mode
- "mcr p14, 0, r1, c6, c0, 0;" // frequency change sequence
- :
- : "r"(reg)
- : "r1", "r2"
- );
- break;
- case 300:
- reg = CCCR_MEMCLK_99 | CCCR_RUN_2T_MEM | CCCR_TURBO_15;
- asm volatile (
- "mov r1, %0;"
- "ldr r2, =0x41300000;" // Core Clock Config Reg
- "str r1, [r2];" // set speed
- "mov r1, #0x3;" // set turbo mode
- "mcr p14, 0, r1, c6, c0, 0;" // frequency change sequence
- :
- : "r"(reg)
- : "r1", "r2"
- );
- break;
- case 400:
- reg = CCCR_MEMCLK_99 | CCCR_RUN_2T_MEM | CCCR_TURBO_20;
- asm volatile (
- "mov r1, %0;"
- "ldr r2, =0x41300000;" // Core Clock Config Reg
- "str r1, [r2];" // set speed
- "mov r1, #0x3;" // set turbo mode
- "mcr p14, 0, r1, c6, c0, 0;" // frequency change sequence
- :
- : "r"(reg)
- : "r1", "r2"
- );
- break;
- default:
- clock_ok = 0;
- diag_printf("\ndon't know how to install %d MHz, keeping clock speed at %d MHz\n\n", new_clock, get_clock_rate());
- }
- if (clock_ok) {
- diag_printf("\nclock speed set to %d MHz ...\n", new_clock);
- }
-
-//#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
-// opt.type = CONFIG_INT;
-// opt.enable = (char *)0;
-// opt.enable_sense = 1;
-// opt.key = "console_baud_rate";
-// opt.dflt = new_rate;
-// flash_add_config(&opt, true);
-//#endif
- } else {
- ret = get_clock_rate();
- diag_printf("Clock = ");
- if (ret == 0) {
- diag_printf("unknown\n");
- } else {
- diag_printf("%d\n", ret);
- }
- }
-}
-
-RedBoot_cmd("run",
- "Execute code at a location",
- "[-w <timeout>] [entry]",
- do_run
- );
-
-void do_run(int argc, char *argv[])
-{
- typedef void code_fun(void);
- unsigned long entry;
- unsigned long oldints;
- code_fun *fun;
- bool wait_time_set;
- int wait_time, res;
- struct option_info opts[1];
- char line[8];
-
- entry = entry_address; // Default from last 'load' operation
- init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM,
- (void *)&wait_time, (bool *)&wait_time_set, "wait timeout");
- if (!scan_opts(argc, argv, 1, opts, 1, (void *)&entry, OPTION_ARG_TYPE_NUM,
- "starting address")) {
- entry = 0xa0100000;
- diag_printf("starting run at address 0x%08X ...\n", entry);
- }
- if (wait_time_set) {
- int script_timeout_ms = wait_time * 1000;
-#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
- unsigned char *hold_script = script;
- script = (unsigned char *)0;
-#endif
- diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
- (void *)entry, wait_time);
- while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
- res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
- if (res == _GETS_CTRLC) {
-#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
- script = hold_script; // Re-enable script
-#endif
- return;
- }
- script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
- }
- }
- fun = (code_fun *)entry;
- HAL_DISABLE_INTERRUPTS(oldints);
- HAL_DCACHE_SYNC();
- HAL_ICACHE_DISABLE();
- HAL_DCACHE_DISABLE();
- HAL_DCACHE_SYNC();
- HAL_ICACHE_INVALIDATE_ALL();
- HAL_DCACHE_INVALIDATE_ALL();
-#ifdef HAL_ARCH_PROGRAM_NEW_STACK
- HAL_ARCH_PROGRAM_NEW_STACK(fun);
-#else
- (*fun)();
-#endif
- HAL_ICACHE_ENABLE();
- HAL_DCACHE_ENABLE();
- HAL_RESTORE_INTERRUPTS(oldints);
-}