1 ;;;; CPUID handling for X86-based systems
5 (defun u32-to-string (&rest rest)
7 with length = (length rest)
8 with result = (make-string (* 4 length))
13 do (setf (char result (+ i j)) (code-char (ldb (byte 8 (* j 8)) u32))))
14 finally (return result)))
16 (defparameter *cpuid-vendor-ids*
17 '(("AMDisbetter!" :oldamd)
19 ("GenuineIntel" :intel)
21 ("TransmetaCPU" :oldtransmeta)
22 ("GenuineTMx86" :transmeta)
23 ("CyrixInstead" :cyrix)
24 ("CentaurHauls" :centaur)
25 ("NexGenDriven" :nexgen)
29 ("RiseRiseRise" :rise)
31 ("Vortex86 SoC" :vortex)
33 ("Microsoft Hv" :hyperv)
34 ("VMwareVMware" :vmware)
35 ("XenVMMXenVMM" :xen)))
37 (defun %cpuid (eax &optional (ebx 0) (ecx 0) (edx 0))
38 (%cpuid/4 eax ebx ecx edx))
40 (defun cpuid-highest-parameter ()
43 (defun cpuid-highest-extended-parameter ()
44 (values (%cpuid #x80000000)))
46 (defun cpuid-vendor-id ()
47 (multiple-value-bind (eax ebx ecx edx)
49 (let ((decoded (u32-to-string ebx edx ecx)))
50 (values (cadr (assoc decoded *cpuid-vendor-ids* :test #'string=)) decoded eax))))
52 (defparameter *cpuid-feature-flags*
57 :pat :pse36 :psn :clfl
60 :htt :tm1 :ia-64 :pbe)
61 (:sse3 :pclmul :dtes64 :mon
64 :fma :cx16 :etprd :pdcm
65 NIL :pcid :dca :sse4.1
66 :sse4.2 :x2apic :movbe :popcnt
67 :tscd :aes :xsave :osxsave
68 :avx :f16c :rdrand NIL)))
70 (defun decode-cpuid-feature-flags (value flags)
72 (dolist (flag flags result)
73 (when (and flag (logbitp i value))
77 (defun decode-cpuid-processor-info (vendor eax)
78 (let ((stepping (ldb (byte 4 0) eax))
79 (model (ldb (byte 4 4) eax))
80 (family (ldb (byte 4 8) eax))
81 (processor-type (ldb (byte 2 12) eax))
82 (extended-model (ldb (byte 4 16) eax))
83 (extended-family (ldb (byte 4 20) eax)))
86 (+ model (ash extended-model 4))
87 (+ family extended-family)
93 (list stepping model family processor-type)))
97 (defun cpuid-signature (&optional (vendor-id (cpuid-vendor-id)))
98 (when (< (cpuid-highest-parameter) 1)
99 (warn "Processor info feature unsupported by CPU.")
100 (return-from cpuid-signature))
101 (multiple-value-bind (eax ebx ecx edx)
104 (append (decode-cpuid-feature-flags edx (car *cpuid-feature-flags*))
105 (decode-cpuid-feature-flags ecx (cadr *cpuid-feature-flags*)))
106 (decode-cpuid-processor-info vendor-id eax))))
108 (defun cpuid-processor-name ()
109 (when (< (cpuid-highest-extended-parameter) #x80000004)
110 (warn "Processor name feature unsupported by CPU.")
111 (return-from cpuid-processor-name))
114 (multiple-value-call #'u32-to-string
117 (%cpuid #x80000004))))
120 (unless (cpuid-available-p)
121 (warn "CPUID instruction unsupported by CPU.")
124 (:vendor-id (cpuid-vendor-id))
125 (:signature (cpuid-signature))
126 (:processor-name (cpuid-processor-name))))