]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/xscale/triton/v2_0/src/redboot_cmds.c
RedBoot TX53 Release 2012-02-15
[karo-tx-redboot.git] / packages / hal / arm / xscale / triton / v2_0 / src / redboot_cmds.c
1 //==========================================================================
2 //
3 //      redboot_cmds.c
4 //
5 //      TRITON [platform] specific RedBoot commands
6 //
7 //==========================================================================
8 //#####ECOSGPLCOPYRIGHTBEGIN####
9 //## -------------------------------------------
10 //## This file is part of eCos, the Embedded Configurable Operating System.
11 //## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //##
13 //## eCos is free software; you can redistribute it and/or modify it under
14 //## the terms of the GNU General Public License as published by the Free
15 //## Software Foundation; either version 2 or (at your option) any later version.
16 //##
17 //## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 //## WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 //## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 //## for more details.
21 //##
22 //## You should have received a copy of the GNU General Public License along
23 //## with eCos; if not, write to the Free Software Foundation, Inc.,
24 //## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //##
26 //## As a special exception, if other files instantiate templates or use macros
27 //## or inline functions from this file, or you compile this file and link it
28 //## with other works to produce a work based on this file, this file does not
29 //## by itself cause the resulting work to be covered by the GNU General Public
30 //## License. However the source code for this file must still be made available
31 //## in accordance with section (3) of the GNU General Public License.
32 //##
33 //## This exception does not invalidate any other reasons why a work based on
34 //## this file might be covered by the GNU General Public License.
35 //##
36 //## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 //## at http://sources.redhat.com/ecos/ecos-license/
38 //## -------------------------------------------
39 //#####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):    gthomas
44 // Contributors: gthomas
45 //               Richard Panton <richard.panton@3glab.com>
46 // Date:         2001-02-24
47 // Purpose:      
48 // Description:  
49 //              
50 // This code is part of RedBoot (tm).
51 //
52 //####DESCRIPTIONEND####
53 //
54 //==========================================================================
55
56 #include <redboot.h>
57
58 #include <cyg/hal/hal_triton.h>
59 #include <cyg/hal/hal_intr.h>
60 #include <cyg/hal/hal_cache.h>
61
62 // Exported CLI function(s)
63
64
65
66 #define CCCR_MEMCLK_99          0x00000001
67 #define CCCR_MEMCLK_117         0x00000002
68 #define CCCR_MEMCLK_132         0x00000003
69 #define CCCR_MEMCLK_147         0x00000004
70 #define CCCR_MEMCLK_165         0x00000005
71
72 #define CCCR_RUN_EQ_MEM         0x00000020
73 #define CCCR_RUN_2T_MEM         0x00000040
74
75 #define CCCR_TURBO_10           0x00000100
76 #define CCCR_TURBO_15           0x00000180
77 #define CCCR_TURBO_20           0x00000200
78 #define CCCR_TURBO_30           0x00000300
79
80
81
82 RedBoot_cmd("mem",
83             "Set a memory location",
84             "[-h|-b] [-a <address>] <data>",
85             do_mem
86             );
87
88 void do_mem(int argc, char *argv[])
89 {
90         struct option_info opts[3];
91         bool mem_half_word, mem_byte;
92         volatile cyg_uint32 *address = NULL;
93         cyg_uint32 value;
94
95         init_opts(&opts[0], 'b', false, OPTION_ARG_TYPE_FLG,
96                   (void *)&mem_byte, 0, "write a byte");
97         init_opts(&opts[1], 'h', false, OPTION_ARG_TYPE_FLG,
98                   (void *)&mem_half_word, 0, "write a half-word");
99         init_opts(&opts[2], 'a', true, OPTION_ARG_TYPE_NUM,
100                   (void *)&address, NULL, "address to write at");
101         if (!scan_opts(argc, argv, 1, opts, 3, (void *)&value, OPTION_ARG_TYPE_NUM, "address to set"))
102                 return;
103         if (mem_byte && mem_half_word) {
104                 diag_printf("*ERR: Should not specify both byte and half-word access\n");
105         } else if (mem_byte) {
106                 *(cyg_uint8*)address = (cyg_uint8)(value & 255);
107                 diag_printf("  Set 0x%08X to 0x%02X (result 0x%02X)\n", address, value & 255, (int)*(cyg_uint8*)address);
108         } else if (mem_half_word) {
109                 if ((unsigned long)address & 1) {
110                         diag_printf("*ERR: Badly aligned address 0x%08X for half-word store\n", address);
111                 } else {
112                         *(cyg_uint16*)address = (cyg_uint16)(value & 0xffff);
113                         diag_printf("  Set 0x%08X to 0x%04X (result 0x%04X)\n", address, value & 0xffff, (int)*(cyg_uint16*)address);
114                 }
115         } else {
116                 if ((unsigned long)address & 3) {
117                         diag_printf("*ERR: Badly aligned address 0x%08X for word store\n", address);
118                 } else {
119                         *address = value;
120                         diag_printf("  Set 0x%08X to 0x%08X (result 0x%08X)\n", address, value,
121                                     *address);
122                 }
123         }
124 }
125
126 RedBoot_cmd("clock", 
127             "Set/Query the system clock speed", 
128             "[-s <clock>]",
129             do_clock
130             );
131
132 int get_clock_rate(void) {
133         
134         unsigned long CCCR_reg, CCLKCFG_reg;
135         
136         
137         asm volatile (
138                       "ldr r1, =0x41300000;"            // Core Clock Config Reg
139                       "ldr %0, [r1];"
140                       "mrc p14, 0, %1, c6, c0, 0;"      // read CCLKCFG register
141                       : "=r"(CCCR_reg), "=r"(CCLKCFG_reg)
142                       :  
143                       : "r1"
144                       );
145
146         CCCR_reg &= 0x3ff;                      // blank reserved bits
147
148         if (!(CCLKCFG_reg & 1)) {               // we do not stay in turbo mode
149                 CCCR_reg &= 0x7f;               // delete turbo information
150                 switch (CCCR_reg) {
151                 case (CCCR_MEMCLK_99 | CCCR_RUN_EQ_MEM):
152                         return 100;
153                         break;
154                 case (CCCR_MEMCLK_99 | CCCR_RUN_2T_MEM):
155                         return 200;
156                         break;
157                 default:
158                         return 0;
159                 }
160         } else {                                // we stay in turbo mode
161                 switch (CCCR_reg) {
162                 case (CCCR_MEMCLK_99 | CCCR_RUN_2T_MEM | CCCR_TURBO_15):
163                         return 300;
164                         break;
165                 case (CCCR_MEMCLK_99 | CCCR_RUN_2T_MEM | CCCR_TURBO_20):
166                         return 400;
167                         break;
168                 default:
169                         return 0;
170                 }
171         }
172 }
173 void do_clock(int argc, char *argv[])
174 {
175         int new_clock, ret;
176         bool new_clock_set, clock_ok;
177         struct option_info opts[1];
178 //#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
179 //    struct config_option opt;
180 //#endif
181         unsigned long reg;
182
183         init_opts(&opts[0], 's', true, OPTION_ARG_TYPE_NUM,
184                   (void *)&new_clock, (bool *)&new_clock_set, "new clock speed");
185         if (!scan_opts(argc, argv, 1, opts, 1, 0, 0, "")) {
186                 return;
187         }
188
189         if (new_clock_set) {
190                 diag_printf("Clock speed will be changed to %d MHz\n", new_clock);
191         
192                 clock_ok = 1;    
193         
194                 switch (new_clock) {
195                 case 100:
196                         reg =   CCCR_MEMCLK_99  | CCCR_RUN_EQ_MEM | CCCR_TURBO_10;
197                         asm volatile (
198                                       "mov      r1,     %0;"
199                                       "ldr    r2, =0x41300000;"                 // Core Clock Config Reg
200                                       "str    r1, [r2];"                                // set speed
201                                       "mov      r1, #0x2;"                                      // no turbo mode
202                                       "mcr      p14, 0, r1, c6, c0, 0;"         // frequency change  sequence
203                                       :  
204                                       : "r"(reg)  
205                                       : "r1", "r2"
206                                       );        
207                         break;
208                 case 200:
209                         reg =   CCCR_MEMCLK_99 | CCCR_RUN_2T_MEM | CCCR_TURBO_10;
210                         asm volatile (
211                                       "mov      r1,     %0;"
212                                       "ldr    r2, =0x41300000;"                 // Core Clock Config Reg
213                                       "str    r1, [r2];"                                // set speed
214                                       "mov      r1, #0x2;"                                      // no turbo mode
215                                       "mcr      p14, 0, r1, c6, c0, 0;"         // frequency change  sequence
216                                       :  
217                                       : "r"(reg)  
218                                       : "r1", "r2"
219                                       );        
220                         break;
221                 case 300:       
222                         reg =   CCCR_MEMCLK_99 | CCCR_RUN_2T_MEM | CCCR_TURBO_15;
223                         asm volatile (
224                                       "mov      r1,     %0;"
225                                       "ldr    r2, =0x41300000;"                 // Core Clock Config Reg
226                                       "str    r1, [r2];"                                // set speed
227                                       "mov      r1, #0x3;"                                      // set turbo mode
228                                       "mcr      p14, 0, r1, c6, c0, 0;"         // frequency change  sequence
229                                       :  
230                                       : "r"(reg)  
231                                       : "r1", "r2"
232                                       );        
233                         break;
234                 case 400:
235                         reg =   CCCR_MEMCLK_99 | CCCR_RUN_2T_MEM | CCCR_TURBO_20;
236                         asm volatile (
237                                       "mov      r1,     %0;"
238                                       "ldr    r2, =0x41300000;"                 // Core Clock Config Reg
239                                       "str    r1, [r2];"                                // set speed
240                                       "mov      r1, #0x3;"                                      // set turbo mode
241                                       "mcr      p14, 0, r1, c6, c0, 0;"         // frequency change  sequence
242                                       :  
243                                       : "r"(reg)  
244                                       : "r1", "r2"
245                                       );        
246                         break;
247                 default:
248                         clock_ok = 0;
249                         diag_printf("\ndon't know how to install %d MHz, keeping clock speed at %d MHz\n\n", new_clock, get_clock_rate());
250                 }       
251                 if (clock_ok) {    
252                         diag_printf("\nclock speed set to %d MHz ...\n", new_clock);
253                 }
254
255 //#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
256 //        opt.type = CONFIG_INT;
257 //        opt.enable = (char *)0;
258 //        opt.enable_sense = 1;
259 //        opt.key = "console_baud_rate";
260 //        opt.dflt = new_rate;
261 //        flash_add_config(&opt, true);
262 //#endif
263         } else {
264                 ret = get_clock_rate();
265                 diag_printf("Clock = ");
266                 if (ret == 0) {
267                         diag_printf("unknown\n");
268                 } else {
269                         diag_printf("%d\n", ret);
270                 }
271         }
272 }
273
274 RedBoot_cmd("run",
275             "Execute code at a location",
276             "[-w <timeout>] [entry]",
277             do_run
278             );
279
280 void do_run(int argc, char *argv[])
281 {
282         typedef void code_fun(void);
283         unsigned long entry;
284         unsigned long oldints;
285         code_fun *fun;
286         bool wait_time_set;
287         int  wait_time, res;
288         struct option_info opts[1];
289         char line[8];
290
291         entry = entry_address;  // Default from last 'load' operation
292         init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM,
293                   (void *)&wait_time, (bool *)&wait_time_set, "wait timeout");
294         if (!scan_opts(argc, argv, 1, opts, 1, (void *)&entry, OPTION_ARG_TYPE_NUM,
295                        "starting address")) {
296                 entry = 0xa0100000;
297                 diag_printf("starting run at address 0x%08X ...\n", entry);
298         }
299         if (wait_time_set) {
300                 int script_timeout_ms = wait_time * 1000;
301 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
302                 unsigned char *hold_script = script;
303                 script = (unsigned char *)0;
304 #endif
305                 diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
306                             (void *)entry, wait_time);
307                 while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
308                         res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
309                         if (res == _GETS_CTRLC) {
310 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
311                                 script = hold_script;  // Re-enable script
312 #endif
313                                 return;
314                         }
315                         script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
316                 }
317         }
318         fun = (code_fun *)entry;
319         HAL_DISABLE_INTERRUPTS(oldints);
320         HAL_DCACHE_SYNC();
321         HAL_ICACHE_DISABLE();
322         HAL_DCACHE_DISABLE();
323         HAL_DCACHE_SYNC();
324         HAL_ICACHE_INVALIDATE_ALL();
325         HAL_DCACHE_INVALIDATE_ALL();
326 #ifdef HAL_ARCH_PROGRAM_NEW_STACK
327         HAL_ARCH_PROGRAM_NEW_STACK(fun);
328 #else
329         (*fun)();
330 #endif
331         HAL_ICACHE_ENABLE();
332         HAL_DCACHE_ENABLE();
333         HAL_RESTORE_INTERRUPTS(oldints);
334 }