/**************************************************************************** REMARKS: Call the assembler Zen Timer functions to do the timing. ****************************************************************************/ static ulong __LZTimerLap( LZTimerObject *tm) { CPU_largeInteger lap,count; VTD_Get_Real_Time(&lap.high,&lap.low); _CPU_diffTime64(&tm->start,&lap,&count); return _CPU_calcMicroSec(&count,frequency); }
/**************************************************************************** REMARKS: This function reads the high resolution timer. ****************************************************************************/ void NAPI GA_TimerRead( GA_largeInteger *value) { if (haveRDTSC) _GA_readTimeStamp(value); else VTD_Get_Real_Time(&value->high,&value->low); }
//---------------------------------------------------------------------- // // LogRecord // // Add a new string to Log, if it fits. // //---------------------------------------------------------------------- VOID LogRecord( const char * format, ... ) { PENTRY Entry; ULONG len; va_list arg_ptr; static CHAR text[MAXPATHLEN]; DWORD timehi; DWORD time, date; // // If no filtering is desired, don't bother // if( !FilterOn ) { return; } // // Lock the output buffer. // Wait_Semaphore( LogMutex, BLOCK_SVC_INTS ); // // Vsprintf to determine length of the buffer // _asm cld; va_start( arg_ptr, format ); len = vsprintf( text, format, arg_ptr ); va_end( arg_ptr ); // // Only log it if it passes the filtes // if( ApplyFilters( text )) { // // If the current output buffer is near capacity, move to a new // output buffer // if( (ULONG) (Log->Len + len + sizeof(ENTRY) +1) >= LOGBUFSIZE ) { RegmonNewLog(); } // // Extract the sequence number and Log it // dprintf("%s\n", text ); Entry = (void *)(Log->Data+Log->Len); _asm cld; memcpy( Entry->text, text, len+1 ); Entry->time.u.HighPart = IFSMgr_Get_DOSTime( &Entry->time.u.LowPart ); // // We calculate milliseconds to get around a bug in // IFSMgr_Get_DOSTime // time = VTD_Get_Date_And_Time( &date ); Entry->time.u.LowPart = time - ((Entry->time.u.HighPart >> 11)& 0x1F)*60*60*1000 - ((Entry->time.u.HighPart >> 5) & 0x3F)*60*1000 - ((Entry->time.u.HighPart & 0x1F)*2000); VTD_Get_Real_Time( &Entry->perftime.u.HighPart, &Entry->perftime.u.LowPart ); Entry->seq = Sequence++; Entry->perftime.u.HighPart -= StartTime.u.HighPart; Entry->perftime.u.LowPart -= StartTime.u.LowPart; // // Log the length of the string, plus 1 for the terminating // NULL // Log->Len += (Entry->text - (PCHAR) Entry) + len + 1; } // // Release the output buffer lock // Signal_Semaphore( LogMutex ); }
//---------------------------------------------------------------------- // // OnW32Deviceiocontrol // // Interface with the GUI. // //---------------------------------------------------------------------- DWORD OnW32Deviceiocontrol( PIOCTLPARAMS p ) { PLOG_BUF old; static BOOLEAN connected = FALSE; switch( p->dioc_IOCtlCode ) { case 0: return 0; case IOCTL_REGMON_ZEROSTATS: Wait_Semaphore( LogMutex, BLOCK_SVC_INTS ); while ( Log->Next ) { // // Release the next entry. // old = Log->Next; Log->Next = old->Next; Signal_Semaphore( LogMutex ); PageFree( old->Handle, 0 ); Wait_Semaphore( LogMutex, BLOCK_SVC_INTS ); NumLog--; } Log->Len = 0; Sequence = 0; VTD_Get_Real_Time( &StartTime.u.HighPart, &StartTime.u.LowPart ); Signal_Semaphore( LogMutex ); return 0; case IOCTL_REGMON_GETSTATS: // // Copy buffer into user space. Wait_Semaphore( LogMutex, BLOCK_SVC_INTS ); if ( LOGBUFSIZE > p->dioc_cbOutBuf ) { // // Buffer is too small. Return error. // Signal_Semaphore( LogMutex ); return 1; } else if ( Log->Len || Log->Next ) { // // Switch to a new buffer. // RegmonNewLog(); // // Fetch the oldest buffer to give to caller. // old = RegmonOldestLog(); Signal_Semaphore( LogMutex ); // // Copy it into the caller's buffer. // memcpy( p->dioc_OutBuf, old->Data, old->Len ); // // Return length of copied info. // *p->dioc_bytesret = old->Len; // // Deallocate the buffer. // PageFree( old->Handle, 0 ); NumLog--; } else { // // There is no unread data. // Signal_Semaphore( LogMutex ); *p->dioc_bytesret = 0; } return 0; case IOCTL_REGMON_UNHOOK: FilterOn = FALSE; return 0; case IOCTL_REGMON_HOOK: FilterOn = TRUE; return 0; case IOCTL_REGMON_SETFILTER: FilterDef = * (PFILTER) p->dioc_InBuf; RegmonUpdateFilters(); return 0; } return 0; }
/**************************************************************************** REMARKS: Read the Long Period timer value from the BIOS timer tick. ****************************************************************************/ static ulong __ULZReadTime(void) { CPU_largeInteger count; VTD_Get_Real_Time(&count.high,&count.low); return (count.low * 1000.0 / frequency); }