2024-08-12 10:30:59 +01:00
|
|
|
# typed: true # rubocop:disable Sorbet/StrictSigil
|
2019-04-19 15:38:03 +09:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2020-06-23 14:11:05 +01:00
|
|
|
require "macho"
|
|
|
|
|
2024-09-21 12:24:21 -07:00
|
|
|
module OS
|
|
|
|
module Mac
|
|
|
|
module Hardware
|
|
|
|
module CPU
|
2025-06-21 21:40:57 -04:00
|
|
|
module ClassMethods
|
|
|
|
extend T::Helpers
|
2024-09-21 12:24:21 -07:00
|
|
|
|
2025-06-21 21:40:57 -04:00
|
|
|
# These methods use info spewed out by sysctl.
|
|
|
|
# Look in <mach/machine.h> for decoding info.
|
|
|
|
def type
|
|
|
|
case ::Hardware::CPU.sysctl_int("hw.cputype")
|
|
|
|
when MachO::Headers::CPU_TYPE_I386
|
|
|
|
:intel
|
|
|
|
when MachO::Headers::CPU_TYPE_ARM64
|
|
|
|
:arm
|
|
|
|
else
|
|
|
|
:dunno
|
|
|
|
end
|
2024-09-21 12:24:21 -07:00
|
|
|
end
|
2016-04-25 18:00:01 +01:00
|
|
|
|
2025-06-21 21:40:57 -04:00
|
|
|
def family
|
|
|
|
if ::Hardware::CPU.arm?
|
|
|
|
::Hardware::CPU.arm_family
|
|
|
|
elsif ::Hardware::CPU.intel?
|
|
|
|
::Hardware::CPU.intel_family
|
|
|
|
else
|
|
|
|
:dunno
|
|
|
|
end
|
2024-09-21 12:24:21 -07:00
|
|
|
end
|
2016-04-25 18:00:01 +01:00
|
|
|
|
2025-06-21 21:40:57 -04:00
|
|
|
# True when running under an Intel-based shell via Rosetta 2 on an
|
|
|
|
# Apple Silicon Mac. This can be detected via seeing if there's a
|
|
|
|
# conflict between what `uname` reports and the underlying `sysctl` flags,
|
|
|
|
# since the `sysctl` flags don't change behaviour under Rosetta 2.
|
|
|
|
def in_rosetta2?
|
|
|
|
::Hardware::CPU.sysctl_bool("sysctl.proc_translated")
|
|
|
|
end
|
2020-07-13 11:00:14 -07:00
|
|
|
|
2025-06-21 21:40:57 -04:00
|
|
|
def features
|
|
|
|
@features ||= ::Hardware::CPU.sysctl_n(
|
|
|
|
"machdep.cpu.features",
|
|
|
|
"machdep.cpu.extfeatures",
|
|
|
|
"machdep.cpu.leaf7_features",
|
|
|
|
).split.map { |s| s.downcase.to_sym }
|
|
|
|
end
|
2016-04-25 18:00:01 +01:00
|
|
|
|
2025-06-21 21:40:57 -04:00
|
|
|
def sse4?
|
|
|
|
::Hardware::CPU.sysctl_bool("hw.optional.sse4_1")
|
|
|
|
end
|
2024-09-21 12:24:21 -07:00
|
|
|
end
|
2024-09-22 11:10:40 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-04-07 20:28:56 +01:00
|
|
|
|
2025-06-21 21:40:57 -04:00
|
|
|
Hardware::CPU.singleton_class.prepend(OS::Mac::Hardware::CPU::ClassMethods)
|
2018-04-07 20:28:56 +01:00
|
|
|
|
2024-09-22 11:10:40 -07:00
|
|
|
module Hardware
|
|
|
|
class CPU
|
|
|
|
class << self
|
|
|
|
def extmodel
|
|
|
|
sysctl_int("machdep.cpu.extmodel")
|
|
|
|
end
|
2016-04-25 18:00:01 +01:00
|
|
|
|
2024-09-22 11:10:40 -07:00
|
|
|
def aes?
|
|
|
|
sysctl_bool("hw.optional.aes")
|
|
|
|
end
|
2016-04-25 18:00:01 +01:00
|
|
|
|
2024-09-22 11:10:40 -07:00
|
|
|
def altivec?
|
|
|
|
sysctl_bool("hw.optional.altivec")
|
|
|
|
end
|
2016-04-25 18:00:01 +01:00
|
|
|
|
2024-09-22 11:10:40 -07:00
|
|
|
def avx?
|
|
|
|
sysctl_bool("hw.optional.avx1_0")
|
|
|
|
end
|
2016-04-25 18:00:01 +01:00
|
|
|
|
2024-09-22 11:10:40 -07:00
|
|
|
def avx2?
|
|
|
|
sysctl_bool("hw.optional.avx2_0")
|
|
|
|
end
|
2016-04-25 18:00:01 +01:00
|
|
|
|
2024-09-22 11:10:40 -07:00
|
|
|
def sse3?
|
|
|
|
sysctl_bool("hw.optional.sse3")
|
|
|
|
end
|
2016-04-25 18:00:01 +01:00
|
|
|
|
2024-09-22 11:10:40 -07:00
|
|
|
def ssse3?
|
|
|
|
sysctl_bool("hw.optional.supplementalsse3")
|
|
|
|
end
|
2016-04-25 18:00:01 +01:00
|
|
|
|
2024-09-22 11:10:40 -07:00
|
|
|
def sse4_2?
|
|
|
|
sysctl_bool("hw.optional.sse4_2")
|
|
|
|
end
|
2020-07-13 11:00:14 -07:00
|
|
|
|
2024-09-22 11:10:40 -07:00
|
|
|
# NOTE: This is more reliable than checking `uname`. `sysctl` returns
|
|
|
|
# the right answer even when running in Rosetta 2.
|
|
|
|
def physical_cpu_arm64?
|
|
|
|
sysctl_bool("hw.optional.arm64")
|
|
|
|
end
|
2024-01-18 14:18:46 -08:00
|
|
|
|
2024-09-22 11:10:40 -07:00
|
|
|
def virtualized?
|
|
|
|
sysctl_bool("kern.hv_vmm_present")
|
|
|
|
end
|
2020-11-17 09:34:00 +01:00
|
|
|
|
2024-09-22 11:10:40 -07:00
|
|
|
def arm_family
|
|
|
|
case sysctl_int("hw.cpufamily")
|
|
|
|
when 0x2c91a47e # ARMv8.0-A (Typhoon)
|
|
|
|
:arm_typhoon
|
|
|
|
when 0x92fb37c8 # ARMv8.0-A (Twister)
|
|
|
|
:arm_twister
|
|
|
|
when 0x67ceee93 # ARMv8.1-A (Hurricane, Zephyr)
|
|
|
|
:arm_hurricane_zephyr
|
|
|
|
when 0xe81e7ef6 # ARMv8.2-A (Monsoon, Mistral)
|
|
|
|
:arm_monsoon_mistral
|
|
|
|
when 0x07d34b9f # ARMv8.3-A (Vortex, Tempest)
|
|
|
|
:arm_vortex_tempest
|
|
|
|
when 0x462504d2 # ARMv8.4-A (Lightning, Thunder)
|
|
|
|
:arm_lightning_thunder
|
|
|
|
when 0x573b5eec, 0x1b588bb3 # ARMv8.4-A (Firestorm, Icestorm)
|
|
|
|
:arm_firestorm_icestorm
|
|
|
|
when 0xda33d83d # ARMv8.5-A (Blizzard, Avalanche)
|
|
|
|
:arm_blizzard_avalanche
|
|
|
|
when 0xfa33415e # ARMv8.6-A (M3, Ibiza)
|
|
|
|
:arm_ibiza
|
|
|
|
when 0x5f4dea93 # ARMv8.6-A (M3 Pro, Lobos)
|
|
|
|
:arm_lobos
|
|
|
|
when 0x72015832 # ARMv8.6-A (M3 Max, Palma)
|
|
|
|
:arm_palma
|
2024-11-16 09:28:44 -08:00
|
|
|
when 0x6f5129ac # ARMv9.2-A (M4, Donan)
|
|
|
|
:arm_donan
|
2024-12-06 16:06:09 +08:00
|
|
|
when 0x17d5b93a # ARMv9.2-A (M4 Pro / M4 Max, Brava)
|
|
|
|
:arm_brava
|
2024-09-22 11:10:40 -07:00
|
|
|
else
|
|
|
|
# When adding new ARM CPU families, please also update
|
|
|
|
# test/hardware/cpu_spec.rb to include the new families.
|
|
|
|
:dunno
|
2020-11-17 09:34:00 +01:00
|
|
|
end
|
2024-09-22 11:10:40 -07:00
|
|
|
end
|
2020-11-17 09:34:00 +01:00
|
|
|
|
2024-09-22 11:10:40 -07:00
|
|
|
def intel_family(_family = nil, _cpu_model = nil)
|
|
|
|
case sysctl_int("hw.cpufamily")
|
|
|
|
when 0x73d67300 # Yonah: Core Solo/Duo
|
|
|
|
:core
|
|
|
|
when 0x426f69ef # Merom: Core 2 Duo
|
|
|
|
:core2
|
|
|
|
when 0x78ea4fbc # Penryn
|
|
|
|
:penryn
|
|
|
|
when 0x6b5a4cd2 # Nehalem
|
|
|
|
:nehalem
|
|
|
|
when 0x573b5eec # Westmere
|
|
|
|
:westmere
|
|
|
|
when 0x5490b78c # Sandy Bridge
|
|
|
|
:sandybridge
|
|
|
|
when 0x1f65e835 # Ivy Bridge
|
|
|
|
:ivybridge
|
|
|
|
when 0x10b282dc # Haswell
|
|
|
|
:haswell
|
|
|
|
when 0x582ed09c # Broadwell
|
|
|
|
:broadwell
|
|
|
|
when 0x37fc219f # Skylake
|
|
|
|
:skylake
|
|
|
|
when 0x0f817246 # Kaby Lake
|
|
|
|
:kabylake
|
|
|
|
when 0x38435547 # Ice Lake
|
|
|
|
:icelake
|
|
|
|
when 0x1cf8a03e # Comet Lake
|
|
|
|
:cometlake
|
|
|
|
else
|
|
|
|
:dunno
|
2024-09-21 12:24:21 -07:00
|
|
|
end
|
2024-09-22 11:10:40 -07:00
|
|
|
end
|
2016-04-25 18:00:01 +01:00
|
|
|
|
2024-09-22 11:10:40 -07:00
|
|
|
def sysctl_bool(key)
|
|
|
|
sysctl_int(key) == 1
|
|
|
|
end
|
2016-04-25 18:00:01 +01:00
|
|
|
|
2024-09-22 11:10:40 -07:00
|
|
|
def sysctl_int(key)
|
|
|
|
sysctl_n(key).to_i & 0xffffffff
|
|
|
|
end
|
|
|
|
|
|
|
|
def sysctl_n(*keys)
|
|
|
|
(@properties ||= {}).fetch(keys) do
|
|
|
|
@properties[keys] = Utils.popen_read("/usr/sbin/sysctl", "-n", *keys)
|
2016-04-25 18:00:01 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|