X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;f=packages%2Fhal%2Farm%2Fxscale%2Ftriton%2Fv2_0%2Fsrc%2Fredboot_cmds.c;fp=packages%2Fhal%2Farm%2Fxscale%2Ftriton%2Fv2_0%2Fsrc%2Fredboot_cmds.c;h=f9f73f397284260d472718b54de99184fa07ca67;hb=2b5bec7716c03d42cfb16d8c98c9cea573bf6722;hp=0000000000000000000000000000000000000000;hpb=47412fc4bd1aefc0d5498bcb3860a9d727196f16;p=karo-tx-redboot.git diff --git a/packages/hal/arm/xscale/triton/v2_0/src/redboot_cmds.c b/packages/hal/arm/xscale/triton/v2_0/src/redboot_cmds.c new file mode 100755 index 00000000..f9f73f39 --- /dev/null +++ b/packages/hal/arm/xscale/triton/v2_0/src/redboot_cmds.c @@ -0,0 +1,334 @@ +//========================================================================== +// +// 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 +// Date: 2001-02-24 +// Purpose: +// Description: +// +// This code is part of RedBoot (tm). +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include + +#include +#include +#include + +// 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
] ", + 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 ]", + 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 ] [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); +}