/*********************************************************************** * * Function: flash_image_load * * Purpose: Moves FLASH application in load region to memory * * Processing: * See function. * * Parameters: None * * Outputs: None * * Returns: Always returns TRUE. * * Notes: None * **********************************************************************/ BOOL_32 flash_image_load(void) { UNS_32 fblock; INT_32 sector; if (syscfg.fsave.valid == FALSE) { term_dat_out_crlf(noiif_msg); return TRUE; } /* Find starting block of burned image */ fblock = sysinfo.sysrtcfg.bl_num_blks; /* Read data into memory */ sector = conv_to_sector(fblock, 0); if (nand_to_mem(sector, (UNS_8 *) syscfg.fsave.loadaddr, (syscfg.fsave.secs_used * sysinfo.nandgeom->data_bytes_per_page)) == FALSE) { term_dat_out_crlf(nloeerr_msg); } else { /* Load image */ sysinfo.lfile.num_bytes = syscfg.fsave.num_bytes; sysinfo.lfile.startaddr = (PFV) syscfg.fsave.startaddr; sysinfo.lfile.loadaddr = syscfg.fsave.loadaddr; sysinfo.lfile.flt = FLT_RAW; sysinfo.lfile.contiguous = TRUE; sysinfo.lfile.loaded = TRUE; } return TRUE; }
/*********************************************************************** * * Function: output_formatted_mode * * Purpose: Outputs a formatted mode word in bitwise format * * Processing: * See function. * * Parameters: * modestr: Mode string * mode : Mode word to output * * Outputs: None * * Returns: Nothing * * Notes: None * **********************************************************************/ static void output_formatted_mode(char *modestr, UNS_32 mode) { UNS_32 hiperfmode = ((EMC->emcdynamicconfig0 & ((1 << 5) << 7)) == 0); /* Output mode word name */ term_dat_out_crlf((UNS_8 *) modestr); /* Depending on the current mode, the bus and rows may be swapped */ term_dat_out((UNS_8 *) " "); if (hiperfmode) { /* Row - bank - column mode */ output_char_multiple((UNS_8) 'R', SDRAM_ROWS); term_dat_out((UNS_8 *) " "); output_char_multiple((UNS_8) 'B', SDRAM_BANK_BITS); term_dat_out((UNS_8 *) " "); output_char_multiple((UNS_8) 'C', SDRAM_COLS); term_dat_out((UNS_8 *) " "); output_char_multiple((UNS_8) '0', (bus32 + 1)); term_dat_out_crlf((UNS_8 *) ""); term_dat_out((UNS_8 *) " "); Output_bit_multiple((mode >> modeshift), SDRAM_ROWS); term_dat_out((UNS_8 *) " "); Output_bit_multiple((mode >> bankshift), SDRAM_BANK_BITS); } else {
/*********************************************************************** * * Function: cmd_process * * Purpose: Parses and processes the passed command string * * Processing: * Break up the parse string into whitespace seperated components * and convert the components according to the parse list. Route * to the command function based on the parsed command. * * Parameters: * parse_str : String to parse * * Outputs: None * * Returns: TRUE if the command was processed, otherwise FALSE * * Notes: None * **********************************************************************/ BOOL_32 cmd_process(UNS_8 *parse_str) { CMD_ROUTE_T *pCmd; BOOL_32 cmdok = TRUE; GROUP_LIST_T *pGroup = &group_list_head; // Parse the string into whitespace seperated elements and find // matching command parse_string(parse_str); cmdok = cmd_find_index(get_parsed_entry(0), &pGroup, &pCmd); if (cmdok == FALSE) { term_dat_out_crlf(errorcmd_msg); } else if (pCmd == NULL) { // Group command only term_dat_out_crlf(errorgrp_msg); } else if (cmd_parse_fields(pCmd) == FALSE) { term_dat_out(errorparse_msg); cmd_show_cmd_syntax(pCmd); cmdok = FALSE; } else { // Process command cmdok = pCmd->func(); } return cmdok; }
/*********************************************************************** * * Function: cmd_nandrs * * Purpose: Displays a list of reserved NAND blocks * * Processing: * See function. * * Parameters: None * * Outputs: None * * Returns: Always returns TRUE. * * Notes: None * **********************************************************************/ BOOL_32 cmd_nandrs(void) { UNS_8 blk [16]; UNS_32 idx = 0; UNS_32 fblock = 0, nblks = 0; BOOL_32 ct, newct; if (sysinfo.nandgood == FALSE) { term_dat_out(noflash_msg); } else { term_dat_out_crlf(rsvlist_msg); ct = flash_is_rsv_block((UNS_32) idx); while (idx < sysinfo.nandgeom.blocks) { /* Read "extra" data area */ newct = flash_is_rsv_block((UNS_32) idx); if ((newct != ct) || (idx == (sysinfo.nandgeom.blocks - 1))) { if (ct == FALSE) { term_dat_out("Nonreserved blocks :"); } else { term_dat_out("Reserved blocks :"); } if (idx == (sysinfo.nandgeom.blocks - 1)) { nblks++; } str_makedec(blk, fblock); term_dat_out(blk); term_dat_out("("); str_makedec(blk, nblks); term_dat_out(blk); term_dat_out_crlf(" block(s))"); ct = newct; nblks = 0; fblock = (UNS_32) idx; } nblks++; idx++; } } return TRUE; }
/*********************************************************************** * * Function: script_capture * * Purpose: Captures script entries to play back on S1L boot * * Processing: * See function. * * Parameters: None * * Outputs: None * * Returns: TRUE if the commands were captured, otherwise FALSE * * Notes: None * **********************************************************************/ static BOOL_32 script_capture(void) { int sz, idx = 0, i = 0; BOOL_32 entered = FALSE, exits = FALSE, ilp; term_dat_out_crlf(script_entry_msg); /* Get each line */ while ((exits == FALSE) && (idx < 1024) && (i < MAX_SCRIPT_ENTRIES)) { term_dat_out((UNS_8 *) "-S>"); sz = 0; ilp = FALSE; while ((idx < 1024) && (ilp == FALSE)) { if (term_dat_in_ready() > 0) { term_dat_in(&syscfg.scr.script_data[idx], 1); syscfg.scr.script_data[idx + 1] = '\0'; if (syscfg.scr.script_data[idx] == 13) { syscfg.scr.script_data[idx] = '\0'; term_dat_out_crlf((UNS_8 *) ""); ilp = TRUE; if (sz == 0) exits = TRUE; } else { term_dat_out(&syscfg.scr.script_data[idx]); sz++; } idx++; } } syscfg.scr.entry_size[i] = sz; i++; } if (idx >= 256) term_dat_out_crlf((UNS_8 *) "Script buffer overflow, limit 256 bytes!"); else if (i >= MAX_SCRIPT_ENTRIES) term_dat_out_crlf((UNS_8 *) "Script entry limit overflow, limit 12 entries!"); else { entered = TRUE; syscfg.scr.number_entries = i - 1; } return entered; }
/*********************************************************************** * * Function: cmd_clock * * Purpose: Clock command * * Processing: * Parse the string elements for the clock command and sets the * new clock value. * * Parameters: None * * Outputs: None * * Returns: TRUE if the command was processed, otherwise FALSE * * Notes: May not work in DDR systems. * **********************************************************************/ BOOL_32 cmd_clock(void) { UNS_32 freqr, armclk, hclkdiv, pclkdiv; UNS_8 dclk [32]; BOOL_32 processed = TRUE; /* Get arguments */ armclk = cmd_get_field_val(1); hclkdiv = cmd_get_field_val(2); pclkdiv = cmd_get_field_val(3); if (!((hclkdiv == 1) || (hclkdiv == 2) || (hclkdiv == 4))) { processed = FALSE; } if ((pclkdiv < 1) || (pclkdiv > 32)) { processed = FALSE; } if ((armclk < 33) || (armclk > 550)) { term_dat_out_crlf(clockerr_msg); processed = FALSE; } else { armclk = armclk * 1000 * 1000; } if (processed == TRUE) { sys_saved_data.clksetup.armclk = armclk; sys_saved_data.clksetup.hclkdiv = hclkdiv; sys_saved_data.clksetup.pclkdiv = pclkdiv; freqr = clock_adjust(); if (freqr == 0) { term_dat_out_crlf(clockbad_msg); } else { term_dat_out(clock_msg); str_makedec(dclk, freqr); term_dat_out_crlf(dclk); sys_save(&sys_saved_data); } } return TRUE; }
/*********************************************************************** * * Function: cmd_strout_format * * Purpose: Aligned output for commands and groups * * Processing: * See function. * * Parameters: * start_offs : Index where to place first string * start_str : First string * next_offs : Index where to place second string * next_str : Second string * * Outputs: None * * Returns: Nothing * * Notes: None * **********************************************************************/ cmd_strout_format(int start_offs, UNS_8 *start_str, int next_offs, UNS_8 *next_str) { int idx1 = 0; UNS_8 *space = " "; // Fill spaces first while (idx1 < start_offs) { term_dat_out(space); idx1++; } term_dat_out(start_str); // Increment past the first string idx1 += str_size(start_str); while (idx1 < next_offs) { term_dat_out(space); idx1++; } term_dat_out_crlf(next_str); }
/*********************************************************************** * * Function: flash_image_save * * Purpose: Moves image in memory to FLASH application load region * * Processing: * See function. * * Parameters: None * * Outputs: None * * Returns: Always returns TRUE. * * Notes: None * **********************************************************************/ BOOL_32 flash_image_save(void) { UNS_32 fblock, ffblock; INT_32 sector, numsecs, nblks; FLASH_SAVE_T flashsavdat; /* Set first block pat boot loader */ ffblock = fblock = sysinfo.sysrtcfg.bl_num_blks; /* Save programmed FLASH data */ flashsavdat.block_first = fblock; flashsavdat.num_bytes = sysinfo.lfile.num_bytes; flashsavdat.loadaddr = sysinfo.lfile.loadaddr; flashsavdat.startaddr = (UNS_32) sysinfo.lfile.startaddr; flashsavdat.valid = TRUE; /* Get starting sector and number of sectors to program */ numsecs = sysinfo.lfile.num_bytes / sysinfo.nandgeom->data_bytes_per_page; if ((numsecs * sysinfo.nandgeom->data_bytes_per_page) < sysinfo.lfile.num_bytes) { numsecs++; } flashsavdat.secs_used = numsecs; nblks = numsecs / sysinfo.nandgeom->pages_per_block; if ((nblks * sysinfo.nandgeom->pages_per_block) < numsecs) { nblks++; } flashsavdat.blocks_used = nblks; /* Erase necessary blocks first */ while (nblks > 0) { if (flash_is_bad_block(ffblock) == FALSE) { flash_erase_block(ffblock); nblks--; } ffblock++; } /* Burn image into FLASH */ sector = conv_to_sector(fblock, 0); if (mem_to_nand(sector, (UNS_8 *) sysinfo.lfile.loadaddr, (numsecs * sysinfo.nandgeom->data_bytes_per_page)) == FALSE) { term_dat_out_crlf(nsaeerr_msg); } else { /* Update saved NAND configuration */ syscfg.fsave = flashsavdat; cfg_save(&syscfg); } return TRUE; }
/*********************************************************************** * * Function: cmd_ls * * Purpose: Displays files in root directory of block device * * Processing: * See function. * * Parameters: None * * Outputs: None * * Returns: Always returns TRUE * * Notes: None * **********************************************************************/ BOOL_32 cmd_ls(void) { UNS_8 dirname [32]; BOOL_32 lp; /* Initialize FAT interface first */ if (fat_init() == FALSE) { term_dat_out(blkdeverr_msg); } else { /* Show items in BLKDEV root directory */ lp = fat_get_dir(dirname, TRUE); while (lp == FALSE) { term_dat_out(" "); term_dat_out_crlf(dirname); lp = fat_get_dir(dirname, FALSE); } fat_deinit(); } return TRUE; }
/*********************************************************************** * * Function: cmd_comp * * Purpose: Compare data between 2 regions * * Processing: * See function. * * Parameters: None * * Outputs: None * * Returns: TRUE if the command was good, otherwise FALSE * * Notes: None * **********************************************************************/ static BOOL_32 cmd_comp(void) { UNS_8 *ha1, *ha2; UNS_32 hexaddr1, hexaddr2, bytes; UNS_8 str [16]; BOOL_32 mtch; /* Get arguments */ hexaddr1 = cmd_get_field_val(1); hexaddr2 = cmd_get_field_val(2); bytes = cmd_get_field_val(3); mtch = TRUE; ha1 = (UNS_8 *) hexaddr1; ha2 = (UNS_8 *) hexaddr2; term_dat_out(scomp_msg); while (bytes > 0) { if (*ha1 != *ha2) { mtch = FALSE; bytes = 0; } else { bytes--; ha1++; ha2++; } } if (mtch == TRUE) { term_dat_out_crlf(ssame_msg); } else { term_dat_out(snsame_msg); str_makehex(str, (UNS_32) ha1, 8); term_dat_out(str); term_dat_out(and); str_makehex(str, (UNS_32) ha2, 8); term_dat_out_crlf(str); } return TRUE; }
/*********************************************************************** * * Function: cmd_help * * Purpose: Processes the help command * * Processing: * See function. * * Parameters: None * * Outputs: None * * Returns: Nothing * * Notes: None * **********************************************************************/ BOOL_32 cmd_help(void) { GROUP_LIST_T *pGroup = &group_list_head; UNS_8 *str = get_parsed_entry(1); CMD_ROUTE_T *pCmd; // If this is just the help command with no arguments, then display // the standard help message if (parse_get_entry_count() == 1) { cmd_show_group_help(pGroup, FALSE); } else { // Verify second argument if (str_cmp(str, "menu") == 0) { // Show everything while (pGroup != NULL) { cmd_show_group_help(pGroup, FALSE); pGroup = pGroup->next_group; } } else if (str_cmp(str, "all") == 0) { // Show everything while (pGroup != NULL) { cmd_show_group_help(pGroup, TRUE); pGroup = pGroup->next_group; } } else { // Second argument is either a command or group name, so // attempt to find the matching name if (cmd_find_index(str, &pGroup, &pCmd) == FALSE) { // No matching group or command term_dat_out_crlf(helperr_msg); } else { if (pCmd != NULL) { cmd_show_cmd_help(pCmd); } else { cmd_show_group_help(pGroup, TRUE); } } } } return TRUE; }
/*********************************************************************** * * Function: cmd_boot * * Purpose: Autoloads and image and starts boot of it * * Processing: * See function. * * Parameters: None * * Outputs: None * * Returns: TRUE if the command was good, otherwise FALSE * * Notes: None * **********************************************************************/ BOOL_32 cmd_boot(void) { if (autoboot() == TRUE) { menuexit = TRUE; } else { term_dat_out_crlf(cnoboot_msg); } return TRUE; }
/*********************************************************************** * * Function: cmd_maddr * * Purpose: Sets MAC address of ethernet device * * Processing: * See function. * * Parameters: None * * Outputs: None * * Returns: TRUE if the command was good, otherwise FALSE * * Notes: None * **********************************************************************/ BOOL_32 cmd_maddr(void) { int idx, offs; UNS_8 *p8, *curp, mac[8], str[16]; UNS_32 ea; BOOL_32 goodmac = FALSE; str [0] = '0'; str [1] = 'x'; str [4] = '\0'; mac [6] = mac [7] = 0; /* An address was passed, use it */ if (parse_get_entry_count() == 2) { curp = get_parsed_entry(1); goodmac = TRUE; offs = 0; for (idx = 0; idx < 6; idx++) { str [2] = curp[offs]; str [3] = curp[offs + 1]; goodmac &= str_hex_to_val(str, &ea); mac [idx] = (UNS_8) ea; offs += 3; } if (goodmac == TRUE) { /* Yes NO VERIFY? */ term_dat_out(smac_msg); if (prompt_yesno() != FALSE) { /* Save structure */ for (idx = 0; idx < 8; idx++) { phyhwdesc.mac [idx] = mac [idx]; } p8 = (UNS_8 *) &phyhwdesc; for (idx = 0; idx < sizeof(phyhwdesc); idx++) { phy3250_sspwrite(*p8, (PHY3250_SEEPROM_CFGOFS + idx)); p8++; } } } else { term_dat_out_crlf(macafail_msg); } } return goodmac; }
/*********************************************************************** * * Function: cmd_nrsv * * Purpose: Reserve a range of blocks for WinCE * * Processing: * See function. * * Parameters: None * * Outputs: None * * Returns: Always returns TRUE * * Notes: None * **********************************************************************/ BOOL_32 cmd_nrsv(void) { UNS_32 lblock, fblock, nblks; /* Get arguments */ fblock = cmd_get_field_val(1); nblks = cmd_get_field_val(2); /* Limit range outside of boot blocks */ if (fblock < BL_NUM_BLOCKS) { /* Boot blocks are already marked as reserved, so skip them */ /* Get last block to mark */ lblock = (fblock + nblks) - 1; if (lblock < BL_NUM_BLOCKS) { nblks = 0; } else { fblock = 25; nblks = (lblock - fblock) + 1; } } /* Mark all of the blocks, skipping bad blocks */ while (nblks > 0) { if (flash_reserve_block(fblock) == FALSE) { term_dat_out_crlf(blkmkerr_msg); nblks = 0; } else { fblock++; nblks--; } } return TRUE; }
/*********************************************************************** * * Function: cmd_script * * Purpose: Sets up, enables, or disables startup scripting * * Processing: * See function. * * Parameters: None * * Outputs: None * * Returns: TRUE if the command was accepted, otherwise FALSE * * Notes: None * **********************************************************************/ static BOOL_32 cmd_script(void) { BOOL_32 update = FALSE, parsed = FALSE; UNS_8 *str = get_parsed_entry(1); if (parse_get_entry_count() == 2) { /* on, off, or setup commands? */ if (str_cmp(str, "on") == 0) { if ((syscfg.scr.number_entries > 0) && (syscfg.scr.enabled == FALSE)) { syscfg.scr.enabled = TRUE; update = TRUE; } parsed = TRUE; } else if (str_cmp(str, "off") == 0) { if (syscfg.scr.enabled == TRUE) { syscfg.scr.enabled = FALSE; update = TRUE; } parsed = TRUE; } else if (str_cmp(str, "setup") == 0) { syscfg.scr.enabled = TRUE; update = parsed = script_capture(); } else term_dat_out_crlf((UNS_8 *) "Invalid script command, type help script for more " "info"); if (update) cfg_save(&syscfg); } return parsed; }
/*********************************************************************** * * Function: cmd_copy * * Purpose: Copy data between 2 regions * * Processing: * See function. * * Parameters: None * * Outputs: None * * Returns: TRUE if the command was good, otherwise FALSE * * Notes: None * **********************************************************************/ static BOOL_32 cmd_copy(void) { UNS_8 *ha1, *ha2; UNS_32 hexaddr1, hexaddr2, bytes; /* Get arguments */ hexaddr1 = cmd_get_field_val(1); hexaddr2 = cmd_get_field_val(2); bytes = cmd_get_field_val(3); ha1 = (UNS_8 *) hexaddr1; ha2 = (UNS_8 *) hexaddr2; while (bytes > 0) { *ha2 = *ha1; ha1++; ha2++; bytes--; } term_dat_out_crlf(scp_msg); return TRUE; }
/*********************************************************************** * * Function: cmd_update * * Purpose: Updates the stage 1 bootloader * * Processing: * See function. * * Parameters: None * * Outputs: None * * Returns: Always returns TRUE. * * Notes: None * **********************************************************************/ BOOL_32 cmd_update(void) { BOOL_32 updated = FALSE; /* Is an image in memory? */ if (sysinfo.lfile.flt == FLT_NONE) { term_dat_out_crlf(updnoim_msg); return TRUE; } /* Is an image in memory a raw image? */ if (sysinfo.lfile.flt != FLT_RAW) { term_dat_out_crlf(updnotraw_msg); return TRUE; } /* Is the image in memory contiguous? */ if (sysinfo.lfile.contiguous == FALSE) { term_dat_out_crlf(updnotc_msg); return TRUE; } /* Is the image for stage 1 or the kickstart loader */ if (parse_get_entry_count() == 2) { /* Get passed command */ if (str_cmp(get_parsed_entry(1), "kick") == 0) { /* Updating block 0, does the image exceed 15.5K(small block)? * large block 54K */ if (sysinfo.lfile.num_bytes > (31 * 512)) { term_dat_out_crlf(updgt31_msg); return TRUE; } else { updated = nand_kickstart_update(); } } } else { /* Updating block 0, does the image exceed 256K? */ if (sysinfo.lfile.num_bytes > (256 * 512)) { term_dat_out_crlf(updgt256_msg); return TRUE; } else { updated = nand_bootloader_update(); } } /* Image in memory passes all checks, FLASH it at start of block 0 */ if (updated == FALSE) { term_dat_out_crlf(updfail_msg); } else { term_dat_out_crlf(updgood_msg); } return TRUE; }
/*********************************************************************** * * Function: nand_to_mem * * Purpose: Moves data from FLASH to memory * * Processing: * See function. * * Parameters: * starting_sector : Starting sector for read operation * buff : Buffer to place read data * bytes : Number of bytyes to read * * Outputs: None * * Returns: Nothing * * Notes: None * **********************************************************************/ BOOL_32 nand_to_mem(UNS_32 starting_sector, void *buff, UNS_32 bytes) { BOOL_32 blkchk; UNS_32 block, page, sector, toread; UNS_8 str[16], *p8 = (UNS_8 *) buff; if (sysinfo.nandgeom == NULL) { term_dat_out_crlf(noflash_msg); return FALSE; } /* Get block and page for passed sector */ block = starting_sector / sysinfo.nandgeom->pages_per_block; page = starting_sector - (block * sysinfo.nandgeom->pages_per_block); /* Read data */ blkchk = TRUE; while (bytes > 0) { /* Is a block check needed? */ if ((page == 0) && (blkchk == TRUE)) { if (flash_is_bad_block(block) != FALSE) { /* Goto next block */ term_dat_out(bskip_msg); str_makedec(str, block); term_dat_out_crlf(str); block++; page = 0; blkchk = TRUE; } else { blkchk = FALSE; } } else { /* Convert to sector */ sector = conv_to_sector(block, page); toread = bytes; if (toread > sysinfo.nandgeom->data_bytes_per_page) { toread = sysinfo.nandgeom->data_bytes_per_page; } /* Read sector data */ if (flash_read_sector(sector, secdat, NULL) <= 0) { term_dat_out(readerr_msg); str_makedec(str, sector); term_dat_out_crlf(str); } memcpy(p8, secdat, toread); p8 += toread; bytes -= toread; /* Next page and block */ page++; if (page >= sysinfo.nandgeom->pages_per_block) { page = 0; block++; blkchk = TRUE; } } } return TRUE; }
/*********************************************************************** * * Function: mem_to_nand * * Purpose: Moves data from memory to FLASH * * Processing: * See function. * * Parameters: * starting_sector : Starting sector for write * buff : Pointer to buffer to write * bytes : Number of bytes to write * * Outputs: None * * Returns: Nothing * * Notes: None * **********************************************************************/ BOOL_32 mem_to_nand(UNS_32 starting_sector, void *buff, UNS_32 bytes) { BOOL_32 blkchk; UNS_32 block, page, sector, wbytes; UNS_8 str[16], *p8 = (UNS_8 *) buff; if (sysinfo.nandgeom == NULL) { term_dat_out_crlf(noflash_msg); return FALSE; } /* Get block and page for passed sector */ block = starting_sector / sysinfo.nandgeom->pages_per_block; page = starting_sector - (block * sysinfo.nandgeom->pages_per_block); /* Align bytes to a sector boundary */ wbytes = bytes & ~(sysinfo.nandgeom->data_bytes_per_page - 1); if (wbytes < bytes) { bytes = wbytes + sysinfo.nandgeom->data_bytes_per_page; } /* Write data */ blkchk = TRUE; while (bytes > 0) { /* Is a block check needed? */ if ((page == 0) && (blkchk == TRUE)) { if (flash_is_bad_block(block) != FALSE) { /* Goto next block */ term_dat_out(bskip_msg); str_makedec(str, block); term_dat_out_crlf(str); block++; page = 0; } else { /* Block is good */ blkchk = FALSE; } } else { /* Convert to sector */ sector = conv_to_sector(block, page); /* Write sector data */ if (flash_write_sector(sector, p8, NULL) == FALSE) { term_dat_out(writeerr_msg); str_makedec(str, sector); term_dat_out_crlf(str); bytes = 0; return FALSE; } else { p8 += sysinfo.nandgeom->data_bytes_per_page; bytes -= sysinfo.nandgeom->data_bytes_per_page; } /* Next page and block */ page++; if (page >= sysinfo.nandgeom->pages_per_block) { page = 0; block++; blkchk = TRUE; } } } return TRUE; }
/*********************************************************************** * * Function: srec_parse * * Purpose: Load and parse an S-record file * * Processing: * See function. * * Parameters: * fdata : Pointer to file data to fill * src : Data source * filename : Filename (sd cards only) * * Outputs: None * * Returns: E if the file was parsed and loaded, otherwise FALSE * * Notes: None * **********************************************************************/ BOOL_32 srec_parse(FILE_DATA_T *ft, SRC_LOAD_T src, UNS_8 *filename) { UNS_8 line[384]; int idx; BOOL_32 fop = FALSE, parsed = TRUE, done = FALSE; ft->loadaddr = 0xFFFFFFFF; ft->flt = FLT_RAW; /* Loaded as an S-record, saved as RAW */ ft->num_bytes = 0; ft->startaddr = (PFV) 0xFFFFFFFF; ft->contiguous = TRUE; ft->loaded = FALSE; /* Attempt to open file if from SD source */ if (src == SRC_BLKDEV) { /* Init FAT filesystem and block device */ if (fat_init() == FALSE) { term_dat_out(blkdeverr_msg); done = TRUE; } else { /* Try to open file */ parsed = fat_file_open(filename); fop = TRUE; if (parsed == FALSE) { term_dat_out_crlf(nofilmsg); done = TRUE; } } } else if (src == SRC_NAND) { /* Initialize NAND streamer */ if (stream_flash_init() == FALSE) { term_dat_out_crlf(noiif_msg); done = TRUE; } } else { term_dat_out_crlf(rawdl_msg); } while ((done == FALSE) && (ft->loaded == FALSE)) { /* Read line from device */ parsed = readline(line, src); if (parsed == TRUE) { /* Skip whitespace */ idx = skip_whitespace(line, 0); parsed &= srec_parse_line(&line [idx], ft); } if (parsed == FALSE) { done = TRUE; } } if (fop == TRUE) { fat_deinit(); } return parsed; }
/*********************************************************************** * * Function: raw_load * * Purpose: Load a raw file from a source to memory * * Processing: * See function. * * Parameters: * fdata : Pointer to file data to fill * addr : Address to load data * filename : Filename (sd cards only) * src : Data source * * Outputs: None * * Returns: TRUE if the file was loaded, otherwise FALSE * * Notes: None * **********************************************************************/ BOOL_32 raw_load(FILE_DATA_T *fdata, UNS_32 addr, UNS_8 *filename, SRC_LOAD_T src) { UNS_32 rb, bytes = 0; UNS_8 ch, *ptr8 = (UNS_8 *) addr; BOOL_32 readloop, loaded = FALSE; if (src == SRC_TERM) { term_dat_out_crlf(rawdl_msg); /* Read data from terminal until a break is encountered */ while (term_break() == FALSE) { if (term_dat_in(&ch, 1) > 0) { bytes++; *ptr8 = ch; ptr8++; } } fdata->num_bytes = bytes; fdata->contiguous = TRUE; loaded = TRUE; } else if (src == SRC_NAND) { /* Move image in NAND to memory */ term_dat_out_crlf(rawnanddlns_msg); } else if (src == SRC_BLKDEV) { /* Initialize FAT interface first */ if (fat_init() == FALSE) { term_dat_out(blkdeverr_msg); } /* Try to open file */ else if (fat_file_open(filename) == FALSE) { term_dat_out_crlf(nofilmsg); } else { fdata->num_bytes = 0; readloop = TRUE; while (readloop == TRUE) { rb = fat_file_read(ptr8, 8); fdata->num_bytes += rb; ptr8 += 8; if (rb != 8) { readloop = FALSE; } } fdata->contiguous = TRUE; loaded = TRUE; } fat_deinit(); } return loaded; }
/*********************************************************************** * * Function: hex_dump * * Purpose: Dumps a series of data values * * Processing: * Format and dump data based on address and width. * * Parameters: * addr : Starting address of dump * width : Width of the dump in bytes (1, 2, or 4) * numtrans : Number of items to dump * * Outputs: None * * Returns: Nothing * * Notes: None * **********************************************************************/ static void hex_dump(UNS_32 addr, UNS_32 width, UNS_32 numtrans) { int dumpsperline, ldspl, idx; UNS_32 tmp, laddr; UNS_8 daddr [16]; /* Based on width, determine number of dumps per line */ switch (width) { case 4: dumpsperline = 4; break; case 2: dumpsperline = 8; break; case 1: default: width = 1; dumpsperline = 8; break; } laddr = addr + (width * numtrans); /* Start dump */ while (addr < laddr) { /* Dump address first */ str_makehex(daddr, addr, 8); term_dat_out(daddr); term_dat_out((UNS_8 *) " : "); ldspl = dumpsperline; if (ldspl > numtrans) { ldspl = numtrans; } numtrans = numtrans - ldspl; /* Dump data in the line */ for (idx = 0; idx < ldspl; idx++) { if (width == 4) { tmp = * (UNS_32 *) addr; addr = addr + 4; } else if (width == 2) { tmp = (UNS_32) (* (UNS_16 *) addr); addr = addr + 2; } else { tmp = (UNS_32) (* (UNS_8 *) addr); addr = addr + 1; } str_makehex(daddr, tmp, (width * 2)); term_dat_out(daddr); term_dat_out((UNS_8 *) " "); } term_dat_out_crlf((UNS_8 *) ""); } }
/*********************************************************************** * * Function: cmd_load * * Purpose: Load command * * Processing: * For the load command, start parsing subcommand elements and * route to the specific handler. * * Parameters: None * * Outputs: None * * Returns: Always returns TRUE * * Notes: None * **********************************************************************/ BOOL_32 cmd_load(void) { UNS_8 *curp; UNS_32 addr; BOOL_32 processed = TRUE, loaded = FALSE; FILE_DATA_T fdata; SRC_LOAD_T src = SRC_TERM; INT_32 nexidx; UNS_8 *fname; if (parse_get_entry_count() >= 3) { /* Get source */ curp = get_parsed_entry(1); nexidx = 2; if (str_cmp(curp, "term") == 0) { /* Clear break */ term_break(); src = SRC_TERM; } else if (str_cmp(curp, "blk") == 0) { src = SRC_BLKDEV; nexidx = 3; } else if (str_cmp(curp, "flash") == 0) { src = SRC_NAND; } else { term_dat_out_crlf(invalsrc_msg); processed = FALSE; } /* Get file type */ curp = get_parsed_entry(nexidx); fdata.flt = FLT_NONE; if (str_cmp(curp, "elf") == 0) { fdata.flt = FLT_ELF; } else if (str_cmp(curp, "raw") == 0) { fdata.flt = FLT_RAW; } else if (str_cmp(curp, "bin") == 0) { fdata.flt = FLT_BIN; } else if (str_cmp(curp, "srec") == 0) { fdata.flt = FLT_SREC; } else { fdata.flt = FLT_NONE; term_dat_out(unkft_msg); term_dat_out_crlf(curp); processed = FALSE; } /* Next index */ nexidx++; /* Handle each file type */ if (processed == TRUE) { /* Get filename */ fname = get_parsed_entry(2); switch (fdata.flt) { case FLT_RAW: /* Get load address */ curp = get_parsed_entry(nexidx); loaded = str_hex_to_val(curp, &addr); if (loaded == TRUE) { fdata.loadaddr = addr; fdata.startaddr = (PFV) addr; } else { term_dat_out_crlf(rawna_msg); } /* Start address */ nexidx++; curp = get_parsed_entry(nexidx); if (curp != NULL) { loaded &= str_hex_to_val(curp, &addr); if (loaded == TRUE) { fdata.startaddr = (PFV) addr; } } if (loaded == TRUE) { loaded = raw_load(&fdata, fdata.loadaddr, fname, src); } processed = TRUE; break; case FLT_BIN: processed = TRUE; /* TBD not supported yet */ break; case FLT_SREC: loaded = srec_parse(&fdata, src, fname); break; case FLT_ELF: processed = TRUE; /* TBD not supported yet */ break; default: break; } } } if (loaded == TRUE) { term_dat_out_crlf(floaded_msg); sysinfo.lfile.loadaddr = fdata.loadaddr; sysinfo.lfile.flt = fdata.flt; sysinfo.lfile.num_bytes = fdata.num_bytes; sysinfo.lfile.startaddr = fdata.startaddr; sysinfo.lfile.contiguous = fdata.contiguous; sysinfo.lfile.loaded = TRUE; } else { term_dat_out_crlf(notloaded_msg); sysinfo.lfile.loadaddr = 0xFFFFFFFF; sysinfo.lfile.flt = FLT_NONE; sysinfo.lfile.num_bytes = 0; sysinfo.lfile.startaddr = (PFV) 0xFFFFFFFF; processed = FALSE; } return TRUE; }
/*********************************************************************** * * Function: cmd_show_cmd_syntax * * Purpose: Show syntax for a specific command * * Processing: * See function. * * Parameters: * pCmd : Pointer to command to show syntax for * * Outputs: None * * Returns: Nothing * * Notes: None * **********************************************************************/ void cmd_show_cmd_syntax(CMD_ROUTE_T *pCmd) { term_dat_out_crlf(pCmd->keystr); term_dat_out_crlf(pCmd->syntax); }
/*********************************************************************** * * Function: cmd_aboot * * Purpose: Sets autoboot source * * Processing: * See function. * * Parameters: None * * Outputs: None * * Returns: Always returns TRUE * * Notes: None * **********************************************************************/ BOOL_32 cmd_aboot(void) { UNS_8 *curp; UNS_32 addr; BOOL_32 processed = TRUE, ready = FALSE; INT_32 nexidx; ABOOT_SETUP_T abs; abs.fname [0] = '\0'; if (parse_get_entry_count() >= 3) { /* Get source */ curp = get_parsed_entry(1); nexidx = 2; if (str_cmp(curp, "term") == 0) { /* Clear break */ term_break(); abs.abootsrc = SRC_TERM; } else if (str_cmp(curp, "blk") == 0) { abs.abootsrc = SRC_BLKDEV; /* Get filename */ curp = get_parsed_entry(2); memcpy(abs.fname, curp, str_size(curp)); abs.fname[str_size(curp)] = '\0'; nexidx = 3; } else if (str_cmp(curp, "flash") == 0) { abs.abootsrc = SRC_NAND; } else if (str_cmp(curp, "none") == 0) { abs.abootsrc = SRC_NONE; } else { term_dat_out_crlf(invalsrc_msg); processed = FALSE; } /* Get file type */ curp = get_parsed_entry(nexidx); abs.flt = FLT_NONE; if (str_cmp(curp, "elf") == 0) { abs.flt = FLT_ELF; } else if (str_cmp(curp, "raw") == 0) { abs.flt = FLT_RAW; } else if (str_cmp(curp, "bin") == 0) { abs.flt = FLT_BIN; } else if (str_cmp(curp, "srec") == 0) { abs.flt = FLT_SREC; } else { abs.flt = FLT_NONE; term_dat_out(unkft_msg); term_dat_out_crlf(curp); processed = FALSE; } /* Next index */ nexidx++; /* Handle each file type */ if (processed == TRUE) { switch (abs.flt) { case FLT_RAW: /* Get load address */ curp = get_parsed_entry(nexidx); ready = str_hex_to_val(curp, &addr); if (ready == TRUE) { abs.loadaddr = addr; abs.startaddr = addr; } else { term_dat_out_crlf(rawna_msg); } /* Start address */ nexidx++; curp = get_parsed_entry(nexidx); if (curp != NULL) { ready &= str_hex_to_val(curp, &addr); if (ready == TRUE) { abs.startaddr = addr; } } break; case FLT_BIN: ready = FALSE; /* TBD not supported yet */ processed = TRUE; break; case FLT_SREC: ready = TRUE; processed = TRUE; break; case FLT_ELF: ready = FALSE; /* TBD not supported yet */ processed = TRUE; break; default: break; } } } if (ready == TRUE) { syscfg.aboot = abs; cfg_save(&syscfg); term_dat_out_crlf(bsgood_msg); } else { term_dat_out_crlf(bsbad_msg); } return TRUE; }
/*********************************************************************** * * Function: boot_manager * * Purpose: Handle boot configuation and options * * Processing: * See function. * * Parameters: * allow_boot : TRUE to allow the system to autoboot * * Outputs: None * * Returns: Nothing * * Notes: None * **********************************************************************/ void boot_manager(BOOL_32 allow_boot) { UNS_8 key, str[255]; int i, idx; UNS_32 secsmt; BOOL_32 usedef = FALSE; /* Get runtime configuration */ get_rt_s1lsys_cfg(&sysinfo.sysrtcfg); /* Query FLASH */ sysinfo.nandgeom = flash_init(); /* Get S1L configuration */ if (cfg_override() != FALSE) { cfg_default(&syscfg); usedef = TRUE; } else if (cfg_load(&syscfg) == FALSE) { cfg_default(&syscfg); syscfg.scr.number_entries = 0; cfg_save(&syscfg); usedef = TRUE; } /* Initial system setup */ sys_up(); if (sysinfo.nandgeom == NULL) { term_dat_out_crlf(nanderr_msg); } /* Set saved baud rate */ term_setbaud(syscfg.baudrate); /* Default configuration used? */ if (usedef != FALSE) { term_dat_out_crlf(cfggdef_msg); } /* Display system header */ term_dat_out_crlf((UNS_8 *) ""); term_dat_out_crlf(sysinfo.sysrtcfg.system_name); term_dat_out(bdat_msg); term_dat_out((UNS_8 *) __DATE__); term_dat_out((UNS_8 *) " "); term_dat_out_crlf((UNS_8 *) __TIME__); /* No file currently loaded in memory */ sysinfo.lfile.loadaddr = 0xFFFFFFFF; sysinfo.lfile.flt = FLT_NONE; sysinfo.lfile.num_bytes = 0; sysinfo.lfile.startaddr = (PFV) 0xFFFFFFFF; sysinfo.lfile.loaded = FALSE; /* Initialize commands */ cmd_core_add_commands(); cmd_image_add_commands(); cmd_nand_add_commands(); ucmd_init(); /* Initialize line prompt and parser */ key_line_init(syscfg.prmpt); /* Prompt usually appears */ menuexit = FALSE; /* Use built in script capability? */ if ((syscfg.scr.enabled == TRUE) && (syscfg.scr.number_entries > 0)) { term_dat_out_crlf((UNS_8 *) "Running built-in script...\n"); i = idx = 0; while (i < syscfg.scr.number_entries) { /* Execute commands */ term_dat_out((UNS_8 *) "-S>"); term_dat_out_crlf(&syscfg.scr.script_data[idx]); cmd_process(&syscfg.scr.script_data[idx]); idx = idx + syscfg.scr.entry_size[i] + 1; i++; } } else { /* In prompt bypass mode? */ if (syscfg.aboot.abootsrc != SRC_NONE) menuexit = allow_boot; if ((syscfg.prmpt_to > 0) && (menuexit == TRUE)) { secsmt = get_seconds() + syscfg.prmpt_to; term_dat_out_crlf(kp_msg); while (get_seconds() < secsmt) { if (term_dat_in_ready() > 0) { term_dat_in(&key, 1); menuexit = FALSE; secsmt = get_seconds(); } } } /* Perform autoboot if possible */ if (menuexit == TRUE) { menuexit = autoboot(); } } while (menuexit == FALSE) { key_get_command(str); str_upper_to_lower(str); cmd_process(str); } /* Bring down some system items */ sys_down(); /* Execute program */ jumptoprog(sysinfo.lfile.startaddr); }
/*********************************************************************** * * Function: cmd_info * * Purpose: Info command * * Processing: * For the load command, start parsing subcommand elements and * route to the specific handler. * * Parameters: None * * Outputs: None * * Returns: TRUE if the command was processed, otherwise FALSE * * Notes: None * **********************************************************************/ BOOL_32 cmd_info(void) { int i, idx; UNS_8 str [128]; UNS_32 tmp; /* S1L configuration */ term_dat_out(prto_msg); str_makedec(str, syscfg.prmpt_to); term_dat_out_crlf(str); /* Dump FLASH geometry */ term_dat_out(flashsts_msg); if (sysinfo.nandgeom != NULL) { term_dat_out_crlf(present_msg); term_dat_out(numblks_msg); str_makedec(str, sysinfo.nandgeom->num_blocks); term_dat_out_crlf(str); term_dat_out(pgsblk_msg); str_makedec(str, sysinfo.nandgeom->pages_per_block); term_dat_out_crlf(str); term_dat_out(pgsbyt_msg); str_makedec(str, sysinfo.nandgeom->data_bytes_per_page); term_dat_out_crlf(str); tmp = sysinfo.nandgeom->num_blocks * sysinfo.nandgeom->pages_per_block * sysinfo.nandgeom->data_bytes_per_page; tmp = tmp / (1024 * 1024); term_dat_out(ttlsz_msg); str_makedec(str, tmp); term_dat_out_crlf(str); /* Dump FLASH usage for stage 1 loader */ tmp = sysinfo.sysrtcfg.bl_num_blks; term_dat_out(blspace_msg); str_makedec(str, tmp); term_dat_out_crlf(str); } else { term_dat_out_crlf(notpresent_msg); } /* Loaded program status */ term_dat_out(ftloaded_msg); if (sysinfo.lfile.flt == FLT_NONE) { term_dat_out_crlf(ftnone_msg); } else { term_dat_out_crlf(ftimage_msg); term_dat_out(ftaddr_msg); str_makehex(str, sysinfo.lfile.loadaddr, 8); term_dat_out_crlf(str); term_dat_out(ftmbytes_msg); str_makedec(str, sysinfo.lfile.num_bytes); term_dat_out_crlf(str); term_dat_out(fteaddr_msg); if ((UNS_32) sysinfo.lfile.startaddr != 0xFFFFFFFF) { str_makehex(str, (UNS_32) sysinfo.lfile.startaddr, 8); term_dat_out_crlf(str); } else { term_dat_out_crlf(fteaddrunk_msg); } } /* FLASHed program status */ if (syscfg.fsave.valid == FALSE) { term_dat_out_crlf(flsnone_msg); } else { term_dat_out(fifb_msg); str_makedec(str, syscfg.fsave.block_first); term_dat_out_crlf(str); term_dat_out(finbu_msg); str_makedec(str, syscfg.fsave.blocks_used); term_dat_out_crlf(str); term_dat_out(finsu_msg); str_makedec(str, syscfg.fsave.secs_used); term_dat_out_crlf(str); term_dat_out(finnbu_msg); str_makedec(str, syscfg.fsave.num_bytes); term_dat_out_crlf(str); term_dat_out(fladd_msg); str_makehex(str, syscfg.fsave.loadaddr, 8); term_dat_out_crlf(str); term_dat_out(fsadd_msg); str_makehex(str, syscfg.fsave.startaddr, 8); term_dat_out_crlf(str); } /* Autoboot source */ term_dat_out(absrc_msg); switch (syscfg.aboot.abootsrc) { case SRC_TERM: term_dat_out_crlf(absrcterm_msg); break; case SRC_NAND: term_dat_out_crlf(absrcnand_msg); break; case SRC_BLKDEV: term_dat_out(absrcsd_msg); term_dat_out_crlf(syscfg.aboot.fname); break; case SRC_NONE: default: term_dat_out_crlf(absnone_msg); break; } if (syscfg.aboot.abootsrc != SRC_NONE) { term_dat_out(absrcft_msg); switch (syscfg.aboot.flt) { case FLT_RAW: term_dat_out_crlf(absrcraw_msg); break; case FLT_BIN: term_dat_out_crlf(absrcnbin_msg); break; case FLT_SREC: term_dat_out_crlf(absrcsrec_msg); break; case FLT_ELF: term_dat_out_crlf(absrcelf_msg); break; default: /* These should never happen */ break; } if (syscfg.aboot.abootsrc != SRC_NAND) { term_dat_out(abadd_msg); str_makehex(str, syscfg.aboot.loadaddr, 8); term_dat_out_crlf(str); term_dat_out(abeadd_msg); str_makehex(str, syscfg.aboot.startaddr, 8); term_dat_out_crlf(str); } } /* Show any scripts */ term_dat_out((UNS_8 *) "Scripting: "); if ((syscfg.scr.number_entries == 0) || (syscfg.scr.enabled == FALSE)) { term_dat_out_crlf((UNS_8 *) "Disabled"); } else { term_dat_out_crlf((UNS_8 *) "Enabled"); idx = 0; for (i = 0; i < syscfg.scr.number_entries; i++) { term_dat_out((UNS_8 *) "-S>"); term_dat_out_crlf(&syscfg.scr.script_data[idx]); idx = idx + syscfg.scr.entry_size[i] + 1; } } /* Call user defined extended info */ cmd_info_extend(); return TRUE; }