]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/hal/arm/mx37/stk5/v1_0/src/redboot_cmds.c
RedBoot TX53 Release 2012-02-15
[karo-tx-redboot.git] / packages / hal / arm / mx37 / stk5 / v1_0 / src / redboot_cmds.c
1 //==========================================================================
2 //
3 //      redboot_cmds.c
4 //
5 //      Board [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 #include <redboot.h>
42 #include <cyg/hal/hal_intr.h>
43 #include <cyg/hal/hal_cache.h>
44 #include <cyg/hal/plf_mmap.h>
45 #include <cyg/hal/karo_tx37.h>          // Platform specific hardware definitions
46
47 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
48 #include <flash_config.h>
49
50 #if (REDBOOT_IMAGE_SIZE != CYGBLD_REDBOOT_MIN_IMAGE_SIZE)
51 #error REDBOOT_IMAGE_SIZE != CYGBLD_REDBOOT_MIN_IMAGE_SIZE
52 #endif
53
54 #endif  //CYGSEM_REDBOOT_FLASH_CONFIG
55
56 char HAL_PLATFORM_EXTRA[20] = "PASS x.x [x32 DDR]";
57 static void runImg(int argc, char *argv[]);
58 static void do_mem(int argc, char *argv[]);
59
60 RedBoot_cmd("mem",
61             "Set a memory location",
62             "[-h|-b] [-n] [-a <address>] <data>",
63             do_mem
64     );
65
66 RedBoot_cmd("run",
67             "Run an image at a location with MMU off",
68             "[<virtual addr>]",
69             runImg
70            );
71
72 static void do_mem(int argc, char *argv[])
73 {
74         struct option_info opts[4];
75         bool mem_half_word, mem_byte;
76         bool no_verify;
77         bool addr_set;
78         unsigned long address;
79         unsigned int value;
80         int ret;
81         init_opts(&opts[0], 'b', false, OPTION_ARG_TYPE_FLG,
82                   &mem_byte, NULL, "write a byte");
83         init_opts(&opts[1], 'h', false, OPTION_ARG_TYPE_FLG,
84                   &mem_half_word, NULL, "write a half-word");
85         init_opts(&opts[2], 'a', true, OPTION_ARG_TYPE_NUM,
86                   &address, &addr_set, "address to write to");
87         init_opts(&opts[3], 'n', false, OPTION_ARG_TYPE_FLG,
88                   &no_verify, NULL, "noverify");
89
90         ret = scan_opts(argc, argv, 1, opts, sizeof(opts) / sizeof(opts[0]),
91                         &value, OPTION_ARG_TYPE_NUM, "value to be written");
92         if (ret == 0) {
93                 return;
94         }
95         if (!addr_set) {
96                 diag_printf("** Error: '-a <address>' must be specified\n");
97                 return;
98         }
99         if (ret == argc + 1) {
100                 diag_printf("** Error: non-option argument '<value>' must be specified\n");
101                 return;
102         }
103         if (mem_byte && mem_half_word) {
104                 diag_printf("** Error: Should not specify both byte and half-word access\n");
105         } else if (mem_byte) {
106                 value &= 0xff;
107                 *(volatile cyg_uint8*)address = (cyg_uint8)value;
108                 if (no_verify) {
109                         diag_printf("  Set 0x%08lX to 0x%02X\n", address, value);
110                 } else {
111                         diag_printf("  Set 0x%08lX to 0x%02X (result 0x%02X)\n",
112                                     address, value, (int)*(cyg_uint8*)address );
113                 }
114         } else if (mem_half_word) {
115                 if (address & 1) {
116                         diag_printf("** Error: address for half-word access must be half-word aligned\n");
117                 } else {
118                         value &= 0xffff;
119                         *(volatile cyg_uint16*)address = (cyg_uint16)value;
120                         if (no_verify) {
121                                 diag_printf("  Set 0x%08lX to 0x%04X\n", address, value);
122                         } else {
123                                 diag_printf("  Set 0x%08lX to 0x%04X (result 0x%04X)\n",
124                                             address, value, (int)*(cyg_uint16*)address);
125                         }
126                 }
127         } else {
128                 if (address & 3) {
129                         diag_printf("** Error: address for word access must be word aligned\n");
130                 } else {
131                         *(volatile cyg_uint32*)address = (cyg_uint32)value;
132                         if (no_verify) {
133                                 diag_printf("  Set 0x%08lX to 0x%08X\n", address, value);
134                         } else {
135                                 diag_printf("  Set 0x%08lX to 0x%08X (result 0x%08X)\n",
136                                             address, value, (int)*(cyg_uint32*)address);
137                         }
138                 }
139         }
140 }
141
142 void launchRunImg(unsigned long addr)
143 {
144     asm volatile ("mov r12, r0;");
145     HAL_CLEAN_INVALIDATE_L2();
146     HAL_DISABLE_L2();
147     HAL_MMU_OFF();
148     asm volatile (
149                  "mov r0, #0;"
150                  "mov r1, r12;"
151                  "mov r11, #0;"
152                  "mov r12, #0;"
153                  "mrs r10, cpsr;"
154                  "bic r10, r10, #0xF0000000;"
155                  "msr cpsr_f, r10;"
156                  "mov pc, r1"
157                  );
158 }
159
160 extern unsigned long entry_address;
161
162 static void runImg(int argc,char *argv[])
163 {
164         unsigned int virt_addr, phys_addr;
165
166         // Default physical entry point for Symbian
167         if (entry_address == 0xFFFFFFFF)
168                 virt_addr = 0x800000;
169         else
170                 virt_addr = entry_address;
171
172         if (!scan_opts(argc, argv, 1, 0, 0, &virt_addr,
173                        OPTION_ARG_TYPE_NUM, "virtual address"))
174                 return;
175
176         if (entry_address != 0xFFFFFFFF)
177                 diag_printf("load entry_address=0x%lx\n", entry_address);
178         HAL_VIRT_TO_PHYS_ADDRESS(virt_addr, phys_addr);
179
180         diag_printf("virt_addr=0x%x\n",virt_addr);
181         diag_printf("phys_addr=0x%x\n",phys_addr);
182
183         launchRunImg(phys_addr);
184 }
185
186 #if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && defined(CYG_HAL_STARTUP_ROMRAM)
187
188 RedBoot_cmd("romupdate",
189             "Update Redboot with currently running image",
190             "",
191             romupdate
192            );
193
194 extern int flash_program(void *_addr, void *_data, int len, void **err_addr);
195 extern int flash_erase(void *addr, int len, void **err_addr);
196 extern char *flash_errmsg(int err);
197
198 #ifdef CYGPKG_IO_FLASH
199 void romupdate(int argc, char *argv[])
200 {
201         void *err_addr, *base_addr;
202         int stat;
203
204         base_addr = (void*)MXC_NAND_BASE_DUMMY;
205         diag_printf("Updating RedBoot in NAND flash\n");
206
207         // Erase area to be programmed
208         if ((stat = flash_erase(base_addr, CYGBLD_REDBOOT_MIN_IMAGE_SIZE, &err_addr)) != 0) {
209                 diag_printf("Can't erase region at %p: %s\n",
210                             err_addr, flash_errmsg(stat));
211                 return;
212         }
213         // Now program it
214         if ((stat = flash_program(base_addr, ram_end - CYGMEM_REGION_rom_SIZE,
215                                   CYGBLD_REDBOOT_MIN_IMAGE_SIZE, &err_addr)) != 0) {
216                 diag_printf("Can't program region at %p: %s\n",
217                             err_addr, flash_errmsg(stat));
218         }
219 }
220 #endif //CYGPKG_IO_FLASH
221 #endif /* CYG_HAL_STARTUP_ROMRAM */
222
223 static void setcorevol(int argc, char *argv[]);
224
225 RedBoot_cmd("setcorevol",
226             "Set the core voltage. Setting is not checked against current core frequency.",
227             "[1.2 | 1.25 | 1.3 | 1.35 | 1.4 | 1.45 | 1.5 | 1.55 | 1.6]",
228             setcorevol
229            );
230
231 /*
232  * This function communicates with LP3972 to set the core voltage according to
233  * the argument
234  */
235 // LW: revisit use I2C routines for LP3972
236 unsigned int setCoreVoltage(unsigned int coreVol)
237 {
238         /* Set the core voltage */
239         diag_printf("%s: Not yet implemented\n", __FUNCTION__);
240         return 0;
241 }
242
243 static void setcorevol(int argc, char *argv[])
244 {
245         unsigned int coreVol;
246
247         /* check if the number of args is OK. 1 arg expected. argc = 2 */
248         if (argc != 2) {
249                 diag_printf("Invalid argument. Need to specify a voltage\n");
250                 return;
251         }
252
253         /* check if the argument is valid. */
254         if (strcasecmp(argv[1], "1.2") == 0) {
255                 coreVol = 0xC;
256         } else if (strcasecmp(argv[1], "1.25") == 0) {
257                 coreVol = 0xE;
258         } else if (strcasecmp(argv[1], "1.3") == 0) {
259                 coreVol = 0x10;
260         } else if (strcasecmp(argv[1], "1.35") == 0) {
261                 coreVol = 0x12;
262         } else if (strcasecmp(argv[1], "1.4") == 0) {
263                 coreVol = 0x14;
264         } else if (strcasecmp(argv[1], "1.45") == 0) {
265                 coreVol = 0x16;
266         } else if (strcasecmp(argv[1], "1.5") == 0) {
267                 coreVol = 0x18;
268         } else if (strcasecmp(argv[1], "1.55") == 0) {
269                 coreVol = 0x1A;
270         } else if (strcasecmp(argv[1], "1.6") == 0) {
271                 coreVol = 0x1C;
272         } else {
273                 diag_printf("Invalid argument. Type help setcorevol for valid values\n");
274                 return ;
275         }
276
277         setCoreVoltage(coreVol);
278         return;
279 }