This class provides low-level access to CPU identification and feature flags. It loads a platform-specific native library (libjcpuid.so / jcpuid.dll) that executes the CPUID assembly instruction and returns register values.
CPUID Register Layout (Leaf 1, EAX)
Bits 31:28 Reserved Bits 27:20 Extended Family ID Bits 19:16 Extended Model ID Bits 15:12 Processor Type (Intel only; AMD reserved) Bits 11:8 Base Family ID Bits 7:4 Base Model ID Bits 3:0 Stepping ID
Family/Model Computation
The actual (displayed) family and model are computed as follows:
- Actual Family = Base Family + Extended Family (only when Base Family == 0xF for Intel; always for AMD)
- Actual Model = Base Model + (Extended Model << 4) (only when Base Family == 0x6 or 0xF for Intel; always for AMD)
AMD Family/Microarchitecture Mapping
| Family (hex) | Microarchitecture | Products |
|---|---|---|
| 15 (0xF) | K8 / Hammer | Athlon 64, Opteron |
| 16 (0x10) | K10 | Phenom, Athlon II |
| 20 (0x14) | Bobcat | Ontario, Zacate |
| 21 (0x15) | Bulldozer family | FX, Opteron |
| 22 (0x16) | Jaguar | Kabini, Temash |
| 23 (0x17) | Zen / Zen+ / Zen 2 | Ryzen 1000-3000, EPYC 7001-7002 |
| 25 (0x19) | Zen 3 / Zen 4 | Ryzen 5000-8000, EPYC 7003-9004 |
| 26 (0x1A) | Zen 5 | Ryzen 9000, EPYC 9005, Ryzen AI 300 |
AMD Family 19h (Zen 3/4) Model Ranges
0x00-0x0F Milan/Chagall (Zen 3) - EPYC 7003, Threadripper 5000 0x10-0x1F Stones/Storm Peak (Zen 4) - EPYC 9004, Threadripper 7000 0x20-0x2F Vermeer (Zen 3) - Ryzen 5000 desktop 0x30-0x3F Badami (Zen 3) - EPYC (internal) 0x40-0x4F Rembrandt (Zen 3+) - Ryzen 6000 mobile 0x50-0x5F Cezanne (Zen 3) - Ryzen 5000 APU 0x60-0x6F Raphael (Zen 4) - Ryzen 7000 desktop (AM5) 0x70-0x77 Phoenix/HawkPoint1 (Zen 4) - Ryzen 7040/8040 APU 0x78-0x7F Phoenix2/HawkPoint2(Zen 4) - Ryzen 8040 APU 0xA0-0xAF Stones-Dense (Zen 4) - EPYC 4004/Siena
AMD Family 1Ah (Zen 5) Model Ranges
Sources: LLVM Host.cpp, Linux kernel amd.c, InstLatx64 CPUID dumps.
0x00-0x0F Breithorn/Turin (Zen 5) - EPYC 9005 server 0x10-0x1F Breithorn-Dense (Zen 5) - EPYC 9005 dense 0x20-0x2F Strix Point (Zen 5) - Ryzen AI 300 mobile 0x30-0x37 Strix Point (2nd) (Zen 5) - Ryzen AI 300 mobile 0x38-0x3F Strix Point (3rd) (Zen 5) - Ryzen AI 300 mobile 0x40-0x4F Granite Ridge (Zen 5) - Ryzen 9000 desktop (AM5) 0x50-0x5F Weisshorn (Zen 6) - NOT Zen 5! 0x60-0x6F Krackan Point (Zen 5) - Ryzen AI 300 mobile 0x70-0x77 Sarlak/Strix Halo (Zen 5) - Ryzen AI Max 300 0xD0-0xD7 Annapurna (Zen 5) - Future EPYC
CPUID Brand String (Most Reliable Identification)
CPUID leaves 0x80000002-0x80000004 return a 48-byte ASCII brand string programmed by AMD/Intel into the CPU. This is the most reliable way to identify a specific CPU model, as model number ranges can overlap across product lines (e.g., model 0x44 is Granite Ridge desktop, not Strix Halo).
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected static classHolds the four 32-bit register values (EAX, EBX, ECX, EDX) returned by a single CPUID instruction call.Field Summary
FieldsModifier and TypeFieldDescriptionprivate static booleanShould basic success and failure info be dumped to stderr during initialization? This would otherwise use the Log component, but this makes it easier for other systems to reuse this class.private static intVersion of the loaded jcpuid library.private static CPUID.CPUIDResultCPUID leaf 1 result cache.private static booleandid we load the native lib correctly?private static final booleanTrue on FreeBSD, not counting kFreeBSD.private static final booleanTrue on kFreeBSD.private static final booleanTrue on Linux.private static final booleanTrue on a Mac.private static final booleanTrue on NetBSD.private static final booleanTrue on OpenBSD.private static final booleanTrue on Solaris.private static final booleanTrue on Windows.private static final booleanTrue on an x86 CPU.private static final StringThe lower case name of the operating system.Constructor Summary
ConstructorsConstructorDescriptionCPUID()Constructs an instance that carries no per-instance state: every detection method here is static and reads process-global CPUID state.Method Summary
Modifier and TypeMethodDescriptionprivate static CPUID.CPUIDResultdoCPUID(int iFunction) Executes a CPUID instruction with the given function number and returns the register values.private static final booleanextractLoadAndCopy(String resourceName) Extract a single resource, copy it to a temp location in the file system, and attempt to load it.private static voidextractReg(int reg, StringBuilder buf) Extracts up to 4 bytes from a CPUID register into a StringBuilder.private static intGet the jcpuid version(package private) static intReturns the Extended Family ID from CPUID leaf 1, EAX bits 27:20.(package private) static intReturns the Extended Model ID from CPUID leaf 1, EAX bits 19:16.(package private) static intReturns the Base Family ID from CPUID leaf 1, EAX bits 11:8.(package private) static intReturns the Base Model ID from CPUID leaf 1, EAX bits 7:4.(package private) static StringReturns the CPU brand string from CPUID extended leaves 0x80000002-0x80000004.(package private) static intReturns the Stepping ID from CPUID leaf 1, EAX bits 3:0.(package private) static intReturns the Type field from CPUID leaf 1, EAX bits 15:12.(package private) static StringReturns the 12-byte CPU vendor ID string from CPUID leaf 0.(package private) static intReturn the ECX feature flags(package private) static intReturn the EDX feature flags(package private) static intReturn the EBX feature flags from CPUID leaf 7.(package private) static intReturn the extended ECX feature flags(package private) static intThere's almost nothing in here.(package private) static intReturn the extended EDX feature flags from CPUID leaf 0x80000001.static CPUInfogetInfo()Return aCPUInfoinstance for the current CPU.static intReturn the jcpuid versionprivate static CPUID.CPUIDResultgetLeaf1()Returns cached CPUID leaf 1 result, performing the native call only once.private static final String64-bit only, jcpuid is not built for 32-bit platformsprivate static final StringFile name prefix of the native library for this OS.private static final StringFile name suffix of the native library for this OS.private static final StringResource name of the cpuid native library.private static final booleanCheck all of the jars in the classpath for the jcpuid dll/so.private static final booleanTry loading it from an explicitly built jcpuid.dll / libjcpuid.soprivate static final voidDo whatever we can to load up the native library.static voidPrint the detected CPU details to stdout, for scripts and diagnostics.private static intGet the jbigi version, only available since jbigi version 3 Caller must catch Throwable
Field Details
_nativeOk
private static boolean _nativeOkdid we load the native lib correctly?_jcpuidVersion
private static int _jcpuidVersionVersion of the loaded jcpuid library._doLog
private static boolean _doLogShould basic success and failure info be dumped to stderr during initialization? This would otherwise use the Log component, but this makes it easier for other systems to reuse this class. Well, we really want to use Log so if you are one of those "other systems" then comment out the I2PAppContext usage below. Set to false if not in router context, so scripts using TrustedUpdate don't spew log messages.main(String[])below overrides to true.isX86
private static final boolean isX86True on an x86 CPU.isWindows
private static final boolean isWindowsTrue on Windows.OS_NAME
The lower case name of the operating system.isLinux
private static final boolean isLinuxTrue on Linux.isKFreebsd
private static final boolean isKFreebsdTrue on kFreeBSD.isFreebsd
private static final boolean isFreebsdTrue on FreeBSD, not counting kFreeBSD.isNetbsd
private static final boolean isNetbsdTrue on NetBSD.isOpenbsd
private static final boolean isOpenbsdTrue on OpenBSD.isSunos
private static final boolean isSunosTrue on Solaris.isMac
private static final boolean isMacTrue on a Mac._leaf1Cache
CPUID leaf 1 result cache. CPUID leaf 1 (function 0x01) returns processor version information (family, model, stepping) and feature bits (SSE, AVX, etc.). This is called by nearly every method in this class, so caching eliminates ~8 redundant native JNI round-trips per CPU detection cycle.
Constructor Details
CPUID
public CPUID()Constructs an instance that carries no per-instance state: every detection method here is static and reads process-global CPUID state.
Method Details
doCPUID
Executes a CPUID instruction with the given function number and returns the register values.Common CPUID functions:
- 0x00 - Highest basic function, vendor ID string
- 0x01 - Family/model/stepping, feature flags (SSE, AVX, etc.)
- 0x07 - Extended feature flags (AVX2, AVX-512, SHA, etc.)
- 0x80000000 - Highest extended function
- 0x80000001 - Extended feature flags (LZCNT, SSE4A, etc.)
- 0x80000002-4 - CPU brand string (48 bytes ASCII)
- 0x80000008 - Virtual/physical address sizes
- Parameters:
iFunction- The CPUID function number (EAX value)- Returns:
- Register values after execution
- Throws:
UnsatisfiedLinkError- if native library not loaded
nativeJcpuidVersion
private static int nativeJcpuidVersion()Get the jbigi version, only available since jbigi version 3 Caller must catch Throwable- Returns:
- the version reported by the native jcpuid code
fetchJcpuidVersion
private static int fetchJcpuidVersion()Get the jcpuid version- Returns:
- 0 if no jcpuid available, 2 if version not supported
getJcpuidVersion
public static int getJcpuidVersion()Return the jcpuid version- Returns:
- 0 if no jcpuid available, 2 if version not supported
getLeaf1
Returns cached CPUID leaf 1 result, performing the native call only once.- Returns:
- the cached leaf 1 result
getCPUVendorID
Returns the 12-byte CPU vendor ID string from CPUID leaf 0. The string is constructed from EBX:EDX:ECX (in that order).Known vendor strings:
"AuthenticAMD"- AMD"GenuineIntel"- Intel"CentaurHauls"- VIA/Centaur"HygonGenuine"- Hygon (AMD-based Chinese JV)
- Returns:
- 12-character vendor string, or empty string if native library not loaded
getCPUFamily
static int getCPUFamily()Returns the Base Family ID from CPUID leaf 1, EAX bits 11:8.WARNING: This is the raw Base Family, NOT the computed family. For AMD CPUs with Base Family == 0xF (15), you must add
getCPUExtendedFamily()to get the actual family. For other AMD families (17h, 19h, 1Ah), the extended family is always added to the base family to form the actual family.- Returns:
- Base Family ID (0-15)
- See Also:
getCPUModel
static int getCPUModel()Returns the Base Model ID from CPUID leaf 1, EAX bits 7:4.WARNING: This is the raw Base Model, NOT the computed model. For CPUs with Base Family == 0x6 or 0xF, you must add
getCPUExtendedModel()<< 4 to get the actual model. For AMD CPUs, the extended model is always applied when computing the actual model.- Returns:
- Base Model ID (0-15)
- See Also:
getCPUExtendedModel
static int getCPUExtendedModel()Returns the Extended Model ID from CPUID leaf 1, EAX bits 19:16.To compute the actual model for CPUs where Base Family is 6 or 0xF:
actualModel = baseModel + (extendedModel << 4)
For AMD CPUs, this is always added to the base model.
- Returns:
- Extended Model ID (0-15)
getCPUType
static int getCPUType()Returns the Type field from CPUID leaf 1, EAX bits 15:12.- Returns:
- the Type field, 0 through 15
getCPUExtendedFamily
static int getCPUExtendedFamily()Returns the Extended Family ID from CPUID leaf 1, EAX bits 27:20.To compute the actual family when Base Family == 0xF:
actualFamily = baseFamily + extendedFamily
For AMD CPUs, this is always added to the base family.
- Returns:
- Extended Family ID (0-255)
getCPUStepping
static int getCPUStepping()Returns the Stepping ID from CPUID leaf 1, EAX bits 3:0.- Returns:
- the Stepping ID, 0 through 15
getEDXCPUFlags
static int getEDXCPUFlags()Return the EDX feature flags- Returns:
- the raw 32 bit feature flags from CPUID leaf 1, EDX
getECXCPUFlags
static int getECXCPUFlags()Return the ECX feature flags- Returns:
- the raw 32 bit feature flags from CPUID leaf 1, ECX
getExtendedECXCPUFlags
static int getExtendedECXCPUFlags()Return the extended ECX feature flags- Returns:
- the raw 32 bit feature flags from CPUID leaf 0x80000001, ECX
getExtendedEDXCPUFlags
static int getExtendedEDXCPUFlags()Return the extended EDX feature flags from CPUID leaf 0x80000001.- Returns:
- the raw 32 bit feature flags from CPUID leaf 0x80000001, EDX
getExtendedEBXFeatureFlags
static int getExtendedEBXFeatureFlags()Return the EBX feature flags from CPUID leaf 7.- Returns:
- the raw 32 bit feature flags from CPUID leaf 7, EBX
getExtendedECXFeatureFlags
static int getExtendedECXFeatureFlags()There's almost nothing in here.- Returns:
- the raw 32 bit feature flags from CPUID leaf 7, ECX
getCPUModelName
Returns the CPU brand string from CPUID extended leaves 0x80000002-0x80000004.This is the most reliable way to identify a specific CPU model. The brand string is a 48-byte ASCII string programmed by AMD/Intel into the CPU. Examples:
"AMD Ryzen 9 9900X 12-Core Processor""Intel(R) Core(TM) i9-14900K""AMD EPYC 9754 128-Core Processor"
IMPORTANT: This is preferred over model-based identification. AMD model number ranges overlap across product lines (e.g., model 0x44 is Granite Ridge desktop, but model ranges can be ambiguous). The brand string is always correct when available.
- Returns:
- CPU brand string, or null if unsupported or native library not loaded
extractReg
Extracts up to 4 bytes from a CPUID register into a StringBuilder. Stops at the first null byte (CPUID strings are null-terminated).- Parameters:
reg- 32-bit register value (little-endian byte order)buf- the buffer the four decoded characters are appended to
getInfo
Return aCPUInfoinstance for the current CPU.Detects the CPU vendor via CPUID leaf 0, then returns the appropriate implementation:
"AuthenticAMD"/"HygonGenuine"→AMDInfoImpl"GenuineIntel"→IntelInfoImpl"CentaurHauls"→VIAInfoImpl
- Returns:
- CPUInfo for the detected CPU type
- Throws:
UnknownCPUException- if native library not loaded, not x86, or unknown vendor
main
Print the detected CPU details to stdout, for scripts and diagnostics.- Parameters:
args- currently unused; the CPU details come from the native library
loadNative
private static final void loadNative()Do whatever we can to load up the native library. If it can find a custom built jcpuid.dll / libjcpuid.so, it'll use that. Otherwise it'll try to look in the classpath for the correct library (see loadFromResource). If the user specifies -Djcpuid.enable=false it'll skip all of this.
loadGeneric
private static final boolean loadGeneric()Try loading it from an explicitly built jcpuid.dll / libjcpuid.so
The file name must be (e.g. on linux) libjcpuid-x86_64-linux.so.- Returns:
- true if it was loaded successfully, else false
loadFromResource
private static final boolean loadFromResource()Check all of the jars in the classpath for the jcpuid dll/so. This file should be stored in the resource in the same package as this class.
This is a pretty ugly hack, using the general technique illustrated by the onion FEC libraries. It works by pulling the resource, writing out the byte stream to a temporary file, loading the native library from that file. We then attempt to copy the file from the temporary dir to the base install dir, so we don't have to do this next time - but we don't complain if it fails, so we transparently support read-only base dirs.
Only 64-bit jcpuid libraries are shipped.- Returns:
- true if it was loaded successfully, else false
extractLoadAndCopy
Extract a single resource, copy it to a temp location in the file system, and attempt to load it. If the load succeeds, copy it to the installation directory. Return value reflects only load success - copy will fail silently.- Parameters:
resourceName- the classpath resource holding the native library to extract, load and copy- Returns:
- true if it was loaded successfully, else false.
getResourceName
Resource name of the cpuid native library.- Returns:
- non-null
getLibraryPrefix
File name prefix of the native library for this OS.- Returns:
- the prefix, empty if none
getLibraryMiddlePart
64-bit only, jcpuid is not built for 32-bit platforms- Returns:
- the platform-specific library name, e.g. jcpuid-x86_64-linux
getLibrarySuffix
File name suffix of the native library for this OS.- Returns:
- the suffix, empty if none