示例#1
0
cyg_uint32
hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
{
    cyg_uint32 result;

#if (defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)           \
     || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)) &&    \
        (defined(CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT) ||     \
          defined(CYGHWR_HAL_GDB_PORT_VECTOR) &&           \
          defined(HAL_CTRLC_ISR))

#ifndef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN    
#if CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
    int gdb_vector = -1;
    // This check only to avoid crash on older stubs in case of unhandled
    // interrupts. It is a bit messy, but required in a transition period.
#ifndef CYGSEM_HAL_ROM_MONITOR
    if (CYGNUM_CALL_IF_TABLE_VERSION_CALL_HACK ==
        (CYGACC_CALL_IF_VERSION() & CYGNUM_CALL_IF_TABLE_VERSION_CALL_MASK))
#endif
    {
        hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
        if (__chan)
            gdb_vector = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DBG_ISR_VECTOR);
    }
    if( CYGHWR_HAL_GDB_PORT_VECTORS_MATCH(vector, gdb_vector) )
#else
    // Old code using hardwired channels. This should go away eventually.
    if( vector == CYGHWR_HAL_GDB_PORT_VECTOR )
#endif
#endif
    {
        result = HAL_CTRLC_ISR( vector, data );
        if( 0 != result ) return result;
    }
#endif

    result = hal_arch_default_isr (vector, data);
    if( 0 != result) return result;

    CYG_TRACE2(true, "Interrupt: %d, Data: 0x%08x", vector, data);
    CYG_FAIL("Spurious Interrupt!!!");
    return 0;
}
示例#2
0
int
set_console_baud_rate(int rate)
{
    hal_virtual_comm_table_t *__chan;
    static int current_rate = CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD;
    int ret = current_rate;

    if (rate != current_rate) {
        __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
        ret = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SETBAUD, rate);
        if (ret < 0) {
            diag_printf("Setting console baud rate to %d failed\n", rate);
            return ret;
        }
        ret = current_rate;
        current_rate = rate;
    }
    return ret;
}
示例#3
0
cyg_bool
hal_ctrlc_check(CYG_ADDRWORD vector, CYG_ADDRWORD data)
{
    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
    int gdb_vector = vector-1;
    int isr_ret, ctrlc = 0;

    // This check only to avoid crash on older stubs in case of unhandled
    // interrupts. It is a bit messy, but required in a transition period.
    if (__chan && 
        (CYGNUM_CALL_IF_TABLE_VERSION_CALL_HACK == 
         (CYGACC_CALL_IF_VERSION() & CYGNUM_CALL_IF_TABLE_VERSION_CALL_MASK))){
        gdb_vector = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DBG_ISR_VECTOR);
    }
    if (vector == gdb_vector) {
        isr_ret = CYGACC_COMM_IF_DBG_ISR(*__chan, &ctrlc, vector, data);
        if (ctrlc) {
            cyg_hal_user_break( (CYG_ADDRWORD *)hal_saved_interrupt_state );
            return true;
        }
    }
    return false;
}
示例#4
0
static void
cyg_hal_diag_mangler_gdb_flush(void* __ch_data)
{
    CYG_INTERRUPT_STATE old;
    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
#if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0
    int tries = CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES;
#endif


    // Nothing to do if mangler buffer is empty.
    if (__mangler_pos == 0)
        return;

    // Disable interrupts. This prevents GDB trying to interrupt us
    // while we are in the middle of sending a packet. The serial
    // receive interrupt will be seen when we re-enable interrupts
    // later.
#if defined(CYG_HAL_STARTUP_ROM) \
    || !defined(CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION)
    HAL_DISABLE_INTERRUPTS(old);
#else
    CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old);
#endif
        
#if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0
    // Only wait 500ms for data to arrive - avoid "stuck" connections
    CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SET_TIMEOUT, CYGNUM_HAL_DEBUG_GDB_PROTOCOL_TIMEOUT);
