package com.mindprod.pentium;
import com.mindprod.common11.ST;
/**
* Access Pentium/AMD specific features, e.g. RDTSC, CPUSERNO.
* <p/>
* Uses JNI native C++/ASM code that only works on Windows.
*
* @author Roedy Green, Canadian Mind Products
* @version 1.5 2008-09-23 document need for C++ runtime library install.
* @since 2005
*/
public final class Pentium
{
/**
* undisplayed copyright notice
*
* @noinspection UnusedDeclaration
*/
public static final String EMBEDDED_COPYRIGHT =
"Copyright: (c) 2005-2012 Roedy Green, Canadian Mind Products, http://mindprod.com";
private static final String RELEASE_DATE = "2008-09-23";
/**
* embedded version string.
*/
public static final String VERSION_STRING = "1.5";
/**
* Get the brand/model of the CPU.
*
* @return brand, e.g. "AMD Athlon(TM) XP 2000+"
*/
public static native String cpuIdBrand();
/**
* Get the instruction set family of the CPU.
*
* @return family, possibly null if not Pentium.
*/
public static native int cpuIdFamily();
/**
* Get the model of the CPU.
*
* @return model, possibly 0 if not Pentium.
*/
public static native int cpuIdModel();
/**
* Get the stepping ID of the CPU.
*
* @return stepping ID.
*/
public static native int cpuIdStep();
/**
* Get the vendor ID of the CPU.
*
* @return vendor, "GenuineIntel" for Intel chips, "AuthenticAMD" for AMD.
*/
public static native String cpuIdVendor();
/**
* Get the 64-bit cpu Serial number for Pentium
*
* @return cpu serial number, possibly 0 if not Pentium.
*/
public static native long cpuSerNo64();
/**
* Get the 96-bit cpu serial number for Xeon.
*
* @param select 0 for most significant 32 bits, 1 for middle, 2 for least significant.
*
* @return family, possibly 0 if not Xeon.
*/
public static native int cpuSerNo96( int select );
/**
* Get the time stamp counter register with the RDTSC instruction giving the count of machine cycles since last
* boot. This is very high resolution timer, with frequency matching the cpu clock crystal, not any defined time
* unit.
*
* @return RDTSC Timestamp counter.
*/
public static native long rdtsc();
/**
* display a 64 bit serial number in hex in 4 groups of 4 hex digits
*
* @param serno serial number to display
*
* @return hex string equivalent.
*/
private static String display64BitSerialNumber( long serno )
{
final int ms = ( int ) ( serno >>> 32 );
final int ls = ( int ) serno;
final String mss = ST.toLZHexString( ms, 8 );
final String lss = ST.toLZHexString( ls, 8 );
final StringBuffer sb = new StringBuffer( 19 );
sb.append( mss.substring( 0, 4 ) );
sb.append( '-' );
sb.append( mss.substring( 4, 8 ) );
sb.append( '-' );
sb.append( lss.substring( 0, 4 ) );
sb.append( '-' );
sb.append( lss.substring( 4, 8 ) );
return sb.toString().toUpperCase();
}
/**
* display a 96 bit serial number in hex in 6 groups of 4 hex digits
*
* @param serno serial number to display, three 32 bit numbers msb in serno[0]
*
* @return hex string equivalent.
*/
private static String display96BitSerialNumber( int[] serno )
{
final StringBuffer sb = new StringBuffer( 30 );
for ( int i = 0; i < 3; i++ )
{
final String hex = ST.toLZHexString( serno[ i ], 8 );
sb.append( hex.substring( 0, 4 ) );
sb.append( '-' );
sb.append( hex.substring( 4, 8 ) );
sb.append( '-' );
}
sb.setLength( 29 );
return sb.toString().toUpperCase();
}
/**
* test harness
*
* @param args not used
*/
public static void main( String[] args )
{
System.loadLibrary( "nativepentium" );
System.out.println( "cpuIdVendor:" + Pentium.cpuIdVendor() );
System.out.println( "cpuIdBrand:" + Pentium.cpuIdBrand() );
System.out.println( "cpuIdStep:" + ST.toLZHexString( Pentium.cpuIdStep(), 2 ) );
System.out.println( "cpuIdModel:" + ST.toLZHexString( Pentium.cpuIdModel(), 2 ) );
System.out.println( "cpuIdFamily:" + ST.toLZHexString( Pentium.cpuIdModel(), 2 ) );
System.out.println( "cpuSerNo64:" + display64BitSerialNumber( Pentium.cpuSerNo64() ) );
final int[] serno = new int[ 3 ];
serno[ 0 ] = Pentium.cpuSerNo96( 0 );
serno[ 1 ] = Pentium.cpuSerNo96( 1 );
serno[ 2 ] = Pentium.cpuSerNo96( 2 );
System.out.println( "cpuSerNo96:" + display96BitSerialNumber( serno ) );
System.out.println( "rdtsc:" + Long.toHexString( Pentium.rdtsc() ) );
}
}