]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/mx27/ads/v2_0/src/redboot_cmds.c
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / mx27 / ads / v2_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/fsl_board.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 RedBoot_config_option("Board specifics",
55                       brd_specs,
56                       ALWAYS_ENABLED,
57                       true,
58                       CONFIG_INT,
59                       0
60                      );
61 #endif  //CYGSEM_REDBOOT_FLASH_CONFIG
62
63 extern unsigned int spi_xchg_single(unsigned int data, unsigned int base);
64 #define REG_SWITCHER_0  24
65
66 static void runImg(int argc, char *argv[]);
67
68 RedBoot_cmd("run",
69             "Run an image at a location with MMU off",
70             "[<virtual addr>]",
71             runImg
72            );
73
74 void launchRunImg(unsigned long addr)
75 {
76     asm volatile ("mov r1, r0;");
77     HAL_MMU_OFF();
78     asm volatile (
79                  "mov r11, #0;"
80                  "mov r12, #0;"
81                  "mrs r10, cpsr;"
82                  "bic r10, r10, #0xF0000000;"
83                  "msr cpsr_f, r10;"
84                  "mov pc, r1"
85                  );
86 }
87
88 extern unsigned long entry_address;
89
90 static void runImg(int argc,char *argv[])
91 {
92     unsigned int virt_addr, phys_addr;
93
94     // Default physical entry point for Symbian
95     if (entry_address == 0xFFFFFFFF)
96         virt_addr = 0x800000;
97     else
98     virt_addr = entry_address;
99
100     if (!scan_opts(argc,argv,1,0,0,(void*)&virt_addr,
101                    OPTION_ARG_TYPE_NUM, "virtual address"))
102         return;
103
104     if (entry_address != 0xFFFFFFFF)
105         diag_printf("load entry_address=0x%lx\n", entry_address);
106     HAL_VIRT_TO_PHYS_ADDRESS(virt_addr, phys_addr);
107
108     diag_printf("virt_addr=0x%x\n",virt_addr);
109     diag_printf("phys_addr=0x%x\n",phys_addr);
110
111     launchRunImg(phys_addr);
112 }
113
114 #if CYGPKG_REDBOOT_NETWORKING
115 #define LAN_BASE        BOARD_CS_LAN_BASE
116
117 #define PP_EE_ADDR_W0   0x001C
118 #define PP_EE_ADDR_W1   0x001D
119 #define PP_EE_ADDR_W2   0x001E
120
121 extern cyg_uint16 read_eeprom(cyg_addrword_t base, cyg_uint16 offset);
122 extern void write_eeprom(cyg_addrword_t base, cyg_uint16 offset, cyg_uint16 data);
123
124 // Exported CLI function(s)
125 static void setMac(int argc, char *argv[]);
126 RedBoot_cmd("setmac",
127             "Set Ethernet MAC address in EEPROM",
128             "[0x##:0x##:0x##:0x##:0x##:0x##]",
129             setMac
130            );
131
132 const static unsigned short RESET_CONFIG_BLOCK[] = {
133     0xA002,
134     0x5E00,
135 };
136
137 #define DRIVER_CONFIG_BASE        0x1C   //Cirrus driver config base
138
139 static unsigned short g_drv_cfg_blk[] = {
140     0xFFFF, //1C - MAC 4,5
141     0xFFFF, //1D - MAC 2,3
142     0xFFFF, //1E - MAC 0,1
143     0x0000, //1F - ISA config
144     0x0000, //20 - PP mem base
145     0x0000, //21 - Boot PROM base
146     0x0000, //22 - Boot PROM mask
147     0x8040, //23 - Tx ctrl: Full duplex, media not required
148     0x0021, //24 - Adapter config: 10Base-T, 10Base-T circuitry
149     0x0001, //25 - EEPROM rev: 1.0
150     0x0000, //26 - resvd
151     0x0A2D, //27 - Mfg date
152     0xFFFF, //28 - copy of 1C
153     0xFFFF, //29 - copy of 1D
154     0xFFFF, //2A - copy of 1E
155     0x0000, //2B - resvd
156     0x0000, //2C - resvd
157     0x0000, //2D - resvd
158     0x0000, //2E - resvd
159     0x0000, //2F - Checksum
160 };
161
162 static void setMac(int argc,char *argv[])
163 {
164     int i, ret, wsize = sizeof(g_drv_cfg_blk) / 2;  // word size
165     unsigned char data[6];
166     unsigned long temp;
167     unsigned short ee_word[3];
168
169     if (argc == 1) {
170         ee_word[0] = read_eeprom(LAN_BASE, PP_EE_ADDR_W0 + 0);
171         ee_word[1] = read_eeprom(LAN_BASE, PP_EE_ADDR_W0 + 1);
172         ee_word[2] = read_eeprom(LAN_BASE, PP_EE_ADDR_W0 + 2);
173         if (ee_word[0] == 0 && ee_word[1] == 0 && ee_word[2] == 0) {
174             diag_printf("Can't read MAC address\n\n");
175             return;
176         }
177
178         diag_printf("MAC address: ");
179         diag_printf("0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n\n",
180                     (ee_word[0] & 0x00FF), (ee_word[0] >> 8),
181                     (ee_word[1] & 0x00FF), (ee_word[1] >> 8),
182                     (ee_word[2] & 0x00FF), (ee_word[2] >> 8));
183         return;
184     }
185
186     if (argc != 2) {
187         ret = -1; goto error;
188     }
189
190     for (i = 0;  i < 6;  i++) {
191         if (!parse_num(*(&argv[1]), &temp, &argv[1], ":")) {
192             ret = -2; goto error;
193         }
194         if (temp > 0xFF) {
195             ret = -3; goto error;
196         }
197         data[i] = temp & 0xFF;
198     }
199
200     g_drv_cfg_blk[0] = g_drv_cfg_blk[12] = *(unsigned short*)(&data[0]);
201     g_drv_cfg_blk[1] = g_drv_cfg_blk[13] = *(unsigned short*)(&data[2]);
202     g_drv_cfg_blk[2] = g_drv_cfg_blk[14] = *(unsigned short*)(&data[4]);
203
204     // Calculate checksum
205     temp = 0;
206     for (i = 0; i < wsize-1; i++) {
207         temp += g_drv_cfg_blk[i];
208     }
209     temp = (~temp + 1) & 0xFFFF;
210     g_drv_cfg_blk[wsize-1] = temp;
211
212     // Program the EEPROM
213     // Reset config block first
214     for (i = 0; i < sizeof(RESET_CONFIG_BLOCK)/2; i++) {
215         write_eeprom(LAN_BASE, i, RESET_CONFIG_BLOCK[i]);
216     }
217     // Driver config block 2nd
218     for (i = 0; i < wsize; i++) {
219         write_eeprom(LAN_BASE, DRIVER_CONFIG_BASE+i,
220                      g_drv_cfg_blk[i]);
221     }
222     return;
223     error:
224     diag_printf("Wrong value for setMac. Error=%d\n\n", ret);
225 }
226
227 //#define EEPROM_DEBUG
228 #ifdef EEPROM_DEBUG
229 RedBoot_cmd("eefun",
230             "read/write a word into EEPROM",
231             "[0-based IO Base offset:value]",
232             eefun
233            );
234
235 static void eefun(int argc,char *argv[])
236 {
237     int i, ret;
238     unsigned short data[2];
239     unsigned int temp;
240
241     if (argc != 2) {
242         ret=-1; goto error;
243     }
244
245     for (i = 0;  i < 2;  i++) {
246         if (!parse_num(*(&argv[1]), &temp, &argv[1], ":")) {
247             ret=-2; goto error;
248         }
249         if (temp > 0xFFFF) {
250             ret=-3; goto error;
251         }
252         data[i] = (unsigned short)temp;
253     }
254
255     if (data[0] >= 0x30 && data[0] != 0xFFFF) {
256         ret=-4; goto error;
257     }
258
259     if (data[0] == 0xFFFF) {
260         for (i = 0; i < 0x30; i++) {
261             if (i % 8 == 0) diag_printf("0x%02x: ", i);
262             diag_printf("%04x ", read_eeprom(LAN_BASE, i));
263             if (i % 8 == 7) diag_printf("\n");
264         }
265         return;
266     }
267
268     diag_printf("writeEE() Offset: 0x%x, value=0x%x\n", data[0], data[1]);
269     write_eeprom(LAN_BASE, data[0], data[1]);
270     diag_printf("Reading back: 0x%x\n\n", read_eeprom(LAN_BASE, data[0]));
271     return;
272     error:
273     diag_printf("Wrong value %d for writeEE\n\n", ret);
274 }
275 #endif //EEPROM_DEBUG
276
277 #endif //CYGPKG_REDBOOT_NETWORKING
278
279 #if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && defined(CYG_HAL_STARTUP_ROMRAM)
280
281 RedBoot_cmd("romupdate",
282             "Update Redboot with currently running image",
283             "",
284             romupdate
285            );
286
287 extern int flash_program(void *_addr, void *_data, int len, void **err_addr);
288 extern int flash_erase(void *addr, int len, void **err_addr);
289 extern char *flash_errmsg(int err);
290 extern unsigned char *ram_end; //ram end is where the redboot starts FIXME: use PC value
291
292 #ifdef CYGPKG_IO_FLASH
293 void romupdate(int argc, char *argv[])
294 {
295     void *err_addr, *base_addr;
296     int stat;
297
298     if (IS_FIS_FROM_NAND()) {
299         base_addr = (void*)MXC_NAND_BASE_DUMMY;
300         diag_printf("Updating ROM in NAND flash\n");
301     } else if (IS_FIS_FROM_NOR()) {
302         base_addr = (void*)BOARD_FLASH_START;
303         diag_printf("Updating ROM in NOR flash\n");
304     } else {
305         diag_printf("romupdate not supported\n");
306         diag_printf("Use \"factive [NOR|NAND]\" to select either NOR or NAND flash\n");
307         return;
308     }
309     // Erase area to be programmed
310     if ((stat = flash_erase((void *)base_addr,
311                             CYGBLD_REDBOOT_MIN_IMAGE_SIZE,
312                             (void **)&err_addr)) != 0) {
313         diag_printf("Can't erase region at %p: %s\n",
314                     err_addr, flash_errmsg(stat));
315         return;
316     }
317     // Now program it
318     if ((stat = flash_program((void *)base_addr, (void *)ram_end,
319                               CYGBLD_REDBOOT_MIN_IMAGE_SIZE,
320                               (void **)&err_addr)) != 0) {
321         diag_printf("Can't program region at %p: %s\n",
322                     err_addr, flash_errmsg(stat));
323     }
324 }
325 RedBoot_cmd("factive",
326             "Enable one flash media for Redboot",
327             "[NOR | NAND]",
328             factive
329            );
330
331 void factive(int argc, char *argv[])
332 {
333     unsigned long phys_addr;
334
335     if (argc != 2) {
336         diag_printf("Invalid factive cmd\n");
337         return;
338     }
339
340     if (strcasecmp(argv[1], "NOR") == 0) {
341 #ifndef MXCFLASH_SELECT_NOR
342         diag_printf("Not supported\n");
343         return;
344 #else
345         MXC_ASSERT_NOR_BOOT();
346 #endif
347     } else if (strcasecmp(argv[1], "NAND") == 0) {
348 #ifndef MXCFLASH_SELECT_NAND
349         diag_printf("Not supported\n");
350         return;
351 #else
352         MXC_ASSERT_NAND_BOOT();
353 #endif
354     } else {
355         diag_printf("Invalid command: %s\n", argv[1]);
356         return;
357     }
358     HAL_VIRT_TO_PHYS_ADDRESS(ram_end, phys_addr);
359
360     launchRunImg(phys_addr);
361 }
362 #endif //CYGPKG_IO_FLASH
363 #endif /* CYG_HAL_STARTUP_ROMRAM */
364
365 static void setcorevol(int argc, char *argv[]);
366
367 RedBoot_cmd("setcorevol",
368             "Set the core voltage. Setting is not checked against current core frequency.",
369             "[1.2 | 1.25 | 1.3 | 1.35 | 1.4 | 1.45 | 1.5 | 1.55 | 1.6]",
370             setcorevol
371            );
372
373 /*
374  * This function communicates with ATLAS to set the core voltage according to
375  * the argument
376  */
377 unsigned int setCoreVoltage(unsigned int coreVol)
378 {
379     unsigned int reg_val = 0, reg_mask = 0;
380     unsigned int reg, curr_val, val = 0, temp;
381
382     val = (0 << 31) | (REG_SWITCHER_0 << 25);
383
384     temp = spi_xchg_single(val, PMIC_SPI_BASE);
385     reg_val = temp & (~0x3F);
386     reg_val |= coreVol;
387
388     val = (1 << 31) | (REG_SWITCHER_0 << 25) | (reg_val & 0x00FFFFFF);
389     /* Set the core voltage */
390     spi_xchg_single(val, PMIC_SPI_BASE);
391     return 0;
392 }
393
394 static void setcorevol(int argc, char *argv[])
395 {
396     unsigned int coreVol;
397
398     /* check if the number of args is OK. 1 arg expected. argc = 2 */
399     if(argc != 2) {
400         diag_printf("Invalid argument. Need to specify a voltage\n");
401         return;
402     }
403
404     /* check if the argument is valid. */
405     if (strcasecmp(argv[1], "1.2") == 0) {
406         coreVol = 0xC;
407     } else if (strcasecmp(argv[1], "1.25") == 0) {
408         coreVol = 0xE;
409     } else if (strcasecmp(argv[1], "1.3") == 0) {
410         coreVol = 0x10;
411     } else if (strcasecmp(argv[1], "1.35") == 0) {
412         coreVol = 0x12;
413     } else if (strcasecmp(argv[1], "1.4") == 0) {
414         coreVol = 0x14;
415     } else if (strcasecmp(argv[1], "1.45") == 0) {
416         coreVol = 0x16;
417     } else if (strcasecmp(argv[1], "1.5") == 0) {
418         coreVol = 0x18;
419     } else if (strcasecmp(argv[1], "1.55") == 0) {
420         coreVol = 0x1A;
421     } else if (strcasecmp(argv[1], "1.6") == 0) {
422         coreVol = 0x1C;
423     } else {
424         diag_printf("Invalid argument. Type help setcorevol for valid values\n");
425         return ;
426     }
427
428     setCoreVoltage(coreVol);
429     return;
430 }
431