/*********************************************************************** * * 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_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: 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_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_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: Output_bit_multiple * * Purpose: Outputs a string of the same character * * Processing: * See function. * * Parameters: * value: Value to perform bit operations on * bits : Number of bits to output * * Outputs: None * * Returns: Nothing * * Notes: None * **********************************************************************/ void Output_bit_multiple(UNS_32 value, int bits) { int shift = bits - 1; UNS_8 ch0[] = "0"; UNS_8 ch1[] = "1"; while (bits > 0) { if (value & (1 << shift)) { term_dat_out(ch1); } else { term_dat_out(ch0); } bits--; shift--; } }
/*********************************************************************** * * Function: output_char_multiple * * Purpose: Outputs a string of the same character * * Processing: * See function. * * Parameters: * value: Character value to output * rep : Number of times to repeat the character * * Outputs: None * * Returns: Nothing * * Notes: None * **********************************************************************/ void output_char_multiple(UNS_8 value, int rep) { UNS_8 ch[2]; ch[0] = value; ch[1] = '\0'; while (rep > 0) { term_dat_out(ch); rep--; } }
/*********************************************************************** * * 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 {
void start_uart_write() { // UNS_8 ch[16]; /* Loop returning the data from the terminal */ term_dat_out(sendstr, sizeof(sendstr)); // ch[0] = 0; // while (ch[0] != 27) // { // if (term_dat_in(&ch[0], 16) > 0) // { // term_dat_out(&ch[0], 1); // } // } }
/*********************************************************************** * * 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_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_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: 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: term_dat_out_crlf * * Purpose: * Send some data on the terminal interface up to NULL character * with a linefeed * * Processing: * Move data into the UART ring buffer. * * Parameters: * dat : Data to send * * Outputs: None * * Returns: Nothing * * Notes: Will block until all bytes are sent. * **********************************************************************/ void term_dat_out_crlf(UNS_8 *dat) { term_dat_out(dat); term_dat_out(crlf); }
/*********************************************************************** * * 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_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; }
/*********************************************************************** * * Function: stream_flash_read * * Purpose: Read data from FLASH * * Processing: * See function. * * Parameters: * fdata : Pointer to file data to fill * bytes : BYtes to read * * Outputs: None * * Returns: Number of bytes read * * Notes: None * **********************************************************************/ static INT_32 stream_flash_read(UNS_8 *data, int bytes) { UNS_32 sector; INT_32 btoread, bread = 0; /* Limit read size */ if (bytes > bytestoread) { bytes = bytestoread; } while (bytes > 0) { /* Is a bad block check needed? */ if (checkblk == TRUE) { /* Start of block, read bad block marker */ if (flash_is_bad_block(curblock) == FALSE) { /* Block is good */ checkblk = FALSE; } else { /* Block is bad, go to next block */ curblock++; } } /* Read more data if needed */ if (checkblk == FALSE) { /* Is a data read needed? */ if (lefttoread == 0) { /* Out of pages in the block? */ if (curpage >= sysinfo.nandgeom->pages_per_block) { /* Reset block and page marker */ curblock++; curpage = 0; checkblk = TRUE; } else { /* Time to read in a new sector */ sector = conv_to_sector(curblock, curpage); if (flash_read_sector(sector, secdat, NULL) <= 0) term_dat_out((UNS_8 *) "Read error: data may be corrupt\r\n"); lefttoread = sysinfo.nandgeom->data_bytes_per_page; cindex = 0; curpage++; } } /* Move data into user buffer */ btoread = lefttoread; if (btoread > bytes) { btoread = bytes; } while (btoread > 0) { bread++; *data = secdat [cindex]; cindex++; btoread--; lefttoread--; bytes--; } } } return bread; }
/*********************************************************************** * * 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: 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: 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: 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); }