// ============================================================================= // spal_GdbBreakPrint // ----------------------------------------------------------------------------- // ============================================================================= VOID spal_GdbBreakPrint(VOID) { UINT32 nLen; UINT8 * str; VOLATILE UINT32 * spal_GdbRegs; VOLATILE UINT32 * v_regs; spal_GdbRegs = bcpu_sp_context; v_regs=(UINT32*)KSEG1((UINT32)spal_GdbRegs); str = (UINT8*)(spal_GdbRegs[4]); // a0 before break nLen = spal_GdbStrLen(str); // prepare command v_regs[SPAL_GDB_CMD_OFF]=SPAL_GDB_CMD_PRINT; v_regs[SPAL_GDB_CMDPARAM_OFF]=nLen; // trigger command spal_DbgGdbHstSendEvent(SPAL_GDB_BCPU_EVENT); // wait for the debug server to complete while(v_regs[SPAL_GDB_CMD_OFF]!=SPAL_GDB_CMD_DONE); spal_GdbRegs[37]+=INC_STEP; // restart the watchdog return; }
// ============================================================================= // spal_GdbException // ----------------------------------------------------------------------------- // ============================================================================= VOID spal_GdbException(UINT32 cause) { VOLATILE UINT32 * spal_GdbRegs; VOLATILE UINT32 * v_regs; UINT32 signal; spal_GdbRegs = spal_GdbPrepare(SPAL_DBG_ERROR_IT, cause, TRUE); v_regs=(UINT32*)KSEG1((UINT32)spal_GdbRegs); #if (ASICSIMU == 1) asicsimu_Fatal("BCPU EXCEPTION"); #endif // send command switch(cause){ case ExcCode_IBE: case ExcCode_DBE: signal = SPAL_GDB_SIGBUS; break; case ExcCode_RI: signal = SPAL_GDB_SIGILL; break; default: signal = SPAL_GDB_SIGSEGV; break; } spal_GdbSendcmd(spal_GdbRegs, signal, TRUE); spal_GdbLoop(v_regs, TRUE); }
// ============================================================================= // spal_GdbBreakRaise // ----------------------------------------------------------------------------- /// same as breakpoint but skip the break instruction as it is placed in code not by gdb /// used by stack for raises // ============================================================================= VOID spal_GdbBreakRaise(VOID) { VOLATILE UINT32 * spal_GdbRegs; VOLATILE UINT32 * v_regs; spal_GdbRegs = spal_GdbPrepare(SPAL_DBG_ERROR_RAISE, 0, TRUE); v_regs=(UINT32*)KSEG1((UINT32)spal_GdbRegs); v_regs[37]+=INC_STEP; // send command spal_GdbSendcmd(spal_GdbRegs, SPAL_GDB_SIGKILL, TRUE); spal_GdbLoop(v_regs, TRUE); }
// ============================================================================= // spal_GdbBreakSoftBreakPoint // ----------------------------------------------------------------------------- /// same as breakpoint but skip the break instruction as it is placed in code not by gdb // ============================================================================= VOID spal_GdbBreakSoftBreakPoint(VOID) { VOLATILE UINT32 * spal_GdbRegs; VOLATILE UINT32 * v_regs; spal_GdbRegs = spal_GdbPrepare(SPAL_DBG_ERROR_GDB, 0, FALSE); v_regs=(UINT32*)KSEG1((UINT32)spal_GdbRegs); v_regs[37]+=INC_STEP; // send command spal_GdbSendcmd(spal_GdbRegs, SPAL_GDB_SIGTRAP, FALSE); spal_GdbLoop(v_regs, FALSE); }
// ============================================================================= // spal_GdbIrqDebug // ----------------------------------------------------------------------------- // ============================================================================= VOID spal_GdbIrqDebug(UINT32 cause) { VOLATILE UINT32 * spal_GdbRegs; VOLATILE UINT32 * v_regs; UINT32 error_code = SPAL_DBG_ERROR_GDB; BOOL fatal = FALSE; hwp_bbIrq->NonMaskable = 0; spal_GdbRegs = spal_GdbPrepare(error_code, 0, fatal); v_regs=(UINT32*)KSEG1((UINT32)spal_GdbRegs); if(!fatal) { // don't actually send command if the BCPU triggered the IT spal_GdbSendcmd(spal_GdbRegs, SPAL_GDB_SIGINT, FALSE); } spal_GdbLoop(v_regs, fatal); }
// ============================================================================= // spal_GdbBreakDivBy0 // ----------------------------------------------------------------------------- // ============================================================================= VOID spal_GdbBreakDivBy0(VOID) { VOLATILE UINT32 * spal_GdbRegs; VOLATILE UINT32 * v_regs; spal_GdbRegs = spal_GdbPrepare(SPAL_DBG_ERROR_DIV0, 0, TRUE); spal_DbgGdbHstSendEvent(SPAL_GDB_BCPU_EVENT+0xd0); spal_GdbRegs[37]+=INC_STEP; #if (ASICSIMU == 1) asicsimu_Fatal("BCPU Division by 0 exception\n"); #endif // trigger GDB on /0 for both CPUs v_regs=(UINT32*)KSEG1((UINT32)spal_GdbRegs); // send command spal_GdbSendcmd(spal_GdbRegs, SPAL_GDB_SIGFPE, TRUE); spal_GdbLoop(v_regs, TRUE); }
static int __sys_setpermenv( const char *env_nm, const char *env_val ) { PERM_ENV_VAR *new_var; unsigned int pVar; unsigned int i, len; /* Check for pre-existance of the variable */ if( __sys_ispermenv(env_nm) ) { sys_printf("Env: Variable %s already defined\n", env_nm ); return SBL_ERESCRUNCH; } /* Calculate length of new variable (including NULLs) */ len = strlen( env_nm ) + strlen( env_val ) + 2; /* Check if there is enough space */ if( perm_cur_index + len > MAX_PERM_VAR_SIZE ) { sys_printf("Env: No space for another permanent variable: %s\n", env_nm ); return SBL_ERESCRUNCH; } /* Allocate memory for new node in the linked list */ new_var = _malloc( sizeof( PERM_ENV_VAR ) ); if ( !new_var ) { sys_printf("Env: No space for another permanent variable: %s\n", env_nm ); return SBL_ERESCRUNCH; } #if ENV_DEBUG sys_printf("New PERMANENT Environment to be written at index %d\n", nextslot ); #endif enter_critical_section(); /* Prepare a new permanent variable cell */ /* Initialize flash address */ pVar = ( unsigned int )KSEG1( perm_env_ptr + perm_cur_index ); /* Open flash for writing */ if( !FWBOpen( pVar ) ) { #if ENV_DEBUG sys_printf("Cannot open flash!\n" ); #endif _free( (void *)new_var ); return SBL_EFAILURE; } /* initialize name field */ new_var->name = ( const char *) pVar; /* Write the permanent variable name to the flash (including NULL) */ for(i = 0; i <= strlen( env_nm ); i++, perm_cur_index++, pVar++ ) { if( !FWBWriteByte( pVar, env_nm[ i ]) ) { #if ENV_DEBUG sys_printf("Cannot write byte %d of variable %s!\n", i, env_nm ); #endif FWBClose(); _free( (void *)new_var ); return SBL_EFAILURE; } } /* initialize value field */ new_var->value = ( const char *) KSEG1( perm_env_ptr + perm_cur_index ); /* Write the permanent variable value to the flash (including NULL) */ for(i = 0; i <= strlen( env_val ); i++, perm_cur_index++, pVar++ ) { if( !FWBWriteByte( pVar, env_val[ i ]) ) { #if ENV_DEBUG sys_printf("Cannot write byte %d of variable %s!\n", i + strlen( env_nm ), env_nm ); #endif FWBClose(); _free( (void *)new_var ); return SBL_EFAILURE; } } /* Close flash */ if( !FWBClose() ) { #if ENV_DEBUG sys_printf("Cannot close flash!\n" ); #endif _free( (void *)new_var ); return SBL_EFAILURE; } exit_critical_section(); /* Add the node to the linked list */ if ( !perm_env_list_head ) { new_var->next = NULL; /* This is the new head */ perm_env_list_head = new_var; } else { /* This is the next node on the list */ new_var->next = ( PERM_ENV_VAR *)perm_env_list_head; perm_env_list_head = new_var; } /* Backup the new variable */ return __sys_setenv( env_nm, env_val, TRUE ); }