/* * $QNXLicenseC: * Copyright 2007, QNX Software Systems. All Rights Reserved. * * You must obtain a written license from and pay applicable license fees to QNX * Software Systems before you may reproduce, modify or distribute this software, * or any work that includes all or part of this software. Free development * licenses are available for evaluation and non-commercial purposes. For more * information visit http://licensing.qnx.com or email licensing@qnx.com. * * This file may contain contributions from others. Please review this entire * file for other proprietary rights or license notices, as well as the QNX * Development Suite License Guide at http://licensing.qnx.com/license-guide/ * for other information. * $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "yarrow.h" extern yarrow_t *Yarrow; static void *timer_thread( void *p ) { int pool_id; int ret; uint64_t clk; uint64_t rdata; int timeout; ret = yarrow_add_source( Yarrow, &pool_id ); if( ret != 0 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: Unable to get pool_id for timer thread." ); return NULL; } timeout = 100; rdata = 0; while( 1 ) { if( Yarrow ) { yarrow_output( Yarrow, (uint8_t *)&rdata, sizeof( rdata ) ); /* Wait for between 10ms and 1033ms */ timeout = ( rdata & 0x3FF ) + 10; } delay( timeout ); clk = ClockCycles(); clk = clk ^ rdata; if( Yarrow ) yarrow_input( Yarrow, (uint8_t *)&clk, sizeof( clk ), pool_id, 8 ); } return NULL; } static void *syspoll_thread( void *p ) { int pool_id; int ret; uint64_t clk; uint64_t rdata; int timeout; DIR *dir; struct dirent* dir_entry; sha1_ctx_t context; uint8_t digest[20]; char as_path[256]; int fd; int i; debug_thread_t debug_tid; debug_process_t debug_pid; ret = yarrow_add_source( Yarrow, &pool_id ); if( ret != 0 ) { slogf( _SLOGC_CHAR, _SLOG_CRITICAL, "random: Unable to get pool_id for syspoll thread." ); return NULL; } /* Setup a default 1 minute timeout */ timeout = 1000 * 60; while( 1 ) { if( Yarrow ) { yarrow_output( Yarrow, (uint8_t *)&rdata, sizeof( rdata ) ); /* Wait from ~16s to ~17.5 minutes */ timeout = ( ( rdata & 0x3F ) + 1 ) << 14; } delay( timeout ); SHA1Init( &context ); dir = opendir( "/proc" ); if( dir == NULL ) continue; dir_entry = readdir( dir ); while( dir_entry != NULL ) { SHA1Update( &context, (uint8_t *)dir_entry, sizeof( struct dirent ) + dir_entry->d_namelen - 1 ); if( dir_entry->d_name[0] < '0' || dir_entry->d_name[1] > '9' ) { dir_entry = readdir( dir ); continue; } sprintf( as_path, "/proc/%s/as", dir_entry->d_name ); fd = open( as_path, O_RDONLY ); while( fd != -1 ) { memset( &debug_pid, 0, sizeof( debug_pid ) ); ret = devctl( fd, DCMD_PROC_INFO, &debug_pid, sizeof( debug_pid ), NULL ); if( ret == -1 ) break; SHA1Update( &context, (uint8_t *)&debug_pid, sizeof( debug_pid ) ); for( i=0; i= target ) { ClockTime( CLOCK_REALTIME, NULL, &clk ); clk = clk ^ rdata; if( Yarrow ) { yarrow_input( Yarrow, (uint8_t *)&clk, sizeof( clk ), pool_id, 8 ); yarrow_output( Yarrow, (uint8_t *)&rdata, sizeof( rdata ) ); } target = rdata & 0x1FF; count = 0; } break; default: if( rcvid ) MsgError( rcvid, ENOTSUP ); } } return NULL; } int start_syspoll_source( void ) { pthread_attr_t pattr; struct sched_param param; pthread_attr_init( &pattr ); param.sched_priority = 11; pthread_attr_setschedparam( &pattr, ¶m ); pthread_attr_setinheritsched( &pattr, PTHREAD_EXPLICIT_SCHED ); pthread_attr_setstacksize( &pattr, 16*1024 ); return pthread_create( NULL, NULL, syspoll_thread, NULL ); } int start_interrupt_source( int intr ) { pthread_attr_t pattr; struct sched_param param; pthread_attr_init( &pattr ); param.sched_priority = 15; pthread_attr_setschedparam( &pattr, ¶m ); pthread_attr_setinheritsched( &pattr, PTHREAD_EXPLICIT_SCHED ); return pthread_create( NULL, NULL, interrupt_thread, (void *)intr ); } int start_timer_source( void ) { pthread_attr_t pattr; struct sched_param param; pthread_attr_init( &pattr ); param.sched_priority = 10; pthread_attr_setschedparam( &pattr, ¶m ); pthread_attr_setinheritsched( &pattr, PTHREAD_EXPLICIT_SCHED ); return pthread_create( NULL, &pattr, timer_thread, NULL ); }