#endif

    while(1)
    {
	static const char hex[] = "0123456789ABCDEF";
	cyg_uint8 csum = 0;
	char c1;
	int i;
        
	CYGACC_COMM_IF_PUTC(*__chan, '$');
	CYGACC_COMM_IF_PUTC(*__chan, 'O');
	csum += 'O';
	for( i = 0; i < __mangler_pos; i++ )
        {
	    char ch = __mangler_line[i];
	    char h = hex[(ch>>4)&0xF];
	    char l = hex[ch&0xF];
	    CYGACC_COMM_IF_PUTC(*__chan, h);
	    CYGACC_COMM_IF_PUTC(*__chan, l);
	    csum += h;
	    csum += l;
	}
	CYGACC_COMM_IF_PUTC(*__chan, '#');
	CYGACC_COMM_IF_PUTC(*__chan, hex[(csum>>4)&0xF]);
	CYGACC_COMM_IF_PUTC(*__chan, hex[csum&0xF]);

    nak:
#if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0
	if (CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, &c1) == 0) {
	    c1 = '-';
	    if (tries && (--tries == 0)) c1 = '+';
	}
#else
	c1 = CYGACC_COMM_IF_GETC(*__chan);
#endif

	if( c1 == '+' ) break;

	if( cyg_hal_is_break( &c1 , 1 ) ) {
	    // Caller's responsibility to react on this.
	    CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(1);
	    break;
	}
	if( c1 != '-' ) goto nak;
    }

    __mangler_pos = 0;
    // And re-enable interrupts
#if defined(CYG_HAL_STARTUP_ROM) \
    || !defined(CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION)
    HAL_RESTORE_INTERRUPTS(old);
#else
    CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old);
#endif
}
示例#5
0
//
// This is the main entry point for RedBoot
//
void
cyg_start(void)
{
    int res = 0;
    bool prompt = true;
    static char line[CYGPKG_REDBOOT_MAX_CMD_LINE];
    char *command;
    struct cmd *cmd;
    int cur;
    struct init_tab_entry *init_entry;

    // Make sure the channels are properly initialized.
    diag_init_putc(_mon_write_char);
    hal_if_diag_init();

    // Force console to output raw text - but remember the old setting
    // so it can be restored if interaction with a debugger is
    // required.
    cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
    CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL);
#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
    console_selected = false;
#endif
    console_echo = true;
    CYGACC_CALL_IF_DELAY_US((cyg_int32)2*100000);

    ram_start = (unsigned char *)CYGMEM_REGION_ram;
    ram_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE);
#ifdef HAL_MEM_REAL_REGION_TOP
    {
        unsigned char *ram_end_tmp = ram_end;
        ram_end = HAL_MEM_REAL_REGION_TOP( ram_end_tmp );
    }
#endif
#ifdef CYGMEM_SECTION_heap1
    workspace_start = (unsigned char *)CYGMEM_SECTION_heap1;
    workspace_end = (unsigned char *)(CYGMEM_SECTION_heap1+CYGMEM_SECTION_heap1_SIZE);
    workspace_size = CYGMEM_SECTION_heap1_SIZE;
#else
    workspace_start = (unsigned char *)CYGMEM_REGION_ram;
    workspace_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE);
    workspace_size = CYGMEM_REGION_ram_SIZE;
#endif

    if ( ram_end < workspace_end ) {
        // when *less* SDRAM is installed than the possible maximum,
        // but the heap1 region remains greater...
        workspace_end = ram_end;
        workspace_size = workspace_end - workspace_start;
    }

    bist();

    for (init_entry = __RedBoot_INIT_TAB__; init_entry != &__RedBoot_INIT_TAB_END__;  init_entry++) {
        (*init_entry->fun)();
    }

    user_ram_start = workspace_start;
    user_ram_end = workspace_end;

    do_version(0,0);

#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
# ifdef CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT
    if (!script) {
      script = CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT;
#  ifndef CYGSEM_REDBOOT_FLASH_CONFIG
      script_timeout = CYGNUM_REDBOOT_BOOT_SCRIPT_DEFAULT_TIMEOUT;
#  endif
    }
# endif
    if (script) {
        // Give the guy a chance to abort any boot script
        unsigned char *hold_script = script;
        int script_timeout_ms = script_timeout * CYGNUM_REDBOOT_BOOT_SCRIPT_TIMEOUT_RESOLUTION;
        diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", 
                    script_timeout_ms/1000, script_timeout_ms%1000);
        script = (unsigned char *)0;
        res = _GETS_CTRLC;  // Treat 0 timeout as ^C
        while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
            res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
            if (res >= _GETS_OK) {
                diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", 
                            script_timeout_ms/1000, script_timeout_ms%1000);
                continue;  // Ignore anything but ^C
            }
            if (res != _GETS_TIMEOUT) break;
            script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
        }
        if (res == _GETS_CTRLC) {
            script = (unsigned char *)0;  // Disable script
        } else {
            script = hold_script;  // Re-enable script
        }
    }
