cpuid 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.0
@@ -1,3 +1,5 @@
1
1
  $:.unshift File.expand_path(File.dirname(__FILE__))
2
2
  require 'cpuid/cpuid_ext'
3
- require 'cpuid/cpuid'
3
+ require 'cpuid/cpuid'
4
+ require 'cpuid/features'
5
+ require 'cpuid/processor'
@@ -1,193 +1,20 @@
1
+ require 'cpuid/features'
2
+ require 'cpuid/processor'
3
+
1
4
  ##
2
5
  # = CPUID
3
6
  # Module that accesses CPUID information available on x86 processors.
4
7
  # Currently mostly supports only Intel meanings behind certain values.
5
8
  module CPUID
6
9
  class UnsupportedFunction < StandardError; end
7
- extend self
10
+ include Features
11
+ include Processor
8
12
 
9
- VENDOR_ID_FN = 0
10
- SIGNATURE_FEATURES_FN = 1
11
- SERIAL_NUMBER_FN = 3
12
- MAX_EXT_FN = 0x80000000
13
- EXT_FEATURE_FN = 0x80000001
14
- BRAND_STR_FN_1 = 0x80000002
15
- BRAND_STR_FN_2 = 0x80000003
16
- BRAND_STR_FN_3 = 0x80000004
17
- EXT_L2_FN = 0x80000006
18
- POWER_MANAGEMENT_FN = 0x80000007
19
- ADDRESS_SIZE_FN = 0x80000008
13
+ extend self
20
14
 
21
- INTEL_SYSCALL_CHECK_BIT = 1 << 11
22
- INTEL_XD_CHECK_BIT = 1 << 20
23
- INTEL_64_CHECK_BIT = 1 << 29
24
- INTEL_LAHF_CHECK_BIT = 1
25
- INTEL_TSC_INVARIANCE_CHECK_BIT = 1 << 7
26
- ##
27
- # Returns the model information of the processor, which can be used
28
- # for telling individual processors apart. Note: you will need to use
29
- # cache information as well to tell some processors apart.
30
- #
31
- # @return [Hash] a set of data about the processor. Keys in these results:
32
- # :family => the family number of the processor
33
- # :model => the model number of the processor
34
- # :type => what type of processor it is
35
- # :step => the stepping of the processor
36
- # :model_string => a textual meaning behind the "type" value
37
- def model_information
38
- processor_type = [
39
- "Original OEM Processor",
40
- "Intel OverDrive",
41
- "Dual Processor"
42
- ]
43
-
44
- {:family => family, :model => model, :type => type, :step => stepping, :model_string => processor_type[type]}
45
- end
46
-
47
- ##
48
- # The "stepping" of the processor, in number form. Intel term for differentiating processors.
49
- #
50
- # @return [Fixnum] the stepping of the processor.
51
- def stepping; signature & 0xF; end
52
-
53
- ##
54
- # The "type" of the processor, in number form. Intel term for differentiating processors.
55
- # Possible values:
56
- #
57
- # 0: Original OEM Processor
58
- # 1: Intel OverDrive
59
- # 2: Dual Processor
60
- #
61
- # @return [Fixnum] the stepping of the processor.
62
- def type; (signature >> 12) & 0x3; end
63
-
64
- ##
65
- # The full model number of the intel processor.
66
- #
67
- # @return [Fixnum] the full model number of the processor.
68
- def model
69
- ext_model = ((signature >> 16) & 0xf)
70
- (ext_model << 4) | ((signature >> 3) & 0xf)
71
- end
72
-
73
- ##
74
- # The full family number of the intel processor.
75
- #
76
- # @return [Fixnum] the full family number of the processor.
77
- def family
78
- ext_family = (signature >> 20) & 0xff
79
- (ext_family << 4) | ((signature >> 8) & 0xf)
80
- end
81
-
82
- ##
83
- # Access the serial number of the processor. Will likely fail, because this feature
84
- # was only enabled for the Pentium III line of intel processors and some very
85
- # uncommon other manufacturers.
86
- #
87
- # TODO: raise UnsupportedFunction if PSN is unavailable instead of retrieving PSN = 0
88
- #
89
- # @return [String] the serial number of the processor, in the format
90
- # "XXXX-XXXX-XXXX-XXXX-XXXX-XXXX"
91
- def processor_serial_number
92
- eax, ebx, ecx, edx = run_function(SERIAL_NUMBER_FN)
93
- [signature, edx, ecx].map {|reg| register_to_hex_s(reg)}.join("-")
94
- end
95
-
96
- ##
97
- # Returns the vendor string, available on all processors.
98
- # Examples: "GenuineIntel", "AuthenticAMD"
99
- #
100
- # @return [String] vendor string for the process.
101
- def vendor_string
102
- eax, ebx, ecx, edx = run_function(VENDOR_ID_FN)
103
- register_to_s(ebx) + register_to_s(edx) + register_to_s(ecx)
104
- end
105
-
106
- ##
107
- # Returns the full brand string of the processor
108
- #
109
- # @example
110
- # CPUID.brand_string
111
- # #=> "Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz\000"
112
- # @return [String] the brand string of the processor
113
- def brand_string
114
- [BRAND_STR_FN_1, BRAND_STR_FN_2, BRAND_STR_FN_3].map do |fxn|
115
- reg_array_to_s(run_function(fxn))
116
- end.join
117
- end
118
-
119
- ##
120
- # Returns the number of maximum bits in this processor's virtual address space
121
- def virtual_address_size
122
- (run_function(ADDRESS_SIZE_FN).first >> 8) & 0xFF
123
- end
124
-
125
- ##
126
- # Returns the number of maximum bits this processor can address in physical memory
127
- def physical_address_size
128
- run_function(ADDRESS_SIZE_FN).first & 0xFF
129
- end
130
-
131
- ##
132
- # Returns whether the process supports the SYSCALL and SYSRET instructions.
133
- #
134
- # @return [Boolean]
135
- def has_syscall?
136
- (run_function(EXT_FEATURE_FN)[3] & INTEL_SYSCALL_CHECK_BIT) > 0
137
- end
138
-
139
- ##
140
- # Returns whether the process supports the SYSCALL and SYSRET instructions.
141
- #
142
- # @return [Boolean]
143
- def has_xd_bit?
144
- (run_function(EXT_FEATURE_FN)[3] & INTEL_XD_CHECK_BIT) > 0
145
- end
146
-
147
- ##
148
- # Returns whether the process supports the LAHF and SAHF instructions.
149
- #
150
- # @return [Boolean]
151
- def has_lahf?
152
- (run_function(EXT_FEATURE_FN)[2] & INTEL_LAHF_CHECK_BIT) > 0
153
- end
154
-
155
- ##
156
- # Returns whether the processor supports the x86_64 instruction set.
157
- #
158
- # @return [Boolean] does the processor support x86_64?
159
- def has_x64?
160
- (run_function(EXT_FEATURE_FN)[3] & INTEL_64_CHECK_BIT) > 0
161
- end
162
-
163
- ##
164
- # Returns whether the processor supports TSC invariance.
165
- #
166
- # I honestly don't know what this is, but it's in the intel spec.
167
- def has_tsc_invariance?
168
- (run_function(POWER_MANAGEMENT_FN).last & INTEL_TSC_INVARIANCE_CHECK_BIT) > 0
169
- end
170
-
171
- ##
172
- # Access L2 information via the extended function, 0x80000006.
173
- def easy_L2_info
174
- ecx = run_function(SIGNATURE_FEATURES_FN)[2]
175
- assoc_bits = ((ecx >> 12) & 0xF)
176
- assoc = {}
177
- case assoc_bits
178
- when 0x0
179
- assoc[:disabled] = true
180
- when 0xF
181
- assoc[:fully_associative] = true
182
- else
183
- assoc[:direct_mapped] = true if assoc_bits & 0x1 > 0
184
- assoc[:sixteen_way] = true if assoc_bits & 0x8 > 0
185
- assoc[:eight_way] = true if assoc_bits & 0x6 > 0
186
- assoc[:four_way] = true if assoc_bits & 0x4 > 0
187
- assoc[:two_way] = true if assoc_bits & 0x2 > 0
188
- end
189
- {:line_size => ecx & 0xFF, :cache_size => (ecx >> 16) * 1024, :associativity => assoc}
190
- end
15
+ ###########################################
16
+ # Support functions for the CPUID module. #
17
+ ###########################################
191
18
 
192
19
  #private
193
20
 
@@ -0,0 +1,45 @@
1
+ module CPUID
2
+ module Features
3
+ SIGNATURE_FEATURES_FN = 1
4
+ EXT_FEATURE_FN = 0x80000001
5
+ POWER_MANAGEMENT_FN = 0x80000007
6
+
7
+ INTEL_SYSCALL_CHECK_BIT = 1 << 11
8
+ INTEL_XD_CHECK_BIT = 1 << 20
9
+ INTEL_64_CHECK_BIT = 1 << 29
10
+ INTEL_LAHF_CHECK_BIT = 1
11
+ INTEL_TSC_INVARIANCE_CHECK_BIT = 1 << 7
12
+
13
+ def features
14
+ @features ||= load_features
15
+ end
16
+
17
+ private
18
+
19
+ def load_features
20
+ result = {}
21
+
22
+ ext_features = run_function(EXT_FEATURE_FN)
23
+ result[:syscall] = (ext_features[3] & INTEL_SYSCALL_CHECK_BIT) > 0
24
+ result[:xd_bit] = (ext_features[3] & INTEL_XD_CHECK_BIT) > 0
25
+ result[:lahf] = (ext_features[2] & INTEL_LAHF_CHECK_BIT) > 0
26
+ result[:x64] = (ext_features[3] & INTEL_64_CHECK_BIT) > 0
27
+
28
+ power_features = run_function(POWER_MANAGEMENT_FN)
29
+ result[:tsc_invariance] = (power_features.last & INTEL_TSC_INVARIANCE_CHECK_BIT) > 0
30
+
31
+ result
32
+ end
33
+
34
+ def method_missing(meth, *args, &block)
35
+ if features.include?(meth)
36
+ features[meth]
37
+ elsif meth.to_s[-1,1] == "?" && features.include?(meth.to_s[0..-2].to_sym)
38
+ features[meth.to_s[0..-2].to_sym]
39
+ else
40
+ super(meth, *args, &block)
41
+ end
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,152 @@
1
+ module CPUID
2
+ module Processor
3
+
4
+ VENDOR_ID_FN = 0
5
+ SIGNATURE_FEATURES_FN = 1
6
+ SERIAL_NUMBER_FN = 3
7
+ MAX_EXT_FN = 0x80000000
8
+ BRAND_STR_FN_1 = 0x80000002
9
+ BRAND_STR_FN_2 = 0x80000003
10
+ BRAND_STR_FN_3 = 0x80000004
11
+ EXT_L2_FN = 0x80000006
12
+ ADDRESS_SIZE_FN = 0x80000008
13
+
14
+ ##
15
+ # Returns the model information of the processor, which can be used
16
+ # for telling individual processors apart. Note: you will need to use
17
+ # cache information as well to tell some processors apart.
18
+ #
19
+ # @return [Hash] a set of data about the processor. Keys in these results:
20
+ # :family => the family number of the processor
21
+ # :model => the model number of the processor
22
+ # :type => what type of processor it is
23
+ # :step => the stepping of the processor
24
+ # :model_string => a textual meaning behind the "type" value
25
+ def model_information
26
+ processor_type = [
27
+ "Original OEM Processor",
28
+ "Intel OverDrive",
29
+ "Dual Processor"
30
+ ]
31
+
32
+ {:family => family, :model => model, :type => type, :step => stepping, :model_string => processor_type[type]}
33
+ end
34
+
35
+ ##
36
+ # Is the processor an Intel-made processor?
37
+ def intel?
38
+ vendor_string == "GenuineIntel"
39
+ end
40
+
41
+ ##
42
+ # Is the process an AMD-made processor?
43
+ def amd?
44
+ vendor_string == "AuthenticAMD"
45
+ end
46
+
47
+ ##
48
+ # The "stepping" of the processor, in number form. Intel term for differentiating processors.
49
+ #
50
+ # @return [Fixnum] the stepping of the processor.
51
+ def stepping; signature & 0xF; end
52
+
53
+ ##
54
+ # The "type" of the processor, in number form. Intel term for differentiating processors.
55
+ # Possible values:
56
+ #
57
+ # 0: Original OEM Processor
58
+ # 1: Intel OverDrive
59
+ # 2: Dual Processor
60
+ #
61
+ # @return [Fixnum] the stepping of the processor.
62
+ def type; (signature >> 12) & 0x3; end
63
+
64
+ ##
65
+ # The full model number of the intel processor.
66
+ #
67
+ # @return [Fixnum] the full model number of the processor.
68
+ def model
69
+ ext_model = ((signature >> 16) & 0xf)
70
+ (ext_model << 4) | ((signature >> 3) & 0xf)
71
+ end
72
+
73
+ ##
74
+ # The full family number of the intel processor.
75
+ #
76
+ # @return [Fixnum] the full family number of the processor.
77
+ def family
78
+ ext_family = (signature >> 20) & 0xff
79
+ (ext_family << 4) | ((signature >> 8) & 0xf)
80
+ end
81
+
82
+ ##
83
+ # Access the serial number of the processor. Will likely fail, because this feature
84
+ # was only enabled for the Pentium III line of intel processors and some very
85
+ # uncommon other manufacturers.
86
+ #
87
+ # TODO: raise UnsupportedFunction if PSN is unavailable instead of retrieving PSN = 0
88
+ #
89
+ # @return [String] the serial number of the processor, in the format
90
+ # "XXXX-XXXX-XXXX-XXXX-XXXX-XXXX"
91
+ def processor_serial_number
92
+ eax, ebx, ecx, edx = run_function(SERIAL_NUMBER_FN)
93
+ [signature, edx, ecx].map {|reg| register_to_hex_s(reg)}.join("-")
94
+ end
95
+
96
+ ##
97
+ # Returns the vendor string, available on all processors.
98
+ # Examples: "GenuineIntel", "AuthenticAMD"
99
+ #
100
+ # @return [String] vendor string for the process.
101
+ def vendor_string
102
+ eax, ebx, ecx, edx = run_function(VENDOR_ID_FN)
103
+ register_to_s(ebx) + register_to_s(edx) + register_to_s(ecx)
104
+ end
105
+
106
+ ##
107
+ # Returns the full brand string of the processor
108
+ #
109
+ # @example
110
+ # CPUID.brand_string
111
+ # #=> "Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz\000"
112
+ # @return [String] the brand string of the processor
113
+ def brand_string
114
+ [BRAND_STR_FN_1, BRAND_STR_FN_2, BRAND_STR_FN_3].map do |fxn|
115
+ reg_array_to_s(run_function(fxn))
116
+ end.join
117
+ end
118
+
119
+ ##
120
+ # Returns the number of maximum bits in this processor's virtual address space
121
+ def virtual_address_size
122
+ (run_function(ADDRESS_SIZE_FN).first >> 8) & 0xFF
123
+ end
124
+
125
+ ##
126
+ # Returns the number of maximum bits this processor can address in physical memory
127
+ def physical_address_size
128
+ run_function(ADDRESS_SIZE_FN).first & 0xFF
129
+ end
130
+
131
+ ##
132
+ # Access L2 information via the extended function, 0x80000006.
133
+ def easy_L2_info
134
+ ecx = run_function(SIGNATURE_FEATURES_FN)[2]
135
+ assoc_bits = ((ecx >> 12) & 0xF)
136
+ assoc = {}
137
+ case assoc_bits
138
+ when 0x0
139
+ assoc[:disabled] = true
140
+ when 0xF
141
+ assoc[:fully_associative] = true
142
+ else
143
+ assoc[:direct_mapped] = true if assoc_bits & 0x1 > 0
144
+ assoc[:sixteen_way] = true if assoc_bits & 0x8 > 0
145
+ assoc[:eight_way] = true if assoc_bits & 0x6 > 0
146
+ assoc[:four_way] = true if assoc_bits & 0x4 > 0
147
+ assoc[:two_way] = true if assoc_bits & 0x2 > 0
148
+ end
149
+ {:line_size => ecx & 0xFF, :cache_size => (ecx >> 16) * 1024, :associativity => assoc}
150
+ end
151
+ end
152
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpuid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Edgar
@@ -43,6 +43,8 @@ files:
43
43
  - ext/cpuid/cpuid_ext/extconf.rb
44
44
  - lib/cpuid.rb
45
45
  - lib/cpuid/cpuid.rb
46
+ - lib/cpuid/features.rb
47
+ - lib/cpuid/processor.rb
46
48
  - test/helper.rb
47
49
  - test/test_cpuid.rb
48
50
  has_rdoc: true