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 (defun cpuid-vendor-id ()
32 (multiple-value-bind (eax ebx ecx edx)
34 (let ((decoded (u32-to-string ebx edx ecx)))
35 (values eax (cadr (assoc decoded *cpuid-vendor-ids* :test #'string=)) decoded))))
37 (defparameter *cpuid-feature-flags*
38 '((:sse3 :pclmul :dtes64 :mon
41 :fma :cx16 :etprd :pdcm
42 NIL :pcid :dca :sse4.1
43 sse4.2 :x2apic :movbe :popcnt
44 :tscd :aes :xsave :osxsave
45 :avx :f16c :rdrand NIL)
50 :pat :pse36 :psn :clfl
53 :htt :tm1 :ia-64 :pbe)))
55 (defun decode-cpuid-feature-flags (value flags)
57 (dolist (flag flags result)
58 (when (and flag (logbitp i value))
62 (defun cpuid-signature ()
63 (multiple-value-bind (eax ebx ecx edx)
67 ;; (ldb (byte 4 0) eax) ; stepping
68 ;; (ldb (byte 4 4) eax) ; model
69 ;; (ldb (byte 4 8) eax) ; family
70 (append (decode-cpuid-feature-flags ecx (car *cpuid-feature-flags*))
71 (decode-cpuid-feature-flags edx (cadr *cpuid-feature-flags*)))
74 (defun cpuid-processor-name ()
75 (string-trim '(#\Space #\0)
78 (multiple-value-call #'u32-to-string (%cpuid/4 #x80000002 0 0 0))
79 (multiple-value-call #'u32-to-string (%cpuid/4 #x80000003 0 0 0))
80 (multiple-value-call #'u32-to-string (%cpuid/4 #x80000004 0 0 0)))))
84 (:vendor-id (cpuid-vendor-id))
85 (:signature (cpuid-signature))
86 (:processor-name (cpuid-processor-name))))