📄 go.c
字号:
/************************************************************************ * shell_shift_to_user ************************************************************************//************************************************************************ * * shell_shift_to_user * Description : * ------------- * * Shift/return to user context * * Return values : * --------------- * * TRUE -> application ended. * ************************************************************************/boolshell_shift_to_user( bool from_gdb, /* TRUE -> invoked from GDB */ bool first ) /* TRUE -> Start application (only FALSE for GDB reentry) */{ UINT32 old_ie; /* also used as switch in appl_exception() */ shift_gdb_retval = from_gdb; /* Stop DMA */ sys_dma_enable( FALSE ); if( first ) { /* Register default exc handler */ EXCEP_register_esr( EXCEP_DEFAULT_HANDLER, FALSE, appl_exception, NULL, NULL ); if( from_gdb ) { /* GDB stub needs to own BREAK exception */ EXCEP_register_esr( EX_BP, FALSE, appl_exception, NULL, NULL ); } } else { /* GDB only (otherwise 'first' is always TRUE). * Restore ESR settings as they were at last breakpoint. */ EXCEP_set_handlers( EXCEP_HANDLERS_GDB ); } /* Save our (yamon) shell context as if an exception had occurred */ old_ie = sys_disable_int(); if ( EXCEP_save_context(&shell_context) == 0 ) { /* first return - after context save */ /* Shift to application */ EXCEP_exc_handler_ret( &appl_context ); /* dead end */ } else { /* second return - after application has ended (or GDB break happens) */ if( from_gdb) { /* GDB breakpoint : Store current ESR settings */ EXCEP_store_handlers( EXCEP_HANDLERS_GDB ); } /* Restore shell setup (incl. ESR settings) */ shell_restore(); if (old_ie) sys_enable_int(); } return shift_gdb_retval;}/************************************************************************ * appl_shell_func ************************************************************************/UINT32appl_shell_func( UINT32 arg0, UINT32 arg1, UINT32 arg2, UINT32 arg3 ){ bool exit2yamon; char *s; UINT32 i, rc; UINT64 epc; /* Called from appl_if.S */ exit2yamon = FALSE; /* Default */ switch( appl_shell_func_code ) { case SHELL_FUNC_EXIT_CODE : /* Normal return / exit() function */ printf("User application returned with code = 0x%08x\n", (UINT32)SYS_CPUREG(&appl_context, SYS_CPUREG_A0) ); exit2yamon = TRUE; break; case SHELL_FUNC_PRINT_COUNT_CODE : /* a0 = Output port (ignored). * a1 = String pointer. * a2 = Number of characters. */ s = (char *)arg1; for( i = arg2; i; i-- ) { sys_putchar( DEFAULT_PORT, *s ); s++; } rc = OK; break; case SHELL_FUNC_PRINT_CODE : /* a0 = Output port (ignored). * a1 = Null terminated string. */ sys_puts( DEFAULT_PORT, (char *)arg1 ); rc = OK; break; case SHELL_FUNC_GETCHAR_CODE : /* a0 = Input port (ignored). * a1 = Pointer to char. */ rc = sys_getchar( DEFAULT_PORT, (char *)arg1 ); break; case SHELL_FUNC_SYSCON_READ_CODE : /* a0 = SYSCON id. * a1 = Pointer to param. * a2 = size of param. */ rc = SYSCON_read( (t_syscon_ids) arg0, (void *) arg1, arg2 ); break; case SHELL_FUNC_FLUSH_CODE : /* a0 = * YAMON_FLUSH_ICACHE : Flush ICACHE * YAMON_FLUSH_DCACHE : Flush DCACHE */ if( arg0 == YAMON_FLUSH_ICACHE ) sys_icache_invalidate_all(); else sys_dcache_flush_all(); rc = OK; break; case SHELL_FUNC_REGISTER_CPU_ISR_CODE : /* a0 = CPU interrupt number * a1 = Pointer to ISR * a2 = Pointer to data * a3 = Pointer to ref */ EXCEP_register_cpu_isr( arg0, (t_EXCEP_isr)arg1, (void *)arg2, (t_EXCEP_ref *)arg3 ); /* return value is set to the contents of the STATUS register */ SYSCON_read( SYSCON_CPU_CP0_STATUS_ID, (void *)&rc, sizeof(UINT32) ); break; case SHELL_FUNC_DEREGISTER_CPU_ISR_CODE : /* a0 = ref */ EXCEP_deregister_cpu_isr( (t_EXCEP_ref)arg0 ); /* return value is set to the contents of the STATUS register */ SYSCON_read( SYSCON_CPU_CP0_STATUS_ID, (void *)&rc, sizeof(UINT32) ); break; case SHELL_FUNC_REGISTER_IC_ISR_CODE : /* a0 = IC line number * a1 = Pointer to ISR * a2 = Pointer to data * a3 = Pointer to ref */ rc = EXCEP_register_ic_isr( arg0, (t_EXCEP_isr)arg1, (void *)arg2, (t_EXCEP_ref *)arg3 ); break; case SHELL_FUNC_DEREGISTER_IC_ISR_CODE : /* a0 = ref */ rc = EXCEP_deregister_ic_isr( (t_EXCEP_ref)arg0 ); break; case SHELL_FUNC_REGISTER_ESR_CODE : /* a0 = Exception code * a1 = Pointer to ESR * a2 = Pointer to ref * a3 = Pointer to retfunc */ rc = EXCEP_register_esr( arg0, TRUE, (t_EXCEP_esr)arg1, (t_EXCEP_ref *)arg2, (t_EXCEP_retfunc *)arg3 ); break; case SHELL_FUNC_DEREGISTER_ESR_CODE : /* a0 = ref */ rc = EXCEP_deregister_esr( (t_EXCEP_ref)arg0 ); break; default : /* Should not happen */ printf( "appl_shell_func: unknown argument = 0x%08x\n",appl_shell_func_code); exit2yamon = TRUE; break; } if( exit2yamon ) { /* return to (yamon) shell */ EXCEP_exc_handler_ret_ss( &shell_context ); } else { /* return to application. */ SYS_CPUREG(&appl_context, SYS_CPUREG_V0) = rc; }}/************************************************************************ * * shell_setup_default_cpu * Description : * ------------- * * Setup CPU (incl. CP0) registers in context structure so that they * contain values suiting an application. * * Return values : * --------------- * * void * ************************************************************************/voidshell_setup_default_cpu( t_gdb_regs *regs, UINT32 epc ){ /* Clear data */ memset( regs, 0, sizeof(t_gdb_regs) ); /* ra (make sure jr ra is handled the same way as exit()) */ SYS_CPUREG(regs, SYS_CPUREG_RA) = (UINT64)shell_return; /* sp (4 words below top according to C-calling convention) */ SYS_CPUREG(regs, SYS_CPUREG_SP) = (UINT64)(sys_freemem - 4 * sizeof(UINT32)); /* fp (set equal to sp) */ SYS_CPUREG(regs, SYS_CPUREG_FP) = SYS_CPUREG(regs, SYS_CPUREG_SP); /* frame_ptr field (Dummy GDB reg, should not be used) */ regs->frame_ptr = 0; /* a0 */ SYS_CPUREG(regs, SYS_CPUREG_A0) = (UINT64)shell_argc_appl; /* a1 */ SYS_CPUREG(regs, SYS_CPUREG_A1) = (INT64)((INT32)shell_argv_appl); /* a2 points to environment variables */ SYS_CPUREG(regs, SYS_CPUREG_A2) = (INT64)((INT32)env_get_all()); /* a3 is set to the memory size */ SYS_CPUREG(regs, SYS_CPUREG_A3) = (UINT64)sys_ramsize; /* Retrieve current setting of CP0/CP1 control registers */ sys_store_control_regs( regs ); /* CP0 status : * Clear ERL and set EXL so that EPC will be used upon eret. * Disable interrupts. */ regs->cp0_status &= ~(M_StatusERL | M_StatusIE); regs->cp0_status |= M_StatusEXL; /* EPC (sign extended) */ regs->cp0_epc = (INT64)((INT32)epc);}/************************************************************************ * * shell_go_init * Description : * ------------- * * Initialise command * * Return values : * --------------- * * void * ************************************************************************/t_cmd *shell_go_init( void ){ UINT32 code; for (code = 0; code < SHELL_FUNC_COUNT; code++) { /* set up vectorized calls to appl_shell_func() */ shell_api_vector_setup(SHELL_VECTOR_ADDR | (code<<3), code); } return &cmd_def;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -