1 //==========================================================================
5 // Board [platform] specific RedBoot commands
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.
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.
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
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.
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.
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.
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 //==========================================================================
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
47 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
48 #include <flash_config.h>
50 #if (REDBOOT_IMAGE_SIZE != CYGBLD_REDBOOT_MIN_IMAGE_SIZE)
51 #error REDBOOT_IMAGE_SIZE != CYGBLD_REDBOOT_MIN_IMAGE_SIZE
54 RedBoot_config_option("Board specifics",
61 #endif //CYGSEM_REDBOOT_FLASH_CONFIG
63 extern unsigned int spi_xchg_single(unsigned int data, unsigned int base);
64 #define REG_SWITCHER_0 24
66 static void runImg(int argc, char *argv[]);
69 "Run an image at a location with MMU off",
74 void launchRunImg(unsigned long addr)
76 asm volatile ("mov r1, r0;");
82 "bic r10, r10, #0xF0000000;"
88 extern unsigned long entry_address;
90 static void runImg(int argc,char *argv[])
92 unsigned int virt_addr, phys_addr;
94 // Default physical entry point for Symbian
95 if (entry_address == 0xFFFFFFFF)
98 virt_addr = entry_address;
100 if (!scan_opts(argc,argv,1,0,0,(void*)&virt_addr,
101 OPTION_ARG_TYPE_NUM, "virtual address"))
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);
108 diag_printf("virt_addr=0x%x\n",virt_addr);
109 diag_printf("phys_addr=0x%x\n",phys_addr);
111 launchRunImg(phys_addr);
114 #if CYGPKG_REDBOOT_NETWORKING
115 #define LAN_BASE BOARD_CS_LAN_BASE
117 #define PP_EE_ADDR_W0 0x001C
118 #define PP_EE_ADDR_W1 0x001D
119 #define PP_EE_ADDR_W2 0x001E
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);
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##]",
132 const static unsigned short RESET_CONFIG_BLOCK[] = {
137 #define DRIVER_CONFIG_BASE 0x1C //Cirrus driver config base
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
151 0x0A2D, //27 - Mfg date
152 0xFFFF, //28 - copy of 1C
153 0xFFFF, //29 - copy of 1D
154 0xFFFF, //2A - copy of 1E
159 0x0000, //2F - Checksum
162 static void setMac(int argc,char *argv[])
164 int i, ret, wsize = sizeof(g_drv_cfg_blk) / 2; // word size
165 unsigned char data[6];
167 unsigned short ee_word[3];
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");
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));
187 ret = -1; goto error;
190 for (i = 0; i < 6; i++) {
191 if (!parse_num(*(&argv[1]), &temp, &argv[1], ":")) {
192 ret = -2; goto error;
195 ret = -3; goto error;
197 data[i] = temp & 0xFF;
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]);
204 // Calculate checksum
206 for (i = 0; i < wsize-1; i++) {
207 temp += g_drv_cfg_blk[i];
209 temp = (~temp + 1) & 0xFFFF;
210 g_drv_cfg_blk[wsize-1] = temp;
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]);
217 // Driver config block 2nd
218 for (i = 0; i < wsize; i++) {
219 write_eeprom(LAN_BASE, DRIVER_CONFIG_BASE+i,
224 diag_printf("Wrong value for setMac. Error=%d\n\n", ret);
227 //#define EEPROM_DEBUG
230 "read/write a word into EEPROM",
231 "[0-based IO Base offset:value]",
235 static void eefun(int argc,char *argv[])
238 unsigned short data[2];
245 for (i = 0; i < 2; i++) {
246 if (!parse_num(*(&argv[1]), &temp, &argv[1], ":")) {
252 data[i] = (unsigned short)temp;
255 if (data[0] >= 0x30 && data[0] != 0xFFFF) {
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");
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]));
273 diag_printf("Wrong value %d for writeEE\n\n", ret);
275 #endif //EEPROM_DEBUG
277 #endif //CYGPKG_REDBOOT_NETWORKING
279 #if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && defined(CYG_HAL_STARTUP_ROMRAM)
281 RedBoot_cmd("romupdate",
282 "Update Redboot with currently running image",
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
292 #ifdef CYGPKG_IO_FLASH
293 void romupdate(int argc, char *argv[])
295 void *err_addr, *base_addr;
298 if (IS_FIS_FROM_NAND()) {
299 base_addr = (void*)0;
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");
305 diag_printf("romupdate not supported\n");
306 diag_printf("Use \"factive [NOR|NAND]\" to select either NOR or NAND flash\n");
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));
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));
325 RedBoot_cmd("factive",
326 "Enable one flash media for Redboot",
331 void factive(int argc, char *argv[])
333 unsigned long phys_addr;
336 diag_printf("Invalid factive cmd\n");
340 if (strcasecmp(argv[1], "NOR") == 0) {
341 #ifndef MXCFLASH_SELECT_NOR
342 diag_printf("Not supported\n");
345 MXC_ASSERT_NOR_BOOT();
347 } else if (strcasecmp(argv[1], "NAND") == 0) {
348 #ifndef MXCFLASH_SELECT_NAND
349 diag_printf("Not supported\n");
352 MXC_ASSERT_NAND_BOOT();
355 diag_printf("Invalid command: %s\n", argv[1]);
358 HAL_VIRT_TO_PHYS_ADDRESS(ram_end, phys_addr);
360 launchRunImg(phys_addr);
362 #endif //CYGPKG_IO_FLASH
363 #endif /* CYG_HAL_STARTUP_ROMRAM */
365 static void setcorevol(int argc, char *argv[]);
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]",
374 * This function communicates with ATLAS to set the core voltage according to
377 unsigned int setCoreVoltage(unsigned int coreVol)
379 unsigned int reg_val = 0, reg_mask = 0;
380 unsigned int reg, curr_val, val = 0, temp;
382 val = (0 << 31) | (REG_SWITCHER_0 << 25);
384 temp = spi_xchg_single(val, PMIC_SPI_BASE);
385 reg_val = temp & (~0x3F);
388 val = (1 << 31) | (REG_SWITCHER_0 << 25) | (reg_val & 0x00FFFFFF);
389 /* Set the core voltage */
390 spi_xchg_single(val, PMIC_SPI_BASE);
394 static void setcorevol(int argc, char *argv[])
396 unsigned int coreVol;
398 /* check if the number of args is OK. 1 arg expected. argc = 2 */
400 diag_printf("Invalid argument. Need to specify a voltage\n");
404 /* check if the argument is valid. */
405 if (strcasecmp(argv[1], "1.2") == 0) {
407 } else if (strcasecmp(argv[1], "1.25") == 0) {
409 } else if (strcasecmp(argv[1], "1.3") == 0) {
411 } else if (strcasecmp(argv[1], "1.35") == 0) {
413 } else if (strcasecmp(argv[1], "1.4") == 0) {
415 } else if (strcasecmp(argv[1], "1.45") == 0) {
417 } else if (strcasecmp(argv[1], "1.5") == 0) {
419 } else if (strcasecmp(argv[1], "1.55") == 0) {
421 } else if (strcasecmp(argv[1], "1.6") == 0) {
424 diag_printf("Invalid argument. Type help setcorevol for valid values\n");
428 setCoreVoltage(coreVol);