#endif

    while (true) {
        if (prompt) {
            diag_printf("RedBoot> ");
            prompt = false;
        }
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
        cmd_history = true;  // Enable history collection
#endif
        res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
        cmd_history = false;  // Enable history collection
#endif
        if (res == _GETS_TIMEOUT) {
            // No input arrived
        } else {
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
            if (res == _GETS_GDB) {
		int dbgchan;
                hal_virtual_comm_table_t *__chan;
                int i;
                // Special case of '$' - need to start GDB protocol
                gdb_active = true;
                // Mask interrupts on all channels
                for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS;  i++) {
                    CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
                    __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
                    CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE );
                }
    
                CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
#ifdef HAL_ARCH_PROGRAM_NEW_STACK
                HAL_ARCH_PROGRAM_NEW_STACK(breakpoint);
#else
                breakpoint();  // Get GDB stubs started, with a proper environment, etc.
#endif
		dbgchan = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
		CYGACC_CALL_IF_SET_CONSOLE_COMM(dbgchan);
            } else 
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
            {
                expand_aliases(line, sizeof(line));
		command = (char *)&line;
                if ((*command == '#') || (*command == '=')) {
                    // Special cases
                    if (*command == '=') {
                        // Print line on console
                        diag_printf("%s\n", &line[2]);
                    }
                } else {
                    while (strlen(command) > 0) {                    
                        if ((cmd = parse(&command, &argc, &argv[0])) != (struct cmd *)0) {
                            (cmd->fun)(argc, argv);
                        } else {
                            diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]);
                        }
                    }
                }
                prompt = true;
            }
        }
    }
}
int
xyzModem_stream_open (connection_info_t * info, int *err)
{
#ifdef REDBOOT
  int console_chan;
#endif
  int stat = 0;
  int retries = xyzModem_MAX_RETRIES;
  int crc_retries = xyzModem_MAX_RETRIES_WITH_CRC;

/*    ZM_DEBUG(zm_out = zm_out_start); */
#ifdef xyzModem_zmodem
  if (info->mode == xyzModem_zmodem)
    {
      *err = xyzModem_noZmodem;
      return -1;
    }
#endif

#ifdef REDBOOT
  /* Set up the I/O channel.  Note: this allows for using a different port in the future */
  console_chan =
    CYGACC_CALL_IF_SET_CONSOLE_COMM
    (CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
  if (info->chan >= 0)
    {
      CYGACC_CALL_IF_SET_CONSOLE_COMM (info->chan);
    }
  else
    {
      CYGACC_CALL_IF_SET_CONSOLE_COMM (console_chan);
    }
  xyz.__chan = CYGACC_CALL_IF_CONSOLE_PROCS ();

  CYGACC_CALL_IF_SET_CONSOLE_COMM (console_chan);
  CYGACC_COMM_IF_CONTROL (*xyz.__chan, __COMMCTL_SET_TIMEOUT,
			  xyzModem_CHAR_TIMEOUT);
#else
/* TODO: CHECK ! */
  int dummy;
  xyz.__chan = &dummy;
#endif
  xyz.len = 0;
  xyz.crc_mode = true;
  xyz.at_eof = false;
  xyz.tx_ack = false;
  xyz.mode = info->mode;
  xyz.total_retries = 0;
  xyz.total_SOH = 0;
  xyz.total_STX = 0;
  xyz.total_CAN = 0;
#ifdef USE_YMODEM_LENGTH
  xyz.read_length = 0;
  xyz.file_length = 0;
#endif

  CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));

  if (xyz.mode == xyzModem_xmodem)
    {
      /* X-modem doesn't have an information header - exit here */
      xyz.next_blk = 1;
      return 0;
    }

  while (retries-- > 0)
    {
      stat = xyzModem_get_hdr ();
      if (stat == 0)
	{
	  /* Y-modem file information header */
	  if (xyz.blk == 0)
	    {
#ifdef USE_YMODEM_LENGTH
	      /* skip filename */
	      while (*xyz.bufp++);
	      /* get the length */
	      parse_num ((char *) xyz.bufp, &xyz.file_length, NULL, " ");
#endif
	      /* The rest of the file name data block quietly discarded */
	      xyz.tx_ack = true;
	    }
	  xyz.next_blk = 1;
	  xyz.len = 0;
	  return 0;
	}
      else if (stat == xyzModem_timeout)
	{
	  if (--crc_retries <= 0)
	    xyz.crc_mode = false;
	  CYGACC_CALL_IF_DELAY_US (5 * 100000);	/* Extra delay for startup */
	  CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
	  xyz.total_retries++;
	  ZM_DEBUG (zm_dprintf ("NAK (%d)\n", __LINE__));
	}
      if (stat == xyzModem_cancel)
	{
	  break;
	}
    }
  *err = stat;
  ZM_DEBUG (zm_flush ());
  return -1;
}
//
// Execute a Linux kernel - this is a RedBoot CLI command
//
static void 
do_exec(int argc, char *argv[])
{
    unsigned long entry;
    bool wait_time_set, cmd_line_set;
    int  wait_time;
    char *cmd_line;
    char *cline;
    struct option_info opts[2];
    hal_virtual_comm_table_t *__chan;
    int baud_rate;

    bd_t *board_info;
    CYG_INTERRUPT_STATE oldints;
    unsigned long sp = CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE;
    
    init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM, 
              (void *)&wait_time, (bool *)&wait_time_set, "wait timeout");
    init_opts(&opts[1], 'c', true, OPTION_ARG_TYPE_STR, 
              (void *)&cmd_line, (bool *)&cmd_line_set, "kernel command line");
    entry = entry_address;  // Default from last 'load' operation
    if (!scan_opts(argc, argv, 1, opts, 2, (void *)&entry, OPTION_ARG_TYPE_NUM, 
                   "[physical] starting address")) {
        return;
    }
    if (entry == (unsigned long)NO_MEMORY) {
        diag_printf("Can't execute Linux - invalid entry address\n");
        return;
    }

    // Determine baud rate on current console
    __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
    baud_rate = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);
    if (baud_rate <= 0) {
        baud_rate = CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD;
    }

    // Make a little space at the top of the stack, and align to
    // 64-bit boundary.
    sp = (sp-128) & ~7;  // The Linux boot code uses this space for FIFOs
    
    // Copy the commandline onto the stack, and set the SP to just below it.
    if (cmd_line_set) {
	int len,i;

	// get length of string
	for( len = 0; cmd_line[len] != '\0'; len++ );

	// decrement sp by length of string and align to
	// word boundary.
	sp = (sp-(len+1)) & ~3;

	// assign this SP value to command line start
	cline = (char *)sp;

	// copy command line over.
	for( i = 0; i < len; i++ )
	    cline[i] = cmd_line[i];
	cline[len] = '\0';

    } else {
        cline = (char *)NULL;
    }
    
    // Set up parameter struct at top of stack
    sp = sp-sizeof(bd_t);
    board_info = (bd_t *)sp;
    memset(board_info, sizeof(*board_info), 0);
    
    board_info->bi_tag		= 0x42444944;
    board_info->bi_size		= sizeof(*board_info);
    board_info->bi_revision	= 1;
    board_info->bi_bdate	= 0x06012002;
    board_info->bi_memstart	= CYGMEM_REGION_ram;
    board_info->bi_memsize	= CYGMEM_REGION_ram_SIZE;
    board_info->bi_baudrate     = baud_rate;
    board_info->bi_cmdline      = cline;
