📄 btldr_ui.c~
字号:
/* * File: btldr_ui.c * * An implementation of a menu based UI which takes user input and forms it * into commands to the bootloader Programmer's Interface (pi). * * Copyright (C) 2002 RidgeRun, Inc. * Author: RidgeRun, Inc <skranz@ridgerun.com> * - Support for DSC25 added, 9-6-02, Gregory Nutt * - Support for DM270 added, 2-19-03, Gregory Nutt * - Support for DM310 added, 6-20-03, Gregory Nutt * * This program 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 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * * Please report all bugs/problems to the author or <support@dsplinux.net> * * key: RRGPLCR (do not remove) * */#include "types.h"#include "io.h"#include "memconfig.h"#include "btldr_pi.h"#include "util.h"#include "flash.h"#include "version.h"/*//Added By Lee....#include "pmpConfig.h"#include "i2c.h"#if defined(USE_PMU)#include "pmu.h"#endif*/#if defined(DM270)# include "dm270-registers.h"#endif#if defined(BSPCONF_BTLDR_MEMORY_DEBUG)# define MEMORY_DEBUG_CHAR '6'# if defined(BSPCONF_BTLDR_MEMMAP_DEBUG)# define MEMMAP_DEBUG_CHAR '7'# define CS8900_DEBUG_CHAR '8'# else# define CS8900_DEBUG_CHAR '7'# endif#elif defined(BSPCONF_BTLDR_MEMMAP_DEBUG)# define MEMMAP_DEBUG_CHAR '6'# define CS8900_DEBUG_CHAR '7'#else# define CS8900_DEBUG_CHAR '6'#endifextern int ForUpGrade; // defined by linker script.extern void modify_memory(void);extern void verify_sdram_menu(void);// The bootloader's Programmers Interface (btldr_pi.h) is// nice enough to set aside several data fields within the// btldr_pi.h:params_t structure that we can use however// we want for things that we decide need to be stored// persistently (flashed) along with the other bootloader// params. To make things easier we'll assign our own// special meanings to those data fields now. In a// nutshell, we'll be using these fields to hold default// UI settings that survive power cycles.#define MODE_FIELD user_data_1 /* see note above */#define CMD_FIELD user_data_2#define FORMAT_FIELD user_data_3#define PORT_FIELD user_data_4#define CON_FIELD user_data_5#define CMDMAX 10unsigned char cmd[CMDMAX];#define METER_INTERV 500static int meter_line_len;static unsigned char UI_mode;static params_t *par;static void process_default_boot_cmd(unsigned char *command);#ifdef DSC25#define DSC25_REVR 0x30906/****************************** Routine: chip_major Description: returns the chip revision number, major portion. ******************************/short chip_major(void) { volatile unsigned short *addr; addr = (unsigned short *) DSC25_REVR; return( (addr[0] >> 4) && 0xFF);}/****************************** Routine: chip_minor Description: returns the chip revision number, minor portion. ******************************/int chip_minor(void) { volatile unsigned short *addr; addr = (unsigned short *) DSC25_REVR; return(addr[0] && 0xFF);}#endif/****************************** Routine: Description: ******************************/static void invalid_command(void){ util_printf("Error: invalid command.\n");}/****************************** Routine: Description: ******************************/static void progress_meter(void){ // The progress meter for this UI will be a series of '.' chars // marching across the user's screen and wrapping to the next line // only at distinct line lengths. Also, if the board has a seven // segment led digit then it too will be cycling to indicate progress. util_printf("."); display_board_digit(meter_line_len); meter_line_len++; if (meter_line_len > 50) { meter_line_len = 0; util_printf("\n"); }}/****************************** Routine: Description: ******************************/static void clear(void){ // util_printf("\033[2J"); // clear term window. util_printf("\n\n"); // cursor to top left corner.}/****************************** Routine: Description: ******************************/void do_param_listing(void){ util_printf( " mode : %s\n",par->MODE_FIELD ); util_printf( " bootcmd : %s\n",par->CMD_FIELD ); util_printf( " loadfmt : %s\n",par->FORMAT_FIELD ); util_printf( " loadport : %s\n",par->PORT_FIELD ); util_printf( "consoleport : %s\n",par->CON_FIELD ); util_printf( " serverip : %s\n",par->server_IP ); util_printf( " servermac : %s\n",par->server_MAC ); util_printf( " devip : %s\n",par->device_IP ); util_printf( " devmac : %s\n",par->device_MAC ); util_printf( " kpath : %s\n",par->kernel_path ); util_printf( " fpath : %s\n",par->filesys_path );#if defined(DSC24_OSD) util_printf( " opath : %s\n",par->OSD_path ); util_printf( " osdenable : %s\n",par->OSD_enable );#endif util_printf( " kcmdline : %s\n",par->kernel_cmdline);}/****************************** Routine: Description: Usage: set [param val] ******************************/static int find_param(char *param, char *line){ int found, l_index, i, j, k; found = l_index = j = 0; for (i=0; i<util_strlen(line); i++) { if (' ' == line[i]) continue; // eat leading spaces. // Okay, we found the start of param word, now find the end. for (j=i; j<util_strlen(line); j++) { if (' ' == line[j]) { l_index = j; // l_index now the 1st char of the string following param word. j--; // i is first char of param word and j is last char. found = 1; break; } } if (j==util_strlen(line)) { found = 1; } if (found) break; } if (j) { // At this point line[i] represents the 1st char of the // param word while j is the last char. for (k=0; k<(j-i+1); k++) { param[k] = line[i+k]; // fill in caller's param. } param[k] = 0; // ... and terminate it. } return l_index;}/****************************** Routine: Description: Usage: set [param val] ^ ^ | | token1 token2 ******************************/static void do_set_command(char *line){ #define MAXLEN 100 /* best guess at a realistic limit. */ char param[MAXLEN]; char *val; int l_index; l_index = find_param(param,line); if (l_index) { val = &(line[l_index]); // Address of val string following param word. while (' ' == *val) {val++;} // Eat leading spaces. if (0 == util_strncmp("mode",param,util_strlen("mode"))) { util_strncpy(par->MODE_FIELD,val,par->MAX_STR_LEN); } else if (0 == util_strncmp("bootcmd",param,util_strlen("bootcmd"))) { util_strncpy(par->CMD_FIELD,val,par->MAX_STR_LEN); } else if (0 == util_strncmp("loadfmt",param,util_strlen("loadfmt"))) { util_strncpy(par->FORMAT_FIELD,val,par->MAX_STR_LEN); } else if (0 == util_strncmp("loadport",param,util_strlen("loadport"))) { util_strncpy(par->PORT_FIELD,val,par->MAX_STR_LEN); } else if (0 == util_strncmp("consoleport",param,util_strlen("consoleport"))) { util_strncpy(par->CON_FIELD,val,par->MAX_STR_LEN); switch (par->CON_FIELD[0]) { case 'S': case 's': io_change_con(SER); break; case 'P': case 'p': io_change_con(PAR); break;#ifdef USE_USB case 'U': case 'u': io_change_con(USB); break;#endif } } else if (0 == util_strncmp("serverip",param,util_strlen("serverip"))) { util_strncpy(par->server_IP,val,par->MAX_STR_LEN); } else if (0 == util_strncmp("servermac",param,util_strlen("servermac"))) { util_strncpy(par->server_MAC,val,par->MAX_STR_LEN); } else if (0 == util_strncmp("devip",param,util_strlen("devip"))) { util_strncpy(par->device_IP,val,par->MAX_STR_LEN); } else if (0 == util_strncmp("devmac",param,util_strlen("devmac"))) { util_strncpy(par->device_MAC,val,par->MAX_STR_LEN); } else if (0 == util_strncmp("kpath",param,util_strlen("kpath"))) { util_strncpy(par->kernel_path,val,par->MAX_STR_LEN); } else if (0 == util_strncmp("fpath",param,util_strlen("fpath"))) { util_strncpy(par->filesys_path,val,par->MAX_STR_LEN); }#if defined(DSC24_OSD) else if (0 == util_strncmp("osdenable",param,util_strlen("osdenable"))) { util_strncpy(par->OSD_enable,val,par->MAX_STR_LEN); }#endif else if (0 == util_strncmp("kcmdline",param,util_strlen("kcmdline"))) { util_strncpy(par->kernel_cmdline,val,par->MAX_STR_LEN); } else { invalid_command(); } } else { // 'set' by itself, like we see here, means the user wants // a listing of current param settings. do_param_listing(); }}/****************************** Routine: Description: ******************************/static void do_erase_flash_cmd(char *line){ #define MAXLEN 100 /* best guess at a realistic limit. */ char param[MAXLEN]; if (0 == util_strlen(line)) { // missing [comp] portion of line. Example: "eraseflash kernel" invalid_command(); } else { find_param(param,line); if ('b' == *param) { util_printf("Are you sure? "); util_gets(cmd,CMDMAX); if (('y' == cmd[0]) || ('Y' == cmd[0])) { erase_comp(c_BOOTLDR); } } else if ('p' == *param) { util_printf("Are you sure? "); util_gets(cmd,CMDMAX); if (('y' == cmd[0]) || ('Y' == cmd[0])) { erase_comp(c_PARAMS); } } else if ('k' == *param) { util_printf("Are you sure? "); util_gets(cmd,CMDMAX); if (('y' == cmd[0]) || ('Y' == cmd[0])) { erase_comp(c_KERNEL); } } else if ('f' == *param) { util_printf("Are you sure? "); util_gets(cmd,CMDMAX); if (('y' == cmd[0]) || ('Y' == cmd[0])) { erase_comp(c_FILESYS); } } else if ('a' == *param) { util_printf("Are you sure? "); util_gets(cmd,CMDMAX); if (('y' == cmd[0]) || ('Y' == cmd[0])) { flash_erase(); } } else { invalid_command(); } }}/****************************** Routine: Description: ******************************/static int find_comp(comp_t *comp, char *line){ int i,j; for (i=0; i<util_strlen(line); i++) { if ('-' == line[i]) { if ('c' == line[i+1]) { // we found the "-c", now find the token that follows. for (j=i+2; j<util_strlen(line); j++) { if (' ' == line[j]) continue; // Found the start of next token. Luckily // the first character is all we really need. switch (line[j]) { case 'b': case 'B': *comp = c_BOOTLDR; return 1; break; case 'p': case 'P': *comp = c_PARAMS; return 1; break; case 'k': case 'K': *comp = c_KERNEL; return 1; break; case 'f': case 'F': *comp = c_FILESYS; return 1; break; default: return 0; // Failed. break; } } } } } return 0; // Failed.}/****************************** Routine: Description: ******************************/static int find_src(src_dest_t *src, char *line){ int i,j; for (i=0; i<util_strlen(line); i++) { if ('-' == line[i]) { if ('s' == line[i+1]) { // we found the "-s", now find the token that follows. for (j=i+2; j<util_strlen(line); j++) { if (' ' == line[j]) continue; // Found the start of next token. Luckily // the first character is all we really need. switch (line[j]) { case 'r': case 'R': *src = sd_SDRAM; return 1; break; case 'f': case 'F': *src = sd_FLASH; return 1; break; case 'e': case 'E': *src = sd_TFTP; return 1; break; case 's': case 'S': *src = sd_SERPORT; return 1; break; case 'p': case 'P': *src = sd_PARPORT; return 1; break; default: return 0; // Failed. break; } } } } } return 0; // Failed.}/****************************** Routine: Description: ******************************/static int find_dest(src_dest_t *dest, char *line){ int i,j; for (i=0; i<util_strlen(line); i++) { if ('-' == line[i]) { if ('d' == line[i+1]) { // we found the "-d", now find the token that follows. for (j=i+2; j<util_strlen(line); j++) { if (' ' == line[j]) continue; // Found the start of next token. Luckily // the first character is all we really need. switch (line[j]) { case 'r': case 'R': *dest = sd_SDRAM; return 1; break; case 'f': case 'F': *dest = sd_FLASH; return 1; break; case 'e': case 'E': *dest = sd_TFTP; return 1; break; case 's': case 'S': *dest = sd_SERPORT; return 1; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -