cpuid 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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