#ifdef CYGPKG_REDBOOT_NETWORKING
    memcpy(board_info->bi_enetaddr, __local_enet_addr, sizeof(enet_addr_t));
#endif
    // Call platform specific code to fill in the platform/architecture specific details
    plf_redboot_linux_exec(board_info);

    // adjust SP to 64 byte boundary, and leave a little space
    // between it and the commandline for PowerPC calling
    // conventions.
	
    sp = (sp-64)&~63;

    if (wait_time_set) {
        int script_timeout_ms = wait_time * 1000;
#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
        unsigned char *hold_script = script;
        script = (unsigned char *)0;
#endif
        diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
                    (void *)entry, wait_time);
        while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
            int res;
            char line[80];
            res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
            if (res == _GETS_CTRLC) {
#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
                script = hold_script;  // Re-enable script
#endif
                return;
            }
            script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
        }
    }

#ifdef CYGPKG_IO_ETH_DRIVERS
    eth_drv_stop();
#endif

    // Disable interrupts
    HAL_DISABLE_INTERRUPTS(oldints);

    // Put the caches to sleep.
    HAL_DCACHE_SYNC();
    HAL_ICACHE_DISABLE();
    HAL_DCACHE_DISABLE();
    HAL_DCACHE_SYNC();
    HAL_ICACHE_INVALIDATE_ALL();
    HAL_DCACHE_INVALIDATE_ALL();

//    diag_printf("entry %08x, sp %08x, info %08x, cmd line %08x, baud %d\n",
//		entry, sp, board_info, cline, baud_rate);
//    breakpoint();
    
    // Call into Linux
    __asm__ volatile (        
	               // Start by disabling MMU - the mappings are
	               // 1-1 so this should not cause any problems
	               "mfmsr	3\n"
		       "li      4,0xFFFFFFCF\n"
		       "and	3,3,4\n"
		       "sync\n"
		       "mtmsr	3\n"
		       "sync\n"

		       // Now set up parameters to jump into linux

		       "mtlr	%0\n"		// set entry address in LR
		       "mr	1,%1\n"		// set stack pointer
		       "mr	3,%2\n"		// set board info in R3
		       "mr	4,%3\n"		// set command line in R4
		       "blr          \n"	// jump into linux
		       :
		       : "r"(entry),"r"(sp),"r"(board_info),"r"(cline)
		       : "r3", "r4"
	             
	             );
}
示例#8
0
文件: main.c 项目: cilynx/dd-wrt
void
do_go(int argc, char *argv[])
{
    int i, cur, num_options;
    unsigned long entry;
    unsigned long oldints;
    bool wait_time_set;
    int  wait_time, res;
    bool cache_enabled = false;
#ifdef CYGPKG_IO_ETH_DRIVERS
    bool stop_net = false;
#endif
    struct option_info opts[3];
    char line[8];
    hal_virtual_comm_table_t *__chan;

    __mem_fault_handler = 0; // Let GDB handle any faults directly
    entry = entry_address;  // Default from last 'load' operation
    init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM, 
              (void *)&wait_time, (bool *)&wait_time_set, "wait timeout");
    init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, 
              (void *)&cache_enabled, (bool *)0, "go with caches enabled");
    num_options = 2;
#ifdef CYGPKG_IO_ETH_DRIVERS
    init_opts(&opts[2], 'n', false, OPTION_ARG_TYPE_FLG, 
              (void *)&stop_net, (bool *)0, "go with network driver stopped");
    num_options++;
#endif

    CYG_ASSERT(num_options <= NUM_ELEMS(opts), "Too many options");

    if (!scan_opts(argc, argv, 1, opts, num_options, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address"))
    {
        return;
    }
    if (entry == (unsigned long)NO_MEMORY) {
        diag_printf("No entry point known - aborted\n");
        return;
    }
    if (wait_time_set) {
        int script_timeout_ms = wait_time * 1000;
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
        unsigned char *hold_script = script;
        script = (unsigned char *)0;
#endif
        diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
                    (void *)entry, wait_time);
        while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
            res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
            if (res == _GETS_CTRLC) {
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
                script = hold_script;  // Re-enable script
#endif
                return;
            }
            script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
        }
    }

    // Mask interrupts on all channels
    cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
    for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS;  i++) {
	CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
	__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
	CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE );
    }
    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);

    __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
    CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH);

#ifdef CYGPKG_IO_ETH_DRIVERS
    if (stop_net)
	eth_drv_stop();
#endif
	
    HAL_DISABLE_INTERRUPTS(oldints);
    HAL_DCACHE_SYNC();
    if (!cache_enabled) {
	HAL_ICACHE_DISABLE();
	HAL_DCACHE_DISABLE();
	HAL_DCACHE_SYNC();
    }
    HAL_ICACHE_INVALIDATE_ALL();
    HAL_DCACHE_INVALIDATE_ALL();
    // set up a temporary context that will take us to the trampoline
    HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end, entry, trampoline, 0);

    // switch context to trampoline
    HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end);

    // we get back here by way of return_to_redboot()

    // undo the changes we made before switching context
    if (!cache_enabled) {
	HAL_ICACHE_ENABLE();
	HAL_DCACHE_ENABLE();
    }

    CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DISABLE_LINE_FLUSH);

    HAL_RESTORE_INTERRUPTS(oldints);

    diag_printf("\nProgram completed with status %d\n", return_status);
}
示例#9
0
文件: main.c 项目: cilynx/dd-wrt
//
// This is the main entry point for RedBoot
//
void
cyg_start(void)
{
    int res = 0;
    bool prompt = true;
    static char line[CYGPKG_REDBOOT_MAX_CMD_LINE];
    char *command;
    struct cmd *cmd;
    int cur;
    struct init_tab_entry *init_entry;
    extern char RedBoot_version[];
#if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1
    int seg;
#endif

    // Export version information
    CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);

    CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot);

    // Make sure the channels are properly initialized.
    diag_init_putc(_mon_write_char);
    hal_if_diag_init();

    // Force console to output raw text - but remember the old setting
    // so it can be restored if interaction with a debugger is
    // required.
    cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
    CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL);
#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
    console_selected = false;
#endif
    console_echo = true;
    CYGACC_CALL_IF_DELAY_US((cyg_int32)2*100000);

    ram_start = (unsigned char *)CYGMEM_REGION_ram;
    ram_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE);
#ifdef HAL_MEM_REAL_REGION_TOP
    {
        unsigned char *ram_end_tmp = ram_end;
        ram_end = HAL_MEM_REAL_REGION_TOP( ram_end_tmp );
    }
#endif
#ifdef CYGMEM_SECTION_heap1
    workspace_start = (unsigned char *)CYGMEM_SECTION_heap1;
    workspace_end = (unsigned char *)(CYGMEM_SECTION_heap1+CYGMEM_SECTION_heap1_SIZE);
#else
    workspace_start = (unsigned char *)CYGMEM_REGION_ram;
    workspace_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE);
#endif

    if ( ram_end < workspace_end ) {
        // when *less* SDRAM is installed than the possible maximum,
        // but the heap1 region remains greater...
        workspace_end = ram_end;
    }

    // Nothing has ever been loaded into memory
    entry_address = (unsigned long)NO_MEMORY;

    bist();

#if defined(CYGPRI_REDBOOT_ZLIB_FLASH) && defined(CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER)
    fis_zlib_common_buffer =
    workspace_end -= CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE;
#endif

#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
    script_timeout = CYGNUM_REDBOOT_BOOT_SCRIPT_DEFAULT_TIMEOUT;
#endif

    for (init_entry = __RedBoot_INIT_TAB__; init_entry != &__RedBoot_INIT_TAB_END__;  init_entry++) {
        (*init_entry->fun)();
    }

    mem_segments[0].start = workspace_start;
    mem_segments[0].end = workspace_end;
#if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1
    for (seg = 1;  seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS;  seg++) {
        cyg_plf_memory_segment(seg, &mem_segments[seg].start, &mem_segments[seg].end);
    }
#endif

#ifdef CYGSEM_REDBOOT_PLF_STARTUP
    cyg_plf_redboot_startup();
#endif
    do_version(0,0);

#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
# ifdef CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT
    if (!script) {
      script = CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT;
    }
# endif
    if (script) {
        // Give the guy a chance to abort any boot script
        unsigned char *hold_script = script;
        int script_timeout_ms = script_timeout * CYGNUM_REDBOOT_BOOT_SCRIPT_TIMEOUT_RESOLUTION;
        diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", 
                    script_timeout_ms/1000, script_timeout_ms%1000);
        script = (unsigned char *)0;
        res = _GETS_CTRLC;  // Treat 0 timeout as ^C
        while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
            res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
            if (res >= _GETS_OK) {
                diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", 
                            script_timeout_ms/1000, script_timeout_ms%1000);
                continue;  // Ignore anything but ^C
            }
            if (res != _GETS_TIMEOUT) break;
            script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
        }
        if (res == _GETS_CTRLC) {
            script = (unsigned char *)0;  // Disable script
        } else {
            script = hold_script;  // Re-enable script
        }
    }
#endif

    while (true) {
        if (prompt) {
            diag_printf("RedBoot> ");
            prompt = false;
        }
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
        cmd_history = true;  // Enable history collection
#endif
        res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
        cmd_history = false;  // Enable history collection
#endif
        if (res == _GETS_TIMEOUT) {
            // No input arrived
        } else {
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
            if (res == _GETS_GDB) {
		int dbgchan;
                hal_virtual_comm_table_t *__chan;
                int i;
                // Special case of '$' - need to start GDB protocol
                gdb_active = true;
                // Mask interrupts on all channels
                for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS;  i++) {
                    CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
                    __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
                    CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE );
                }
    
                CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);

                // set up a temporary context that will take us to the trampoline
                HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end,
                                        breakpoint, trampoline, 0);

                // switch context to trampoline (get GDB stubs started)
                HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end);

                gdb_active = false;

		dbgchan = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
		CYGACC_CALL_IF_SET_CONSOLE_COMM(dbgchan);
            } else 
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
            {
#ifdef CYGSEM_REDBOOT_FLASH_ALIASES              
                expand_aliases(line, sizeof(line));
#endif
		command = (char *)&line;
                if ((*command == '#') || (*command == '=')) {
                    // Special cases
                    if (*command == '=') {
                        // Print line on console
                        diag_printf("%s\n", &line[2]);
                    }
                } else {
                    while (strlen(command) > 0) {                    
                        if ((cmd = parse(&command, &argc, &argv[0])) != (struct cmd *)0) {
                            // Try to handle aborts - messy because of the stack unwinding...
                            __mem_fault_handler = error_handler;
                            if (hal_setjmp(error_jmpbuf)) {
                                diag_printf("** command abort - illegal memory access?\n");
                            } else {
                                (cmd->fun)(argc, argv);
                            }
                            __mem_fault_handler = 0;
                        } else {
                            diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]);
                        }
                    }
                }
                prompt = true;
            }
        }
    }
}
示例#10
0
void
do_go(int argc, char *argv[])
{
    unsigned long entry;
    unsigned long oldints;
    bool wait_time_set;
    int  wait_time, res;
    bool cache_enabled = false;
    struct option_info opts[2];
    char line[8];
    hal_virtual_comm_table_t *__chan = CYGACC_CALL_IF_CONSOLE_PROCS();

    entry = entry_address;  // Default from last 'load' operation
    init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM,
              (void **)&wait_time, (bool *)&wait_time_set, "wait timeout");
    init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG,
              (void **)&cache_enabled, (bool *)0, "go with caches enabled");
    if (!scan_opts(argc, argv, 1, opts, 2, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address"))
    {
        return;
    }
    if (wait_time_set) {
        int script_timeout_ms = wait_time * 1000;
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
        unsigned char *hold_script = script;
        script = (unsigned char *)0;
#endif
        diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
                    (void *)entry, wait_time);
        while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
            res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
            if (res == _GETS_CTRLC) {
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
                script = hold_script;  // Re-enable script
#endif
                return;
            }
            script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
        }
    }
    CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH);

    HAL_DISABLE_INTERRUPTS(oldints);
    HAL_DCACHE_SYNC();
    if (!cache_enabled) {
        HAL_ICACHE_DISABLE();
        HAL_DCACHE_DISABLE();
        HAL_DCACHE_SYNC();
    }
    HAL_ICACHE_INVALIDATE_ALL();
    HAL_DCACHE_INVALIDATE_ALL();

    // set up a temporary context that will take us to the trampoline
    HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end, entry, go_trampoline, 0);

    // switch context to trampoline
    HAL_THREAD_SWITCH_CONTEXT(&go_saved_context, &workspace_end);

    // we get back here by way of return_to_redboot()

    // undo the changes we made before switching context
    if (!cache_enabled) {
        HAL_ICACHE_ENABLE();
        HAL_DCACHE_ENABLE();
    }

    CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DISABLE_LINE_FLUSH);

    HAL_RESTORE_INTERRUPTS(oldints);

    diag_printf("\nProgram completed with status %d\n", go_return_status);
}