void test_errors(void) { rtems_status_code sc; void *value; /* * task variable add error status codes */ puts( "task variable add - NULL pointer - RTEMS_INVALID_ADDRESS" ); sc = rtems_task_variable_add(RTEMS_SELF, NULL, NULL ); fatal_directive_status( sc, RTEMS_INVALID_ADDRESS, "add NULL pointer" ); /* * task variable get error status codes */ puts( "task variable get - bad Id - RTEMS_INVALID_ID" ); sc = rtems_task_variable_get( rtems_task_self() + 10, (void **)&taskvar1, &value ); fatal_directive_status( sc, RTEMS_INVALID_ID, "bad Id" ); puts( "task variable get - NULL pointer - RTEMS_INVALID_ADDRESS" ); sc = rtems_task_variable_get(RTEMS_SELF, NULL, &value ); fatal_directive_status( sc, RTEMS_INVALID_ADDRESS, "get NULL pointer" ); puts( "task variable get - bad result - RTEMS_INVALID_ADDRESS" ); sc = rtems_task_variable_get(RTEMS_SELF, (void **)&taskvar1, NULL); fatal_directive_status( sc, RTEMS_INVALID_ADDRESS, "get bad result" ); puts( "task variable get - bad pointer - RTEMS_INVALID_ADDRESS" ); sc = rtems_task_variable_get(RTEMS_SELF, (void **)&taskvar1, &value); fatal_directive_status( sc, RTEMS_INVALID_ADDRESS, "get bad pointer" ); /* * task variable delete error status codes */ puts( "task variable delete - bad Id - RTEMS_INVALID_ID" ); sc = rtems_task_variable_delete( rtems_task_self() + 10, (void **)&taskvar1 ); fatal_directive_status( sc, RTEMS_INVALID_ID, "bad Id" ); puts( "task variable delete - NULL pointer - RTEMS_INVALID_ADDRESS" ); sc = rtems_task_variable_delete(RTEMS_SELF, NULL); fatal_directive_status( sc, RTEMS_INVALID_ADDRESS, "delete NULL pointer" ); puts( "task variable delete - bad pointer - RTEMS_INVALID_ADDRESS" ); sc = rtems_task_variable_delete(RTEMS_SELF, (void **)&taskvar1); fatal_directive_status( sc, RTEMS_INVALID_ADDRESS, "delete bad pointer" ); }
void *rtems_gxx_getspecific(__gthread_key_t key) { rtems_status_code status; void *p= 0; /* register with RTEMS the buffer that will hold the key values */ status = rtems_task_variable_get( RTEMS_SELF, (void **)key, &p ); if ( status == RTEMS_SUCCESSFUL ) { /* We do not have to do this, but what the heck ! */ p= key->val; } else { /* fisrt time, always set to zero, it is unknown the value that the others * threads are using at the moment of this call */ status = rtems_task_variable_add( RTEMS_SELF, (void **)key, key->dtor ); if ( status != RTEMS_SUCCESSFUL ) { _Internal_error_Occurred( INTERNAL_ERROR_CORE, true, INTERNAL_ERROR_GXX_KEY_ADD_FAILED ); } key->val = (void *)0; } #ifdef DEBUG_GXX_WRAPPERS printk( "gxx_wrappers: getspecific key=%x, ptr=%x, id=%x\n", key, p, rtems_task_self() ); #endif return p; }
rtems_status_code rtems_libio_share_private_env(rtems_id task_id) { rtems_status_code sc; rtems_user_env_t * shared_user_env; rtems_id current_task_id; /* * get current task id */ current_task_id = rtems_task_self(); /* * If this was an attempt to share the task with self, * if somebody wanted to do it... Lets tell them, its shared */ if( task_id == current_task_id ) return RTEMS_SUCCESSFUL; /* * Try to get the requested user environment */ sc = rtems_task_variable_get( task_id, (void*)&rtems_current_user_env, (void*)&shared_user_env ); /* * If it was not successful, return the error code */ if (sc != RTEMS_SUCCESSFUL) return sc; /* * If we are here, we have the required environment to be * shared with the current task */ /* * If we have a current environment in place, we need to * free it, since we will be sharing the variable with the * shared_user_env */ if (rtems_current_user_env->task_id==current_task_id) { rtems_user_env_t *tmp = rtems_current_user_env; free_user_env( tmp ); } /* the current_user_env is the same pointer that remote env */ rtems_current_user_env = shared_user_env; /* increase the reference count */ #ifdef HAVE_USERENV_REFCNT rtems_current_user_env->refcnt++; #endif return RTEMS_SUCCESSFUL; }
BSP_ExceptionExtension BSP_exceptionHandlerInstall(BSP_ExceptionExtension e) { volatile BSP_ExceptionExtension test; if ( RTEMS_SUCCESSFUL != rtems_task_variable_get(RTEMS_SELF, (void*)&BSP_exceptionExtension, (void**)&test) ) { /* not yet added */ rtems_task_variable_add(RTEMS_SELF, (void*)&BSP_exceptionExtension, 0); } test = BSP_exceptionExtension; BSP_exceptionExtension = e; return test; }
rtems_status_code rtems_libio_share_private_env(rtems_id task_id) { rtems_status_code sc; rtems_user_env_t * shared_user_env; rtems_id current_task_id; sc=rtems_task_ident(RTEMS_SELF,0,¤t_task_id); if (sc != RTEMS_SUCCESSFUL) return sc; if (rtems_current_user_env->task_id==current_task_id) { /* kill the current user env & task_var*/ rtems_user_env_t *tmp = rtems_current_user_env; sc = rtems_task_variable_delete(RTEMS_SELF,(void*)&rtems_current_user_env); if (sc != RTEMS_SUCCESSFUL) return sc; free_user_env(tmp); }; /* AT THIS POINT, rtems_current_user_env is DANGLING */ sc = rtems_task_variable_get(task_id,(void*)&rtems_current_user_env, (void*)&shared_user_env ); if (sc != RTEMS_SUCCESSFUL) goto bailout; sc = rtems_task_variable_add(RTEMS_SELF,(void*)&rtems_current_user_env,free_user_env); if (sc != RTEMS_SUCCESSFUL) goto bailout; /* the current_user_env is the same pointer that remote env */ rtems_current_user_env = shared_user_env; /* increase the reference count */ #ifdef HAVE_USERENV_REFCNT rtems_current_user_env->refcnt++; #endif return RTEMS_SUCCESSFUL; bailout: /* fallback to the global env */ rtems_current_user_env = &rtems_global_user_env; return sc; }
void BSP_exceptionHandler(BSP_Exception_frame* excPtr) { uint32_t note; BSP_ExceptionExtension ext=0; rtems_id id=0; int recoverable = 0; char *fmt="Uhuuuh, Exception %d in unknown task???\n"; int quiet=0; if (!quiet) printk("In BSP_exceptionHandler()\n"); /* If we are in interrupt context, we are in trouble - skip the user * hook and panic */ if (rtems_interrupt_is_in_progress()) { fmt="Aieeh, Exception %d in interrupt handler\n"; } else if ( !_Thread_Executing) { fmt="Aieeh, Exception %d in initialization code\n"; } else { /* retrieve the notepad which possibly holds an extention pointer */ if (RTEMS_SUCCESSFUL==rtems_task_ident(RTEMS_SELF,RTEMS_LOCAL,&id) && #if 0 /* Must not use a notepad due to unknown initial value (notepad memory is allocated from the * workspace)! */ RTEMS_SUCCESSFUL==rtems_task_get_note(id, BSP_EXCEPTION_NOTEPAD, ¬e) #else RTEMS_SUCCESSFUL==rtems_task_variable_get(id, (void*)&BSP_exceptionExtension, (void**)¬e) #endif ) { ext = (BSP_ExceptionExtension)note; if (ext) quiet=ext->quiet; if (!quiet) { printk("Task (Id 0x%08x) got ",id); } fmt="exception %d\n"; } } if (ext && ext->lowlevelHook && ext->lowlevelHook(excPtr,ext,0)) { /* they did all the work and want us to do nothing! */ printk("they did all the work and want us to do nothing!\n"); return; } if (!quiet) { /* message about exception */ printk(fmt, excPtr->_EXC_number); /* register dump */ printk("\t Next PC or Address of fault = %x, ", excPtr->EXC_SRR0); printk("Mvme5500 Saved MSR = %x\n", excPtr->EXC_SRR1); printk("\t R0 = %08x", excPtr->GPR0); printk(" R1 = %08x", excPtr->GPR1); printk(" R2 = %08x", excPtr->GPR2); printk(" R3 = %08x\n", excPtr->GPR3); printk("\t R4 = %08x", excPtr->GPR4); printk(" R5 = %08x", excPtr->GPR5); printk(" R6 = %08x", excPtr->GPR6); printk(" R7 = %08x\n", excPtr->GPR7); printk("\t R8 = %08x", excPtr->GPR8); printk(" R9 = %08x", excPtr->GPR9); printk(" R10 = %08x", excPtr->GPR10); printk(" R11 = %08x\n", excPtr->GPR11); printk("\t R12 = %08x", excPtr->GPR12); printk(" R13 = %08x", excPtr->GPR13); printk(" R14 = %08x", excPtr->GPR14); printk(" R15 = %08x\n", excPtr->GPR15); printk("\t R16 = %08x", excPtr->GPR16); printk(" R17 = %08x", excPtr->GPR17); printk(" R18 = %08x", excPtr->GPR18); printk(" R19 = %08x\n", excPtr->GPR19); printk("\t R20 = %08x", excPtr->GPR20); printk(" R21 = %08x", excPtr->GPR21); printk(" R22 = %08x", excPtr->GPR22); printk(" R23 = %08x\n", excPtr->GPR23); printk("\t R24 = %08x", excPtr->GPR24); printk(" R25 = %08x", excPtr->GPR25); printk(" R26 = %08x", excPtr->GPR26); printk(" R27 = %08x\n", excPtr->GPR27); printk("\t R28 = %08x", excPtr->GPR28); printk(" R29 = %08x", excPtr->GPR29); printk(" R30 = %08x", excPtr->GPR30); printk(" R31 = %08x\n", excPtr->GPR31); printk("\t CR = %08x\n", excPtr->EXC_CR); printk("\t CTR = %08x\n", excPtr->EXC_CTR); printk("\t XER = %08x\n", excPtr->EXC_XER); printk("\t LR = %08x\n", excPtr->EXC_LR); BSP_printStackTrace(excPtr); } if (ASM_MACH_VECTOR == excPtr->_EXC_number) { /* ollah , we got a machine check - this could either * be a TEA, MCP or internal; let's see and provide more info */ if (!quiet) printk("Machine check; reason:"); if ( ! (excPtr->EXC_SRR1 & (SRR1_TEA_EXC | SRR1_MCP_EXC)) ) { if (!quiet) printk("SRR1\n"); } else { if (excPtr->EXC_SRR1 & (SRR1_TEA_EXC)) { if (!quiet) printk(" TEA"); } if (excPtr->EXC_SRR1 & (SRR1_MCP_EXC)) { unsigned long gerr; if (!quiet) printk(" MCP\n"); /* it's MCP; gather info from the host bridge */ gerr=_BSP_clear_hostbridge_errors(0,0); if (gerr&0x80000000) printk("GT64260 Parity error\n"); if (gerr&0x40000000) printk("GT64260 SysErr\n"); if ((!quiet) && (!gerr)) printk("GT64260 host bridge seems OK\n"); } } } else if (ASM_DEC_VECTOR == excPtr->_EXC_number) { recoverable = 1; } else if (ASM_SYS_VECTOR == excPtr->_EXC_number) { #ifdef TEST_RAW_EXCEPTION_CODE recoverable = 1; #else recoverable = 0; #endif } /* call them for a second time giving a chance to intercept * the task_suspend */ if (ext && ext->lowlevelHook && ext->lowlevelHook(excPtr, ext, 1)) return; if (!recoverable) { if (id) { /* if there's a highlevel hook, install it */ if (ext && ext->highlevelHook) { excPtr->EXC_SRR0 = (uint32_t)ext->highlevelHook; excPtr->GPR3 = (uint32_t)ext; return; } if (excPtr->EXC_SRR1 & MSR_FP) { /* thread dispatching is _not_ disabled at this point; hence * we must make sure we have the FPU enabled... */ _write_MSR( _read_MSR() | MSR_FP ); __asm__ __volatile__("isync"); } printk("unrecoverable exception!!! task %08x suspended\n",id); rtems_task_suspend(id); } else { printk("PANIC, rebooting...\n"); bsp_reset(); } } }
void test_multiple_taskvars(void) { rtems_status_code sc; void *value; test_dtor_ran = 0; /* * Add multiple task variables and add each twice to * verify that behavior is OK */ puts( "task variable add - bad Id - RTEMS_INVALID_ID" ); sc = rtems_task_variable_add( rtems_task_self() + 10, (void **)&taskvar1, NULL ); fatal_directive_status( sc, RTEMS_INVALID_ID, "bad Id" ); puts( "Adding multiple task variables" ); sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar1, NULL); directive_failed( sc, "add multiple #1" ); sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar1, test_dtor); directive_failed( sc, "add multiple #2" ); sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar2, test_dtor); directive_failed( sc, "add multiple #3" ); sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar2, NULL); directive_failed( sc, "add multiple #4" ); sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar3, NULL); directive_failed( sc, "add multiple #5" ); sc = rtems_task_variable_add(RTEMS_SELF, (void **)&taskvar3, test_dtor); directive_failed( sc, "add multiple #6" ); /* * Obtain task variables in various spots on the chain */ puts( "Obtaining multiple task variables" ); sc = rtems_task_variable_get( RTEMS_SELF, (void **)&taskvar3, &value ); directive_failed( sc, "get multiple #1" ); sc = rtems_task_variable_get( RTEMS_SELF, (void **)&taskvar2, &value ); directive_failed( sc, "get multiple #2" ); sc = rtems_task_variable_get( RTEMS_SELF, (void **)&taskvar1, &value ); directive_failed( sc, "get multiple #2" ); /* * Delete task variables in various spots on the chain */ /* to trip the destructors */ taskvar1 = (void *)1; taskvar2 = (void *)2; taskvar3 = (void *)3; puts( "Deleting multiple task variables" ); sc = rtems_task_variable_delete(RTEMS_SELF, (void **)&taskvar2); directive_failed( sc, "delete multiple #1" ); sc = rtems_task_variable_delete(RTEMS_SELF, (void **)&taskvar3); directive_failed( sc, "delete multiple #2" ); sc = rtems_task_variable_delete(RTEMS_SELF, (void **)&taskvar1); directive_failed( sc, "delete multiple #3" ); if ( test_dtor_ran != 2 ) { printf( "Test dtor ran %" PRIu32 " times not 2 times as expected\n", test_dtor_ran ); rtems_test_exit(0); } }